diff --git a/.changeset/beige-eagles-cheat.md b/.changeset/beige-eagles-cheat.md deleted file mode 100644 index 5b5081d2ee..0000000000 --- a/.changeset/beige-eagles-cheat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli-node': patch ---- - -Updated doc link. diff --git a/.changeset/blue-hairs-marry.md b/.changeset/blue-hairs-marry.md deleted file mode 100644 index 2ca1a3d47e..0000000000 --- a/.changeset/blue-hairs-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli-node': patch ---- - -Added new plugin metadata fields to `BackstagePackageJson` type. diff --git a/.changeset/brave-apples-move.md b/.changeset/brave-apples-move.md deleted file mode 100644 index 7a1fa86a56..0000000000 --- a/.changeset/brave-apples-move.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Fixed a potential crash when passing an object with a `null` prototype as log meta. diff --git a/.changeset/breezy-badgers-train.md b/.changeset/breezy-badgers-train.md deleted file mode 100644 index 8f747b8602..0000000000 --- a/.changeset/breezy-badgers-train.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli-node': patch ---- - -Upgraded @yarnpkg/parsers to stable 3.0 diff --git a/.changeset/breezy-planets-sparkle.md b/.changeset/breezy-planets-sparkle.md deleted file mode 100644 index eea9e5c6bf..0000000000 --- a/.changeset/breezy-planets-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-onelogin-provider': minor ---- - -Separate out the OneLogin provider into its own module diff --git a/.changeset/bright-panthers-leave.md b/.changeset/bright-panthers-leave.md new file mode 100644 index 0000000000..35d9c0f869 --- /dev/null +++ b/.changeset/bright-panthers-leave.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-plugin-api': patch +'@backstage/backend-defaults': patch +--- + +Added a new Root Health Service which adds new endpoints for health checks. diff --git a/.changeset/brown-bananas-talk.md b/.changeset/brown-bananas-talk.md deleted file mode 100644 index 71020b787a..0000000000 --- a/.changeset/brown-bananas-talk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Having tooltip inherit font size for consistency in catalog table columns diff --git a/.changeset/calm-cars-serve.md b/.changeset/calm-cars-serve.md deleted file mode 100644 index 5df2a18cd4..0000000000 --- a/.changeset/calm-cars-serve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-tasks': patch ---- - -Marked all exports as deprecated and pointed at `@backstage/backend-plugin-api` and `@backstage/backend-defaults` diff --git a/.changeset/calm-files-sort.md b/.changeset/calm-files-sort.md deleted file mode 100644 index a487c00eb4..0000000000 --- a/.changeset/calm-files-sort.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch ---- - -In tests, return `null` rather than throwing an error when trying to get the `ExtensionPoint.T` property, so that tests asserting the property are not easily broken. diff --git a/.changeset/calm-jeans-ring.md b/.changeset/calm-jeans-ring.md new file mode 100644 index 0000000000..3d1efcf7bd --- /dev/null +++ b/.changeset/calm-jeans-ring.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Use virtualization with `EntityPicker` as done earlier with `MultiEntityPicker` to fix performance issues with large data sets. `VirtualizedListbox` extracted into reusable component. diff --git a/.changeset/calm-plums-wink.md b/.changeset/calm-plums-wink.md deleted file mode 100644 index edb991f616..0000000000 --- a/.changeset/calm-plums-wink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -mkdocs-material have updated their CSS variable template, and a few are unset in Backstage. This patch adds the missing variables to ensure coverage. diff --git a/.changeset/chilled-planes-sniff.md b/.changeset/chilled-planes-sniff.md deleted file mode 100644 index e4084ea561..0000000000 --- a/.changeset/chilled-planes-sniff.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -The `registerComponent` external route will now by default bind to the catalog import page if it is available. diff --git a/.changeset/chilled-suns-camp.md b/.changeset/chilled-suns-camp.md deleted file mode 100644 index 1ab603abfa..0000000000 --- a/.changeset/chilled-suns-camp.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Removed accents on deprecation note diff --git a/.changeset/chilly-roses-trade.md b/.changeset/chilly-roses-trade.md new file mode 100644 index 0000000000..73fc3ff766 --- /dev/null +++ b/.changeset/chilly-roses-trade.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Deprecate legacy status check factory, handler and types. diff --git a/.changeset/clever-kids-return.md b/.changeset/clever-kids-return.md deleted file mode 100644 index a6cab79f2b..0000000000 --- a/.changeset/clever-kids-return.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@backstage/plugin-auth-node': patch ---- - -Updated scope management for OAuth providers, where the `createOAuthAuthenticator` now accepts a new collection of `scopes` options: - -- `scopes.persist` - Whether scopes should be persisted, replaces the `shouldPersistScopes` option. -- `scopes.required` - A list of required scopes that will always be requested. -- `scopes.transform` - A function that can be used to transform the scopes before they are requested. - -The `createOAuthProviderFactory` has also received a new `additionalScopes` option, and will also read `additionalScopes` from the auth provider configuration. Both of these can be used to add additional scopes that should always be requested. - -A significant change under the hood that this new scope management brings is that providers that persist scopes will now always merge the already granted scopes with the requested ones. The previous behavior was that the full authorization flow would not include existing scopes, while the refresh flow would only include the existing scopes. diff --git a/.changeset/clever-radios-yawn.md b/.changeset/clever-radios-yawn.md deleted file mode 100644 index e5600183f5..0000000000 --- a/.changeset/clever-radios-yawn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Make sure that the toggle button state is properly reflected in API cards diff --git a/.changeset/clever-waves-judge.md b/.changeset/clever-waves-judge.md new file mode 100644 index 0000000000..585ad01bbe --- /dev/null +++ b/.changeset/clever-waves-judge.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-techdocs-react': patch +'@backstage/plugin-techdocs': patch +--- + +Fixed a bug with the TechDocsReaderPageProvider not re-rendering when setShadowDom is called, meaning that the useShadowDom hooks were inconsistent. This issue caused the TextSize addon changes not to reapply during navigation. diff --git a/.changeset/cold-seas-end.md b/.changeset/cold-seas-end.md deleted file mode 100644 index 96fa048fbd..0000000000 --- a/.changeset/cold-seas-end.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Updated configuration schema to include the `useRedisSets` cache config option. diff --git a/.changeset/create-app-1716903719.md b/.changeset/create-app-1716903719.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1716903719.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/create-app-1716302437.md b/.changeset/create-app-1719320674.md similarity index 100% rename from .changeset/create-app-1716302437.md rename to .changeset/create-app-1719320674.md diff --git a/.changeset/cuddly-jobs-kick.md b/.changeset/cuddly-jobs-kick.md deleted file mode 100644 index aa62efb88b..0000000000 --- a/.changeset/cuddly-jobs-kick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-compat-api': patch ---- - -Add support for forwarding default target from legacy external route refs. diff --git a/.changeset/curvy-teachers-smell.md b/.changeset/curvy-teachers-smell.md new file mode 100644 index 0000000000..3f032f2177 --- /dev/null +++ b/.changeset/curvy-teachers-smell.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-catalog-backend-module-ldap': patch +'@backstage/backend-plugin-api': patch +'@backstage/backend-defaults': patch +'@backstage/backend-tasks': patch +--- + +Fix bug where ISO durations could no longer be used for schedules diff --git a/.changeset/cyan-jobs-visit.md b/.changeset/cyan-jobs-visit.md deleted file mode 100644 index ccc8c90adf..0000000000 --- a/.changeset/cyan-jobs-visit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': minor ---- - -Added `TestCaches` that functions just like `TestDatabases` diff --git a/.changeset/cyan-paws-beg.md b/.changeset/cyan-paws-beg.md deleted file mode 100644 index 87c2b746a4..0000000000 --- a/.changeset/cyan-paws-beg.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': patch ---- - -Added handling for dry run to githubPullRequest and githubWebhook and added tests for this functionality diff --git a/.changeset/cyan-snails-peel.md b/.changeset/cyan-snails-peel.md deleted file mode 100644 index 4da79258fb..0000000000 --- a/.changeset/cyan-snails-peel.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/plugin-user-settings-backend': patch -'@backstage/plugin-devtools-backend': patch -'@backstage/plugin-techdocs-backend': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-search-backend': patch -'@backstage/plugin-proxy-backend': patch -'@backstage/plugin-auth-backend': patch -'@backstage/plugin-app-backend': patch ---- - -Updated local development setup. diff --git a/.changeset/dull-moose-cough.md b/.changeset/dull-moose-cough.md deleted file mode 100644 index 4de43fb35f..0000000000 --- a/.changeset/dull-moose-cough.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/integration': patch ---- - -Updated function for getHarnessEditContentsUrl diff --git a/.changeset/early-eggs-press.md b/.changeset/early-eggs-press.md deleted file mode 100644 index ff6658f7ca..0000000000 --- a/.changeset/early-eggs-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -The `TokenManager` has been deprecated in preparation for the [stable release of the New Backend System](https://github.com/backstage/backstage/issues/24493). Please [migrate](https://backstage.io/docs/tutorials/auth-service-migration) to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. diff --git a/.changeset/eighty-games-wink.md b/.changeset/eighty-games-wink.md new file mode 100644 index 0000000000..e87dc56b5f --- /dev/null +++ b/.changeset/eighty-games-wink.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Fixed bug where `` component with empty string as placeholder gave an error +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/version-bridge@1.0.8 + +## @backstage/create-app@0.5.17-next.0 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/dev-utils@1.0.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/app-defaults@1.5.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/theme@0.5.6 + +## @backstage/frontend-app-api@0.7.2-next.0 + +### Patch Changes + +- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. + + ```yaml + app: + routes: + bindings: + # This has the effect of removing the button for registering new + # catalog entities in the scaffolder template list view + scaffolder.registerComponent: false + ``` + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-plugin-api@0.6.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-test-utils@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.7.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/test-utils@1.5.7-next.0 + - @backstage/types@1.1.1 + +## @backstage/integration-react@1.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.13.0-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + +## @backstage/repo-tools@0.9.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + +## @techdocs/cli@1.8.15-next.0 + +### Patch Changes + +- c964a3d: Import discovery from backend-defaults instead of backend-common +- Updated dependencies + - @backstage/backend-defaults@0.3.3-next.0 + - @backstage/plugin-techdocs-node@1.12.7-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## @backstage/test-utils@1.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-react@0.4.23 + +## @backstage/plugin-api-docs@0.11.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-catalog@1.21.1-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + +## @backstage/plugin-app-backend@0.3.70-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-app-node@0.1.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-app-node@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/config-loader@1.8.1 + +## @backstage/plugin-app-visualizer@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-auth-backend@0.22.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.2.2-next.0 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.13-next.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.4-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.4-next.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.4-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.16-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.18-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.18-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.1.18-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.16-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.2.2-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.14-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.2.2-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.0.14-next.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.1.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-backend@0.22.8-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-backend@0.22.8-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/catalog-model@1.5.0 + +## @backstage/plugin-auth-node@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-bitbucket-cloud-common@0.2.21-next.0 + +### Patch Changes + +- b5deed0: Add support for `autocomplete` handler to provide autocomplete options for `RepoUrlPicker` +- Updated dependencies + - @backstage/integration@1.13.0-next.0 + +## @backstage/plugin-catalog@1.21.1-next.0 + +### Patch Changes + +- d133eaa: Added small notes to AboutCard to discourage customizability PRs +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-scaffolder-common@1.5.3 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-catalog-backend@1.23.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/backend-openapi-utils@0.1.14-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.27-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-catalog-backend-module-aws@0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-catalog-backend-module-azure@0.1.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/backend-openapi-utils@0.1.14-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.21-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-gcp@0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-github@0.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-backend@1.23.2-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-catalog-backend-module-github-org@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-backend-module-github@0.6.4-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.3.20-next.0 + +### Patch Changes + +- 8db30ad: The Gitlab configuration supports an additional optional boolean key `catalog.providers.gitlab..restrictUsersToGroup`. Setting this to `true` will make Backstage only import users from the group defined in the `group` key, instead of all users in the organisation (self-hosted) or of the root group (SaaS). It will default to false, keeping the original implementation intact, when not explicitly set. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.3.20-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.4.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-backend@1.23.2-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-catalog-backend-module-ldap@0.6.2-next.0 + +### Patch Changes + +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-catalog-backend-module-logs@0.0.1-next.0 + +### Patch Changes + +- 97caf55: Creates a new module to make logging catalog errors simple. This module subscribes to catalog events and logs them. + + See [Backstage documentation](https://backstage.io/docs/features/software-catalog/configuration#subscribing-to-catalog-errors) for details on how to install + and configure the plugin. + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-catalog-backend@1.23.2-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-backend@1.23.2-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.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.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-scaffolder-common@1.5.3 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.2 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-catalog-graph@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-catalog-node@1.12.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-catalog-react@1.12.2-next.0 + +### Patch Changes + +- 2030962: Make EntityOwnerPicker display metadata.title or spec.profile.displayName for mode=only-owners instead of metadata.name +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-permission-react@0.4.23 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-config-schema@0.1.57-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.10 + - @backstage/plugin-permission-react@0.4.23 + +## @backstage/plugin-devtools-backend@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.10 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-events-backend@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + +## @backstage/plugin-events-backend-module-github@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-test-utils@0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.3.7-next.0 + +## @backstage/plugin-events-node@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + +## @backstage/plugin-home@0.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/plugin-home-react@0.1.15-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.6 + +## @backstage/plugin-home-react@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-kubernetes@0.11.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-kubernetes-react@0.4.1-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-kubernetes-backend@0.18.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-kubernetes-node@0.1.15-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.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-kubernetes-common@0.8.0 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-kubernetes-cluster@0.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-kubernetes-react@0.4.1-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-kubernetes-node@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-kubernetes-react@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.0 + +## @backstage/plugin-notifications@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.4 + - @backstage/plugin-signals-react@0.0.4 + +## @backstage/plugin-notifications-backend@0.3.2-next.0 + +### Patch Changes + +- d7b8ca5: Added an option to filter notifications by topic +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/plugin-notifications-node@0.2.2-next.0 + - @backstage/plugin-signals-node@0.1.7-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.4 + +## @backstage/plugin-notifications-backend-module-email@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-notifications-node@0.2.2-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.4 + +## @backstage/plugin-notifications-node@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-signals-node@0.1.7-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-notifications-common@0.0.4 + +## @backstage/plugin-org@0.6.27-next.0 + +### Patch Changes + +- c307ef4: Added `relationType` property to EntityMembersListCard component that allows for display users related to a group via some other relationship aside from `memberOf`. + + Also, as a side effect, the `relationsType` property has been deprecated in favor of a more accurately named `relationAggregation` property. + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-catalog-common@1.0.24 + +## @backstage/plugin-org-react@0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + +## @backstage/plugin-permission-backend@0.5.45-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-permission-node@0.7.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-proxy-backend@0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.1.13-next.0 + +### Patch Changes + +- 661b354: Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.11-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.1.11-next.0 + +### Patch Changes + +- b5deed0: Add support for `autocomplete` handler to provide autocomplete options for `RepoUrlPicker` +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.21-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.1.11-next.0 + +### Patch Changes + +- 6a4ad4e: Instead of using hardcoded `targetBranch` now fetch the default branch from Bitbucket repository. + This prevents from errors when no `targetBranch` is provided and the default repository branch is different from `master`, for example: `main`. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.45-next.0 + +### Patch Changes + +- 0ac124b: Updated configuration instructions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.4.3-next.0 + +### Patch Changes + +- 0ac124b: Updated configuration instructions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/plugin-notifications-node@0.2.2-next.0 + - @backstage/plugin-notifications-common@0.0.4 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.38-next.0 + +### Patch Changes + +- 0ac124b: Updated configuration instructions +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.1.8-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node@0.4.7-next.0 + +### Patch Changes + +- 661b354: Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` +- b5deed0: Add support for `autocomplete` extension point to provide additional `autocomplete` handlers +- 0b52438: Serialization of the scaffolder workspace into GCP bucket +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.3 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/backend-test-utils@0.4.3-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-search@1.4.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend@1.5.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-defaults@0.3.3-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-openapi-utils@0.1.14-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-catalog@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-explore@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-pg@0.5.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-app-api@0.7.9-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-module-techdocs@0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/plugin-techdocs-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-backend-node@1.2.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-search-react@1.7.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-signals@0.0.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + +## @backstage/plugin-signals-backend@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/plugin-signals-node@0.1.7-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-techdocs@1.10.7-next.0 + +### Patch Changes + +- 8ac9ce5: Fixed a bug with the TechDocsReaderPageProvider not re-rendering when setShadowDom is called, meaning that the useShadowDom hooks were inconsistent. This issue caused the TextSize addon changes not to reapply during navigation. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/plugin-techdocs@1.10.7-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-catalog@1.21.1-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/test-utils@1.5.7-next.0 + +## @backstage/plugin-techdocs-backend@1.10.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.26-next.0 + - @backstage/plugin-techdocs-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-techdocs-node@1.12.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.12 + +## @backstage/plugin-techdocs-react@1.2.6-next.0 + +### Patch Changes + +- 8ac9ce5: Fixed a bug with the TechDocsReaderPageProvider not re-rendering when setShadowDom is called, meaning that the useShadowDom hooks were inconsistent. This issue caused the TextSize addon changes not to reapply during navigation. +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-user-settings@0.8.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-signals-node@0.1.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.99-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.22.0-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/plugin-techdocs@1.10.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/frontend-app-api@0.7.2-next.0 + - @backstage/cli@0.26.10-next.0 + - @backstage/plugin-org@0.6.27-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-catalog@1.21.1-next.0 + - @backstage/plugin-scaffolder-react@1.10.0-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.0 + - @backstage/app-defaults@1.5.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-api-docs@0.11.7-next.0 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-catalog-graph@0.4.7-next.0 + - @backstage/plugin-catalog-import@0.12.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.0 + - @backstage/plugin-devtools@0.1.16-next.0 + - @backstage/plugin-home@0.7.6-next.0 + - @backstage/plugin-kubernetes@0.11.12-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.0 + - @backstage/plugin-notifications@0.2.3-next.0 + - @backstage/plugin-search@1.4.13-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/plugin-signals@0.0.8-next.0 + - @backstage/plugin-user-settings@0.8.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-search-common@1.2.12 + +## example-app-next@0.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.22.0-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/plugin-techdocs@1.10.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/frontend-app-api@0.7.2-next.0 + - @backstage/cli@0.26.10-next.0 + - @backstage/plugin-org@0.6.27-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-catalog@1.21.1-next.0 + - @backstage/plugin-scaffolder-react@1.10.0-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.0 + - @backstage/app-defaults@1.5.7-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-api-docs@0.11.7-next.0 + - @backstage/plugin-app-visualizer@0.1.8-next.0 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-catalog-graph@0.4.7-next.0 + - @backstage/plugin-catalog-import@0.12.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.0 + - @backstage/plugin-home@0.7.6-next.0 + - @backstage/plugin-kubernetes@0.11.12-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.0 + - @backstage/plugin-notifications@0.2.3-next.0 + - @backstage/plugin-search@1.4.13-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/plugin-signals@0.0.8-next.0 + - @backstage/plugin-user-settings@0.8.8-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-search-common@1.2.12 + +## app-next-example-plugin@0.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + +## example-backend@0.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-defaults@0.3.3-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-scaffolder-backend@1.23.0-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.4.0-next.0 + - @backstage/plugin-notifications-backend@0.3.2-next.0 + - @backstage/plugin-app-backend@0.3.70-next.0 + - @backstage/plugin-auth-backend@0.22.8-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.18-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.7-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-catalog-backend@1.23.2-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.4-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.1.39-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.19-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.8-next.0 + - @backstage/plugin-devtools-backend@0.3.7-next.0 + - @backstage/plugin-kubernetes-backend@0.18.2-next.0 + - @backstage/plugin-permission-backend@0.5.45-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.18-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/plugin-proxy-backend@0.5.2-next.0 + - @backstage/plugin-search-backend@1.5.13-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.27-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.27-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.26-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/plugin-signals-backend@0.1.7-next.0 + - @backstage/plugin-techdocs-backend@1.10.8-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-permission-common@0.7.14 + +## example-backend-legacy@0.2.100-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.3-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.38-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-backend@1.23.0-next.0 + - @backstage/plugin-app-backend@0.3.70-next.0 + - @backstage/plugin-auth-backend@0.22.8-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-catalog-backend@1.23.2-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.19-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.8-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-devtools-backend@0.3.7-next.0 + - @backstage/plugin-events-backend@0.3.8-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/plugin-kubernetes-backend@0.18.2-next.0 + - @backstage/plugin-permission-backend@0.5.45-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/plugin-proxy-backend@0.5.2-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.22-next.0 + - @backstage/plugin-search-backend@1.5.13-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.27-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.2-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.27-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.31-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.26-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/plugin-signals-backend@0.1.7-next.0 + - @backstage/plugin-signals-node@0.1.7-next.0 + - @backstage/plugin-techdocs-backend@1.10.8-next.0 + - example-app@0.2.99-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.7.14 + +## e2e-test@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.17-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.98-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/plugin-techdocs@1.10.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/cli@0.26.10-next.0 + - @backstage/plugin-catalog@1.21.1-next.0 + - @backstage/app-defaults@1.5.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/test-utils@1.5.7-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.6 + +## @internal/plugin-todo-list@1.0.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @internal/plugin-todo-list-backend@1.0.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/errors@1.2.4 diff --git a/docs/tutorials/setup-opentelemetry.md b/docs/tutorials/setup-opentelemetry.md index 30dde79db8..faaeab49f4 100644 --- a/docs/tutorials/setup-opentelemetry.md +++ b/docs/tutorials/setup-opentelemetry.md @@ -33,6 +33,7 @@ const { } = require('@opentelemetry/auto-instrumentations-node'); const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); +// By default exports the metrics on localhost:9464/metrics const prometheus = new PrometheusExporter(); const sdk = new NodeSDK({ // You can add a traceExporter field here too diff --git a/microsite/blog/2024-06-27-backstage-engineer-journey.mdx b/microsite/blog/2024-06-27-backstage-engineer-journey.mdx new file mode 100644 index 0000000000..b9bfc20e4e --- /dev/null +++ b/microsite/blog/2024-06-27-backstage-engineer-journey.mdx @@ -0,0 +1,135 @@ +--- +# prettier-ignore +title: "1,186 days with Backstage: A journey through the eyes of a developer" +author: Camila Loiola, Spotify +authorURL: https://github.com/camilaibs +authorImageURL: https://avatars.githubusercontent.com/u/6290749?v=4 +--- + +**TL;DR** There is no shortage of content that discusses the benefits that Backstage brings to organizations (and if you want to read more on that, you can just click [here](https://engineering.atspotify.com/category/backstage/), [here](https://backstage.io/blog), or [here](https://backstage.spotify.com/discover/blog/)). But I want to share what it did for me, a developer here at Spotify. And not just what it did, but how I’ve used Backstage to help me achieve goals at each stage of my journey at Spotify — from my first day as a brand new employee to today, my 1,186th day as a contributor. + +![Backstage Engineer Journey](assets/2024-06-27/backstage-engineer-journey.svg) + +{/* truncate */} + +## A new joiner with a need to get up to speed + +My first six months after joining Spotify, I was eager and determined to get up to speed so that I’d be able to start contributing as soon as possible. I set goals for myself and developed concrete activities to reach those goals: + +### Goal 1: Learn the internal process to develop, test, secure, and publish applications. + +Understanding a company’s practices and technologies is absolutely essential to getting started, no matter what company you join. + +At Spotify, we use a Backstage plugin called [TechDocs](https://backstage.io/docs/features/techdocs/) to document [Golden Paths](https://engineering.atspotify.com/2020/08/how-we-use-golden-paths-to-solve-fragmentation-in-our-software-ecosystem/) — tutorials that teach us the development process for each role at the company — for web, backend, mobile, data science development, and so on. + +With Backstage, I had an understanding of how to put things into production, even before I had my first task. I used the web Golden Path to guide me on setting up my environment; creating and structuring projects; and building, publishing, and monitoring production applications. + +> **Reflection:**
_“Is it easy for newly hired engineers to settle in and find information critical to getting started?”_ + +With Backstage, new hires can quickly and easily understand the nuances of their particular positions and be ready to deliver their first task to production. + +### Goal 2: Find and read the documentation and source code of the products my team maintains. + +Having familiarized myself with the ways of working, it was a good time to understand my specific team’s business domain. This meant spending time reading through documentation and source code to find out the value we provide to our customers. In the past, I would spend time with colleagues for knowledge transfer as opposed to learning on my own and consult my colleagues if needed. + +With the [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/), I could easily browse the components my team owns, find the source repo and documentation. + +> **Reflection:**
_“Are you able to accomplish this without asking a teammate for help?”_ + +Use Backstage to get to know the products that you will be working on, and use your peers' time to ask contextualized clarifying questions instead. + +### Goal 3: Figure out where my team fits within the company and with other teams. + +It was also crucial for me to build a network from the beginning so that I could explore collaboration opportunities. + +At Spotify, we use a Backstage plugin called Band Manager which displays information about each team and allows employees to see not only their own teams but also those within the same product area and company domain. + +> **Reflection:**
_“Are you going to need a one-on-one with your manager to ask this question?”_ + +Backstage helped me find the teams close to mine, and I took the opportunity to develop my network and talk to members from those teams to understand our boundaries and gather ideas to contribute. + +It’s pretty likely that you can relate to one or more of these examples, so use Backstage to support your goals from the very beginning! + +Now let’s move on to the middle of the journey, between six months and two years into life at the company. + +## Two years in — from contributor to leader + +After about two years of contributing to my team’s products, I began to look for opportunities to actually lead initiatives and create a new project. One of my objectives was to ensure I was upholding Spotify’s standards and choosing Spotify-approved technologies. + +My goal has changed from being a contributor to being the driver, i.e., from doing what I was told to do to defining what needed to be done. I “started driving initiatives” and “supporting my peers” in order to position myself as a reference in my technical area. + +### Goal 1: Quickly spin up new projects using the most appropriate technology stack. + +At Spotify, we expect engineers to use technologies approved by our [Tech Radar](https://backstage.io/blog/2020/05/14/tech-radar-plugin/#what-is-tech-radar) and follow the best quality standards. + +To do so, we use a plugin called [Scaffolder](https://backstage.io/docs/reference/plugin-scaffolder) (aka Software Templates), which allows engineers to create templates for setting up new projects. Templates automate actions such as creating repositories, allocating resources, registering in the catalog, configuring deployments, and connecting to other internal systems. + +> **Reflection:**
_“Do you need to create a ticket to get these things done before you even start coding? And is there a lot of time spent looking for boilerplate code to start a new project and connecting it to other internal systems?"_ + +Backstage enabled me to quickly create and publish a new backend that can deploy code to production with just a few clicks, so I could focus on building solutions for the business. I could use Backstage to easily build the right thing. Instead of spending time scaffolding projects, I could spend my time writing code. + +### Goal 2: Create products that have a healthy operational state and are easy to evolve. + +Keeping track of vulnerabilities and letting my team know about technical debts were other parts of my routine. + +With the [Soundcheck plugin](https://backstage.spotify.com/marketplace/spotify/plugin/soundcheck/), developers can easily configure checks to verify component health, such as reliability and other development and operational standards. We also have an internal Vulnerabilities plugin that displays fragilities in our components, so we can continuously prevent security issues. + +> **Reflection:**
_“Do you know which components owned by your team follows best practices and standards and which ones are lagging behind?”_ + +Backstage helped me gather and better understand our technical debts, enabling me to effectively prioritize during our team’s planning, visualize which entities were compliant to our team’s best practices, and identify which ones needed improvement. + +### Goal 3: Respond effectively to incidents within our components or their dependencies. + +If you’ve been with a company for around two years, you might have had to manage incidents in one way or another — this was certainly the case for me. A typical problem was to determine if the issue is with the service that I own or a downstream dependency. + +Spotify has adopted [PagerDuty](https://backstage.spotify.com/marketplace/pagerduty/plugin/pagerduty/) to manage on-call rotation and to track incident resolutions. We integrated the PagerDuty plugin in Backstage, so we see who is on call and if there is an incident for a particular component. + +> **Reflection:**
_“When a downstream dependency is failing, do you know who to contact?”_ + +In the event that one of our components starts failing, I check whether any of the systems we rely on is experiencing an incident, and Backstage again makes it easy for me to see the dependencies between systems and the status of those dependencies. + +## Today and beyond! + +With three-plus years of experience at Spotify, I’m taking on more and more responsibility by embracing challenges outside my team’s scope, coordinating cross-team collaboration, attending and facilitating courses for personal development and growth, and mentoring my peers. + +Backstage has allowed me to drive my pursuit of growth in a multitude of ways. + +### Goal 1: Stay in the flow and optimize my time management practices. + +At this point, finding time to focus — with all that I have on my plate — while also making time to learn new concepts is both fundamental and challenging for me. + +Spotify encourages its developers to manage their time in order to stay in the flow and to turn to the tools that help them prioritize effectively and focus on their work. + +> **Reflection:**
_“How do you surface the most important notifications and avoid non-emergency distractions?”_ + +Backstage has been instrumental in helping me stay in the flow by surfacing the most critical notifications and call to actions related to cost spikes, security vulnerabilities in my homepage. + +### Goal 2: Platformize our solutions and reuse code to boost my productivity. + +Reinventing the wheel is a common problem in software development and Spotify is no different. + +Autonomous teams tend to prioritize speed over reuse and develop the same solutions in different places (1) as it unblocks the delivery for their team and (2) there is no easy way to discover if a particular functionality has been developed in another part of the company and if it can be reused for their requirement. + +> **Reflection:**
_“Do you find yourself wondering if someone else already did it before starting a task?”_ + +With the [Backstage Search plugin](https://backstage.io/docs/features/search/), I can discover solutions to reuse, find inspiration, and also share what I’ve built for other developers to discover and use. + +### Goal 3: Grow my career and take steps toward the next level. + +I began looking for opportunities to gain new experiences and responsibilities while expanding my knowledge. + +With Spotify’s [Skill Exchange plugin](https://backstage.spotify.com/marketplace/spotify/plugin/skill-exchange/) for Backstage, engineers temporarily embed with a different team, allowing them to partake in work outside their day-to-day. The plugin also helps engineers connect with mentees or mentors that align with their skills profiles. + +> **Reflection:**
_“Are you able to find opportunities that match your current skill set?”_ + +With Backstage, I've applied for an embed to experience working with another team and eventually make a permanent move to this new team, calling it my new home. + +I am passionate about teaching and eager to share my knowledge to help others. Through Skill Exchange, I found a mentee, a colleague transitioning into engineering, and I am helping them take their first steps. + +## What’s next? + +Backstage is highly customizable, and with its extensive plugin ecosystem, engineers can use it strategically to achieve their goals. + +No matter what point in your journey you are, you can find value with [Backstage](http://backstage.io). It was, after all, made by engineers for engineers. 💚 + +Special thanks to [Stanley Nicholl](https://github.com/stanley-nicholl), [Patrik Oldsberg](https://github.com/Rugvip), [Vincenzo Scamporlino](https://github.com/vinzscam), [Mihai Tabara](https://github.com/MihaiTabara), [Emma Indal](https://github.com/emmaindal), [Raghunandan Balachandran](https://github.com/soapraj) for all of their support. diff --git a/microsite/blog/assets/2024-06-27/backstage-engineer-journey.svg b/microsite/blog/assets/2024-06-27/backstage-engineer-journey.svg new file mode 100644 index 0000000000..1e302206a5 --- /dev/null +++ b/microsite/blog/assets/2024-06-27/backstage-engineer-journey.svg @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/microsite/data/plugins/digital.ai-release.yaml b/microsite/data/plugins/digital.ai-release.yaml new file mode 100644 index 0000000000..288a95a123 --- /dev/null +++ b/microsite/data/plugins/digital.ai-release.yaml @@ -0,0 +1,18 @@ +--- +title: Digital.ai Release +author: digital.ai +authorUrl: https://digital.ai/ +category: CI/CD +description: The plugin offers integration with Digital.ai Release and backstage. It provide access to active releases, templates and manage workflow executions. +documentation: https://docs.digital.ai/bundle/devops-release-version-v.24.1/page/release/concept/release-backstage-overview.html +iconUrl: /img/digital.ai-release.svg +npmPackageName: '@digital-ai/plugin-dai-release' +tags: + - ci + - cd + - release + - orchestration + - devops + - pipeline + - automation +addedDate: '2024-05-28' diff --git a/microsite/data/plugins/harness-chaos.yaml b/microsite/data/plugins/harness-chaos.yaml new file mode 100644 index 0000000000..ade6f9e566 --- /dev/null +++ b/microsite/data/plugins/harness-chaos.yaml @@ -0,0 +1,11 @@ +title: Harness Service Reliability Management +author: harness.io +authorUrl: https://github.com/harness/backstage-plugins +category: Chaos Engineering +description: This plugin lets you view the status of Harness Chaos Engineering Resources and launch Chaos Experiments directly inside Backstage. +documentation: https://github.com/harness/backstage-plugins/tree/main/plugins/harness-chaos +iconUrl: https://static.harness.io/ng-static/images/favicon.png +npmPackageName: '@harnessio/backstage-plugin-harness-chaos' +tags: + - resiliency +addedDate: '2024-06-25' diff --git a/microsite/docusaurus.config.ts b/microsite/docusaurus.config.ts index 9e2a70e74e..b1a6533ab9 100644 --- a/microsite/docusaurus.config.ts +++ b/microsite/docusaurus.config.ts @@ -241,7 +241,7 @@ const config: Config = { position: 'left', }, { - to: 'docs/releases/v1.27.0', + to: 'docs/releases/v1.28.0', label: 'Releases', position: 'left', }, diff --git a/microsite/sidebars.json b/microsite/sidebars.json index e81a410825..075025afbb 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -1,6 +1,7 @@ { "releases": { "Release Notes": [ + "releases/v1.28.0", "releases/v1.27.0", "releases/v1.26.0", "releases/v1.25.0", diff --git a/microsite/static/img/digital.ai-release.svg b/microsite/static/img/digital.ai-release.svg new file mode 100644 index 0000000000..ba510e2a79 --- /dev/null +++ b/microsite/static/img/digital.ai-release.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/microsite/yarn.lock b/microsite/yarn.lock index 08d343e681..00732d79f2 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -11872,8 +11872,8 @@ __metadata: linkType: hard "ws@npm:^7.3.1": - version: 7.5.9 - resolution: "ws@npm:7.5.9" + version: 7.5.10 + resolution: "ws@npm:7.5.10" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ^5.0.2 @@ -11882,7 +11882,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138 + checksum: f9bb062abf54cc8f02d94ca86dcd349c3945d63851f5d07a3a61c2fcb755b15a88e943a63cf580cbdb5b74436d67ef6b67f745b8f7c0814e411379138e1863cb languageName: node linkType: hard diff --git a/package.json b/package.json index 03b152d1e6..0946671f12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.28.0-next.3", + "version": "1.29.0-next.0", "private": true, "repository": { "type": "git", @@ -17,7 +17,7 @@ "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": "NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --allow-warnings 'packages/backend-common,packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", + "build:api-reports:only": "NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --allow-warnings 'packages/backend-app-api,packages/backend-common,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", @@ -94,6 +94,7 @@ "dependencies": { "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3", + "@types/global-agent": "^2.1.3", "@useoptic/optic": "^0.50.10" }, "devDependencies": { diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index dc03f00faf..40ee32565f 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/app-defaults +## 1.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.23 + +## 1.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/core-app-api@1.12.6 + ## 1.5.6-next.2 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index df20b60bf9..5dc9e3d617 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.5.6-next.2", + "version": "1.5.7-next.0", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index c915ed8ff9..e6788c8566 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,21 @@ # app-next-example-plugin +## 0.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + +## 0.0.12 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/frontend-plugin-api@0.6.6 + ## 0.0.12-next.2 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index c17e398482..9d2e76c418 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,6 +1,6 @@ { "name": "app-next-example-plugin", - "version": "0.0.12-next.2", + "version": "0.0.13-next.0", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 1f0ae7b5e4..979284c459 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,91 @@ # example-app-next +## 0.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.22.0-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/plugin-techdocs@1.10.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/frontend-app-api@0.7.2-next.0 + - @backstage/cli@0.26.10-next.0 + - @backstage/plugin-org@0.6.27-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-catalog@1.21.1-next.0 + - @backstage/plugin-scaffolder-react@1.10.0-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.0 + - @backstage/app-defaults@1.5.7-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-api-docs@0.11.7-next.0 + - @backstage/plugin-app-visualizer@0.1.8-next.0 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-catalog-graph@0.4.7-next.0 + - @backstage/plugin-catalog-import@0.12.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.0 + - @backstage/plugin-home@0.7.6-next.0 + - @backstage/plugin-kubernetes@0.11.12-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.0 + - @backstage/plugin-notifications@0.2.3-next.0 + - @backstage/plugin-search@1.4.13-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/plugin-signals@0.0.8-next.0 + - @backstage/plugin-user-settings@0.8.8-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-search-common@1.2.12 + +## 0.0.12 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/plugin-techdocs@1.10.6 + - @backstage/plugin-api-docs@0.11.6 + - @backstage/core-compat-api@0.2.6 + - @backstage/cli@0.26.7 + - @backstage/plugin-scaffolder@1.21.0 + - @backstage/plugin-catalog-import@0.12.0 + - @backstage/plugin-kubernetes@0.11.11 + - @backstage/plugin-search@1.4.12 + - @backstage/plugin-catalog-graph@0.4.6 + - @backstage/plugin-notifications@0.2.2 + - @backstage/plugin-org@0.6.26 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-scaffolder-react@1.9.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.11 + - @backstage/plugin-catalog-unprocessed-entities@0.2.5 + - @backstage/plugin-kubernetes-cluster@0.0.12 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-app-visualizer@0.1.7 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-techdocs-react@1.2.5 + - @backstage/plugin-catalog-react@1.12.1 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-user-settings@0.8.7 + - @backstage/plugin-search-react@1.7.12 + - @backstage/plugin-auth-react@0.1.3 + - @backstage/plugin-catalog@1.21.0 + - @backstage/plugin-signals@0.0.7 + - @backstage/plugin-home@0.7.5 + - @backstage/core-app-api@1.12.6 + - @backstage/integration-react@1.1.28 + - @backstage/app-defaults@1.5.6 + - @backstage/frontend-app-api@0.7.1 + - @backstage/frontend-plugin-api@0.6.6 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.0.12-next.3 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index 9277888dc9..73141946ea 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.12-next.3", + "version": "0.0.13-next.0", "private": true, "repository": { "type": "git", @@ -62,7 +62,7 @@ "react-use": "^17.2.4", "vite": "^4.4.9", "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.21.0", + "vite-plugin-node-polyfills": "^0.22.0", "zen-observable": "^0.10.0" }, "devDependencies": { diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 50e0487a21..ca64c31049 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,87 @@ # example-app +## 0.2.99-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.22.0-next.0 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/plugin-techdocs@1.10.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/frontend-app-api@0.7.2-next.0 + - @backstage/cli@0.26.10-next.0 + - @backstage/plugin-org@0.6.27-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-catalog@1.21.1-next.0 + - @backstage/plugin-scaffolder-react@1.10.0-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.12-next.0 + - @backstage/app-defaults@1.5.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-api-docs@0.11.7-next.0 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-catalog-graph@0.4.7-next.0 + - @backstage/plugin-catalog-import@0.12.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.6-next.0 + - @backstage/plugin-devtools@0.1.16-next.0 + - @backstage/plugin-home@0.7.6-next.0 + - @backstage/plugin-kubernetes@0.11.12-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.13-next.0 + - @backstage/plugin-notifications@0.2.3-next.0 + - @backstage/plugin-search@1.4.13-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/plugin-signals@0.0.8-next.0 + - @backstage/plugin-user-settings@0.8.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-search-common@1.2.12 + +## 0.2.98 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/plugin-techdocs@1.10.6 + - @backstage/plugin-api-docs@0.11.6 + - @backstage/cli@0.26.7 + - @backstage/plugin-scaffolder@1.21.0 + - @backstage/plugin-catalog-import@0.12.0 + - @backstage/plugin-kubernetes@0.11.11 + - @backstage/plugin-search@1.4.12 + - @backstage/plugin-catalog-graph@0.4.6 + - @backstage/plugin-notifications@0.2.2 + - @backstage/plugin-org@0.6.26 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-scaffolder-react@1.9.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.11 + - @backstage/plugin-catalog-unprocessed-entities@0.2.5 + - @backstage/plugin-kubernetes-cluster@0.0.12 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-techdocs-react@1.2.5 + - @backstage/plugin-catalog-react@1.12.1 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-user-settings@0.8.7 + - @backstage/plugin-search-react@1.7.12 + - @backstage/plugin-auth-react@0.1.3 + - @backstage/plugin-devtools@0.1.15 + - @backstage/plugin-catalog@1.21.0 + - @backstage/plugin-signals@0.0.7 + - @backstage/plugin-home@0.7.5 + - @backstage/core-app-api@1.12.6 + - @backstage/integration-react@1.1.28 + - @backstage/app-defaults@1.5.6 + - @backstage/frontend-app-api@0.7.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.2.98-next.3 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 70512e9362..067b2d84eb 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.98-next.3", + "version": "0.2.99-next.0", "backstage": { "role": "frontend" }, @@ -83,7 +83,7 @@ "react-use": "^17.2.4", "vite": "^4.4.9", "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.21.0", + "vite-plugin-node-polyfills": "^0.22.0", "zen-observable": "^0.10.0" }, "devDependencies": { diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 1d23c727bc..c9fe21c89e 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,93 @@ # @backstage/backend-app-api +## 0.7.9-next.0 + +### Patch Changes + +- b60db08: Fixing exporting of classes properly from new packages +- a63c4b6: Fixing issue with `MiddlewareFactory` deprecation wrapping +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.7.6 + +### Patch Changes + +- b7de623: Fixed a potential crash when passing an object with a `null` prototype as log meta. +- 9539a0b: Deprecated `authServiceFactory`, `httpAuthServiceFactory`, and `userInfoServiceFactory`. Please import them from `@backstage/backend-defaults/auth`, `@backstage/backend-defaults/httpAuth`, and `@backstage/backend-defaults/userInfo` respectively instead. +- 3e823d3: Limited user tokens will no longer include the `ent` field in its payload. Ownership claims will now be fetched from the user info service. + + NOTE: Limited tokens issued prior to this change will no longer be valid. Users may have to clear their browser cookies in order to refresh their auth tokens. + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- 398b82a: Add support for JWKS tokens in ExternalTokenHandler. +- 9e63318: Added an optional `accessRestrictions` to external access service tokens and service principals in general, such that you can limit their access to certain plugins or permissions. +- e25e467: Added a new static key based method for plugin-to-plugin auth. This is useful for example if you are running readonly service nodes that cannot use a database for the default public-key signature scheme outlined in [BEP-0003](https://github.com/backstage/backstage/tree/master/beps/0003-auth-architecture-evolution). Most users should want to stay on the more secure zero-config database signature scheme. + + You can generate a public and private key pair using `openssl`. + + - First generate a private key using the ES256 algorithm + + ```sh + openssl ecparam -name prime256v1 -genkey -out private.ec.key + ``` + + - Convert it to PKCS#8 format + + ```sh + openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private.ec.key -out private.key + ``` + + - Extract the public key + + ```sh + openssl ec -inform PEM -outform PEM -pubout -in private.key -out public.key + ``` + + After this you have the files `private.key` and `public.key`. Put them in a place where you know their absolute paths, and then set up your app-config accordingly: + + ```yaml + backend: + auth: + keyStore: + type: static + static: + keys: + - publicKeyFile: /absolute/path/to/public.key + privateKeyFile: /absolute/path/to/private.key + keyId: some-custom-id + ``` + +- 7d30d95: Fixing issue with log meta fields possibly being circular refs +- 6a576dc: Stop using `getVoidLogger` in tests to reduce the dependency on the soon-to-deprecate `backstage-common` package. +- 6551b3d: Deprecated core service factories and implementations and moved them over to + subpath exports on `@backstage/backend-defaults` instead. E.g. + `@backstage/backend-defaults/scheduler` is where the service factory and default + implementation of `coreServices.scheduler` now lives. +- d617103: Updating the logger redaction message to something less dramatic +- Updated dependencies + - @backstage/cli-node@0.2.6 + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/backend-tasks@0.5.24 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/plugin-permission-node@0.7.30 + - @backstage/cli-common@0.1.14 + - @backstage/config-loader@1.8.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.7.6-next.3 ### Patch Changes diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index 3d7357cb87..7518f8e2cc 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -12,6 +12,7 @@ import { CacheService } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { ConfigSchema } from '@backstage/config-loader'; import { CorsOptions } from 'cors'; +import { DatabaseService } from '@backstage/backend-plugin-api'; import { DiscoveryService } from '@backstage/backend-plugin-api'; import { ErrorRequestHandler } from 'express'; import { Express as Express_2 } from 'express'; @@ -28,7 +29,6 @@ import { LifecycleService } from '@backstage/backend-plugin-api'; import { LoadConfigOptionsRemote } from '@backstage/config-loader'; import { LoggerService } from '@backstage/backend-plugin-api'; import { PermissionsService } from '@backstage/backend-plugin-api'; -import { PluginDatabaseManager } from '@backstage/backend-common'; import { RemoteConfigSourceOptions } from '@backstage/config-loader'; import { RequestHandler } from 'express'; import { RequestListener } from 'http'; @@ -45,7 +45,7 @@ import { transport } from 'winston'; import { UrlReaderService } from '@backstage/backend-plugin-api'; import { UserInfoService } from '@backstage/backend-plugin-api'; -// @public (undocumented) +// @public @deprecated (undocumented) export const authServiceFactory: () => ServiceFactory; // @public (undocumented) @@ -68,26 +68,20 @@ export interface Backend { // @public @deprecated (undocumented) export const cacheServiceFactory: () => ServiceFactory; -// @public (undocumented) -export function createConfigSecretEnumerator(options: { - logger: LoggerService; - dir?: string; - schema?: ConfigSchema; -}): Promise<(config: Config) => Iterable>; +// Warning: (ae-forgotten-export) The symbol "createConfigSecretEnumerator_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export const createConfigSecretEnumerator: typeof createConfigSecretEnumerator_2; -// @public -export function createHttpServer( - listener: RequestListener, - options: HttpServerOptions, - deps: { - logger: LoggerService; - }, -): Promise; +// Warning: (ae-forgotten-export) The symbol "createHttpServer_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export const createHttpServer: typeof createHttpServer_2; -// @public -export function createLifecycleMiddleware( - options: LifecycleMiddlewareOptions, -): RequestHandler; +// Warning: (ae-forgotten-export) The symbol "createLifecycleMiddleware_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated +export const createLifecycleMiddleware: typeof createLifecycleMiddleware_2; // @public (undocumented) export function createSpecializedBackend( @@ -102,11 +96,11 @@ export interface CreateSpecializedBackendOptions { // @public @deprecated (undocumented) export const databaseServiceFactory: () => ServiceFactory< - PluginDatabaseManager, + DatabaseService, 'plugin' >; -// @public +// @public @deprecated export class DefaultRootHttpRouter implements RootHttpRouterService { // (undocumented) static create(options?: DefaultRootHttpRouterOptions): DefaultRootHttpRouter; @@ -116,10 +110,10 @@ export class DefaultRootHttpRouter implements RootHttpRouterService { use(path: string, handler: Handler): void; } -// @public -export interface DefaultRootHttpRouterOptions { - indexPath?: string | false; -} +// Warning: (ae-forgotten-export) The symbol "DefaultRootHttpRouterOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated +export type DefaultRootHttpRouterOptions = DefaultRootHttpRouterOptions_2; // @public @deprecated (undocumented) export const discoveryServiceFactory: () => ServiceFactory< @@ -127,15 +121,10 @@ export const discoveryServiceFactory: () => ServiceFactory< 'plugin' >; -// @public -export interface ExtendedHttpServer extends http.Server { - // (undocumented) - port(): number; - // (undocumented) - start(): Promise; - // (undocumented) - stop(): Promise; -} +// Warning: (ae-forgotten-export) The symbol "ExtendedHttpServer_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type ExtendedHttpServer = ExtendedHttpServer_2; // @public @deprecated export class HostDiscovery implements DiscoveryService { @@ -151,44 +140,31 @@ export class HostDiscovery implements DiscoveryService { getExternalBaseUrl(pluginId: string): Promise; } -// @public (undocumented) +// @public @deprecated (undocumented) export const httpAuthServiceFactory: () => ServiceFactory< HttpAuthService, 'plugin' >; -// @public (undocumented) -export interface HttpRouterFactoryOptions { - getPath?(pluginId: string): string; -} +// Warning: (ae-forgotten-export) The symbol "HttpRouterFactoryOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type HttpRouterFactoryOptions = HttpRouterFactoryOptions_2; -// @public (undocumented) +// @public @deprecated export const httpRouterServiceFactory: ( - options?: HttpRouterFactoryOptions | undefined, + options?: HttpRouterFactoryOptions_2 | undefined, ) => ServiceFactory; -// @public -export type HttpServerCertificateOptions = - | { - type: 'pem'; - key: string; - cert: string; - } - | { - type: 'generated'; - hostname: string; - }; +// Warning: (ae-forgotten-export) The symbol "HttpServerCertificateOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type HttpServerCertificateOptions = HttpServerCertificateOptions_2; -// @public -export type HttpServerOptions = { - listen: { - port: number; - host: string; - }; - https?: { - certificate: HttpServerCertificateOptions; - }; -}; +// Warning: (ae-forgotten-export) The symbol "HttpServerOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type HttpServerOptions = HttpServerOptions_2; // @public @deprecated export type IdentityFactoryOptions = { @@ -201,12 +177,10 @@ export const identityServiceFactory: ( options?: IdentityFactoryOptions | undefined, ) => ServiceFactory; -// @public -export interface LifecycleMiddlewareOptions { - // (undocumented) - lifecycle: LifecycleService; - startupRequestPauseTimeout?: HumanDuration; -} +// Warning: (ae-forgotten-export) The symbol "LifecycleMiddlewareOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated +export type LifecycleMiddlewareOptions = LifecycleMiddlewareOptions_2; // @public @deprecated export const lifecycleServiceFactory: () => ServiceFactory< @@ -214,7 +188,7 @@ export const lifecycleServiceFactory: () => ServiceFactory< 'plugin' >; -// @public +// @public @deprecated export function loadBackendConfig(options: { remote?: LoadConfigOptionsRemote; argv: string[]; @@ -224,13 +198,13 @@ export function loadBackendConfig(options: { config: Config; }>; -// @public (undocumented) +// @public @deprecated export const loggerServiceFactory: () => ServiceFactory< LoggerService, 'plugin' >; -// @public +// @public @deprecated (undocumented) export class MiddlewareFactory { compression(): RequestHandler; cors(): RequestHandler; @@ -241,19 +215,15 @@ export class MiddlewareFactory { notFound(): RequestHandler; } -// @public -export interface MiddlewareFactoryErrorOptions { - logAllErrors?: boolean; - showStackTraces?: boolean; -} +// Warning: (ae-forgotten-export) The symbol "MiddlewareFactoryErrorOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type MiddlewareFactoryErrorOptions = MiddlewareFactoryErrorOptions_2; -// @public -export interface MiddlewareFactoryOptions { - // (undocumented) - config: RootConfigService; - // (undocumented) - logger: LoggerService; -} +// Warning: (ae-forgotten-export) The symbol "MiddlewareFactoryOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type MiddlewareFactoryOptions = MiddlewareFactoryOptions_2; // @public @deprecated (undocumented) export const permissionsServiceFactory: () => ServiceFactory< @@ -261,14 +231,20 @@ export const permissionsServiceFactory: () => ServiceFactory< 'plugin' >; -// @public -export function readCorsOptions(config?: Config): CorsOptions; +// Warning: (ae-forgotten-export) The symbol "readCorsOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export const readCorsOptions: typeof readCorsOptions_2; -// @public -export function readHelmetOptions(config?: Config): HelmetOptions; +// Warning: (ae-forgotten-export) The symbol "readHelmetOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export const readHelmetOptions: typeof readHelmetOptions_2; -// @public -export function readHttpServerOptions(config?: Config): HttpServerOptions; +// Warning: (ae-forgotten-export) The symbol "readHttpServerOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export const readHttpServerOptions: typeof readHttpServerOptions_2; // @public @deprecated (undocumented) export interface RootConfigFactoryOptions { @@ -283,35 +259,19 @@ export const rootConfigServiceFactory: ( options?: RootConfigFactoryOptions | undefined, ) => ServiceFactory; -// @public (undocumented) -export interface RootHttpRouterConfigureContext { - // (undocumented) - app: Express_2; - // (undocumented) - applyDefaults: () => void; - // (undocumented) - config: RootConfigService; - // (undocumented) - lifecycle: LifecycleService; - // (undocumented) - logger: LoggerService; - // (undocumented) - middleware: MiddlewareFactory; - // (undocumented) - routes: RequestHandler; - // (undocumented) - server: Server; -} +// Warning: (ae-forgotten-export) The symbol "RootHttpRouterConfigureContext_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type RootHttpRouterConfigureContext = RootHttpRouterConfigureContext_2; -// @public (undocumented) -export type RootHttpRouterFactoryOptions = { - indexPath?: string | false; - configure?(context: RootHttpRouterConfigureContext): void; -}; +// Warning: (ae-forgotten-export) The symbol "RootHttpRouterFactoryOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated +export type RootHttpRouterFactoryOptions = RootHttpRouterFactoryOptions_2; -// @public (undocumented) +// @public @deprecated (undocumented) export const rootHttpRouterServiceFactory: ( - options?: RootHttpRouterFactoryOptions | undefined, + options?: RootHttpRouterFactoryOptions_2 | undefined, ) => ServiceFactory; // @public @deprecated @@ -320,7 +280,7 @@ export const rootLifecycleServiceFactory: () => ServiceFactory< 'root' >; -// @public (undocumented) +// @public @deprecated export const rootLoggerServiceFactory: () => ServiceFactory< RootLoggerService, 'root' @@ -344,13 +304,13 @@ export const urlReaderServiceFactory: () => ServiceFactory< 'plugin' >; -// @public (undocumented) +// @public @deprecated (undocumented) export const userInfoServiceFactory: () => ServiceFactory< UserInfoService, 'plugin' >; -// @public +// @public @deprecated export class WinstonLogger implements RootLoggerService { // (undocumented) addRedactions(redactions: Iterable): void; @@ -372,15 +332,8 @@ export class WinstonLogger implements RootLoggerService { warn(message: string, meta?: JsonObject): void; } -// @public (undocumented) -export interface WinstonLoggerOptions { - // (undocumented) - format?: Format; - // (undocumented) - level?: string; - // (undocumented) - meta?: JsonObject; - // (undocumented) - transports?: transport[]; -} +// Warning: (ae-forgotten-export) The symbol "WinstonLoggerOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type WinstonLoggerOptions = WinstonLoggerOptions_2; ``` diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 020cdea841..51bbca14bc 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-app-api", - "version": "0.7.6-next.3", + "version": "0.7.9-next.0", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" @@ -79,6 +79,7 @@ "minimatch": "^9.0.0", "minimist": "^1.2.5", "morgan": "^1.10.0", + "node-fetch": "^2.6.7", "node-forge": "^1.3.1", "path-to-regexp": "^6.2.1", "selfsigned": "^2.0.0", @@ -89,6 +90,7 @@ "winston-transport": "^4.5.0" }, "devDependencies": { + "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/compression": "^1.7.0", diff --git a/packages/backend-app-api/src/alpha/featureDiscoveryServiceFactory.ts b/packages/backend-app-api/src/alpha/featureDiscoveryServiceFactory.ts index 5943261b0b..c16a3f6534 100644 --- a/packages/backend-app-api/src/alpha/featureDiscoveryServiceFactory.ts +++ b/packages/backend-app-api/src/alpha/featureDiscoveryServiceFactory.ts @@ -168,7 +168,7 @@ export const featureDiscoveryServiceFactory = createServiceFactory({ function isBackendFeature(value: unknown): value is BackendFeature { return ( !!value && - typeof value === 'object' && + ['object', 'function'].includes(typeof value) && (value as BackendFeature).$$type === '@backstage/BackendFeature' ); } diff --git a/packages/backend-app-api/src/config/config.ts b/packages/backend-app-api/src/config/config.ts index 60d1e46e90..957997849e 100644 --- a/packages/backend-app-api/src/config/config.ts +++ b/packages/backend-app-api/src/config/config.ts @@ -14,56 +14,27 @@ * limitations under the License. */ +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { createConfigSecretEnumerator as _createConfigSecretEnumerator } from '../../../backend-defaults/src/entrypoints/rootConfig/createConfigSecretEnumerator'; + import { resolve as resolvePath } from 'path'; import parseArgs from 'minimist'; -import { LoggerService } from '@backstage/backend-plugin-api'; import { findPaths } from '@backstage/cli-common'; import { - loadConfigSchema, loadConfig, ConfigTarget, LoadConfigOptionsRemote, - ConfigSchema, } from '@backstage/config-loader'; import { ConfigReader } from '@backstage/config'; import type { Config, AppConfig } from '@backstage/config'; -import { getPackages } from '@manypkg/get-packages'; import { ObservableConfigProxy } from './ObservableConfigProxy'; import { isValidUrl } from '../lib/urls'; -/** @public */ -export async function createConfigSecretEnumerator(options: { - logger: LoggerService; - dir?: string; - schema?: ConfigSchema; -}): Promise<(config: Config) => Iterable> { - const { logger, dir = process.cwd() } = options; - const { packages } = await getPackages(dir); - const schema = - options.schema ?? - (await loadConfigSchema({ - dependencies: packages.map(p => p.packageJson.name), - })); - - return (config: Config) => { - const [secretsData] = schema.process( - [{ data: config.getOptional() ?? {}, context: 'schema-enumerator' }], - { - visibility: ['secret'], - ignoreSchemaErrors: true, - }, - ); - const secrets = new Set(); - JSON.parse( - JSON.stringify(secretsData.data), - (_, v) => typeof v === 'string' && secrets.add(v), - ); - logger.info( - `Found ${secrets.size} new secrets in config that will be redacted`, - ); - return secrets; - }; -} +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootConfig` instead. + */ +export const createConfigSecretEnumerator = _createConfigSecretEnumerator; /** * Load configuration for a Backend. @@ -71,6 +42,7 @@ export async function createConfigSecretEnumerator(options: { * This function should only be called once, during the initialization of the backend. * * @public + * @deprecated Please migrate to the new backend system and use `coreServices.rootConfig` instead, or the {@link @backstage/config-loader#ConfigSources} facilities if required. */ export async function loadBackendConfig(options: { remote?: LoadConfigOptionsRemote; diff --git a/packages/backend-app-api/src/http/index.ts b/packages/backend-app-api/src/http/index.ts index 4a9ec14cf8..a056ed2d61 100644 --- a/packages/backend-app-api/src/http/index.ts +++ b/packages/backend-app-api/src/http/index.ts @@ -14,17 +14,174 @@ * limitations under the License. */ -export { readHttpServerOptions } from './config'; -export { createHttpServer } from './createHttpServer'; -export { MiddlewareFactory } from './MiddlewareFactory'; -export type { - MiddlewareFactoryErrorOptions, - MiddlewareFactoryOptions, -} from './MiddlewareFactory'; -export { readCorsOptions } from './readCorsOptions'; -export { readHelmetOptions } from './readHelmetOptions'; -export type { - ExtendedHttpServer, - HttpServerCertificateOptions, - HttpServerOptions, -} from './types'; +import { ErrorRequestHandler, RequestHandler } from 'express'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { + readHttpServerOptions as _readHttpServerOptions, + createHttpServer as _createHttpServer, + MiddlewareFactory as _MiddlewareFactory, + readCorsOptions as _readCorsOptions, + readHelmetOptions as _readHelmetOptions, + type MiddlewareFactoryErrorOptions as _MiddlewareFactoryErrorOptions, + type MiddlewareFactoryOptions as _MiddlewareFactoryOptions, + type ExtendedHttpServer as _ExtendedHttpServer, + type HttpServerCertificateOptions as _HttpServerCertificateOptions, + type HttpServerOptions as _HttpServerOptions, +} from '../../../backend-defaults/src/entrypoints/rootHttpRouter/http'; + +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export const readHttpServerOptions = _readHttpServerOptions; +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export const createHttpServer = _createHttpServer; +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export const readCorsOptions = _readCorsOptions; +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export const readHelmetOptions = _readHelmetOptions; +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export class MiddlewareFactory { + /** + * Creates a new {@link MiddlewareFactory}. + */ + static create(options: MiddlewareFactoryOptions) { + return new MiddlewareFactory(_MiddlewareFactory.create(options)); + } + + private constructor(private readonly impl: _MiddlewareFactory) {} + + /** + * Returns a middleware that unconditionally produces a 404 error response. + * + * @remarks + * + * Typically you want to place this middleware at the end of the chain, such + * that it's the last one attempted after no other routes matched. + * + * @returns An Express request handler + */ + notFound(): RequestHandler { + return this.impl.notFound(); + } + + /** + * Returns the compression middleware. + * + * @remarks + * + * The middleware will attempt to compress response bodies for all requests + * that traverse through the middleware. + */ + compression(): RequestHandler { + return this.impl.compression(); + } + + /** + * Returns a request logging middleware. + * + * @remarks + * + * Typically you want to place this middleware at the start of the chain, such + * that it always logs requests whether they are "caught" by handlers farther + * down or not. + * + * @returns An Express request handler + */ + logging(): RequestHandler { + return this.impl.logging(); + } + + /** + * Returns a middleware that implements the helmet library. + * + * @remarks + * + * This middleware applies security policies to incoming requests and outgoing + * responses. It is configured using config keys such as `backend.csp`. + * + * @see {@link https://helmetjs.github.io/} + * + * @returns An Express request handler + */ + helmet(): RequestHandler { + return this.impl.helmet(); + } + + /** + * Returns a middleware that implements the cors library. + * + * @remarks + * + * This middleware handles CORS. It is configured using the config key + * `backend.cors`. + * + * @see {@link https://github.com/expressjs/cors} + * + * @returns An Express request handler + */ + cors(): RequestHandler { + return this.impl.cors(); + } + + /** + * Express middleware to handle errors during request processing. + * + * @remarks + * + * This is commonly the very last middleware in the chain. + * + * Its primary purpose is not to do translation of business logic exceptions, + * but rather to be a global catch-all for uncaught "fatal" errors that are + * expected to result in a 500 error. However, it also does handle some common + * error types (such as http-error exceptions, and the well-known error types + * in the `@backstage/errors` package) and returns the enclosed status code + * accordingly. + * + * It will also produce a response body with a serialized form of the error, + * unless a previous handler already did send a body. See + * {@link @backstage/errors#ErrorResponseBody} for the response shape used. + * + * @returns An Express error request handler + */ + error(options: MiddlewareFactoryErrorOptions = {}): ErrorRequestHandler { + return this.impl.error(options); + } +} +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export type MiddlewareFactoryErrorOptions = _MiddlewareFactoryErrorOptions; +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export type MiddlewareFactoryOptions = _MiddlewareFactoryOptions; +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export type ExtendedHttpServer = _ExtendedHttpServer; +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export type HttpServerCertificateOptions = _HttpServerCertificateOptions; +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export type HttpServerOptions = _HttpServerOptions; diff --git a/packages/backend-app-api/src/logging/WinstonLogger.ts b/packages/backend-app-api/src/logging/WinstonLogger.ts index 64e97b230c..e5403906ce 100644 --- a/packages/backend-app-api/src/logging/WinstonLogger.ts +++ b/packages/backend-app-api/src/logging/WinstonLogger.ts @@ -14,65 +14,37 @@ * limitations under the License. */ +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { + WinstonLogger as _WinstonLogger, + type WinstonLoggerOptions as _WinstonLoggerOptions, +} from '../../../backend-defaults/src/entrypoints/rootLogger'; + import { LoggerService, RootLoggerService, } from '@backstage/backend-plugin-api'; import { JsonObject } from '@backstage/types'; -import { Format, TransformableInfo } from 'logform'; -import { - Logger, - format, - createLogger, - transports, - transport as Transport, -} from 'winston'; -import { MESSAGE } from 'triple-beam'; -import { escapeRegExp } from '../lib/escapeRegExp'; +import { Format } from 'logform'; /** * @public + * @deprecated Please import from `@backstage/backend-defaults/rootLogger` instead. */ -export interface WinstonLoggerOptions { - meta?: JsonObject; - level?: string; - format?: Format; - transports?: Transport[]; -} +export type WinstonLoggerOptions = _WinstonLoggerOptions; /** * A {@link @backstage/backend-plugin-api#LoggerService} implementation based on winston. * * @public + * @deprecated Please import from `@backstage/backend-defaults/rootLogger` instead. */ 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(); - const defaultFormatter = - process.env.NODE_ENV === 'production' - ? format.json() - : WinstonLogger.colorFormat(); - - let logger = createLogger({ - level: process.env.LOG_LEVEL || options.level || 'info', - format: format.combine( - options.format ?? defaultFormatter, - redacter.format, - ), - transports: options.transports ?? new transports.Console(), - }); - - if (options.meta) { - logger = logger.child(options.meta); - } - - return new WinstonLogger(logger, redacter.add); + return new WinstonLogger(_WinstonLogger.create(options)); } /** @@ -82,111 +54,39 @@ export class WinstonLogger implements RootLoggerService { format: Format; add: (redactions: Iterable) => void; } { - const redactionSet = new Set(); - - let redactionPattern: RegExp | undefined = undefined; - - return { - format: format((obj: TransformableInfo) => { - if (!redactionPattern || !obj) { - return obj; - } - - obj[MESSAGE] = obj[MESSAGE]?.replace?.(redactionPattern, '***'); - - return obj; - })(), - 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'); - } - }, - }; + return _WinstonLogger.redacter(); } /** * 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}`; - }), - ); + return _WinstonLogger.colorFormat(); } - private constructor( - winston: Logger, - addRedactions?: (redactions: Iterable) => void, - ) { - this.#winston = winston; - this.#addRedactions = addRedactions; - } + private constructor(private readonly impl: _WinstonLogger) {} error(message: string, meta?: JsonObject): void { - this.#winston.error(message, meta); + this.impl.error(message, meta); } warn(message: string, meta?: JsonObject): void { - this.#winston.warn(message, meta); + this.impl.warn(message, meta); } info(message: string, meta?: JsonObject): void { - this.#winston.info(message, meta); + this.impl.info(message, meta); } debug(message: string, meta?: JsonObject): void { - this.#winston.debug(message, meta); + this.impl.debug(message, meta); } child(meta: JsonObject): LoggerService { - return new WinstonLogger(this.#winston.child(meta)); + return this.impl.child(meta); } addRedactions(redactions: Iterable) { - this.#addRedactions?.(redactions); + this.impl.addRedactions(redactions); } } diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts index 2a5a210cb7..988b907b4c 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.ts @@ -14,72 +14,11 @@ * limitations under the License. */ -import { - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { DefaultAuthService } from './DefaultAuthService'; -import { ExternalTokenHandler } from './external/ExternalTokenHandler'; -import { PluginTokenHandler } from './plugin/PluginTokenHandler'; -import { createPluginKeySource } from './plugin/keys/createPluginKeySource'; -import { UserTokenHandler } from './user/UserTokenHandler'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { authServiceFactory as _authServiceFactory } from '../../../../../backend-defaults/src/entrypoints/auth'; -/** @public */ -export const authServiceFactory = createServiceFactory({ - service: coreServices.auth, - deps: { - config: coreServices.rootConfig, - logger: coreServices.rootLogger, - discovery: coreServices.discovery, - plugin: coreServices.pluginMetadata, - database: coreServices.database, - // Re-using the token manager makes sure that we use the same generated keys for - // development as plugins that have not yet been migrated. It's important that this - // keeps working as long as there are plugins that have not been migrated to the - // new auth services in the new backend system. - tokenManager: coreServices.tokenManager, - }, - async factory({ config, discovery, plugin, tokenManager, logger, database }) { - const disableDefaultAuthPolicy = - config.getOptionalBoolean( - 'backend.auth.dangerouslyDisableDefaultAuthPolicy', - ) ?? false; - - const keyDuration = { hours: 1 }; - - const keySource = await createPluginKeySource({ - config, - database, - logger, - keyDuration, - }); - - const userTokens = UserTokenHandler.create({ - discovery, - }); - - const pluginTokens = PluginTokenHandler.create({ - ownPluginId: plugin.getId(), - logger, - keySource, - keyDuration, - discovery, - }); - - const externalTokens = ExternalTokenHandler.create({ - ownPluginId: plugin.getId(), - config, - logger, - }); - - return new DefaultAuthService( - userTokens, - pluginTokens, - externalTokens, - tokenManager, - plugin.getId(), - disableDefaultAuthPolicy, - keySource, - ); - }, -}); +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/auth` instead. + */ +export const authServiceFactory = _authServiceFactory; diff --git a/packages/backend-app-api/src/services/implementations/deprecated.ts b/packages/backend-app-api/src/services/implementations/deprecated.ts index 6f4f76e679..347a968bce 100644 --- a/packages/backend-app-api/src/services/implementations/deprecated.ts +++ b/packages/backend-app-api/src/services/implementations/deprecated.ts @@ -14,4 +14,11 @@ * limitations under the License. */ +export * from './auth'; +export * from './httpAuth'; +export * from './httpRouter'; +export * from './logger'; +export * from './rootHttpRouter'; +export * from './rootLogger'; export * from './scheduler'; +export * from './userInfo'; diff --git a/packages/backend-app-api/src/services/implementations/discovery/HostDiscovery.ts b/packages/backend-app-api/src/services/implementations/discovery/HostDiscovery.ts index d337da997a..5909dd1ae6 100644 --- a/packages/backend-app-api/src/services/implementations/discovery/HostDiscovery.ts +++ b/packages/backend-app-api/src/services/implementations/discovery/HostDiscovery.ts @@ -15,10 +15,9 @@ */ import { Config } from '@backstage/config'; -import { readHttpServerOptions } from '@backstage/backend-app-api'; import { DiscoveryService } from '@backstage/backend-plugin-api'; - -type Target = string | { internal: string; external: string }; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { HostDiscovery as _HostDiscovery } from '../../../../../backend-defaults/src/entrypoints/discovery'; /** * HostDiscovery is a basic PluginEndpointDiscovery implementation @@ -57,77 +56,16 @@ export class HostDiscovery implements DiscoveryService { * path for the `catalog` plugin will be `http://localhost:7007/api/catalog`. */ static fromConfig(config: Config, options?: { basePath?: string }) { - const basePath = options?.basePath ?? '/api'; - const externalBaseUrl = config - .getString('backend.baseUrl') - .replace(/\/+$/, ''); - - const { - listen: { host: listenHost = '::', port: listenPort }, - } = readHttpServerOptions(config.getConfig('backend')); - const protocol = config.has('backend.https') ? 'https' : 'http'; - - // Translate bind-all to localhost, and support IPv6 - let host = listenHost; - if (host === '::' || host === '') { - // We use localhost instead of ::1, since IPv6-compatible systems should default - // to using IPv6 when they see localhost, but if the system doesn't support IPv6 - // things will still work. - host = 'localhost'; - } else if (host === '0.0.0.0') { - host = '127.0.0.1'; - } - if (host.includes(':')) { - host = `[${host}]`; - } - - const internalBaseUrl = `${protocol}://${host}:${listenPort}`; - - return new HostDiscovery( - internalBaseUrl + basePath, - externalBaseUrl + basePath, - config.getOptionalConfig('discovery'), - ); + return new HostDiscovery(_HostDiscovery.fromConfig(config, options)); } - private constructor( - private readonly internalBaseUrl: string, - private readonly externalBaseUrl: string, - private readonly discoveryConfig: Config | undefined, - ) {} - - private getTargetFromConfig(pluginId: string, type: 'internal' | 'external') { - const endpoints = this.discoveryConfig?.getOptionalConfigArray('endpoints'); - - const target = endpoints - ?.find(endpoint => endpoint.getStringArray('plugins').includes(pluginId)) - ?.get('target'); - - if (!target) { - const baseUrl = - type === 'external' ? this.externalBaseUrl : this.internalBaseUrl; - - return `${baseUrl}/${encodeURIComponent(pluginId)}`; - } - - if (typeof target === 'string') { - return target.replace( - /\{\{\s*pluginId\s*\}\}/g, - encodeURIComponent(pluginId), - ); - } - - return target[type].replace( - /\{\{\s*pluginId\s*\}\}/g, - encodeURIComponent(pluginId), - ); - } + private constructor(private readonly impl: _HostDiscovery) {} async getBaseUrl(pluginId: string): Promise { - return this.getTargetFromConfig(pluginId, 'internal'); + return this.impl.getBaseUrl(pluginId); } async getExternalBaseUrl(pluginId: string): Promise { - return this.getTargetFromConfig(pluginId, 'external'); + return this.impl.getExternalBaseUrl(pluginId); } } diff --git a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts index c85ba6e4b3..373dd10ead 100644 --- a/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpAuth/httpAuthServiceFactory.ts @@ -14,273 +14,11 @@ * limitations under the License. */ -import { - AuthService, - BackstageCredentials, - BackstagePrincipalTypes, - BackstageUserPrincipal, - DiscoveryService, - HttpAuthService, - coreServices, - createServiceFactory, -} from '@backstage/backend-plugin-api'; -import { AuthenticationError, NotAllowedError } from '@backstage/errors'; -import { parse as parseCookie } from 'cookie'; -import { Request, Response } from 'express'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { httpAuthServiceFactory as _httpAuthServiceFactory } from '../../../../../backend-defaults/src/entrypoints/httpAuth'; -const FIVE_MINUTES_MS = 5 * 60 * 1000; - -const BACKSTAGE_AUTH_COOKIE = 'backstage-auth'; - -function getTokenFromRequest(req: Request) { - // TODO: support multiple auth headers (iterate rawHeaders) - const authHeader = req.headers.authorization; - if (typeof authHeader === 'string') { - const matches = authHeader.match(/^Bearer[ ]+(\S+)$/i); - const token = matches?.[1]; - if (token) { - return token; - } - } - - return undefined; -} - -function getCookieFromRequest(req: Request) { - const cookieHeader = req.headers.cookie; - if (cookieHeader) { - const cookies = parseCookie(cookieHeader); - const token = cookies[BACKSTAGE_AUTH_COOKIE]; - if (token) { - return token; - } - } - - return undefined; -} - -function willExpireSoon(expiresAt: Date) { - return Date.now() + FIVE_MINUTES_MS > expiresAt.getTime(); -} - -const credentialsSymbol = Symbol('backstage-credentials'); -const limitedCredentialsSymbol = Symbol('backstage-limited-credentials'); - -type RequestWithCredentials = Request & { - [credentialsSymbol]?: Promise; - [limitedCredentialsSymbol]?: Promise; -}; - -class DefaultHttpAuthService implements HttpAuthService { - readonly #auth: AuthService; - readonly #discovery: DiscoveryService; - readonly #pluginId: string; - - constructor( - auth: AuthService, - discovery: DiscoveryService, - pluginId: string, - ) { - this.#auth = auth; - this.#discovery = discovery; - this.#pluginId = pluginId; - } - - async #extractCredentialsFromRequest(req: Request) { - const token = getTokenFromRequest(req); - if (!token) { - return await this.#auth.getNoneCredentials(); - } - - return await this.#auth.authenticate(token); - } - - async #extractLimitedCredentialsFromRequest(req: Request) { - const token = getTokenFromRequest(req); - if (token) { - return await this.#auth.authenticate(token, { - allowLimitedAccess: true, - }); - } - - const cookie = getCookieFromRequest(req); - if (cookie) { - return await this.#auth.authenticate(cookie, { - allowLimitedAccess: true, - }); - } - - return await this.#auth.getNoneCredentials(); - } - - async #getCredentials(req: RequestWithCredentials) { - return (req[credentialsSymbol] ??= - this.#extractCredentialsFromRequest(req)); - } - - async #getLimitedCredentials(req: RequestWithCredentials) { - return (req[limitedCredentialsSymbol] ??= - this.#extractLimitedCredentialsFromRequest(req)); - } - - async credentials( - req: Request, - options?: { - allow?: Array; - allowLimitedAccess?: boolean; - }, - ): Promise> { - // Limited and full credentials are treated as two separate cases, this lets - // us avoid internal dependencies between the AuthService and - // HttpAuthService implementations - const credentials = options?.allowLimitedAccess - ? await this.#getLimitedCredentials(req) - : await this.#getCredentials(req); - - const allowed = options?.allow; - if (!allowed) { - return credentials as any; - } - - if (this.#auth.isPrincipal(credentials, 'none')) { - if (allowed.includes('none' as TAllowed)) { - return credentials as any; - } - - throw new AuthenticationError('Missing credentials'); - } else if (this.#auth.isPrincipal(credentials, 'user')) { - if (allowed.includes('user' as TAllowed)) { - return credentials as any; - } - - throw new NotAllowedError( - `This endpoint does not allow 'user' credentials`, - ); - } else if (this.#auth.isPrincipal(credentials, 'service')) { - if (allowed.includes('service' as TAllowed)) { - return credentials as any; - } - - throw new NotAllowedError( - `This endpoint does not allow 'service' credentials`, - ); - } - - throw new NotAllowedError( - 'Unknown principal type, this should never happen', - ); - } - - async issueUserCookie( - res: Response, - options?: { credentials?: BackstageCredentials }, - ): Promise<{ expiresAt: Date }> { - if (res.headersSent) { - throw new Error('Failed to issue user cookie, headers were already sent'); - } - - let credentials: BackstageCredentials; - if (options?.credentials) { - if (this.#auth.isPrincipal(options.credentials, 'none')) { - res.clearCookie( - BACKSTAGE_AUTH_COOKIE, - await this.#getCookieOptions(res.req), - ); - return { expiresAt: new Date() }; - } - if (!this.#auth.isPrincipal(options.credentials, 'user')) { - throw new AuthenticationError( - 'Refused to issue cookie for non-user principal', - ); - } - credentials = options.credentials; - } else { - credentials = await this.credentials(res.req, { allow: ['user'] }); - } - - const existingExpiresAt = await this.#existingCookieExpiration(res.req); - if (existingExpiresAt && !willExpireSoon(existingExpiresAt)) { - return { expiresAt: existingExpiresAt }; - } - - const { token, expiresAt } = await this.#auth.getLimitedUserToken( - credentials, - ); - if (!token) { - throw new Error('User credentials is unexpectedly missing token'); - } - - res.cookie(BACKSTAGE_AUTH_COOKIE, token, { - ...(await this.#getCookieOptions(res.req)), - expires: expiresAt, - }); - - return { expiresAt }; - } - - async #getCookieOptions(_req: Request): Promise<{ - domain: string; - httpOnly: true; - secure: boolean; - priority: 'high'; - sameSite: 'none' | 'lax'; - }> { - // TODO: eventually we should read from `${req.protocol}://${req.hostname}` - // once https://github.com/backstage/backstage/issues/24169 has landed - const externalBaseUrlStr = await this.#discovery.getExternalBaseUrl( - this.#pluginId, - ); - const externalBaseUrl = new URL(externalBaseUrlStr); - - const secure = - externalBaseUrl.protocol === 'https:' || - externalBaseUrl.hostname === 'localhost'; - - return { - domain: externalBaseUrl.hostname, - httpOnly: true, - secure, - priority: 'high', - sameSite: secure ? 'none' : 'lax', - }; - } - - async #existingCookieExpiration(req: Request): Promise { - const existingCookie = getCookieFromRequest(req); - if (!existingCookie) { - return undefined; - } - - try { - const existingCredentials = await this.#auth.authenticate( - existingCookie, - { - allowLimitedAccess: true, - }, - ); - if (!this.#auth.isPrincipal(existingCredentials, 'user')) { - return undefined; - } - - return existingCredentials.expiresAt; - } catch (error) { - if (error.name === 'AuthenticationError') { - return undefined; - } - throw error; - } - } -} - -/** @public */ -export const httpAuthServiceFactory = createServiceFactory({ - service: coreServices.httpAuth, - deps: { - auth: coreServices.auth, - discovery: coreServices.discovery, - plugin: coreServices.pluginMetadata, - }, - async factory({ auth, discovery, plugin }) { - return new DefaultHttpAuthService(auth, discovery, plugin.getId()); - }, -}); +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/httpAuth` instead. + */ +export const httpAuthServiceFactory = _httpAuthServiceFactory; diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createLifecycleMiddleware.ts b/packages/backend-app-api/src/services/implementations/httpRouter/createLifecycleMiddleware.ts index 3f8ee3ea69..d4864a23a6 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/createLifecycleMiddleware.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/createLifecycleMiddleware.ts @@ -14,26 +14,18 @@ * limitations under the License. */ -import { LifecycleService } from '@backstage/backend-plugin-api'; -import { ServiceUnavailableError } from '@backstage/errors'; -import { HumanDuration, durationToMilliseconds } from '@backstage/types'; -import { RequestHandler } from 'express'; - -export const DEFAULT_TIMEOUT = { seconds: 5 }; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { + createLifecycleMiddleware as _createLifecycleMiddleware, + type LifecycleMiddlewareOptions as _LifecycleMiddlewareOptions, +} from '../../../../../backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware'; /** * Options for {@link createLifecycleMiddleware}. * @public + * @deprecated Please import from `@backstage/backend-defaults/httpRouter` instead. */ -export interface LifecycleMiddlewareOptions { - lifecycle: LifecycleService; - /** - * The maximum time that paused requests will wait for the service to start, before returning an error. - * - * Defaults to 5 seconds. - */ - startupRequestPauseTimeout?: HumanDuration; -} +export type LifecycleMiddlewareOptions = _LifecycleMiddlewareOptions; /** * Creates a middleware that pauses requests until the service has started. @@ -48,59 +40,6 @@ export interface LifecycleMiddlewareOptions { * {@link @backstage/errors#ServiceUnavailableError}. * * @public + * @deprecated Please import from `@backstage/backend-defaults/httpRouter` instead. */ -export function createLifecycleMiddleware( - options: LifecycleMiddlewareOptions, -): RequestHandler { - const { lifecycle, startupRequestPauseTimeout = DEFAULT_TIMEOUT } = options; - - let state: 'init' | 'up' | 'down' = 'init'; - const waiting = new Set<{ - next: (err?: Error) => void; - timeout: NodeJS.Timeout; - }>(); - - lifecycle.addStartupHook(async () => { - if (state === 'init') { - state = 'up'; - for (const item of waiting) { - clearTimeout(item.timeout); - item.next(); - } - waiting.clear(); - } - }); - - lifecycle.addShutdownHook(async () => { - state = 'down'; - - for (const item of waiting) { - clearTimeout(item.timeout); - item.next(new ServiceUnavailableError('Service is shutting down')); - } - waiting.clear(); - }); - - const timeoutMs = durationToMilliseconds(startupRequestPauseTimeout); - - return (_req, _res, next) => { - if (state === 'up') { - next(); - return; - } else if (state === 'down') { - next(new ServiceUnavailableError('Service is shutting down')); - return; - } - - const item = { - next, - timeout: setTimeout(() => { - if (waiting.delete(item)) { - next(new ServiceUnavailableError('Service has not started up yet')); - } - }, timeoutMs), - }; - - waiting.add(item); - }; -} +export const createLifecycleMiddleware = _createLifecycleMiddleware; diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts index 5e3a26252f..9d2b74fb43 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.ts @@ -14,80 +14,26 @@ * limitations under the License. */ -import { Handler } from 'express'; -import PromiseRouter from 'express-promise-router'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports import { - coreServices, - createServiceFactory, - HttpRouterServiceAuthPolicy, -} from '@backstage/backend-plugin-api'; -import { createLifecycleMiddleware } from './createLifecycleMiddleware'; -import { createCredentialsBarrier } from './createCredentialsBarrier'; -import { createAuthIntegrationRouter } from './createAuthIntegrationRouter'; -import { createCookieAuthRefreshMiddleware } from './createCookieAuthRefreshMiddleware'; + httpRouterServiceFactory as _httpRouterServiceFactory, + type HttpRouterFactoryOptions as _HttpRouterFactoryOptions, +} from '../../../../../backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory'; /** * @public + * @deprecated Please import from `@backstage/backend-defaults/httpRouter` instead. */ -export interface HttpRouterFactoryOptions { - /** - * A callback used to generate the path for each plugin, defaults to `/api/{pluginId}`. - */ - getPath?(pluginId: string): string; -} +export type HttpRouterFactoryOptions = _HttpRouterFactoryOptions; -/** @public */ -export const httpRouterServiceFactory = createServiceFactory( - (options?: HttpRouterFactoryOptions) => ({ - service: coreServices.httpRouter, - initialization: 'always', - deps: { - plugin: coreServices.pluginMetadata, - config: coreServices.rootConfig, - logger: coreServices.logger, - lifecycle: coreServices.lifecycle, - rootHttpRouter: coreServices.rootHttpRouter, - auth: coreServices.auth, - httpAuth: coreServices.httpAuth, - }, - async factory({ - auth, - httpAuth, - config, - logger, - plugin, - rootHttpRouter, - lifecycle, - }) { - if (options?.getPath) { - logger.warn( - `DEPRECATION WARNING: The 'getPath' option for HttpRouterService is deprecated. The ability to reconfigure the '/api/' path prefix for plugins will be removed in the future.`, - ); - } - const getPath = options?.getPath ?? (id => `/api/${id}`); - const path = getPath(plugin.getId()); - - const router = PromiseRouter(); - rootHttpRouter.use(path, router); - - const credentialsBarrier = createCredentialsBarrier({ - httpAuth, - config, - }); - - router.use(createAuthIntegrationRouter({ auth })); - router.use(createLifecycleMiddleware({ lifecycle })); - router.use(credentialsBarrier.middleware); - router.use(createCookieAuthRefreshMiddleware({ auth, httpAuth })); - - return { - use(handler: Handler): void { - router.use(handler); - }, - addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void { - credentialsBarrier.addAuthPolicy(policy); - }, - }; - }, - }), -); +/** + * HTTP route registration for plugins. + * + * See {@link @backstage/code-plugin-api#HttpRouterService} + * and {@link https://backstage.io/docs/backend-system/core-services/http-router | the service docs} + * for more information. + * + * @public + * @deprecated Please import from `@backstage/backend-defaults/httpRouter` instead. + */ +export const httpRouterServiceFactory = _httpRouterServiceFactory; diff --git a/packages/backend-app-api/src/services/implementations/index.ts b/packages/backend-app-api/src/services/implementations/index.ts index e6656801a9..3a2fe819ed 100644 --- a/packages/backend-app-api/src/services/implementations/index.ts +++ b/packages/backend-app-api/src/services/implementations/index.ts @@ -14,22 +14,15 @@ * limitations under the License. */ -export * from './auth'; export * from './cache'; export * from './config'; export * from './database'; export * from './discovery'; -export * from './httpAuth'; -export * from './httpRouter'; export * from './identity'; export * from './lifecycle'; -export * from './logger'; export * from './permissions'; -export * from './rootHttpRouter'; export * from './rootLifecycle'; -export * from './rootLogger'; export * from './tokenManager'; export * from './urlReader'; -export * from './userInfo'; export * from './deprecated'; diff --git a/packages/backend-app-api/src/services/implementations/logger/loggerServiceFactory.ts b/packages/backend-app-api/src/services/implementations/logger/loggerServiceFactory.ts index d9158529ca..7e7b4b98b0 100644 --- a/packages/backend-app-api/src/services/implementations/logger/loggerServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/logger/loggerServiceFactory.ts @@ -14,19 +14,17 @@ * limitations under the License. */ -import { - createServiceFactory, - coreServices, -} from '@backstage/backend-plugin-api'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { loggerServiceFactory as _loggerServiceFactory } from '../../../../../backend-defaults/src/entrypoints/logger/loggerServiceFactory'; -/** @public */ -export const loggerServiceFactory = createServiceFactory({ - service: coreServices.logger, - deps: { - rootLogger: coreServices.rootLogger, - plugin: coreServices.pluginMetadata, - }, - factory({ rootLogger, plugin }) { - return rootLogger.child({ plugin: plugin.getId() }); - }, -}); +/** + * Plugin-level logging. + * + * See {@link @backstage/code-plugin-api#LoggerService} + * and {@link https://backstage.io/docs/backend-system/core-services/logger | the service docs} + * for more information. + * + * @public + * @deprecated Please import from `@backstage/backend-defaults/logger` instead. + */ +export const loggerServiceFactory = _loggerServiceFactory; diff --git a/packages/backend-app-api/src/services/implementations/rootHttpRouter/DefaultRootHttpRouter.ts b/packages/backend-app-api/src/services/implementations/rootHttpRouter/DefaultRootHttpRouter.ts index 9d7d1de120..617d5055db 100644 --- a/packages/backend-app-api/src/services/implementations/rootHttpRouter/DefaultRootHttpRouter.ts +++ b/packages/backend-app-api/src/services/implementations/rootHttpRouter/DefaultRootHttpRouter.ts @@ -15,101 +15,40 @@ */ import { RootHttpRouterService } from '@backstage/backend-plugin-api'; -import { Handler, Router } from 'express'; -import trimEnd from 'lodash/trimEnd'; - -function normalizePath(path: string): string { - return `${trimEnd(path, '/')}/`; -} +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { + DefaultRootHttpRouter as _DefaultRootHttpRouter, + DefaultRootHttpRouterOptions as _DefaultRootHttpRouterOptions, +} from '../../../../../backend-defaults/src/entrypoints/rootHttpRouter/DefaultRootHttpRouter'; +import { Handler } from 'express'; /** * Options for the {@link DefaultRootHttpRouter} class. * * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. */ -export interface DefaultRootHttpRouterOptions { - /** - * The path to forward all unmatched requests to. Defaults to '/api/app' if - * not given. Disables index path behavior if false is given. - */ - indexPath?: string | false; -} +export type DefaultRootHttpRouterOptions = _DefaultRootHttpRouterOptions; /** * The default implementation of the {@link @backstage/backend-plugin-api#RootHttpRouterService} interface for * {@link @backstage/backend-plugin-api#coreServices.rootHttpRouter}. * * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. */ export class DefaultRootHttpRouter implements RootHttpRouterService { - #indexPath?: string; - - #router = Router(); - #namedRoutes = Router(); - #indexRouter = Router(); - #existingPaths = new Array(); - static create(options?: DefaultRootHttpRouterOptions) { - let indexPath; - if (options?.indexPath === false) { - indexPath = undefined; - } else if (options?.indexPath === undefined) { - indexPath = '/api/app'; - } else if (options?.indexPath === '') { - throw new Error('indexPath option may not be an empty string'); - } else { - indexPath = options.indexPath; - } - return new DefaultRootHttpRouter(indexPath); + return new DefaultRootHttpRouter(_DefaultRootHttpRouter.create(options)); } - private constructor(indexPath?: string) { - this.#indexPath = indexPath; - this.#router.use(this.#namedRoutes); - - // Any request with a /api/ prefix will skip the index router, even if no named router matches - this.#router.use('/api/', (_req, _res, next) => { - next('router'); - }); - - if (this.#indexPath) { - this.#router.use(this.#indexRouter); - } - } + private constructor(private readonly impl: RootHttpRouterService) {} use(path: string, handler: Handler) { - if (path.match(/^[/\s]*$/)) { - throw new Error(`Root router path may not be empty`); - } - const conflictingPath = this.#findConflictingPath(path); - if (conflictingPath) { - throw new Error( - `Path ${path} conflicts with the existing path ${conflictingPath}`, - ); - } - this.#existingPaths.push(path); - this.#namedRoutes.use(path, handler); - - if (this.#indexPath === path) { - this.#indexRouter.use(handler); - } + this.impl.use(path, handler); } handler(): Handler { - return this.#router; - } - - #findConflictingPath(newPath: string): string | undefined { - const normalizedNewPath = normalizePath(newPath); - for (const path of this.#existingPaths) { - const normalizedPath = normalizePath(path); - if (normalizedPath.startsWith(normalizedNewPath)) { - return path; - } - if (normalizedNewPath.startsWith(normalizedPath)) { - return path; - } - } - return undefined; + return (this.impl as any).handler(); } } diff --git a/packages/backend-app-api/src/services/implementations/rootHttpRouter/rootHttpRouterServiceFactory.ts b/packages/backend-app-api/src/services/implementations/rootHttpRouter/rootHttpRouterServiceFactory.ts index a469a2f303..bef1913645 100644 --- a/packages/backend-app-api/src/services/implementations/rootHttpRouter/rootHttpRouterServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/rootHttpRouter/rootHttpRouterServiceFactory.ts @@ -14,100 +14,33 @@ * limitations under the License. */ +// eslint-disable-next-line @backstage/no-relative-monorepo-imports import { - RootConfigService, - coreServices, - createServiceFactory, - LifecycleService, - LoggerService, -} from '@backstage/backend-plugin-api'; -import express, { RequestHandler, Express } from 'express'; -import type { Server } from 'node:http'; -import { - createHttpServer, - MiddlewareFactory, - readHttpServerOptions, -} from '../../../http'; -import { DefaultRootHttpRouter } from './DefaultRootHttpRouter'; + rootHttpRouterServiceFactory as _rootHttpRouterServiceFactory, + RootHttpRouterFactoryOptions as _RootHttpRouterFactoryOptions, + RootHttpRouterConfigureContext as _RootHttpRouterConfigureContext, +} from '../../../../../backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory'; /** * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. */ -export interface RootHttpRouterConfigureContext { - app: Express; - server: Server; - middleware: MiddlewareFactory; - routes: RequestHandler; - config: RootConfigService; - logger: LoggerService; - lifecycle: LifecycleService; - applyDefaults: () => void; -} +export type RootHttpRouterConfigureContext = _RootHttpRouterConfigureContext; + +/** + * HTTP route registration for root services. + * + * See {@link @backstage/code-plugin-api#RootHttpRouterService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-http-router | the service docs} + * for more information. + * + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. + */ +export type RootHttpRouterFactoryOptions = _RootHttpRouterFactoryOptions; /** * @public + * @deprecated Please import from `@backstage/backend-defaults/rootHttpRouter` instead. */ -export type RootHttpRouterFactoryOptions = { - /** - * The path to forward all unmatched requests to. Defaults to '/api/app' if - * not given. Disables index path behavior if false is given. - */ - indexPath?: string | false; - - configure?(context: RootHttpRouterConfigureContext): void; -}; - -function defaultConfigure({ applyDefaults }: RootHttpRouterConfigureContext) { - applyDefaults(); -} - -/** @public */ -export const rootHttpRouterServiceFactory = createServiceFactory( - (options?: RootHttpRouterFactoryOptions) => ({ - service: coreServices.rootHttpRouter, - deps: { - config: coreServices.rootConfig, - rootLogger: coreServices.rootLogger, - lifecycle: coreServices.rootLifecycle, - }, - async factory({ config, rootLogger, lifecycle }) { - const { indexPath, configure = defaultConfigure } = options ?? {}; - const logger = rootLogger.child({ service: 'rootHttpRouter' }); - const app = express(); - - const router = DefaultRootHttpRouter.create({ indexPath }); - const middleware = MiddlewareFactory.create({ config, logger }); - const routes = router.handler(); - const server = await createHttpServer( - app, - readHttpServerOptions(config.getOptionalConfig('backend')), - { logger }, - ); - - configure({ - app, - server, - routes, - middleware, - config, - logger, - lifecycle, - applyDefaults() { - app.use(middleware.helmet()); - app.use(middleware.cors()); - app.use(middleware.compression()); - app.use(middleware.logging()); - app.use(routes); - app.use(middleware.notFound()); - app.use(middleware.error()); - }, - }); - - lifecycle.addShutdownHook(() => server.stop()); - - await server.start(); - - return router; - }, - }), -); +export const rootHttpRouterServiceFactory = _rootHttpRouterServiceFactory; diff --git a/packages/backend-app-api/src/services/implementations/rootLogger/rootLoggerServiceFactory.ts b/packages/backend-app-api/src/services/implementations/rootLogger/rootLoggerServiceFactory.ts index bd45df383f..af1931c438 100644 --- a/packages/backend-app-api/src/services/implementations/rootLogger/rootLoggerServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/rootLogger/rootLoggerServiceFactory.ts @@ -14,37 +14,17 @@ * limitations under the License. */ -import { - createServiceFactory, - coreServices, -} from '@backstage/backend-plugin-api'; -import { WinstonLogger } from '../../../logging'; -import { transports, format } from 'winston'; -import { createConfigSecretEnumerator } from '../../../config'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { rootLoggerServiceFactory as _rootLoggerServiceFactory } from '../../../../../backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory'; -/** @public */ -export const rootLoggerServiceFactory = createServiceFactory({ - service: coreServices.rootLogger, - deps: { - config: coreServices.rootConfig, - }, - async factory({ config }) { - const logger = WinstonLogger.create({ - meta: { - service: 'backstage', - }, - level: process.env.LOG_LEVEL || 'info', - format: - process.env.NODE_ENV === 'production' - ? format.json() - : WinstonLogger.colorFormat(), - transports: [new transports.Console()], - }); - - const secretEnumerator = await createConfigSecretEnumerator({ logger }); - logger.addRedactions(secretEnumerator(config)); - config.subscribe?.(() => logger.addRedactions(secretEnumerator(config))); - - return logger; - }, -}); +/** + * Root-level logging. + * + * See {@link @backstage/code-plugin-api#RootLoggerService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-logger | the service docs} + * for more information. + * + * @public + * @deprecated Please import from `@backstage/backend-defaults/rootLogger` instead. + */ +export const rootLoggerServiceFactory = _rootLoggerServiceFactory; diff --git a/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts b/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts index e88acaf4c2..746f480c41 100644 --- a/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts +++ b/packages/backend-app-api/src/services/implementations/userInfo/userInfoServiceFactory.ts @@ -14,51 +14,11 @@ * limitations under the License. */ -import { - UserInfoService, - BackstageUserInfo, - coreServices, - createServiceFactory, - BackstageCredentials, -} from '@backstage/backend-plugin-api'; -import { decodeJwt } from 'jose'; -import { toInternalBackstageCredentials } from '../auth/helpers'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { userInfoServiceFactory as _userInfoServiceFactory } from '../../../../../backend-defaults/src/entrypoints/userInfo'; -// TODO: The intention is for this to eventually be replaced by a call to the auth-backend -export class DefaultUserInfoService implements UserInfoService { - async getUserInfo( - credentials: BackstageCredentials, - ): Promise { - const internalCredentials = toInternalBackstageCredentials(credentials); - if (internalCredentials.principal.type !== 'user') { - throw new Error('Only user credentials are supported'); - } - if (!internalCredentials.token) { - throw new Error('User credentials is unexpectedly missing token'); - } - const { sub: userEntityRef, ent: ownershipEntityRefs = [] } = decodeJwt( - internalCredentials.token, - ); - - if (typeof userEntityRef !== 'string') { - throw new Error('User entity ref must be a string'); - } - if ( - !Array.isArray(ownershipEntityRefs) || - ownershipEntityRefs.some(ref => typeof ref !== 'string') - ) { - throw new Error('Ownership entity refs must be an array of strings'); - } - - return { userEntityRef, ownershipEntityRefs }; - } -} - -/** @public */ -export const userInfoServiceFactory = createServiceFactory({ - service: coreServices.userInfo, - deps: {}, - async factory() { - return new DefaultUserInfoService(); - }, -}); +/** + * @public + * @deprecated Please import from `@backstage/backend-defaults/userInfo` instead. + */ +export const userInfoServiceFactory = _userInfoServiceFactory; diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts index b60eede277..3bbef5a4c0 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts @@ -14,6 +14,9 @@ * limitations under the License. */ +import { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle'; +import { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle'; +import { loggerServiceFactory } from '@backstage/backend-defaults/logger'; import { createServiceRef, createServiceFactory, @@ -24,12 +27,6 @@ import { } from '@backstage/backend-plugin-api'; import { BackendInitializer } from './BackendInitializer'; -import { - lifecycleServiceFactory, - loggerServiceFactory, - rootLifecycleServiceFactory, -} from '../services/implementations'; - class MockLogger { debug() {} info() {} @@ -153,7 +150,7 @@ describe('BackendInitializer', () => { async init() {}, }); }, - })(), + }), ); await init.start(); @@ -184,7 +181,7 @@ describe('BackendInitializer', () => { }, }); }, - })(), + }), ); init.add( @@ -201,7 +198,7 @@ describe('BackendInitializer', () => { }, }); }, - })(), + }), ); init.add( @@ -217,7 +214,7 @@ describe('BackendInitializer', () => { }, }); }, - })(), + }), ); await init.start(); }); @@ -235,7 +232,7 @@ describe('BackendInitializer', () => { }, }); }, - })(), + }), ); await expect(init.start()).rejects.toThrow( "Plugin 'test' startup failed; caused by Error: NOPE", @@ -257,7 +254,7 @@ describe('BackendInitializer', () => { }, }); }, - })(), + }), ); await expect(init.start()).rejects.toThrow( "Module 'mod' for plugin 'test' startup failed; caused by Error: NOPE", @@ -275,7 +272,7 @@ describe('BackendInitializer', () => { async init() {}, }); }, - })(), + }), ); init.add( createBackendPlugin({ @@ -286,7 +283,7 @@ describe('BackendInitializer', () => { async init() {}, }); }, - })(), + }), ); await expect(init.start()).rejects.toThrow( "Plugin 'test' is already registered", @@ -306,7 +303,7 @@ describe('BackendInitializer', () => { async init() {}, }); }, - })(), + }), ); init.add( createBackendModule({ @@ -318,7 +315,7 @@ describe('BackendInitializer', () => { async init() {}, }); }, - })(), + }), ); await expect(init.start()).rejects.toThrow( "Module 'mod' for plugin 'test' is already registered", @@ -348,7 +345,7 @@ describe('BackendInitializer', () => { async init() {}, }); }, - })(), + }), ); init.add( createBackendModule({ @@ -361,7 +358,7 @@ describe('BackendInitializer', () => { async init() {}, }); }, - })(), + }), ); await expect(init.start()).rejects.toThrow( "Circular dependency detected for modules of plugin 'test', 'mod-a' -> 'mod-b' -> 'mod-a'", @@ -381,7 +378,7 @@ describe('BackendInitializer', () => { async init() {}, }); }, - })(), + }), ); init.add(testPlugin); init.add( @@ -394,7 +391,7 @@ describe('BackendInitializer', () => { async init() {}, }); }, - })(), + }), ); await expect(init.start()).rejects.toThrow( "Illegal dependency: Module 'mod' for plugin 'test' attempted to depend on extension point 'a' for plugin 'test-a'. Extension points can only be used within their plugin's scope.", diff --git a/packages/backend-app-api/src/wiring/BackstageBackend.ts b/packages/backend-app-api/src/wiring/BackstageBackend.ts index d523481cf7..0dd3ba4423 100644 --- a/packages/backend-app-api/src/wiring/BackstageBackend.ts +++ b/packages/backend-app-api/src/wiring/BackstageBackend.ts @@ -65,9 +65,11 @@ function unwrapFeature( if (typeof feature === 'function') { return feature(); } + if ('$$type' in feature) { return feature; } + // This is a workaround where default exports get transpiled to `exports['default'] = ...` // in CommonJS modules, which in turn results in a double `{ default: { default: ... } }` nesting // when importing using a dynamic import. @@ -78,5 +80,6 @@ function unwrapFeature( ? defaultFeature() : defaultFeature; } + return feature; } diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 35cfab0d74..d635b77c72 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,64 @@ # @backstage/backend-common +## 0.23.2-next.0 + +### Patch Changes + +- 8c09c97: Deprecate legacy status check factory, handler and types. +- d228862: Update default backend plugin created by the cli to use non-deprecated error handling middleware +- c964a3d: Add dependencies that are needed by cross-imports from backend-defaults +- b60db08: Fixing exporting of classes properly from new packages +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## 0.23.0 + +### Minor Changes + +- 395b973: Implemented `readTree` for Harness provider to support TechDocs functionality +- 02103be: Deprecated and moved over core services to `@backstage/backend-defaults` + +### Patch Changes + +- 9539a0b: Import utility functions from `backend-defaults` instead of `backend-app-api` +- b2c4607: Removed accents on deprecation note +- c6c0919: Updated configuration schema to include the `useRedisSets` cache config option. +- ed3074e: The `database` types, helpers and implementations were moved to the package `@backstage/backend-defaults` and deprecated from the package `@backstage/backend-commons`. +- 9cca724: The `TokenManager` has been deprecated in preparation for the [stable release of the New Backend System](https://github.com/backstage/backstage/issues/24493). Please [migrate](https://backstage.io/docs/tutorials/auth-service-migration) to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. +- 1779188: In preparation to the new backend system stable release, the `isDatabaseConflictError` helper have been moved to the `@backstage/backend-plugin-api` package and deprecated from `@backstage/backend-common`. +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- e171620: Move `cache` implementation and types to the `@backstage/backend-defaults` package. +- 1a6f38a: `ContainerRunner`, `DockerContainerRunner` and `KubernetesContainerRunner` are now deprecated +- 8869b8e: We are deprecating the legacy `createServiceBuilder` factory, so if you are still using it, please checkout the migration guide and [migrate](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating) your plugin to use the new backend system. +- 0634fdc: Deprecated `dropDatabase` +- b2ee7f3: Moved over all URL reader functionality from `@backstage/backend-common` to `@backstage/backend-defaults/urlReader`. Please update your imports. +- d94a477: Removed the circular dependency on `@backstage/backend-app-api` +- 3bd04bb: We are deprecating the legacy router handlers and contexts in preparation for the new backend system stable release. +- 23ee9ab: Fix AWS CodeCommit integration by allowing to change the host +- e9a03c9: Finalizes the deprecation of legacy backend utilities. Deprecated utilities include the `ServiceBuilder` type, `notFoundHandler` and `redactWintonLogLine` functions. +- 6a576dc: Deprecate legacy service logger helpers and stop using `getVoidLogger` in tests. +- 032a7a6: Deprecate the legacy error and request logging handler types, respectively: `ErrorHandlerOptions` and `RequestLoggingHandlerFactory`. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/integration@1.12.0 + - @backstage/cli-common@0.1.14 + - @backstage/config-loader@1.8.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + ## 0.23.0-next.3 ### Patch Changes diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 84328924bd..52b661bcaf 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -13,7 +13,7 @@ import { AwsCredentialsManager } from '@backstage/integration-aws-node'; import { AwsS3Integration } from '@backstage/integration'; import { AzureDevOpsCredentialsProvider } from '@backstage/integration'; import { AzureIntegration } from '@backstage/integration'; -import { BackendFeature } from '@backstage/backend-plugin-api'; +import { BackendFeatureCompat } from '@backstage/backend-plugin-api'; import { BitbucketCloudIntegration } from '@backstage/integration'; import { BitbucketIntegration } from '@backstage/integration'; import { BitbucketServerIntegration } from '@backstage/integration'; @@ -22,6 +22,7 @@ import { CacheServiceOptions } from '@backstage/backend-plugin-api'; import { CacheServiceSetOptions } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import cors from 'cors'; +import { DatabaseService } from '@backstage/backend-plugin-api'; import { DiscoveryService } from '@backstage/backend-plugin-api'; import Docker from 'dockerode'; import { ErrorRequestHandler } from 'express'; @@ -43,26 +44,25 @@ import { Logger } from 'winston'; import { LoggerService } from '@backstage/backend-plugin-api'; import { MergeResult } from 'isomorphic-git'; import { PermissionsService } from '@backstage/backend-plugin-api'; -import { DatabaseService as PluginDatabaseManager } from '@backstage/backend-plugin-api'; import { PluginMetadataService } from '@backstage/backend-plugin-api'; import { PushResult } from 'isomorphic-git'; import { Readable } from 'stream'; import { ReadCommitResult } from 'isomorphic-git'; -import type { ReadTreeOptions as ReadTreeOptions_2 } from '@backstage/backend-plugin-api'; -import type { ReadTreeResponse as ReadTreeResponse_2 } from '@backstage/backend-plugin-api'; -import type { ReadTreeResponseDirOptions as ReadTreeResponseDirOptions_2 } from '@backstage/backend-plugin-api'; -import type { ReadTreeResponseFile as ReadTreeResponseFile_2 } from '@backstage/backend-plugin-api'; -import type { ReadUrlOptions as ReadUrlOptions_2 } from '@backstage/backend-plugin-api'; -import type { ReadUrlResponse as ReadUrlResponse_2 } from '@backstage/backend-plugin-api'; +import { ReadTreeOptions as ReadTreeOptions_2 } from '@backstage/backend-plugin-api'; +import { ReadTreeResponse as ReadTreeResponse_2 } from '@backstage/backend-plugin-api'; +import { ReadTreeResponseDirOptions as ReadTreeResponseDirOptions_2 } from '@backstage/backend-plugin-api'; +import { ReadTreeResponseFile as ReadTreeResponseFile_2 } from '@backstage/backend-plugin-api'; +import { ReadUrlOptions as ReadUrlOptions_2 } from '@backstage/backend-plugin-api'; +import { ReadUrlResponse as ReadUrlResponse_2 } from '@backstage/backend-plugin-api'; import { RequestHandler } from 'express'; import { resolvePackagePath as resolvePackagePath_2 } from '@backstage/backend-plugin-api'; import { resolveSafeChildPath as resolveSafeChildPath_2 } from '@backstage/backend-plugin-api'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { Router } from 'express'; import { SchedulerService } from '@backstage/backend-plugin-api'; -import type { SearchOptions as SearchOptions_2 } from '@backstage/backend-plugin-api'; -import type { SearchResponse as SearchResponse_2 } from '@backstage/backend-plugin-api'; -import type { SearchResponseFile as SearchResponseFile_2 } from '@backstage/backend-plugin-api'; +import { SearchOptions as SearchOptions_2 } from '@backstage/backend-plugin-api'; +import { SearchResponse as SearchResponse_2 } from '@backstage/backend-plugin-api'; +import { SearchResponseFile as SearchResponseFile_2 } from '@backstage/backend-plugin-api'; import { Server } from 'http'; import { ServiceRef } from '@backstage/backend-plugin-api'; import { TokenManagerService } from '@backstage/backend-plugin-api'; @@ -88,27 +88,27 @@ export type AuthCallbackOptions = { // Warning: (ae-forgotten-export) The symbol "AwsS3UrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const AwsS3UrlReader: typeof AwsS3UrlReader_2; +export class AwsS3UrlReader extends AwsS3UrlReader_2 {} // Warning: (ae-forgotten-export) The symbol "AzureUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const AzureUrlReader: typeof AzureUrlReader_2; +export class AzureUrlReader extends AzureUrlReader_2 {} // Warning: (ae-forgotten-export) The symbol "BitbucketCloudUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const BitbucketCloudUrlReader: typeof BitbucketCloudUrlReader_2; +export class BitbucketCloudUrlReader extends BitbucketCloudUrlReader_2 {} // Warning: (ae-forgotten-export) The symbol "BitbucketServerUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const BitbucketServerUrlReader: typeof BitbucketServerUrlReader_2; +export class BitbucketServerUrlReader extends BitbucketServerUrlReader_2 {} // Warning: (ae-forgotten-export) The symbol "BitbucketUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const BitbucketUrlReader: typeof BitbucketUrlReader_2; +export class BitbucketUrlReader extends BitbucketUrlReader_2 {} // @public @deprecated (undocumented) export type CacheClient = CacheService; @@ -122,7 +122,7 @@ export type CacheClientSetOptions = CacheServiceSetOptions; // Warning: (ae-forgotten-export) The symbol "CacheManager_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const CacheManager: typeof CacheManager_2; +export class CacheManager extends CacheManager_2 {} // Warning: (ae-forgotten-export) The symbol "CacheManagerOptions_2" needs to be exported by the entry point index.d.ts // @@ -137,7 +137,7 @@ export function cacheToPluginCacheManager(cache: CacheService): { // @public @deprecated export const coloredFormat: winston.Logform.Format; -// @public +// @public @deprecated export interface ContainerRunner { runContainer(opts: RunContainerOptions): Promise; } @@ -184,53 +184,55 @@ export function createRootLogger( // @public @deprecated export function createServiceBuilder(_module: NodeModule): ServiceBuilder; -// @public +// @public @deprecated export function createStatusCheckRouter(options: { logger: LoggerService; path?: string; statusCheck?: StatusCheck; }): Promise; -// @public +// @public @deprecated (undocumented) export class DatabaseManager implements LegacyRootDatabaseService { + // (undocumented) forPlugin( pluginId: string, - deps?: { - lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; - }, + deps?: + | { + lifecycle: LifecycleService; + pluginMetadata: PluginMetadataService; + } + | undefined, ): PluginDatabaseManager; + // (undocumented) static fromConfig( config: Config, options?: DatabaseManagerOptions, ): DatabaseManager; } -// @public -export type DatabaseManagerOptions = { - migrations?: PluginDatabaseManager['migrations']; - logger?: LoggerService; -}; +// Warning: (ae-forgotten-export) The symbol "DatabaseManagerOptions_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type DatabaseManagerOptions = DatabaseManagerOptions_2; -// @public +// @public @deprecated export class DockerContainerRunner implements ContainerRunner { constructor(options: { dockerClient: Docker }); // (undocumented) runContainer(options: RunContainerOptions): Promise; } -// @public @deprecated -export function dropDatabase( - dbConfig: Config, - ...databaseNames: string[] -): Promise; +// Warning: (ae-forgotten-export) The symbol "dropDatabase_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export const dropDatabase: typeof dropDatabase_2; // @public @deprecated export function errorHandler( options?: ErrorHandlerOptions, ): ErrorRequestHandler; -// @public +// @public @deprecated export type ErrorHandlerOptions = { showStackTraces?: boolean; logger?: LoggerService; @@ -240,7 +242,7 @@ export type ErrorHandlerOptions = { // Warning: (ae-forgotten-export) The symbol "FetchUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const FetchUrlReader: typeof FetchUrlReader_2; +export class FetchUrlReader extends FetchUrlReader_2 {} // Warning: (ae-forgotten-export) The symbol "FromReadableArrayOptions_2" needs to be exported by the entry point index.d.ts // @@ -250,7 +252,7 @@ export type FromReadableArrayOptions = FromReadableArrayOptions_2; // Warning: (ae-forgotten-export) The symbol "GerritUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const GerritUrlReader: typeof GerritUrlReader_2; +export class GerritUrlReader extends GerritUrlReader_2 {} // @public @deprecated export function getRootLogger(): winston.Logger; @@ -337,27 +339,38 @@ export class Git { // Warning: (ae-forgotten-export) The symbol "GiteaUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const GiteaUrlReader: typeof GiteaUrlReader_2; +export class GiteaUrlReader extends GiteaUrlReader_2 {} // Warning: (ae-forgotten-export) The symbol "GithubUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const GithubUrlReader: typeof GithubUrlReader_2; +export class GithubUrlReader extends GithubUrlReader_2 {} // Warning: (ae-forgotten-export) The symbol "GitlabUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const GitlabUrlReader: typeof GitlabUrlReader_2; +export class GitlabUrlReader extends GitlabUrlReader_2 {} // Warning: (ae-forgotten-export) The symbol "HarnessUrlReader_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const HarnessUrlReader: typeof HarnessUrlReader_2; +export class HarnessUrlReader extends HarnessUrlReader_2 {} -// Warning: (ae-forgotten-export) The symbol "HostDiscovery_2" needs to be exported by the entry point index.d.ts -// // @public @deprecated -export const HostDiscovery: typeof HostDiscovery_2; +class HostDiscovery implements DiscoveryService { + static fromConfig( + config: Config, + options?: { + basePath?: string; + }, + ): HostDiscovery; + // (undocumented) + getBaseUrl(pluginId: string): Promise; + // (undocumented) + getExternalBaseUrl(pluginId: string): Promise; +} +export { HostDiscovery }; +export { HostDiscovery as SingleHostDiscovery }; // @public @deprecated (undocumented) export const isChildPath: typeof isChildPath_2; @@ -365,20 +378,20 @@ export const isChildPath: typeof isChildPath_2; // @public @deprecated (undocumented) export const isDatabaseConflictError: typeof isDatabaseConflictError_2; -// @public +// @public @deprecated export class KubernetesContainerRunner implements ContainerRunner { constructor(options: KubernetesContainerRunnerOptions); // (undocumented) runContainer(options: RunContainerOptions): Promise; } -// @public +// @public @deprecated export type KubernetesContainerRunnerMountBase = { volumeName: string; basePath: string; }; -// @public +// @public @deprecated export type KubernetesContainerRunnerOptions = { kubeConfig: KubeConfig; name: string; @@ -400,7 +413,7 @@ export const legacyPlugin: ( { cache: CacheService; config: RootConfigService; - database: PluginDatabaseManager; + database: DatabaseService; discovery: DiscoveryService; logger: LoggerService; permissions: PermissionsService; @@ -418,12 +431,12 @@ export const legacyPlugin: ( > >; }>, -) => BackendFeature; +) => BackendFeatureCompat; -// @public -export type LegacyRootDatabaseService = { - forPlugin(pluginId: string): PluginDatabaseManager; -}; +// Warning: (ae-forgotten-export) The symbol "LegacyRootDatabaseService_2" needs to be exported by the entry point index.d.ts +// +// @public @deprecated (undocumented) +export type LegacyRootDatabaseService = LegacyRootDatabaseService_2; // @public @deprecated export function loadBackendConfig(options: { @@ -456,7 +469,7 @@ export function makeLegacyPlugin< createRouterImport: Promise<{ default: LegacyCreateRouter>; }>, -) => BackendFeature; +) => BackendFeatureCompat; // @public @deprecated export function notFoundHandler(): RequestHandler; @@ -466,12 +479,13 @@ export function notFoundHandler(): RequestHandler; // @public @deprecated (undocumented) export type PluginCacheManager = PluginCacheManager_2; -export { PluginDatabaseManager }; +// @public @deprecated (undocumented) +export type PluginDatabaseManager = DatabaseService; // @public @deprecated (undocumented) export type PluginEndpointDiscovery = DiscoveryService; -// @public +// @public @deprecated export interface PullOptions { // (undocumented) [key: string]: unknown; @@ -522,7 +536,7 @@ export type ReadUrlResponse = ReadUrlResponse_2; // Warning: (ae-forgotten-export) The symbol "ReadUrlResponseFactory_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const ReadUrlResponseFactory: typeof ReadUrlResponseFactory_2; +export class ReadUrlResponseFactory extends ReadUrlResponseFactory_2 {} // Warning: (ae-forgotten-export) The symbol "ReadUrlResponseFactoryFromStreamOptions_2" needs to be exported by the entry point index.d.ts // @@ -538,7 +552,7 @@ export function redactWinstonLogLine( // @public @deprecated export function requestLoggingHandler(logger?: LoggerService): RequestHandler; -// @public +// @public @deprecated export type RequestLoggingHandlerFactory = ( logger?: LoggerService, ) => RequestHandler; @@ -549,7 +563,7 @@ export const resolvePackagePath: typeof resolvePackagePath_2; // @public @deprecated (undocumented) export const resolveSafeChildPath: typeof resolveSafeChildPath_2; -// @public +// @public @deprecated export type RunContainerOptions = { imageName: string; command?: string | string[]; @@ -623,9 +637,6 @@ export type ServiceBuilder = { // @public @deprecated export function setRootLogger(newLogger: winston.Logger): void; -// @public @deprecated -export const SingleHostDiscovery: typeof HostDiscovery_2; - // @public @deprecated export type StaticAuthOptions = { username?: string; @@ -634,15 +645,15 @@ export type StaticAuthOptions = { logger?: LoggerService; }; -// @public +// @public @deprecated export type StatusCheck = () => Promise; -// @public +// @public @deprecated export function statusCheckHandler( options?: StatusCheckHandlerOptions, ): Promise; -// @public +// @public @deprecated export interface StatusCheckHandlerOptions { statusCheck?: StatusCheck; } @@ -661,7 +672,7 @@ export type UrlReaderPredicateTuple = UrlReaderPredicateTuple_2; // Warning: (ae-forgotten-export) The symbol "UrlReaders_2" needs to be exported by the entry point index.d.ts // // @public @deprecated (undocumented) -export const UrlReaders: typeof UrlReaders_2; +export class UrlReaders extends UrlReaders_2 {} // Warning: (ae-forgotten-export) The symbol "UrlReadersOptions_2" needs to be exported by the entry point index.d.ts // diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 847fefa697..28378f6c41 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-common", - "version": "0.23.0-next.3", + "version": "0.23.2-next.0", "description": "Common functionality library for Backstage backends", "backstage": { "role": "node-library" @@ -99,12 +99,19 @@ "logform": "^2.3.2", "luxon": "^3.0.0", "minimatch": "^9.0.0", + "minimist": "^1.2.5", + "morgan": "^1.10.0", "mysql2": "^3.0.0", "node-fetch": "^2.6.7", + "node-forge": "^1.3.1", "p-limit": "^3.1.0", + "path-to-regexp": "^6.2.1", "pg": "^8.11.3", "raw-body": "^2.4.1", + "selfsigned": "^2.0.0", + "stoppable": "^1.1.0", "tar": "^6.1.12", + "triple-beam": "^1.4.1", "uuid": "^9.0.0", "winston": "^3.2.1", "winston-transport": "^4.5.0", @@ -121,13 +128,16 @@ "@types/concat-stream": "^2.0.0", "@types/fs-extra": "^11.0.0", "@types/http-errors": "^2.0.0", + "@types/morgan": "^1.9.0", + "@types/node-forge": "^1.3.0", "@types/pg": "^8.6.6", + "@types/stoppable": "^1.1.0", "@types/supertest": "^2.0.8", "@types/tar": "^6.1.1", "@types/webpack-env": "^1.15.2", "@types/yauzl": "^2.10.0", "aws-sdk-client-mock": "^4.0.0", - "better-sqlite3": "^9.0.0", + "better-sqlite3": "^11.0.0", "http-errors": "^2.0.0", "msw": "^1.0.0", "mysql2": "^3.0.0", diff --git a/packages/backend-common/src/alpha.ts b/packages/backend-common/src/alpha.ts index e0a5b2ddc2..0fd15459fe 100644 --- a/packages/backend-common/src/alpha.ts +++ b/packages/backend-common/src/alpha.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export * from './context'; +export * from './deprecated/context'; diff --git a/packages/backend-common/src/auth/createLegacyAuthAdapters.test.ts b/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.test.ts similarity index 100% rename from packages/backend-common/src/auth/createLegacyAuthAdapters.test.ts rename to packages/backend-common/src/compat/auth/createLegacyAuthAdapters.test.ts diff --git a/packages/backend-common/src/auth/createLegacyAuthAdapters.ts b/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts similarity index 98% rename from packages/backend-common/src/auth/createLegacyAuthAdapters.ts rename to packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts index 94f997640d..0f591eac6c 100644 --- a/packages/backend-common/src/auth/createLegacyAuthAdapters.ts +++ b/packages/backend-common/src/compat/auth/createLegacyAuthAdapters.ts @@ -35,15 +35,14 @@ import { createCredentialsWithUserPrincipal, createCredentialsWithNonePrincipal, toInternalBackstageCredentials, -} from '../../../backend-app-api/src/services/implementations/auth/helpers'; +} from '../../../../backend-defaults/src/entrypoints/auth/helpers'; // TODO is this circular thingy a problem? Test in e2e import { type IdentityApiGetIdentityRequest, DefaultIdentityClient, } from '@backstage/plugin-auth-node'; import { decodeJwt } from 'jose'; -import { TokenManager } from '../deprecated'; -import { PluginEndpointDiscovery } from '../discovery'; +import { TokenManager, PluginEndpointDiscovery } from '../../deprecated'; import { JsonObject } from '@backstage/types'; class AuthCompat implements AuthService { diff --git a/packages/backend-common/src/auth/index.ts b/packages/backend-common/src/compat/auth/index.ts similarity index 100% rename from packages/backend-common/src/auth/index.ts rename to packages/backend-common/src/compat/auth/index.ts diff --git a/packages/backend-common/src/cache/cacheToPluginCacheManager.ts b/packages/backend-common/src/compat/cache/cacheToPluginCacheManager.ts similarity index 100% rename from packages/backend-common/src/cache/cacheToPluginCacheManager.ts rename to packages/backend-common/src/compat/cache/cacheToPluginCacheManager.ts diff --git a/packages/backend-common/src/cache/index.ts b/packages/backend-common/src/compat/cache/index.ts similarity index 100% rename from packages/backend-common/src/cache/index.ts rename to packages/backend-common/src/compat/cache/index.ts diff --git a/packages/backend-common/src/discovery/index.ts b/packages/backend-common/src/compat/index.ts similarity index 79% rename from packages/backend-common/src/discovery/index.ts rename to packages/backend-common/src/compat/index.ts index 827fd059ad..d702772335 100644 --- a/packages/backend-common/src/discovery/index.ts +++ b/packages/backend-common/src/compat/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 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. @@ -14,8 +14,7 @@ * limitations under the License. */ -export { - HostDiscovery, - SingleHostDiscovery, - type PluginEndpointDiscovery, -} from './HostDiscovery'; +export * from './legacy'; +export * from './auth'; +export * from './cache'; +export * from './logging'; diff --git a/packages/backend-common/src/compat/legacy/index.ts b/packages/backend-common/src/compat/legacy/index.ts new file mode 100644 index 0000000000..1172084cd7 --- /dev/null +++ b/packages/backend-common/src/compat/legacy/index.ts @@ -0,0 +1,18 @@ +/* + * 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 { legacyPlugin, makeLegacyPlugin } from './legacy'; +export type { LegacyCreateRouter } from './legacy'; diff --git a/packages/backend-common/src/legacy.test.ts b/packages/backend-common/src/compat/legacy/legacy.test.ts similarity index 93% rename from packages/backend-common/src/legacy.test.ts rename to packages/backend-common/src/compat/legacy/legacy.test.ts index 09545daef4..e5d395a8f9 100644 --- a/packages/backend-common/src/legacy.test.ts +++ b/packages/backend-common/src/compat/legacy/legacy.test.ts @@ -21,12 +21,12 @@ import { import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; import { EventEmitter } from 'events'; import { Router } from 'express'; -import { createLegacyAuthAdapters } from './auth'; +import { createLegacyAuthAdapters } from '..'; import { legacyPlugin } from './legacy'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { authServiceFactory } from '../../backend-app-api/src/services/implementations/auth'; +import { authServiceFactory } from '../../../../backend-app-api/src/services/implementations/auth'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { tokenManagerServiceFactory } from '../../backend-app-api/src/services/implementations/tokenManager'; +import { tokenManagerServiceFactory } from '../../../../backend-app-api/src/services/implementations/tokenManager'; describe('legacyPlugin', () => { it('can auth across the new and old systems', async () => { diff --git a/packages/backend-common/src/legacy.ts b/packages/backend-common/src/compat/legacy/legacy.ts similarity index 96% rename from packages/backend-common/src/legacy.ts rename to packages/backend-common/src/compat/legacy/legacy.ts index 420126f519..57220a8430 100644 --- a/packages/backend-common/src/legacy.ts +++ b/packages/backend-common/src/compat/legacy/legacy.ts @@ -21,9 +21,9 @@ import { ServiceRef, } from '@backstage/backend-plugin-api'; import { RequestHandler } from 'express'; -import { cacheToPluginCacheManager } from './cache'; -import { loggerToWinstonLogger } from './logging'; -import { TokenManager } from './deprecated'; +import { cacheToPluginCacheManager } from '../cache'; +import { loggerToWinstonLogger } from '../logging'; +import { TokenManager } from '../../deprecated'; /** * @public diff --git a/packages/backend-common/src/database/index.ts b/packages/backend-common/src/compat/logging/index.ts similarity index 88% rename from packages/backend-common/src/database/index.ts rename to packages/backend-common/src/compat/logging/index.ts index 0e95261d82..10f949050c 100644 --- a/packages/backend-common/src/database/index.ts +++ b/packages/backend-common/src/compat/logging/index.ts @@ -14,5 +14,4 @@ * limitations under the License. */ -export * from './reexport'; -export type { PluginDatabaseManager } from './types'; +export { loggerToWinstonLogger } from './loggerToWinstonLogger'; diff --git a/packages/backend-common/src/logging/loggerToWinstonLogger.ts b/packages/backend-common/src/compat/logging/loggerToWinstonLogger.ts similarity index 100% rename from packages/backend-common/src/logging/loggerToWinstonLogger.ts rename to packages/backend-common/src/compat/logging/loggerToWinstonLogger.ts diff --git a/packages/backend-common/src/database/reexport.ts b/packages/backend-common/src/database/reexport.ts deleted file mode 100644 index 1ecff9be15..0000000000 --- a/packages/backend-common/src/database/reexport.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. - */ - -/* - * NOTE(freben): This is a temporary hack. We use cross-package imports so that - * we do not have to maintain double implementations for the time being, until - * backend-common is properly removed. When it is, the impleemntation should be - * moved into this part of the repo instead. - */ - -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { - DatabaseManager, - dropDatabase, - type DatabaseManagerOptions, - type LegacyRootDatabaseService, -} from '../../../backend-defaults/src/entrypoints/database/DatabaseManager'; - -export { - DatabaseManager, - dropDatabase, - type DatabaseManagerOptions, - type LegacyRootDatabaseService, -}; diff --git a/packages/backend-common/src/database/types.ts b/packages/backend-common/src/database/types.ts deleted file mode 100644 index a9cceaa1f9..0000000000 --- a/packages/backend-common/src/database/types.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - LifecycleService, - PluginMetadataService, -} from '@backstage/backend-plugin-api'; -import { Config } from '@backstage/config'; -import { Knex } from 'knex'; - -export type { DatabaseService as PluginDatabaseManager } from '@backstage/backend-plugin-api'; - -/** - * Manages an underlying Knex database driver. - */ -export interface DatabaseConnector { - /** - * Provides an instance of a knex database connector. - */ - createClient( - dbConfig: Config, - overrides?: Partial, - deps?: { - lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; - }, - ): Knex; - - /** - * Provides a partial knex config sufficient to override a database name. - */ - createNameOverride(name: string): Partial; - - /** - * Provides a partial knex config sufficient to override a PostgreSQL schema - * name within utilizing the `searchPath` knex configuration. - */ - createSchemaOverride?(name: string): Partial; - - /** - * Produces a knex connection config object representing a database connection - * string. - */ - parseConnectionString( - connectionString: string, - client?: string, - ): Knex.StaticConnectionConfig; - - /** - * Performs a side-effect to ensure database names passed in are present. - * - * Calling this function on databases which already exist should do nothing. - * Missing databases should be created if needed. - */ - ensureDatabaseExists?( - dbConfig: Config, - ...databases: Array - ): Promise; - - /** - * Performs a side-effect to ensure schema names passed in are present. - * - * Calling this function on schemas which already exist should do nothing. - * Missing schemas should be created if needed. - */ - ensureSchemaExists?( - dbConfig: Config, - ...schemas: Array - ): Promise; - - /** - * Deletes databases. - */ - dropDatabase?(dbConfig: Config, ...databases: Array): Promise; -} - -export interface Connector { - getClient( - pluginId: string, - deps?: { - lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; - }, - ): Promise; - - dropDatabase(...databaseNames: string[]): Promise; -} diff --git a/packages/backend-common/src/config.ts b/packages/backend-common/src/deprecated/config.ts similarity index 97% rename from packages/backend-common/src/config.ts rename to packages/backend-common/src/deprecated/config.ts index 733cd62390..2d06ca2072 100644 --- a/packages/backend-common/src/config.ts +++ b/packages/backend-common/src/deprecated/config.ts @@ -18,7 +18,7 @@ import { createConfigSecretEnumerator, loadBackendConfig as newLoadBackendConfig, -} from '../../backend-app-api/src/config'; +} from '../../../backend-app-api/src/config'; import { LoggerService } from '@backstage/backend-plugin-api'; import { AppConfig, Config } from '@backstage/config'; import { LoadConfigOptionsRemote } from '@backstage/config-loader'; diff --git a/packages/backend-common/src/context/AbortContext.test.ts b/packages/backend-common/src/deprecated/context/AbortContext.test.ts similarity index 100% rename from packages/backend-common/src/context/AbortContext.test.ts rename to packages/backend-common/src/deprecated/context/AbortContext.test.ts diff --git a/packages/backend-common/src/context/AbortContext.ts b/packages/backend-common/src/deprecated/context/AbortContext.ts similarity index 100% rename from packages/backend-common/src/context/AbortContext.ts rename to packages/backend-common/src/deprecated/context/AbortContext.ts diff --git a/packages/backend-common/src/context/Contexts.test.ts b/packages/backend-common/src/deprecated/context/Contexts.test.ts similarity index 100% rename from packages/backend-common/src/context/Contexts.test.ts rename to packages/backend-common/src/deprecated/context/Contexts.test.ts diff --git a/packages/backend-common/src/context/Contexts.ts b/packages/backend-common/src/deprecated/context/Contexts.ts similarity index 100% rename from packages/backend-common/src/context/Contexts.ts rename to packages/backend-common/src/deprecated/context/Contexts.ts diff --git a/packages/backend-common/src/context/RootContext.test.ts b/packages/backend-common/src/deprecated/context/RootContext.test.ts similarity index 100% rename from packages/backend-common/src/context/RootContext.test.ts rename to packages/backend-common/src/deprecated/context/RootContext.test.ts diff --git a/packages/backend-common/src/context/RootContext.ts b/packages/backend-common/src/deprecated/context/RootContext.ts similarity index 100% rename from packages/backend-common/src/context/RootContext.ts rename to packages/backend-common/src/deprecated/context/RootContext.ts diff --git a/packages/backend-common/src/context/ValueContext.test.ts b/packages/backend-common/src/deprecated/context/ValueContext.test.ts similarity index 100% rename from packages/backend-common/src/context/ValueContext.test.ts rename to packages/backend-common/src/deprecated/context/ValueContext.test.ts diff --git a/packages/backend-common/src/context/ValueContext.ts b/packages/backend-common/src/deprecated/context/ValueContext.ts similarity index 100% rename from packages/backend-common/src/context/ValueContext.ts rename to packages/backend-common/src/deprecated/context/ValueContext.ts diff --git a/packages/backend-common/src/context/index.ts b/packages/backend-common/src/deprecated/context/index.ts similarity index 100% rename from packages/backend-common/src/context/index.ts rename to packages/backend-common/src/deprecated/context/index.ts diff --git a/packages/backend-common/src/context/types.ts b/packages/backend-common/src/deprecated/context/types.ts similarity index 100% rename from packages/backend-common/src/context/types.ts rename to packages/backend-common/src/deprecated/context/types.ts diff --git a/packages/backend-common/src/hot.ts b/packages/backend-common/src/deprecated/hot.ts similarity index 100% rename from packages/backend-common/src/hot.ts rename to packages/backend-common/src/deprecated/hot.ts diff --git a/packages/backend-common/src/deprecated/index.ts b/packages/backend-common/src/deprecated/index.ts index 5309240ccb..e3e4101d25 100644 --- a/packages/backend-common/src/deprecated/index.ts +++ b/packages/backend-common/src/deprecated/index.ts @@ -14,32 +14,175 @@ * limitations under the License. */ +import { Config } from '@backstage/config'; + +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { HostDiscovery as _HostDiscovery } from '../../../backend-defaults/src/entrypoints/discovery/HostDiscovery'; + // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { CacheManager as _CacheManager } from '../../../backend-defaults/src/entrypoints/cache/CacheManager'; + // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { type PluginCacheManager as _PluginCacheManager, type CacheManagerOptions as _CacheManagerOptions, } from '../../../backend-defaults/src/entrypoints/cache/types'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports import { + dropDatabase as _dropDatabase, + DatabaseManager as _DatabaseManager, + type DatabaseManagerOptions as _DatabaseManagerOptions, + type LegacyRootDatabaseService as _LegacyRootDatabaseService, +} from '../../../backend-defaults/src/entrypoints/database/DatabaseManager'; + +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { AzureUrlReader as _AzureUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { BitbucketCloudUrlReader as _BitbucketCloudUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { BitbucketUrlReader as _BitbucketUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { BitbucketServerUrlReader as _BitbucketServerUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { GerritUrlReader as _GerritUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { GithubUrlReader as _GithubUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { GitlabUrlReader as _GitlabUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { GiteaUrlReader as _GiteaUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { HarnessUrlReader as _HarnessUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { AwsS3UrlReader as _AwsS3UrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { FetchUrlReader as _FetchUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { UrlReaders as _UrlReaders } from '../../../backend-defaults/src/entrypoints/urlReader/lib/UrlReaders'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { ReadUrlResponseFactory as _ReadUrlResponseFactory } from '../../../backend-defaults/src/entrypoints/urlReader/lib/ReadUrlResponseFactory'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import type { UrlReadersOptions as _UrlReadersOptions } from '../../../backend-defaults/src/entrypoints/urlReader/lib/UrlReaders'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import type { FromReadableArrayOptions as _FromReadableArrayOptions } from '../../../backend-defaults/src/entrypoints/urlReader/lib/types'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import type { + ReaderFactory as _ReaderFactory, + ReadTreeResponseFactory as _ReadTreeResponseFactory, + ReadTreeResponseFactoryOptions as _ReadTreeResponseFactoryOptions, + ReadUrlResponseFactoryFromStreamOptions as _ReadUrlResponseFactoryFromStreamOptions, + UrlReaderPredicateTuple as _UrlReaderPredicateTuple, +} from '../../../backend-defaults/src/entrypoints/urlReader/lib/types'; + +import { + DiscoveryService, CacheService, CacheServiceOptions, CacheServiceSetOptions, + DatabaseService as _PluginDatabaseManager, isDatabaseConflictError as _isDatabaseConflictError, resolvePackagePath as _resolvePackagePath, resolveSafeChildPath as _resolveSafeChildPath, isChildPath as _isChildPath, + ReadTreeOptions as _ReadTreeOptions, + ReadTreeResponse as _ReadTreeResponse, + ReadTreeResponseFile as _ReadTreeResponseFile, + ReadTreeResponseDirOptions as _ReadTreeResponseDirOptions, + ReadUrlOptions as _ReadUrlOptions, + ReadUrlResponse as _ReadUrlResponse, + SearchOptions as _SearchOptions, + SearchResponse as _SearchResponse, + SearchResponseFile as _SearchResponseFile, + UrlReaderService as _UrlReaderService, + LifecycleService, + PluginMetadataService, } from '@backstage/backend-plugin-api'; +export * from './hot'; +export * from './config'; export * from './scm'; export * from './tokens'; +export * from './logging'; +export * from './service'; +export * from './middleware'; +export * from './util'; + +/** + * @public + * @deprecated Use `DiscoveryService` from `@backstage/backend-plugin-api` instead + */ +export type PluginEndpointDiscovery = DiscoveryService; + +/** + * HostDiscovery is a basic PluginEndpointDiscovery implementation + * that can handle plugins that are hosted in a single or multiple deployments. + * + * The deployment may be scaled horizontally, as long as the external URL + * is the same for all instances. However, internal URLs will always be + * resolved to the same host, so there won't be any balancing of internal traffic. + * + * @public + * @deprecated Please import from `@backstage/backend-defaults/discovery` instead. + */ +export class HostDiscovery implements DiscoveryService { + /** + * Creates a new HostDiscovery discovery instance by reading + * from the `backend` config section, specifically the `.baseUrl` for + * discovering the external URL, and the `.listen` and `.https` config + * for the internal one. + * + * Can be overridden in config by providing a target and corresponding plugins in `discovery.endpoints`. + * eg. + * ```yaml + * discovery: + * endpoints: + * - target: https://internal.example.com/internal-catalog + * plugins: [catalog] + * - target: https://internal.example.com/secure/api/{{pluginId}} + * plugins: [auth, permission] + * - target: + * internal: https://internal.example.com/search + * external: https://example.com/search + * plugins: [search] + * ``` + * + * The basePath defaults to `/api`, meaning the default full internal + * path for the `catalog` plugin will be `http://localhost:7007/api/catalog`. + */ + static fromConfig(config: Config, options?: { basePath?: string }) { + return new HostDiscovery(_HostDiscovery.fromConfig(config, options)); + } + + private constructor(private readonly impl: _HostDiscovery) {} + + async getBaseUrl(pluginId: string): Promise { + return this.impl.getBaseUrl(pluginId); + } + + async getExternalBaseUrl(pluginId: string): Promise { + return this.impl.getExternalBaseUrl(pluginId); + } +} + +/** + * SingleHostDiscovery is a basic PluginEndpointDiscovery implementation + * that assumes that all plugins are hosted in a single deployment. + * + * The deployment may be scaled horizontally, as long as the external URL + * is the same for all instances. However, internal URLs will always be + * resolved to the same host, so there won't be any balancing of internal traffic. + * + * @public + * @deprecated Use `HostDiscovery` from `@backstage/backend-defaults/discovery` instead + */ +export { HostDiscovery as SingleHostDiscovery }; /** * @public * @deprecated Use `CacheManager` from the `@backstage/backend-defaults` package instead */ -export const CacheManager = _CacheManager; +export class CacheManager extends _CacheManager {} /** * @public @@ -71,6 +214,55 @@ export type CacheClientSetOptions = CacheServiceSetOptions; */ export type CacheClientOptions = CacheServiceOptions; +/** + * @public + * @deprecated Use `DatabaseManager` from the `@backstage/backend-defaults` package instead + */ +export class DatabaseManager implements LegacyRootDatabaseService { + private constructor(private readonly _databaseManager: _DatabaseManager) {} + + static fromConfig( + config: Config, + options?: DatabaseManagerOptions, + ): DatabaseManager { + const _databaseManager = _DatabaseManager.fromConfig(config, options); + return new DatabaseManager(_databaseManager); + } + + forPlugin( + pluginId: string, + deps?: + | { lifecycle: LifecycleService; pluginMetadata: PluginMetadataService } + | undefined, + ): PluginDatabaseManager { + return this._databaseManager.forPlugin(pluginId, deps); + } +} + +/** + * @public + * @deprecated Use `DatabaseManagerOptions` from the `@backstage/backend-defaults` package instead + */ +export type DatabaseManagerOptions = _DatabaseManagerOptions; + +/** + * @public + * @deprecated Use `DatabaseService` from the `@backstage/backend-plugin-api` package instead + */ +export type PluginDatabaseManager = _PluginDatabaseManager; + +/** + * @public + * @deprecated Use `LegacyRootDatabaseService` from the `@backstage/backend-defaults` package instead + */ +export type LegacyRootDatabaseService = _LegacyRootDatabaseService; + +/** + * @public + * @deprecated Use `dropDatabase` from the `@backstage/backend-defaults` package instead + */ +export const dropDatabase = _dropDatabase; + /** * @public * @deprecated This function is deprecated and will be removed in a future release, see https://github.com/backstage/backstage/issues/24493. @@ -98,3 +290,184 @@ export const resolveSafeChildPath = _resolveSafeChildPath; * Please use the `isChildPath` function from the `@backstage/cli-common` package instead. */ export const isChildPath = _isChildPath; + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class AzureUrlReader extends _AzureUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class BitbucketCloudUrlReader extends _BitbucketCloudUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class BitbucketUrlReader extends _BitbucketUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class BitbucketServerUrlReader extends _BitbucketServerUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class GerritUrlReader extends _GerritUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class GithubUrlReader extends _GithubUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class GitlabUrlReader extends _GitlabUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class GiteaUrlReader extends _GiteaUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class HarnessUrlReader extends _HarnessUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class AwsS3UrlReader extends _AwsS3UrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class FetchUrlReader extends _FetchUrlReader {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class UrlReaders extends _UrlReaders {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export class ReadUrlResponseFactory extends _ReadUrlResponseFactory {} + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export type UrlReadersOptions = _UrlReadersOptions; + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export type FromReadableArrayOptions = _FromReadableArrayOptions; + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export type ReaderFactory = _ReaderFactory; + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export type ReadTreeResponseFactory = _ReadTreeResponseFactory; + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export type ReadTreeResponseFactoryOptions = _ReadTreeResponseFactoryOptions; + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export type ReadUrlResponseFactoryFromStreamOptions = + _ReadUrlResponseFactoryFromStreamOptions; + +/** + * @public + * @deprecated Import from `@backstage/backend-defaults/urlReader` instead + */ +export type UrlReaderPredicateTuple = _UrlReaderPredicateTuple; + +/** + * @public + * @deprecated Use `UrlReaderServiceReadTreeOptions` from `@backstage/backend-plugin-api` instead + */ +export type ReadTreeOptions = _ReadTreeOptions; + +/** + * @public + * @deprecated Use `UrlReaderServiceReadTreeResponse` from `@backstage/backend-plugin-api` instead + */ +export type ReadTreeResponse = _ReadTreeResponse; + +/** + * @public + * @deprecated Use `UrlReaderServiceReadTreeResponseFile` from `@backstage/backend-plugin-api` instead + */ +export type ReadTreeResponseFile = _ReadTreeResponseFile; + +/** + * @public + * @deprecated Use `UrlReaderServiceReadTreeResponseDirOptions` from `@backstage/backend-plugin-api` instead + */ +export type ReadTreeResponseDirOptions = _ReadTreeResponseDirOptions; + +/** + * @public + * @deprecated Use `UrlReaderServiceReadUrlOptions` from `@backstage/backend-plugin-api` instead + */ +export type ReadUrlOptions = _ReadUrlOptions; + +/** + * @public + * @deprecated Use `UrlReaderServiceReadUrlResponse` from `@backstage/backend-plugin-api` instead + */ +export type ReadUrlResponse = _ReadUrlResponse; + +/** + * @public + * @deprecated Use `UrlReaderServiceSearchOptions` from `@backstage/backend-plugin-api` instead + */ +export type SearchOptions = _SearchOptions; + +/** + * @public + * @deprecated Use `UrlReaderServiceSearchResponse` from `@backstage/backend-plugin-api` instead + */ +export type SearchResponse = _SearchResponse; + +/** + * @public + * @deprecated Use `UrlReaderServiceSearchResponseFile` from `@backstage/backend-plugin-api` instead + */ +export type SearchResponseFile = _SearchResponseFile; + +/** + * @public + * @deprecated Use `UrlReaderService` from `@backstage/backend-plugin-api` instead + */ +export type UrlReader = _UrlReaderService; diff --git a/packages/backend-common/src/logging/createRootLogger.ts b/packages/backend-common/src/deprecated/logging/createRootLogger.ts similarity index 98% rename from packages/backend-common/src/logging/createRootLogger.ts rename to packages/backend-common/src/deprecated/logging/createRootLogger.ts index 20ee272b79..b177024601 100644 --- a/packages/backend-common/src/logging/createRootLogger.ts +++ b/packages/backend-common/src/deprecated/logging/createRootLogger.ts @@ -15,12 +15,12 @@ */ // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { WinstonLogger } from '../../../backend-app-api/src/logging/WinstonLogger'; +import { WinstonLogger } from '../../../../backend-app-api/src/logging/WinstonLogger'; import { merge } from 'lodash'; import * as winston from 'winston'; import { format, LoggerOptions } from 'winston'; -import { setRootLogger } from './globalLoggers'; import { TransformableInfo } from 'logform'; +import { setRootLogger } from './globalLoggers'; const getRedacter = (() => { let redacter: ReturnType | undefined = diff --git a/packages/backend-common/src/logging/globalLoggers.ts b/packages/backend-common/src/deprecated/logging/globalLoggers.ts similarity index 100% rename from packages/backend-common/src/logging/globalLoggers.ts rename to packages/backend-common/src/deprecated/logging/globalLoggers.ts diff --git a/packages/backend-common/src/logging/index.ts b/packages/backend-common/src/deprecated/logging/index.ts similarity index 92% rename from packages/backend-common/src/logging/index.ts rename to packages/backend-common/src/deprecated/logging/index.ts index e6b29afa15..b223f5c946 100644 --- a/packages/backend-common/src/logging/index.ts +++ b/packages/backend-common/src/deprecated/logging/index.ts @@ -20,4 +20,3 @@ export { redactWinstonLogLine, coloredFormat, } from './createRootLogger'; -export { loggerToWinstonLogger } from './loggerToWinstonLogger'; diff --git a/packages/backend-common/src/middleware/errorHandler.test.ts b/packages/backend-common/src/deprecated/middleware/errorHandler.test.ts similarity index 100% rename from packages/backend-common/src/middleware/errorHandler.test.ts rename to packages/backend-common/src/deprecated/middleware/errorHandler.test.ts index ab07a91022..2544a0a863 100644 --- a/packages/backend-common/src/middleware/errorHandler.test.ts +++ b/packages/backend-common/src/deprecated/middleware/errorHandler.test.ts @@ -14,6 +14,10 @@ * limitations under the License. */ +import express from 'express'; +import { STATUS_CODES } from 'http'; +import createError from 'http-errors'; +import request from 'supertest'; import { AuthenticationError, ConflictError, @@ -23,11 +27,7 @@ import { NotModifiedError, ResponseError, } from '@backstage/errors'; -import express from 'express'; -import createError from 'http-errors'; -import request from 'supertest'; import { errorHandler } from './errorHandler'; -import { STATUS_CODES } from 'http'; describe('errorHandler', () => { it('gives default code and message', async () => { diff --git a/packages/backend-common/src/middleware/errorHandler.ts b/packages/backend-common/src/deprecated/middleware/errorHandler.ts similarity index 87% rename from packages/backend-common/src/middleware/errorHandler.ts rename to packages/backend-common/src/deprecated/middleware/errorHandler.ts index 346fe01645..b4f07b9320 100644 --- a/packages/backend-common/src/middleware/errorHandler.ts +++ b/packages/backend-common/src/deprecated/middleware/errorHandler.ts @@ -16,15 +16,16 @@ import { ErrorRequestHandler } from 'express'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { getRootLogger } from '../logging'; import { ConfigReader } from '@backstage/config'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { MiddlewareFactory } from '../../../backend-app-api/src/http/MiddlewareFactory'; +import { MiddlewareFactory } from '../../../../backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory'; +import { getRootLogger } from '../logging'; /** * Options passed to the {@link errorHandler} middleware. * * @public + * @deprecated This type is being deprecated along with the {@link @backstage/backend-common#errorHandler} function. */ export type ErrorHandlerOptions = { /** @@ -62,7 +63,7 @@ export type ErrorHandlerOptions = { * * @public * @returns An Express error request handler - * @deprecated Use {@link @backstage/backend-app-api#MiddlewareFactory.create.error} instead + * @deprecated Use {@link @backstage/backend-defaults/rootHttpRouter#MiddlewareFactory.create.error} instead */ export function errorHandler( options: ErrorHandlerOptions = {}, diff --git a/packages/backend-common/src/middleware/index.ts b/packages/backend-common/src/deprecated/middleware/index.ts similarity index 100% rename from packages/backend-common/src/middleware/index.ts rename to packages/backend-common/src/deprecated/middleware/index.ts diff --git a/packages/backend-common/src/middleware/notFoundHandler.test.ts b/packages/backend-common/src/deprecated/middleware/notFoundHandler.test.ts similarity index 100% rename from packages/backend-common/src/middleware/notFoundHandler.test.ts rename to packages/backend-common/src/deprecated/middleware/notFoundHandler.test.ts diff --git a/packages/backend-common/src/middleware/notFoundHandler.ts b/packages/backend-common/src/deprecated/middleware/notFoundHandler.ts similarity index 91% rename from packages/backend-common/src/middleware/notFoundHandler.ts rename to packages/backend-common/src/deprecated/middleware/notFoundHandler.ts index 19c01ede9c..bb9504a9ec 100644 --- a/packages/backend-common/src/middleware/notFoundHandler.ts +++ b/packages/backend-common/src/deprecated/middleware/notFoundHandler.ts @@ -15,7 +15,7 @@ */ // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { MiddlewareFactory } from '../../../backend-app-api/src/http/MiddlewareFactory'; +import { MiddlewareFactory } from '../../../../backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory'; import { ConfigReader } from '@backstage/config'; import { RequestHandler } from 'express'; import { getRootLogger } from '../logging'; diff --git a/packages/backend-common/src/middleware/requestLoggingHandler.test.ts b/packages/backend-common/src/deprecated/middleware/requestLoggingHandler.test.ts similarity index 100% rename from packages/backend-common/src/middleware/requestLoggingHandler.test.ts rename to packages/backend-common/src/deprecated/middleware/requestLoggingHandler.test.ts diff --git a/packages/backend-common/src/middleware/requestLoggingHandler.ts b/packages/backend-common/src/deprecated/middleware/requestLoggingHandler.ts similarity index 85% rename from packages/backend-common/src/middleware/requestLoggingHandler.ts rename to packages/backend-common/src/deprecated/middleware/requestLoggingHandler.ts index fd6973f9b6..f30f2de659 100644 --- a/packages/backend-common/src/middleware/requestLoggingHandler.ts +++ b/packages/backend-common/src/deprecated/middleware/requestLoggingHandler.ts @@ -15,11 +15,11 @@ */ // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { MiddlewareFactory } from '../../../backend-app-api/src/http/MiddlewareFactory'; +import { MiddlewareFactory } from '../../../../backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory'; import { RequestHandler } from 'express'; +import { ConfigReader } from '@backstage/config'; import { LoggerService } from '@backstage/backend-plugin-api'; import { getRootLogger } from '../logging'; -import { ConfigReader } from '@backstage/config'; /** * Logs incoming requests. @@ -27,7 +27,7 @@ import { ConfigReader } from '@backstage/config'; * @public * @param logger - An optional logger to use. If not specified, the root logger will be used. * @returns An Express request handler - * @deprecated @deprecated Use {@link @backstage/backend-app-api#MiddlewareFactory.create.logging} instead + * @deprecated Use {@link @backstage/backend-app-api#MiddlewareFactory.create.logging} instead */ export function requestLoggingHandler(logger?: LoggerService): RequestHandler { return MiddlewareFactory.create({ diff --git a/packages/backend-common/src/middleware/statusCheckHandler.test.ts b/packages/backend-common/src/deprecated/middleware/statusCheckHandler.test.ts similarity index 100% rename from packages/backend-common/src/middleware/statusCheckHandler.test.ts rename to packages/backend-common/src/deprecated/middleware/statusCheckHandler.test.ts diff --git a/packages/backend-common/src/middleware/statusCheckHandler.ts b/packages/backend-common/src/deprecated/middleware/statusCheckHandler.ts similarity index 73% rename from packages/backend-common/src/middleware/statusCheckHandler.ts rename to packages/backend-common/src/deprecated/middleware/statusCheckHandler.ts index 4bd1a701c3..ebaf84c1b9 100644 --- a/packages/backend-common/src/middleware/statusCheckHandler.ts +++ b/packages/backend-common/src/deprecated/middleware/statusCheckHandler.ts @@ -21,6 +21,7 @@ import { NextFunction, Request, Response, RequestHandler } from 'express'; * {@link createStatusCheckRouter}. * * @public + * @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/ | new backend system} and use the {@link https://backstage.io/docs/backend-system/core-services/root-health | Root Health Service} instead. */ export type StatusCheck = () => Promise; @@ -28,6 +29,7 @@ export type StatusCheck = () => Promise; * Options passed to {@link statusCheckHandler}. * * @public + * @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/ | new backend system} and use the {@link https://backstage.io/docs/backend-system/core-services/root-health | Root Health Service} instead. */ export interface StatusCheckHandlerOptions { /** @@ -44,6 +46,7 @@ export interface StatusCheckHandlerOptions { * @public * @param options - An optional configuration object. * @returns An Express error request handler + * @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/ | new backend system} and use the {@link https://backstage.io/docs/backend-system/core-services/root-health | Root Health Service} instead. */ export async function statusCheckHandler( options: StatusCheckHandlerOptions = {}, diff --git a/packages/backend-common/src/service/createServiceBuilder.ts b/packages/backend-common/src/deprecated/service/createServiceBuilder.ts similarity index 100% rename from packages/backend-common/src/service/createServiceBuilder.ts rename to packages/backend-common/src/deprecated/service/createServiceBuilder.ts diff --git a/packages/backend-common/src/service/createStatusCheckRouter.test.ts b/packages/backend-common/src/deprecated/service/createStatusCheckRouter.test.ts similarity index 100% rename from packages/backend-common/src/service/createStatusCheckRouter.test.ts rename to packages/backend-common/src/deprecated/service/createStatusCheckRouter.test.ts diff --git a/packages/backend-common/src/service/createStatusCheckRouter.ts b/packages/backend-common/src/deprecated/service/createStatusCheckRouter.ts similarity index 88% rename from packages/backend-common/src/service/createStatusCheckRouter.ts rename to packages/backend-common/src/deprecated/service/createStatusCheckRouter.ts index b43bd5585c..fdece10ec5 100644 --- a/packages/backend-common/src/service/createStatusCheckRouter.ts +++ b/packages/backend-common/src/deprecated/service/createStatusCheckRouter.ts @@ -17,7 +17,7 @@ import { LoggerService } from '@backstage/backend-plugin-api'; import Router from 'express-promise-router'; import express from 'express'; -import { errorHandler, statusCheckHandler, StatusCheck } from '../middleware'; +import { errorHandler, statusCheckHandler, StatusCheck } from '..'; /** * Creates a default status checking router, that you can add to your express @@ -30,6 +30,7 @@ import { errorHandler, statusCheckHandler, StatusCheck } from '../middleware'; * requests. * * @public + * @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/ | new backend system} and use the {@link https://backstage.io/docs/backend-system/core-services/root-health | Root Health Service} instead. */ export async function createStatusCheckRouter(options: { logger: LoggerService; diff --git a/packages/backend-common/src/service/index.ts b/packages/backend-common/src/deprecated/service/index.ts similarity index 100% rename from packages/backend-common/src/service/index.ts rename to packages/backend-common/src/deprecated/service/index.ts diff --git a/packages/backend-common/src/service/lib/ServiceBuilderImpl.test.ts b/packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.test.ts similarity index 100% rename from packages/backend-common/src/service/lib/ServiceBuilderImpl.test.ts rename to packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.test.ts diff --git a/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts b/packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.ts similarity index 98% rename from packages/backend-common/src/service/lib/ServiceBuilderImpl.ts rename to packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.ts index 039a9a51eb..b338eb20b1 100644 --- a/packages/backend-common/src/service/lib/ServiceBuilderImpl.ts +++ b/packages/backend-common/src/deprecated/service/lib/ServiceBuilderImpl.ts @@ -37,7 +37,7 @@ import { readHttpServerOptions, HttpServerOptions, createHttpServer, -} from '../../../../backend-app-api/src/http'; +} from '../../../../../backend-defaults/src/entrypoints/rootHttpRouter/http'; export type CspOptions = Record; diff --git a/packages/backend-common/src/service/types.ts b/packages/backend-common/src/deprecated/service/types.ts similarity index 96% rename from packages/backend-common/src/service/types.ts rename to packages/backend-common/src/deprecated/service/types.ts index bb4f98cd1c..ace0712d2f 100644 --- a/packages/backend-common/src/service/types.ts +++ b/packages/backend-common/src/deprecated/service/types.ts @@ -128,6 +128,7 @@ export type ServiceBuilder = { * A factory for request loggers. * * @public + * @deprecated This type is being deprecated along with the {@link @backstage/backend-common#createServiceBuilder} function. */ export type RequestLoggingHandlerFactory = ( logger?: LoggerService, diff --git a/packages/backend-common/src/util/ContainerRunner.ts b/packages/backend-common/src/deprecated/util/ContainerRunner.ts similarity index 87% rename from packages/backend-common/src/util/ContainerRunner.ts rename to packages/backend-common/src/deprecated/util/ContainerRunner.ts index 351a5da613..92081cea16 100644 --- a/packages/backend-common/src/util/ContainerRunner.ts +++ b/packages/backend-common/src/deprecated/util/ContainerRunner.ts @@ -22,6 +22,7 @@ import { Writable } from 'stream'; * {@link https://github.com/apocas/dockerode?tab=readme-ov-file#pull-from-private-repos} * * @public + * @deprecated This interface is deprecated and will be removed in a future release. */ export interface PullOptions { authconfig?: { @@ -39,6 +40,7 @@ export interface PullOptions { * Options passed to the {@link ContainerRunner.runContainer} method. * * @public + * @deprecated This type is deprecated and will be removed in a future release. */ export type RunContainerOptions = { imageName: string; @@ -57,6 +59,7 @@ export type RunContainerOptions = { * Handles the running of containers, on behalf of others. * * @public + * @deprecated This interface is deprecated and will be removed in a future release. */ export interface ContainerRunner { /** diff --git a/packages/backend-common/src/util/DockerContainerRunner.test.ts b/packages/backend-common/src/deprecated/util/DockerContainerRunner.test.ts similarity index 100% rename from packages/backend-common/src/util/DockerContainerRunner.test.ts rename to packages/backend-common/src/deprecated/util/DockerContainerRunner.test.ts diff --git a/packages/backend-common/src/util/DockerContainerRunner.ts b/packages/backend-common/src/deprecated/util/DockerContainerRunner.ts similarity index 98% rename from packages/backend-common/src/util/DockerContainerRunner.ts rename to packages/backend-common/src/deprecated/util/DockerContainerRunner.ts index 89a17fff51..ea576e4a3a 100644 --- a/packages/backend-common/src/util/DockerContainerRunner.ts +++ b/packages/backend-common/src/deprecated/util/DockerContainerRunner.ts @@ -28,6 +28,7 @@ export type UserOptions = { * A {@link ContainerRunner} for Docker containers. * * @public + * @deprecated This class is deprecated and will be removed in a future release. */ export class DockerContainerRunner implements ContainerRunner { private readonly dockerClient: Docker; diff --git a/packages/backend-common/src/util/KubernetesContainerRunner.test.ts b/packages/backend-common/src/deprecated/util/KubernetesContainerRunner.test.ts similarity index 100% rename from packages/backend-common/src/util/KubernetesContainerRunner.test.ts rename to packages/backend-common/src/deprecated/util/KubernetesContainerRunner.test.ts diff --git a/packages/backend-common/src/util/KubernetesContainerRunner.ts b/packages/backend-common/src/deprecated/util/KubernetesContainerRunner.ts similarity index 97% rename from packages/backend-common/src/util/KubernetesContainerRunner.ts rename to packages/backend-common/src/deprecated/util/KubernetesContainerRunner.ts index 4b235caf2c..0402f70079 100644 --- a/packages/backend-common/src/util/KubernetesContainerRunner.ts +++ b/packages/backend-common/src/deprecated/util/KubernetesContainerRunner.ts @@ -37,6 +37,7 @@ import { v4 as uuid } from 'uuid'; * Every mount must start with the 'basePath'. * * @public + * @deprecated This type is deprecated and will be removed in a future release. */ export type KubernetesContainerRunnerMountBase = { volumeName: string; @@ -53,6 +54,7 @@ export type KubernetesContainerRunnerMountBase = { * a volume definition named as the {@link KubernetesContainerRunnerMountBase} 'volumeName'. * * @public + * @deprecated This type is deprecated and will be removed in a future release. */ export type KubernetesContainerRunnerOptions = { kubeConfig: KubeConfig; @@ -69,6 +71,7 @@ export type KubernetesContainerRunnerOptions = { * Runs containers leveraging Jobs on a Kubernetes cluster * * @public + * @deprecated This class is deprecated and will be removed in a future release. */ export class KubernetesContainerRunner implements ContainerRunner { private readonly kubeConfig: KubeConfig; diff --git a/packages/backend-common/src/util/index.ts b/packages/backend-common/src/deprecated/util/index.ts similarity index 100% rename from packages/backend-common/src/util/index.ts rename to packages/backend-common/src/deprecated/util/index.ts diff --git a/packages/backend-common/src/discovery/HostDiscovery.ts b/packages/backend-common/src/discovery/HostDiscovery.ts deleted file mode 100644 index ec8d02cce0..0000000000 --- a/packages/backend-common/src/discovery/HostDiscovery.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. - */ - -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { HostDiscovery as _HostDiscovery } from '../../../backend-defaults/src/entrypoints/discovery/HostDiscovery'; -import { DiscoveryService } from '@backstage/backend-plugin-api'; - -/** - * @public - * @deprecated Use `DiscoveryService` from `@backstage/backend-plugin-api` instead - */ -export type PluginEndpointDiscovery = DiscoveryService; - -/** - * HostDiscovery is a basic PluginEndpointDiscovery implementation - * that can handle plugins that are hosted in a single or multiple deployments. - * - * The deployment may be scaled horizontally, as long as the external URL - * is the same for all instances. However, internal URLs will always be - * resolved to the same host, so there won't be any balancing of internal traffic. - * - * @public - * @deprecated Please import from `@backstage/backend-defaults/discovery` instead. - */ -export const HostDiscovery = _HostDiscovery; - -/** - * SingleHostDiscovery is a basic PluginEndpointDiscovery implementation - * that assumes that all plugins are hosted in a single deployment. - * - * The deployment may be scaled horizontally, as long as the external URL - * is the same for all instances. However, internal URLs will always be - * resolved to the same host, so there won't be any balancing of internal traffic. - * - * @public - * @deprecated Use `HostDiscovery` from `@backstage/backend-defaults/discovery` instead - */ -export const SingleHostDiscovery = _HostDiscovery; diff --git a/packages/backend-common/src/index.ts b/packages/backend-common/src/index.ts index bd6fdb2bb6..ad5621b5a9 100644 --- a/packages/backend-common/src/index.ts +++ b/packages/backend-common/src/index.ts @@ -20,17 +20,5 @@ * @packageDocumentation */ -export { legacyPlugin, makeLegacyPlugin } from './legacy'; -export type { LegacyCreateRouter } from './legacy'; -export { loadBackendConfig } from './config'; -export * from './auth'; -export * from './cache'; export * from './deprecated'; -export * from './database'; -export * from './discovery'; -export * from './hot'; -export * from './logging'; -export * from './middleware'; -export * from './reading'; -export * from './service'; -export * from './util'; +export * from './compat'; diff --git a/packages/backend-common/src/reading/index.ts b/packages/backend-common/src/reading/index.ts deleted file mode 100644 index 14863d2044..0000000000 --- a/packages/backend-common/src/reading/index.ts +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT 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-relative-monorepo-imports -import { AzureUrlReader as _AzureUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { BitbucketCloudUrlReader as _BitbucketCloudUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { BitbucketUrlReader as _BitbucketUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { BitbucketServerUrlReader as _BitbucketServerUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { GerritUrlReader as _GerritUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { GithubUrlReader as _GithubUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { GitlabUrlReader as _GitlabUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { GiteaUrlReader as _GiteaUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { HarnessUrlReader as _HarnessUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { AwsS3UrlReader as _AwsS3UrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { FetchUrlReader as _FetchUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { UrlReaders as _UrlReaders } from '../../../backend-defaults/src/entrypoints/urlReader/lib/UrlReaders'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { ReadUrlResponseFactory as _ReadUrlResponseFactory } from '../../../backend-defaults/src/entrypoints/urlReader/lib/ReadUrlResponseFactory'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import type { UrlReadersOptions as _UrlReadersOptions } from '../../../backend-defaults/src/entrypoints/urlReader/lib/UrlReaders'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import type { FromReadableArrayOptions as _FromReadableArrayOptions } from '../../../backend-defaults/src/entrypoints/urlReader/lib/types'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import type { - ReaderFactory as _ReaderFactory, - ReadTreeResponseFactory as _ReadTreeResponseFactory, - ReadTreeResponseFactoryOptions as _ReadTreeResponseFactoryOptions, - ReadUrlResponseFactoryFromStreamOptions as _ReadUrlResponseFactoryFromStreamOptions, - UrlReaderPredicateTuple as _UrlReaderPredicateTuple, -} from '../../../backend-defaults/src/entrypoints/urlReader/lib/types'; - -import type { - ReadTreeOptions as _ReadTreeOptions, - ReadTreeResponse as _ReadTreeResponse, - ReadTreeResponseFile as _ReadTreeResponseFile, - ReadTreeResponseDirOptions as _ReadTreeResponseDirOptions, - ReadUrlOptions as _ReadUrlOptions, - ReadUrlResponse as _ReadUrlResponse, - SearchOptions as _SearchOptions, - SearchResponse as _SearchResponse, - SearchResponseFile as _SearchResponseFile, - UrlReaderService as _UrlReaderService, -} from '@backstage/backend-plugin-api'; - -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const AzureUrlReader = _AzureUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const BitbucketCloudUrlReader = _BitbucketCloudUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const BitbucketUrlReader = _BitbucketUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const BitbucketServerUrlReader = _BitbucketServerUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const GerritUrlReader = _GerritUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const GithubUrlReader = _GithubUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const GitlabUrlReader = _GitlabUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const GiteaUrlReader = _GiteaUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const HarnessUrlReader = _HarnessUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const AwsS3UrlReader = _AwsS3UrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const FetchUrlReader = _FetchUrlReader; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const UrlReaders = _UrlReaders; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export const ReadUrlResponseFactory = _ReadUrlResponseFactory; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export type UrlReadersOptions = _UrlReadersOptions; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export type FromReadableArrayOptions = _FromReadableArrayOptions; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export type ReaderFactory = _ReaderFactory; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export type ReadTreeResponseFactory = _ReadTreeResponseFactory; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export type ReadTreeResponseFactoryOptions = _ReadTreeResponseFactoryOptions; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export type ReadUrlResponseFactoryFromStreamOptions = - _ReadUrlResponseFactoryFromStreamOptions; -/** - * @public - * @deprecated Import from `@backstage/backend-defaults/urlReader` instead - */ -export type UrlReaderPredicateTuple = _UrlReaderPredicateTuple; - -/** - * @public - * @deprecated Use `UrlReaderServiceReadTreeOptions` from `@backstage/backend-plugin-api` instead - */ -export type ReadTreeOptions = _ReadTreeOptions; -/** - * @public - * @deprecated Use `UrlReaderServiceReadTreeResponse` from `@backstage/backend-plugin-api` instead - */ -export type ReadTreeResponse = _ReadTreeResponse; -/** - * @public - * @deprecated Use `UrlReaderServiceReadTreeResponseFile` from `@backstage/backend-plugin-api` instead - */ -export type ReadTreeResponseFile = _ReadTreeResponseFile; -/** - * @public - * @deprecated Use `UrlReaderServiceReadTreeResponseDirOptions` from `@backstage/backend-plugin-api` instead - */ -export type ReadTreeResponseDirOptions = _ReadTreeResponseDirOptions; -/** - * @public - * @deprecated Use `UrlReaderServiceReadUrlOptions` from `@backstage/backend-plugin-api` instead - */ -export type ReadUrlOptions = _ReadUrlOptions; -/** - * @public - * @deprecated Use `UrlReaderServiceReadUrlResponse` from `@backstage/backend-plugin-api` instead - */ -export type ReadUrlResponse = _ReadUrlResponse; -/** - * @public - * @deprecated Use `UrlReaderServiceSearchOptions` from `@backstage/backend-plugin-api` instead - */ -export type SearchOptions = _SearchOptions; -/** - * @public - * @deprecated Use `UrlReaderServiceSearchResponse` from `@backstage/backend-plugin-api` instead - */ -export type SearchResponse = _SearchResponse; -/** - * @public - * @deprecated Use `UrlReaderServiceSearchResponseFile` from `@backstage/backend-plugin-api` instead - */ -export type SearchResponseFile = _SearchResponseFile; -/** - * @public - * @deprecated Use `UrlReaderService` from `@backstage/backend-plugin-api` instead - */ -export type UrlReader = _UrlReaderService; diff --git a/packages/backend-common/src/util/escapeRegExp.test.ts b/packages/backend-common/src/util/escapeRegExp.test.ts deleted file mode 100644 index 13c6ae4a5a..0000000000 --- a/packages/backend-common/src/util/escapeRegExp.test.ts +++ /dev/null @@ -1,84 +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 { escapeRegExp } from './escapeRegExp'; - -describe('escapeRegExp', () => { - test('does not escape non-regex characters', () => { - expect(escapeRegExp('Backstage Backstage')).toBe('Backstage Backstage'); - }); - - test('all the characters', () => { - expect(escapeRegExp('^$\\.*+?()[]{}|')).toBe( - '\\^\\$\\\\\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|', - ); - }); - - test('character: ^', () => { - expect(escapeRegExp('^')).toBe('\\^'); - }); - - test('character: $', () => { - expect(escapeRegExp('$')).toBe('\\$'); - }); - - test('character: \\', () => { - expect(escapeRegExp('\\')).toBe('\\\\'); - }); - - test('character: .', () => { - expect(escapeRegExp('.')).toBe('\\.'); - }); - - test('character: *', () => { - expect(escapeRegExp('*')).toBe('\\*'); - }); - - test('character: +', () => { - expect(escapeRegExp('+')).toBe('\\+'); - }); - - test('character: ?', () => { - expect(escapeRegExp('?')).toBe('\\?'); - }); - - test('character: (', () => { - expect(escapeRegExp('(')).toBe('\\('); - }); - - test('character: )', () => { - expect(escapeRegExp(')')).toBe('\\)'); - }); - - test('character: [', () => { - expect(escapeRegExp('[')).toBe('\\['); - }); - - test('character: ]', () => { - expect(escapeRegExp(']')).toBe('\\]'); - }); - - test('character: {', () => { - expect(escapeRegExp('{')).toBe('\\{'); - }); - - test('character: }', () => { - expect(escapeRegExp('}')).toBe('\\}'); - }); - - test('character: |', () => { - expect(escapeRegExp('|')).toBe('\\|'); - }); -}); diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index c88dc8f587..7e9788756f 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,69 @@ # @backstage/backend-defaults +## 0.3.3-next.0 + +### Patch Changes + +- 53ced70: Added a new Root Health Service which adds new endpoints for health checks. +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- cb14a05: Repack the package to fix issues with typescript with named exports +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/backend-app-api@0.7.9-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## 0.3.0 + +### Minor Changes + +- 662dce8: **BREAKING**: The `workdir` argument have been removed from The `GerritUrlReader` constructor. + + **BREAKING**: The Gerrit `readTree` implementation will now only use the Gitiles api. Support + for using git to clone the repo has been removed. + +- 02103be: Deprecated and moved over core services to `@backstage/backend-defaults` + +### Patch Changes + +- 1897169: Exposed `DefaultSchedulerService` +- b5bc997: Refactor cache manager inline types. +- e171620: Remove dependency with `@backstage/backend-commons` package. +- 6551b3d: Added core service factories and implementations from + `@backstage/backend-app-api`. They are now available as subpath exports, e.g. + `@backstage/backend-defaults/scheduler` is where the service factory and default + implementation of `coreServices.scheduler` now lives. They have been marked as + deprecated in their old locations. +- 8aab451: Internal minor refactors of the database connectors +- 0634fdc: Deprecated `dropDatabase` +- b2ee7f3: Moved over all URL reader functionality from `@backstage/backend-common` to `@backstage/backend-defaults/urlReader`. Please update your imports. +- 9539a0b: Added `@backstage/backend-defaults/auth`, `@backstage/backend-defaults/httpAuth`, and `@backstage/backend-defaults/userInfo` to house their respective backend service factories. You should now import these services from those new locations, instead of `@backstage/backend-app-api`. +- Updated dependencies + - @backstage/backend-app-api@0.7.6 + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/integration@1.12.0 + - @backstage/plugin-events-node@0.3.5 + - @backstage/plugin-permission-node@0.7.30 + - @backstage/cli-common@0.1.14 + - @backstage/config-loader@1.8.1 + - @backstage/backend-dev-utils@0.1.4 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + ## 0.3.0-next.3 ### Patch Changes diff --git a/packages/backend-defaults/api-report-auth.md b/packages/backend-defaults/api-report-auth.md new file mode 100644 index 0000000000..d64ce5bc2a --- /dev/null +++ b/packages/backend-defaults/api-report-auth.md @@ -0,0 +1,13 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { AuthService } from '@backstage/backend-plugin-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @public +export const authServiceFactory: () => ServiceFactory; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/api-report-cache.md b/packages/backend-defaults/api-report-cache.md index 2cd2f3efc9..0bfd7eb463 100644 --- a/packages/backend-defaults/api-report-cache.md +++ b/packages/backend-defaults/api-report-cache.md @@ -11,15 +11,10 @@ import { ServiceFactory } from '@backstage/backend-plugin-api'; // @public export class CacheManager { - forPlugin(pluginId: string): { - getClient(options?: CacheServiceOptions): CacheService; - }; + forPlugin(pluginId: string): PluginCacheManager; static fromConfig( config: Config, - options?: { - logger?: LoggerService; - onError?: (err: Error) => void; - }, + options?: CacheManagerOptions, ): CacheManager; } @@ -29,7 +24,7 @@ export type CacheManagerOptions = { onError?: (err: Error) => void; }; -// @public (undocumented) +// @public export const cacheServiceFactory: () => ServiceFactory; // @public (undocumented) diff --git a/packages/backend-defaults/api-report-database.md b/packages/backend-defaults/api-report-database.md index 728c228899..116830343a 100644 --- a/packages/backend-defaults/api-report-database.md +++ b/packages/backend-defaults/api-report-database.md @@ -31,7 +31,7 @@ export type DatabaseManagerOptions = { logger?: LoggerService; }; -// @public (undocumented) +// @public export const databaseServiceFactory: () => ServiceFactory< DatabaseService, 'plugin' diff --git a/packages/backend-defaults/api-report-discovery.md b/packages/backend-defaults/api-report-discovery.md index 0ff734b8a7..b434dab6fc 100644 --- a/packages/backend-defaults/api-report-discovery.md +++ b/packages/backend-defaults/api-report-discovery.md @@ -7,7 +7,7 @@ import { Config } from '@backstage/config'; import { DiscoveryService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; -// @public (undocumented) +// @public export const discoveryServiceFactory: () => ServiceFactory< DiscoveryService, 'plugin' diff --git a/packages/backend-defaults/api-report-httpAuth.md b/packages/backend-defaults/api-report-httpAuth.md new file mode 100644 index 0000000000..6ffe3d6539 --- /dev/null +++ b/packages/backend-defaults/api-report-httpAuth.md @@ -0,0 +1,16 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { HttpAuthService } from '@backstage/backend-plugin-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @public +export const httpAuthServiceFactory: () => ServiceFactory< + HttpAuthService, + 'plugin' +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/api-report-httpRouter.md b/packages/backend-defaults/api-report-httpRouter.md new file mode 100644 index 0000000000..a7ca2c8dd3 --- /dev/null +++ b/packages/backend-defaults/api-report-httpRouter.md @@ -0,0 +1,35 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { HttpRouterService } from '@backstage/backend-plugin-api'; +import { HumanDuration } from '@backstage/types'; +import { LifecycleService } from '@backstage/backend-plugin-api'; +import { RequestHandler } from 'express'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @public +export function createLifecycleMiddleware( + options: LifecycleMiddlewareOptions, +): RequestHandler; + +// @public (undocumented) +export interface HttpRouterFactoryOptions { + getPath?(pluginId: string): string; +} + +// @public +export const httpRouterServiceFactory: ( + options?: HttpRouterFactoryOptions | undefined, +) => ServiceFactory; + +// @public +export interface LifecycleMiddlewareOptions { + // (undocumented) + lifecycle: LifecycleService; + startupRequestPauseTimeout?: HumanDuration; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/api-report-logger.md b/packages/backend-defaults/api-report-logger.md new file mode 100644 index 0000000000..fa9018a40c --- /dev/null +++ b/packages/backend-defaults/api-report-logger.md @@ -0,0 +1,16 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { LoggerService } from '@backstage/backend-plugin-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @public +export const loggerServiceFactory: () => ServiceFactory< + LoggerService, + 'plugin' +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/api-report-permissions.md b/packages/backend-defaults/api-report-permissions.md index 9006a62018..c436443ff1 100644 --- a/packages/backend-defaults/api-report-permissions.md +++ b/packages/backend-defaults/api-report-permissions.md @@ -6,7 +6,7 @@ import { PermissionsService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; -// @public (undocumented) +// @public export const permissionsServiceFactory: () => ServiceFactory< PermissionsService, 'plugin' diff --git a/packages/backend-defaults/api-report-rootConfig.md b/packages/backend-defaults/api-report-rootConfig.md index 60c8fbcb57..317c451e1b 100644 --- a/packages/backend-defaults/api-report-rootConfig.md +++ b/packages/backend-defaults/api-report-rootConfig.md @@ -3,11 +3,21 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import type { Config } from '@backstage/config'; +import { ConfigSchema } from '@backstage/config-loader'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { RemoteConfigSourceOptions } from '@backstage/config-loader'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; // @public (undocumented) +export function createConfigSecretEnumerator(options: { + logger: LoggerService; + dir?: string; + schema?: ConfigSchema; +}): Promise<(config: Config) => Iterable>; + +// @public export interface RootConfigFactoryOptions { argv?: string[]; remote?: Pick; diff --git a/packages/backend-defaults/api-report-rootHealth.md b/packages/backend-defaults/api-report-rootHealth.md new file mode 100644 index 0000000000..ffa067605a --- /dev/null +++ b/packages/backend-defaults/api-report-rootHealth.md @@ -0,0 +1,16 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { RootHealthService } from '@backstage/backend-plugin-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @public (undocumented) +export const rootHealthServiceFactory: () => ServiceFactory< + RootHealthService, + 'root' +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/api-report-rootHttpRouter.md b/packages/backend-defaults/api-report-rootHttpRouter.md new file mode 100644 index 0000000000..d9727fd36d --- /dev/null +++ b/packages/backend-defaults/api-report-rootHttpRouter.md @@ -0,0 +1,149 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { Config } from '@backstage/config'; +import { CorsOptions } from 'cors'; +import { ErrorRequestHandler } from 'express'; +import { Express as Express_2 } from 'express'; +import { Handler } from 'express'; +import { HelmetOptions } from 'helmet'; +import * as http from 'http'; +import { LifecycleService } from '@backstage/backend-plugin-api'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { RequestHandler } from 'express'; +import { RequestListener } from 'http'; +import { RootConfigService } from '@backstage/backend-plugin-api'; +import { RootHttpRouterService } from '@backstage/backend-plugin-api'; +import type { Server } from 'node:http'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @public +export function createHttpServer( + listener: RequestListener, + options: HttpServerOptions, + deps: { + logger: LoggerService; + }, +): Promise; + +// @public +export class DefaultRootHttpRouter implements RootHttpRouterService { + // (undocumented) + static create(options?: DefaultRootHttpRouterOptions): DefaultRootHttpRouter; + // (undocumented) + handler(): Handler; + // (undocumented) + use(path: string, handler: Handler): void; +} + +// @public +export interface DefaultRootHttpRouterOptions { + indexPath?: string | false; +} + +// @public +export interface ExtendedHttpServer extends http.Server { + // (undocumented) + port(): number; + // (undocumented) + start(): Promise; + // (undocumented) + stop(): Promise; +} + +// @public +export type HttpServerCertificateOptions = + | { + type: 'pem'; + key: string; + cert: string; + } + | { + type: 'generated'; + hostname: string; + }; + +// @public +export type HttpServerOptions = { + listen: { + port: number; + host: string; + }; + https?: { + certificate: HttpServerCertificateOptions; + }; +}; + +// @public +export class MiddlewareFactory { + compression(): RequestHandler; + cors(): RequestHandler; + static create(options: MiddlewareFactoryOptions): MiddlewareFactory; + error(options?: MiddlewareFactoryErrorOptions): ErrorRequestHandler; + helmet(): RequestHandler; + logging(): RequestHandler; + notFound(): RequestHandler; +} + +// @public +export interface MiddlewareFactoryErrorOptions { + logAllErrors?: boolean; + showStackTraces?: boolean; +} + +// @public +export interface MiddlewareFactoryOptions { + // (undocumented) + config: RootConfigService; + // (undocumented) + logger: LoggerService; +} + +// @public +export function readCorsOptions(config?: Config): CorsOptions; + +// @public +export function readHelmetOptions(config?: Config): HelmetOptions; + +// @public +export function readHttpServerOptions(config?: Config): HttpServerOptions; + +// @public (undocumented) +export interface RootHttpRouterConfigureContext { + // (undocumented) + app: Express_2; + // (undocumented) + applyDefaults: () => void; + // (undocumented) + config: RootConfigService; + // (undocumented) + healthRouter: RequestHandler; + // (undocumented) + lifecycle: LifecycleService; + // (undocumented) + logger: LoggerService; + // (undocumented) + middleware: MiddlewareFactory; + // (undocumented) + routes: RequestHandler; + // (undocumented) + server: Server; +} + +// @public +export type RootHttpRouterFactoryOptions = { + indexPath?: string | false; + configure?(context: RootHttpRouterConfigureContext): void; +}; + +// @public (undocumented) +export const rootHttpRouterServiceFactory: ( + options?: RootHttpRouterFactoryOptions | undefined, +) => ServiceFactory; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/api-report-rootLogger.md b/packages/backend-defaults/api-report-rootLogger.md new file mode 100644 index 0000000000..70dc0deee6 --- /dev/null +++ b/packages/backend-defaults/api-report-rootLogger.md @@ -0,0 +1,54 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Format } from 'logform'; +import { JsonObject } from '@backstage/types'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { RootLoggerService } from '@backstage/backend-plugin-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { transport } from 'winston'; + +// @public +export const rootLoggerServiceFactory: () => ServiceFactory< + RootLoggerService, + 'root' +>; + +// @public +export class WinstonLogger implements RootLoggerService { + // (undocumented) + addRedactions(redactions: Iterable): void; + // (undocumented) + child(meta: JsonObject): LoggerService; + static colorFormat(): Format; + static create(options: WinstonLoggerOptions): WinstonLogger; + // (undocumented) + debug(message: string, meta?: JsonObject): void; + // (undocumented) + error(message: string, meta?: JsonObject): void; + // (undocumented) + info(message: string, meta?: JsonObject): void; + static redacter(): { + format: Format; + add: (redactions: Iterable) => void; + }; + // (undocumented) + warn(message: string, meta?: JsonObject): void; +} + +// @public (undocumented) +export interface WinstonLoggerOptions { + // (undocumented) + format?: Format; + // (undocumented) + level?: string; + // (undocumented) + meta?: JsonObject; + // (undocumented) + transports?: transport[]; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/api-report-urlReader.md b/packages/backend-defaults/api-report-urlReader.md index a1976f5a1c..c56cdba69b 100644 --- a/packages/backend-defaults/api-report-urlReader.md +++ b/packages/backend-defaults/api-report-urlReader.md @@ -425,7 +425,7 @@ export class UrlReaders { static default(options: UrlReadersOptions): UrlReaderService; } -// @public (undocumented) +// @public export const urlReaderServiceFactory: () => ServiceFactory< UrlReaderService, 'plugin' diff --git a/packages/backend-defaults/api-report-userInfo.md b/packages/backend-defaults/api-report-userInfo.md new file mode 100644 index 0000000000..d11fb69718 --- /dev/null +++ b/packages/backend-defaults/api-report-userInfo.md @@ -0,0 +1,16 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { UserInfoService } from '@backstage/backend-plugin-api'; + +// @public +export const userInfoServiceFactory: () => ServiceFactory< + UserInfoService, + 'plugin' +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/config.d.ts b/packages/backend-defaults/config.d.ts index 569ab436db..ab1e443fc2 100644 --- a/packages/backend-defaults/config.d.ts +++ b/packages/backend-defaults/config.d.ts @@ -15,6 +15,283 @@ */ export interface Config { + backend?: { + /** + * Options used by the default auth, httpAuth and userInfo services. + */ + auth?: { + /** + * This disables the otherwise default auth policy, which requires all + * requests to be authenticated with either user or service credentials. + * + * Disabling this check means that the backend will no longer block + * unauthenticated requests, but instead allow them to pass through to + * plugins. + * + * If permissions are enabled, unauthenticated requests will be treated + * exactly as such, leaving it to the permission policy to determine what + * permissions should be allowed for an unauthenticated identity. Note + * that this will also apply to service-to-service calls between plugins + * unless you configure credentials for service calls. + */ + dangerouslyDisableDefaultAuthPolicy?: boolean; + + /** Controls how to store keys for plugin-to-plugin auth */ + pluginKeyStore?: + | { type: 'database' } + | { + type: 'static'; + static: { + /** + * Must be declared at least once and the first one will be used for signing. + */ + keys: Array<{ + /** + * Path to the public key file in the SPKI format. Should be an absolute path. + */ + publicKeyFile: string; + /** + * Path to the matching private key file in the PKCS#8 format. Should be an absolute path. + * + * The first array entry must specify a private key file, the rest must not. + */ + privateKeyFile?: string; + /** + * ID to uniquely identify this key within the JWK set. + */ + keyId: string; + /** + * JWS "alg" (Algorithm) Header Parameter value. Defaults to ES256. + * Must match the algorithm used to generate the keys in the provided files + */ + algorithm?: string; + }>; + }; + }; + + /** + * Configures methods of external access, ie ways for callers outside of + * the Backstage ecosystem to get authorized for access to APIs that do + * not permit unauthorized access. + */ + externalAccess: Array< + | { + /** + * This is the legacy service-to-service access method, where a set + * of static keys were shared among plugins and used for symmetric + * signing and verification. These correspond to the old + * `backend.auth.keys` set and retain their behavior for backwards + * compatibility. Please migrate to other access methods when + * possible. + * + * Callers generate JWT tokens with the following payload: + * + * ```json + * { + * "sub": "backstage-plugin", + * "exp": + * } + * ``` + * + * And sign them with HS256, using the base64 decoded secret. The + * tokens are then passed along with requests in the Authorization + * header: + * + * ``` + * Authorization: Bearer eyJhbGciOiJIUzI... + * ``` + */ + type: 'legacy'; + options: { + /** + * Any set of base64 encoded random bytes to be used as both the + * signing and verification key. Should be sufficiently long so as + * not to be easy to guess by brute force. + * + * Can be generated eg using + * + * ```sh + * node -p 'require("crypto").randomBytes(24).toString("base64")' + * ``` + * + * @visibility secret + */ + secret: string; + + /** + * Sets the subject of the principal, when matching this token. + * Useful for debugging and tracking purposes. + */ + subject: string; + }; + /** + * Restricts what types of access that are permitted for this access + * method. If no access restrictions are given, it'll have unlimited + * access. This access restriction applies for the framework level; + * individual plugins may have their own access control mechanisms + * on top of this. + */ + accessRestrictions?: Array<{ + /** + * Permit access to make requests to this plugin. + * + * Can be further refined by setting additional fields below. + */ + plugin: string; + /** + * If given, this method is limited to only performing actions + * with these named permissions in this plugin. + * + * Note that this only applies where permissions checks are + * enabled in the first place. Endpoints that are not protected by + * the permissions system at all, are not affected by this + * setting. + */ + permission?: string | Array; + /** + * If given, this method is limited to only performing actions + * whose permissions have these attributes. + * + * Note that this only applies where permissions checks are + * enabled in the first place. Endpoints that are not protected by + * the permissions system at all, are not affected by this + * setting. + */ + permissionAttribute?: { + /** + * One of more of 'create', 'read', 'update', or 'delete'. + */ + action?: string | Array; + }; + }>; + } + | { + /** + * This access method consists of random static tokens that can be + * handed out to callers. + * + * The tokens are then passed along verbatim with requests in the + * Authorization header: + * + * ``` + * Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW + * ``` + */ + type: 'static'; + options: { + /** + * A raw token that can be any string, but for security reasons + * should be sufficiently long so as not to be easy to guess by + * brute force. + * + * Can be generated eg using + * + * ```sh + * node -p 'require("crypto").randomBytes(24).toString("base64")' + * ``` + * + * Since the tokens can be any string, you are free to add + * additional identifying data to them if you like. For example, + * adding a `freben-local-dev-` prefix for debugging purposes to a + * token that you know will be handed out for use as a personal + * access token during development. + * + * @visibility secret + */ + token: string; + + /** + * Sets the subject of the principal, when matching this token. + * Useful for debugging and tracking purposes. + */ + subject: string; + }; + /** + * Restricts what types of access that are permitted for this access + * method. If no access restrictions are given, it'll have unlimited + * access. This access restriction applies for the framework level; + * individual plugins may have their own access control mechanisms + * on top of this. + */ + accessRestrictions?: Array<{ + /** + * Permit access to make requests to this plugin. + * + * Can be further refined by setting additional fields below. + */ + plugin: string; + /** + * If given, this method is limited to only performing actions + * with these named permissions in this plugin. + * + * Note that this only applies where permissions checks are + * enabled in the first place. Endpoints that are not protected by + * the permissions system at all, are not affected by this + * setting. + */ + permission?: string | Array; + /** + * If given, this method is limited to only performing actions + * whose permissions have these attributes. + * + * Note that this only applies where permissions checks are + * enabled in the first place. Endpoints that are not protected by + * the permissions system at all, are not affected by this + * setting. + */ + permissionAttribute?: { + /** + * One of more of 'create', 'read', 'update', or 'delete'. + */ + action?: string | Array; + }; + }>; + } + | { + /** + * This access method consists of a JWKS endpoint that can be used to + * verify JWT tokens. + * + * Callers generate JWT tokens via 3rd party tooling + * and pass them in the Authorization header: + * + * ``` + * Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW + * ``` + */ + type: 'jwks'; + options: { + /** + * The full URL of the JWKS endpoint. + */ + url: string; + /** + * Sets the algorithm(s) that should be used to verify the JWT tokens. + * The passed JWTs must have been signed using one of the listed algorithms. + */ + algorithm?: string | string[]; + /** + * Sets the issuer(s) that should be used to verify the JWT tokens. + * Passed JWTs must have an `iss` claim which matches one of the specified issuers. + */ + issuer?: string | string[]; + /** + * Sets the audience(s) that should be used to verify the JWT tokens. + * The passed JWTs must have an "aud" claim that matches one of the audiences specified, + * or have no audience specified. + */ + audience?: string | string[]; + /** + * Sets an optional subject prefix. Passes the subject to called plugins. + * Useful for debugging and tracking purposes. + */ + subjectPrefix?: string; + }; + } + >; + }; + }; + /** * Options used by the default discovery service. */ diff --git a/packages/backend-app-api/migrations/20240327104803_public_keys.js b/packages/backend-defaults/migrations/auth/20240327104803_public_keys.js similarity index 100% rename from packages/backend-app-api/migrations/20240327104803_public_keys.js rename to packages/backend-defaults/migrations/auth/20240327104803_public_keys.js diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 2cdf30e0d2..824f1893bd 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.3.0-next.3", + "version": "0.3.3-next.0", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" @@ -20,21 +20,32 @@ "license": "Apache-2.0", "exports": { ".": "./src/index.ts", + "./auth": "./src/entrypoints/auth/index.ts", "./cache": "./src/entrypoints/cache/index.ts", "./database": "./src/entrypoints/database/index.ts", "./discovery": "./src/entrypoints/discovery/index.ts", + "./httpAuth": "./src/entrypoints/httpAuth/index.ts", + "./httpRouter": "./src/entrypoints/httpRouter/index.ts", "./lifecycle": "./src/entrypoints/lifecycle/index.ts", + "./logger": "./src/entrypoints/logger/index.ts", "./permissions": "./src/entrypoints/permissions/index.ts", "./rootConfig": "./src/entrypoints/rootConfig/index.ts", + "./rootHealth": "./src/entrypoints/rootHealth/index.ts", + "./rootHttpRouter": "./src/entrypoints/rootHttpRouter/index.ts", "./rootLifecycle": "./src/entrypoints/rootLifecycle/index.ts", + "./rootLogger": "./src/entrypoints/rootLogger/index.ts", "./scheduler": "./src/entrypoints/scheduler/index.ts", "./urlReader": "./src/entrypoints/urlReader/index.ts", + "./userInfo": "./src/entrypoints/userInfo/index.ts", "./package.json": "./package.json" }, "main": "src/index.ts", "types": "src/index.ts", "typesVersions": { "*": { + "auth": [ + "src/entrypoints/auth/index.ts" + ], "cache": [ "src/entrypoints/cache/index.ts" ], @@ -44,24 +55,45 @@ "discovery": [ "src/entrypoints/discovery/index.ts" ], + "httpAuth": [ + "src/entrypoints/httpAuth/index.ts" + ], + "httpRouter": [ + "src/entrypoints/httpRouter/index.ts" + ], "lifecycle": [ "src/entrypoints/lifecycle/index.ts" ], + "logger": [ + "src/entrypoints/logger/index.ts" + ], "permissions": [ "src/entrypoints/permissions/index.ts" ], "rootConfig": [ "src/entrypoints/rootConfig/index.ts" ], + "rootHealth": [ + "src/entrypoints/rootHealth/index.ts" + ], + "rootHttpRouter": [ + "src/entrypoints/rootHttpRouter/index.ts" + ], "rootLifecycle": [ "src/entrypoints/rootLifecycle/index.ts" ], + "rootLogger": [ + "src/entrypoints/rootLogger/index.ts" + ], "scheduler": [ "src/entrypoints/scheduler/index.ts" ], "urlReader": [ "src/entrypoints/urlReader/index.ts" ], + "userInfo": [ + "src/entrypoints/userInfo/index.ts" + ], "package.json": [ "package.json" ] @@ -88,42 +120,65 @@ "@aws-sdk/credential-providers": "^3.350.0", "@aws-sdk/types": "^3.347.0", "@backstage/backend-app-api": "workspace:^", + "@backstage/backend-common": "workspace:^", "@backstage/backend-dev-utils": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", + "@backstage/cli-common": "workspace:^", "@backstage/config": "workspace:^", "@backstage/config-loader": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/integration-aws-node": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-events-node": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", "@backstage/types": "workspace:^", "@google-cloud/storage": "^7.0.0", "@keyv/memcache": "^1.3.5", "@keyv/redis": "^2.5.3", + "@manypkg/get-packages": "^1.1.3", "@octokit/rest": "^19.0.3", "@opentelemetry/api": "^1.3.0", + "@types/cors": "^2.8.6", + "@types/express": "^4.17.6", "archiver": "^6.0.0", "base64-stream": "^1.0.0", - "better-sqlite3": "^9.0.0", + "better-sqlite3": "^11.0.0", + "compression": "^1.7.4", "concat-stream": "^2.0.0", + "cookie": "^0.6.0", + "cors": "^2.8.5", "cron": "^3.0.0", + "express": "^4.17.1", + "express-promise-router": "^4.1.0", "fs-extra": "^11.2.0", "git-url-parse": "^14.0.0", + "helmet": "^6.0.0", "isomorphic-git": "^1.23.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": "^9.0.0", + "minimist": "^1.2.5", + "morgan": "^1.10.0", "mysql2": "^3.0.0", "node-fetch": "^2.6.7", + "node-forge": "^1.3.1", "p-limit": "^3.1.0", + "path-to-regexp": "^6.2.1", "pg": "^8.11.3", "pg-connection-string": "^2.3.0", "raw-body": "^2.4.1", + "selfsigned": "^2.0.0", + "stoppable": "^1.1.0", "tar": "^6.1.12", + "triple-beam": "^1.4.1", "uuid": "^9.0.0", + "winston": "^3.2.1", + "winston-transport": "^4.5.0", "yauzl": "^3.0.0", "yn": "^4.0.0", "zod": "^3.22.4" @@ -133,8 +188,14 @@ "@backstage/backend-plugin-api": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@types/http-errors": "^2.0.0", + "@types/morgan": "^1.9.0", + "@types/node-forge": "^1.3.0", + "@types/stoppable": "^1.1.0", "aws-sdk-client-mock": "^4.0.0", + "http-errors": "^2.0.0", "msw": "^1.0.0", + "supertest": "^6.1.3", "wait-for-expect": "^3.0.2" }, "configSchema": "config.d.ts" diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts index 823b3c2833..e3195748a6 100644 --- a/packages/backend-defaults/src/CreateBackend.ts +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -16,26 +16,27 @@ import { Backend, - authServiceFactory, createSpecializedBackend, - httpAuthServiceFactory, - httpRouterServiceFactory, identityServiceFactory, - loggerServiceFactory, - rootHttpRouterServiceFactory, - rootLoggerServiceFactory, tokenManagerServiceFactory, - userInfoServiceFactory, } from '@backstage/backend-app-api'; +import { authServiceFactory } from '@backstage/backend-defaults/auth'; import { cacheServiceFactory } from '@backstage/backend-defaults/cache'; import { databaseServiceFactory } from '@backstage/backend-defaults/database'; import { discoveryServiceFactory } from '@backstage/backend-defaults/discovery'; +import { httpAuthServiceFactory } from '@backstage/backend-defaults/httpAuth'; +import { httpRouterServiceFactory } from '@backstage/backend-defaults/httpRouter'; import { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle'; +import { loggerServiceFactory } from '@backstage/backend-defaults/logger'; import { permissionsServiceFactory } from '@backstage/backend-defaults/permissions'; import { rootConfigServiceFactory } from '@backstage/backend-defaults/rootConfig'; +import { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth'; +import { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter'; import { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle'; +import { rootLoggerServiceFactory } from '@backstage/backend-defaults/rootLogger'; import { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler'; import { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader'; +import { userInfoServiceFactory } from '@backstage/backend-defaults/userInfo'; import { eventsServiceFactory } from '@backstage/plugin-events-node'; export const defaultServiceFactories = [ @@ -50,6 +51,7 @@ export const defaultServiceFactories = [ lifecycleServiceFactory(), loggerServiceFactory(), permissionsServiceFactory(), + rootHealthServiceFactory(), rootHttpRouterServiceFactory(), rootLifecycleServiceFactory(), rootLoggerServiceFactory(), diff --git a/packages/backend-app-api/src/services/implementations/auth/DefaultAuthService.ts b/packages/backend-defaults/src/entrypoints/auth/DefaultAuthService.ts similarity index 95% rename from packages/backend-app-api/src/services/implementations/auth/DefaultAuthService.ts rename to packages/backend-defaults/src/entrypoints/auth/DefaultAuthService.ts index 12ccc5fd00..159da79435 100644 --- a/packages/backend-app-api/src/services/implementations/auth/DefaultAuthService.ts +++ b/packages/backend-defaults/src/entrypoints/auth/DefaultAuthService.ts @@ -49,8 +49,12 @@ export class DefaultAuthService implements AuthService { private readonly pluginKeySource: PluginKeySource, ) {} - // allowLimitedAccess is currently ignored, since we currently always use the full user tokens - async authenticate(token: string): Promise { + async authenticate( + token: string, + options?: { + allowLimitedAccess?: boolean; + }, + ): Promise { const pluginResult = await this.pluginTokenHandler.verifyToken(token); if (pluginResult) { if (pluginResult.limitedUserToken) { @@ -73,6 +77,13 @@ export class DefaultAuthService implements AuthService { const userResult = await this.userTokenHandler.verifyToken(token); if (userResult) { + if ( + !options?.allowLimitedAccess && + this.userTokenHandler.isLimitedUserToken(token) + ) { + throw new AuthenticationError('Illegal limited user token'); + } + return createCredentialsWithUserPrincipal( userResult.userEntityRef, token, diff --git a/packages/backend-app-api/src/services/implementations/auth/JwksClient.ts b/packages/backend-defaults/src/entrypoints/auth/JwksClient.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/JwksClient.ts rename to packages/backend-defaults/src/entrypoints/auth/JwksClient.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts similarity index 89% rename from packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts rename to packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts index 71fbe64963..22357d0f49 100644 --- a/packages/backend-app-api/src/services/implementations/auth/authServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts @@ -19,6 +19,7 @@ import { mockServices, setupRequestMockHandlers, } from '@backstage/backend-test-utils'; +import { tokenManagerServiceFactory } from '@backstage/backend-app-api'; import { authServiceFactory } from './authServiceFactory'; import { base64url, decodeJwt } from 'jose'; import { discoveryServiceFactory } from '../discovery'; @@ -26,7 +27,6 @@ import { BackstageServicePrincipal, BackstageUserPrincipal, } from '@backstage/backend-plugin-api'; -import { tokenManagerServiceFactory } from '../tokenManager'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { InternalBackstageCredentials } from './types'; @@ -218,6 +218,17 @@ describe('authServiceFactory', () => { }); it('should issue limited user tokens', async () => { + /* Corresponding private key in case this test needs to be updated in the future: + { + kty: 'EC', + x: 'c9cPvv_S7zETBKDlAa3oOjr7RvyUueIYIak0TRph7mg', + y: 'bKaxDRAWgmEJ9Ix8e85blH_IsnbQxX31x0oQTVwLZ2c', + crv: 'P-256', + d: '2eJlhCDdGx9fxKDL1D9BnY3CCTEKxL60Bkms0hmubmY', + kid: '8d01c3db-56f9-45f0-86dd-05b3c835b3d3', + alg: 'ES256' + } + */ server.use( rest.get( 'http://localhost:7007/api/auth/.well-known/jwks.json', @@ -227,8 +238,8 @@ describe('authServiceFactory', () => { keys: [ { kty: 'EC', - x: '78-Ei1H3nKM23ZpGMMzte2mVoYCcnfnSiLTm1P7vZM0', - y: 'Z9-PjG_EU598tLLUc2f8sCqxT7bjs8WpoV-lHm9GJHY', + x: 'c9cPvv_S7zETBKDlAa3oOjr7RvyUueIYIak0TRph7mg', + y: 'bKaxDRAWgmEJ9Ix8e85blH_IsnbQxX31x0oQTVwLZ2c', crv: 'P-256', kid: '8d01c3db-56f9-45f0-86dd-05b3c835b3d3', alg: 'ES256', @@ -253,7 +264,7 @@ describe('authServiceFactory', () => { const catalogAuth = await tester.get('catalog'); const fullToken = - 'eyJ0eXAiOiJ2bmQuYmFja3N0YWdlLnVzZXIiLCJhbGciOiJFUzI1NiIsImtpZCI6IjhkMDFjM2RiLTU2ZjktNDVmMC04NmRkLTA1YjNjODM1YjNkMyJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjcwMDcvYXBpL2F1dGgiLCJzdWIiOiJ1c2VyOmRldmVsb3BtZW50L2d1ZXN0IiwiZW50IjpbInVzZXI6ZGV2ZWxvcG1lbnQvZ3Vlc3QiLCJncm91cDpkZWZhdWx0L3RlYW0tYSJdLCJhdWQiOiJiYWNrc3RhZ2UiLCJpYXQiOjE3MTIwNzE3MTQsImV4cCI6MTcxMjA3NTMxNCwidWlwIjoiMDFBUUJfSWpHTXRWc2gyWmgzZEg1NXhOX29pSVlhQ1F3ODJjeDZ5M1BQMXlpTjM4eGMzMVpMS2U0YVNDQlJTTy10cjFzZFUzT29ELUxJYV8tNV9RVUEifQ.mjIrZGqbZ2t68fS4U3crlGw-bYJZnMlhMHf-YL7q_u1HfaLr4NMTcHkxdnNS2wfJxCmUBxRfUS8b3nSAKsxcHA'; + 'eyJ0eXAiOiJ2bmQuYmFja3N0YWdlLnVzZXIiLCJhbGciOiJFUzI1NiIsImtpZCI6IjhkMDFjM2RiLTU2ZjktNDVmMC04NmRkLTA1YjNjODM1YjNkMyJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjcwMDcvYXBpL2F1dGgiLCJzdWIiOiJ1c2VyOmRldmVsb3BtZW50L2d1ZXN0IiwiZW50IjpbInVzZXI6ZGV2ZWxvcG1lbnQvZ3Vlc3QiLCJncm91cDpkZWZhdWx0L3RlYW0tYSJdLCJhdWQiOiJiYWNrc3RhZ2UiLCJpYXQiOjE3MTIwNzE3MTQsImV4cCI6MTcxMjA3NTMxNCwidWlwIjoiSmwxVEpycG9VUjR1NENjUE9nalJMeHpEMi1FMGZPR3ptSm81UWI2eS1aN19meG5oVVBEdWVWRE1CS0l6WF9pc0lvSDhlZm9EUFA5bG9aQnpPblB5Z2cifQ.1gVMq1ofO8PzRctu72D6c4IMqXuIabT79WdGEhW6vIrBRs_qhuWAa94Wvz_KYKpBTb2nxgzXJ5OeddeoYApMyQ'; const credentials = await catalogAuth.authenticate(fullToken); if (!catalogAuth.isPrincipal(credentials, 'user')) { @@ -275,7 +286,6 @@ describe('authServiceFactory', () => { const expectedTokenPayload = base64url.encode( JSON.stringify({ sub: 'user:development/guest', - ent: ['user:development/guest', 'group:default/team-a'], iat: expectedIssuedAt, exp: expectedExpiresAt, }), @@ -312,6 +322,17 @@ describe('authServiceFactory', () => { const catalogAuth = await tester.get('catalog'); const permissionAuth = await tester.get('permission'); + /* Corresponding private key in case this test needs to be updated in the future: + { + kty: 'EC', + x: 'c9cPvv_S7zETBKDlAa3oOjr7RvyUueIYIak0TRph7mg', + y: 'bKaxDRAWgmEJ9Ix8e85blH_IsnbQxX31x0oQTVwLZ2c', + crv: 'P-256', + d: '2eJlhCDdGx9fxKDL1D9BnY3CCTEKxL60Bkms0hmubmY', + kid: '8d01c3db-56f9-45f0-86dd-05b3c835b3d3', + alg: 'ES256' + } + */ server.use( rest.get( 'http://localhost:7007/api/auth/.well-known/jwks.json', @@ -321,8 +342,8 @@ describe('authServiceFactory', () => { keys: [ { kty: 'EC', - x: '78-Ei1H3nKM23ZpGMMzte2mVoYCcnfnSiLTm1P7vZM0', - y: 'Z9-PjG_EU598tLLUc2f8sCqxT7bjs8WpoV-lHm9GJHY', + x: 'c9cPvv_S7zETBKDlAa3oOjr7RvyUueIYIak0TRph7mg', + y: 'bKaxDRAWgmEJ9Ix8e85blH_IsnbQxX31x0oQTVwLZ2c', crv: 'P-256', kid: '8d01c3db-56f9-45f0-86dd-05b3c835b3d3', alg: 'ES256', @@ -360,7 +381,7 @@ describe('authServiceFactory', () => { }); const fullToken = - 'eyJ0eXAiOiJ2bmQuYmFja3N0YWdlLnVzZXIiLCJhbGciOiJFUzI1NiIsImtpZCI6IjhkMDFjM2RiLTU2ZjktNDVmMC04NmRkLTA1YjNjODM1YjNkMyJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjcwMDcvYXBpL2F1dGgiLCJzdWIiOiJ1c2VyOmRldmVsb3BtZW50L2d1ZXN0IiwiZW50IjpbInVzZXI6ZGV2ZWxvcG1lbnQvZ3Vlc3QiLCJncm91cDpkZWZhdWx0L3RlYW0tYSJdLCJhdWQiOiJiYWNrc3RhZ2UiLCJpYXQiOjE3MTIwNzE3MTQsImV4cCI6MTcxMjA3NTMxNCwidWlwIjoiMDFBUUJfSWpHTXRWc2gyWmgzZEg1NXhOX29pSVlhQ1F3ODJjeDZ5M1BQMXlpTjM4eGMzMVpMS2U0YVNDQlJTTy10cjFzZFUzT29ELUxJYV8tNV9RVUEifQ.mjIrZGqbZ2t68fS4U3crlGw-bYJZnMlhMHf-YL7q_u1HfaLr4NMTcHkxdnNS2wfJxCmUBxRfUS8b3nSAKsxcHA'; + 'eyJ0eXAiOiJ2bmQuYmFja3N0YWdlLnVzZXIiLCJhbGciOiJFUzI1NiIsImtpZCI6IjhkMDFjM2RiLTU2ZjktNDVmMC04NmRkLTA1YjNjODM1YjNkMyJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjcwMDcvYXBpL2F1dGgiLCJzdWIiOiJ1c2VyOmRldmVsb3BtZW50L2d1ZXN0IiwiZW50IjpbInVzZXI6ZGV2ZWxvcG1lbnQvZ3Vlc3QiLCJncm91cDpkZWZhdWx0L3RlYW0tYSJdLCJhdWQiOiJiYWNrc3RhZ2UiLCJpYXQiOjE3MTIwNzE3MTQsImV4cCI6MTcxMjA3NTMxNCwidWlwIjoiSmwxVEpycG9VUjR1NENjUE9nalJMeHpEMi1FMGZPR3ptSm81UWI2eS1aN19meG5oVVBEdWVWRE1CS0l6WF9pc0lvSDhlZm9EUFA5bG9aQnpPblB5Z2cifQ.1gVMq1ofO8PzRctu72D6c4IMqXuIabT79WdGEhW6vIrBRs_qhuWAa94Wvz_KYKpBTb2nxgzXJ5OeddeoYApMyQ'; const credentials = await searchAuth.authenticate(fullToken); if (!searchAuth.isPrincipal(credentials, 'user')) { diff --git a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.ts b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.ts new file mode 100644 index 0000000000..e275e2be00 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.ts @@ -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 { + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { DefaultAuthService } from './DefaultAuthService'; +import { ExternalTokenHandler } from './external/ExternalTokenHandler'; +import { PluginTokenHandler } from './plugin/PluginTokenHandler'; +import { createPluginKeySource } from './plugin/keys/createPluginKeySource'; +import { UserTokenHandler } from './user/UserTokenHandler'; + +/** + * Handles token authentication and credentials management. + * + * See {@link @backstage/code-plugin-api#AuthService} + * and {@link https://backstage.io/docs/backend-system/core-services/auth | the service docs} + * for more information. + * + * @public + */ +export const authServiceFactory = createServiceFactory({ + service: coreServices.auth, + deps: { + config: coreServices.rootConfig, + logger: coreServices.rootLogger, + discovery: coreServices.discovery, + plugin: coreServices.pluginMetadata, + database: coreServices.database, + // Re-using the token manager makes sure that we use the same generated keys for + // development as plugins that have not yet been migrated. It's important that this + // keeps working as long as there are plugins that have not been migrated to the + // new auth services in the new backend system. + tokenManager: coreServices.tokenManager, + }, + async factory({ config, discovery, plugin, tokenManager, logger, database }) { + const disableDefaultAuthPolicy = + config.getOptionalBoolean( + 'backend.auth.dangerouslyDisableDefaultAuthPolicy', + ) ?? false; + + const keyDuration = { hours: 1 }; + + const keySource = await createPluginKeySource({ + config, + database, + logger, + keyDuration, + }); + + const userTokens = UserTokenHandler.create({ + discovery, + }); + + const pluginTokens = PluginTokenHandler.create({ + ownPluginId: plugin.getId(), + logger, + keySource, + keyDuration, + discovery, + }); + + const externalTokens = ExternalTokenHandler.create({ + ownPluginId: plugin.getId(), + config, + logger, + }); + + return new DefaultAuthService( + userTokens, + pluginTokens, + externalTokens, + tokenManager, + plugin.getId(), + disableDefaultAuthPolicy, + keySource, + ); + }, +}); diff --git a/packages/backend-app-api/src/services/implementations/auth/external/ExternalTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/ExternalTokenHandler.test.ts rename to packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/ExternalTokenHandler.ts b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/ExternalTokenHandler.ts rename to packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/helpers.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/helpers.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/helpers.test.ts rename to packages/backend-defaults/src/entrypoints/auth/external/helpers.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/helpers.ts b/packages/backend-defaults/src/entrypoints/auth/external/helpers.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/helpers.ts rename to packages/backend-defaults/src/entrypoints/auth/external/helpers.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/jwks.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/jwks.test.ts rename to packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/jwks.ts b/packages/backend-defaults/src/entrypoints/auth/external/jwks.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/jwks.ts rename to packages/backend-defaults/src/entrypoints/auth/external/jwks.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/legacy.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/legacy.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/legacy.test.ts rename to packages/backend-defaults/src/entrypoints/auth/external/legacy.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/legacy.ts b/packages/backend-defaults/src/entrypoints/auth/external/legacy.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/legacy.ts rename to packages/backend-defaults/src/entrypoints/auth/external/legacy.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/static.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/static.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/static.test.ts rename to packages/backend-defaults/src/entrypoints/auth/external/static.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/static.ts b/packages/backend-defaults/src/entrypoints/auth/external/static.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/static.ts rename to packages/backend-defaults/src/entrypoints/auth/external/static.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/external/types.ts b/packages/backend-defaults/src/entrypoints/auth/external/types.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/external/types.ts rename to packages/backend-defaults/src/entrypoints/auth/external/types.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/helpers.ts b/packages/backend-defaults/src/entrypoints/auth/helpers.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/helpers.ts rename to packages/backend-defaults/src/entrypoints/auth/helpers.ts diff --git a/packages/backend-defaults/src/entrypoints/auth/index.ts b/packages/backend-defaults/src/entrypoints/auth/index.ts new file mode 100644 index 0000000000..1b55d46a83 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auth/index.ts @@ -0,0 +1,17 @@ +/* + * 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 { authServiceFactory } from './authServiceFactory'; diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/PluginTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/PluginTokenHandler.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/PluginTokenHandler.test.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/PluginTokenHandler.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/PluginTokenHandler.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/PluginTokenHandler.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/PluginTokenHandler.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/PluginTokenHandler.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/DatabaseKeyStore.test.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabaseKeyStore.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/keys/DatabaseKeyStore.test.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabaseKeyStore.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/DatabaseKeyStore.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabaseKeyStore.ts similarity index 98% rename from packages/backend-app-api/src/services/implementations/auth/plugin/keys/DatabaseKeyStore.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabaseKeyStore.ts index aea126d00a..9f5c278a9c 100644 --- a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/DatabaseKeyStore.ts +++ b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabaseKeyStore.ts @@ -37,8 +37,8 @@ type Row = { export function applyDatabaseMigrations(knex: Knex): Promise { const migrationsDir = resolvePackagePath( - '@backstage/backend-app-api', - 'migrations', + '@backstage/backend-defaults', + 'migrations/auth', ); return knex.migrate.latest({ diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/DatabasePluginKeySource.test.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabasePluginKeySource.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/keys/DatabasePluginKeySource.test.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabasePluginKeySource.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/DatabasePluginKeySource.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabasePluginKeySource.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/keys/DatabasePluginKeySource.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabasePluginKeySource.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/StaticConfigPluginKeySource.test.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/keys/StaticConfigPluginKeySource.test.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/StaticConfigPluginKeySource.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/keys/StaticConfigPluginKeySource.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/createPluginKeySource.test.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/createPluginKeySource.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/keys/createPluginKeySource.test.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/keys/createPluginKeySource.test.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/createPluginKeySource.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/createPluginKeySource.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/keys/createPluginKeySource.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/keys/createPluginKeySource.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/plugin/keys/types.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/types.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/plugin/keys/types.ts rename to packages/backend-defaults/src/entrypoints/auth/plugin/keys/types.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/types.ts b/packages/backend-defaults/src/entrypoints/auth/types.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/auth/types.ts rename to packages/backend-defaults/src/entrypoints/auth/types.ts diff --git a/packages/backend-app-api/src/services/implementations/auth/user/UserTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts similarity index 99% rename from packages/backend-app-api/src/services/implementations/auth/user/UserTokenHandler.test.ts rename to packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts index b0e8418655..76bafb2a8f 100644 --- a/packages/backend-app-api/src/services/implementations/auth/user/UserTokenHandler.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.test.ts @@ -346,7 +346,6 @@ describe('UserTokenHandler', () => { header: { typ: 'vnd.backstage.limited-user', alg: 'ES256' }, payload: { sub: 'mock', - ent: ['mock'], iat: 1, exp: 2, }, @@ -384,7 +383,6 @@ describe('UserTokenHandler', () => { new TextEncoder().encode( JSON.stringify({ sub: parts.payload.sub, - ent: parts.payload.ent, iat: parts.payload.iat, exp: parts.payload.exp, }), diff --git a/packages/backend-app-api/src/services/implementations/auth/user/UserTokenHandler.ts b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.ts similarity index 99% rename from packages/backend-app-api/src/services/implementations/auth/user/UserTokenHandler.ts rename to packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.ts index bd73d8701f..4dd1874843 100644 --- a/packages/backend-app-api/src/services/implementations/auth/user/UserTokenHandler.ts +++ b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.ts @@ -137,7 +137,6 @@ export class UserTokenHandler { base64url.encode( JSON.stringify({ sub: payload.sub, - ent: payload.ent, iat: payload.iat, exp: payload.exp, }), diff --git a/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts b/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts index 70f952ea46..89fabfe977 100644 --- a/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts +++ b/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts @@ -15,24 +15,16 @@ */ import { - CacheService, CacheServiceOptions, LoggerService, } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import Keyv from 'keyv'; import { DefaultCacheClient } from './CacheClient'; -import { CacheManagerOptions } from './types'; +import { CacheManagerOptions, PluginCacheManager } from './types'; type StoreFactory = (pluginId: string, defaultTtl: number | undefined) => Keyv; -/* - * TODO(freben): This class intentionally inlines the CacheManagerOptions and - * PluginCacheManager types, to not break the api reports in backend-common - * which re-exports it. When backend-common is deprecated, we can stop inlining - * those types. - */ - /** * Implements a Cache Manager which will automatically create new cache clients * for plugins when requested. All requested cache clients are created with the @@ -66,18 +58,7 @@ export class CacheManager { */ static fromConfig( config: Config, - options: { - /** - * An optional logger for use by the PluginCacheManager. - */ - logger?: LoggerService; - - /** - * An optional handler for connection errors emitted from the underlying data - * store. - */ - onError?: (err: Error) => void; - } = {}, + options: CacheManagerOptions = {}, ): CacheManager { // If no `backend.cache` config is provided, instantiate the CacheManager // with an in-memory cache client. @@ -126,9 +107,7 @@ export class CacheManager { * @param pluginId - The plugin that the cache manager should be created for. * Plugin names should be unique. */ - forPlugin(pluginId: string): { - getClient(options?: CacheServiceOptions): CacheService; - } { + forPlugin(pluginId: string): PluginCacheManager { return { getClient: (defaultOptions = {}) => { const clientFactory = (options: CacheServiceOptions) => { diff --git a/packages/backend-defaults/src/entrypoints/cache/cacheServiceFactory.ts b/packages/backend-defaults/src/entrypoints/cache/cacheServiceFactory.ts index f60d770644..f16b306d81 100644 --- a/packages/backend-defaults/src/entrypoints/cache/cacheServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/cache/cacheServiceFactory.ts @@ -21,6 +21,12 @@ import { import { CacheManager } from './CacheManager'; /** + * Key-value store for caching data. + * + * See {@link @backstage/code-plugin-api#CacheService} + * and {@link https://backstage.io/docs/backend-system/core-services/cache | the service docs} + * for more information. + * * @public */ export const cacheServiceFactory = createServiceFactory({ diff --git a/packages/backend-defaults/src/entrypoints/database/databaseServiceFactory.ts b/packages/backend-defaults/src/entrypoints/database/databaseServiceFactory.ts index 0720d05b43..3bdf1790f3 100644 --- a/packages/backend-defaults/src/entrypoints/database/databaseServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/database/databaseServiceFactory.ts @@ -22,6 +22,12 @@ import { ConfigReader } from '@backstage/config'; import { DatabaseManager } from './DatabaseManager'; /** + * Database access and management via `knex`. + * + * See {@link @backstage/code-plugin-api#DatabaseService} + * and {@link https://backstage.io/docs/backend-system/core-services/database | the service docs} + * for more information. + * * @public */ export const databaseServiceFactory = createServiceFactory({ diff --git a/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.ts b/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.ts index 180c8706d5..559dda2aa0 100644 --- a/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.ts +++ b/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.ts @@ -15,8 +15,8 @@ */ import { Config } from '@backstage/config'; -import { readHttpServerOptions } from '@backstage/backend-app-api'; import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { readHttpServerOptions } from '../rootHttpRouter/http/config'; type Target = string | { internal: string; external: string }; diff --git a/packages/backend-defaults/src/entrypoints/discovery/discoveryServiceFactory.ts b/packages/backend-defaults/src/entrypoints/discovery/discoveryServiceFactory.ts index bfc5a6a489..18ceac4a91 100644 --- a/packages/backend-defaults/src/entrypoints/discovery/discoveryServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/discovery/discoveryServiceFactory.ts @@ -20,7 +20,15 @@ import { } from '@backstage/backend-plugin-api'; import { HostDiscovery } from './HostDiscovery'; -/** @public */ +/** + * Service discovery for inter-plugin communication. + * + * See {@link @backstage/code-plugin-api#DiscoveryService} + * and {@link https://backstage.io/docs/backend-system/core-services/discovery | the service docs} + * for more information. + * + * @public + */ export const discoveryServiceFactory = createServiceFactory({ service: coreServices.discovery, deps: { diff --git a/packages/backend-defaults/src/entrypoints/httpAuth/httpAuthServiceFactory.ts b/packages/backend-defaults/src/entrypoints/httpAuth/httpAuthServiceFactory.ts new file mode 100644 index 0000000000..76550873f6 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/httpAuth/httpAuthServiceFactory.ts @@ -0,0 +1,294 @@ +/* + * 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 { + AuthService, + BackstageCredentials, + BackstagePrincipalTypes, + BackstageUserPrincipal, + DiscoveryService, + HttpAuthService, + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { AuthenticationError, NotAllowedError } from '@backstage/errors'; +import { parse as parseCookie } from 'cookie'; +import { Request, Response } from 'express'; + +const FIVE_MINUTES_MS = 5 * 60 * 1000; + +const BACKSTAGE_AUTH_COOKIE = 'backstage-auth'; + +function getTokenFromRequest(req: Request) { + // TODO: support multiple auth headers (iterate rawHeaders) + const authHeader = req.headers.authorization; + if (typeof authHeader === 'string') { + const matches = authHeader.match(/^Bearer[ ]+(\S+)$/i); + const token = matches?.[1]; + if (token) { + return token; + } + } + + return undefined; +} + +function getCookieFromRequest(req: Request) { + const cookieHeader = req.headers.cookie; + if (cookieHeader) { + const cookies = parseCookie(cookieHeader); + const token = cookies[BACKSTAGE_AUTH_COOKIE]; + if (token) { + return token; + } + } + + return undefined; +} + +function willExpireSoon(expiresAt: Date) { + return Date.now() + FIVE_MINUTES_MS > expiresAt.getTime(); +} + +const credentialsSymbol = Symbol('backstage-credentials'); +const limitedCredentialsSymbol = Symbol('backstage-limited-credentials'); + +type RequestWithCredentials = Request & { + [credentialsSymbol]?: Promise; + [limitedCredentialsSymbol]?: Promise; +}; + +class DefaultHttpAuthService implements HttpAuthService { + readonly #auth: AuthService; + readonly #discovery: DiscoveryService; + readonly #pluginId: string; + + constructor( + auth: AuthService, + discovery: DiscoveryService, + pluginId: string, + ) { + this.#auth = auth; + this.#discovery = discovery; + this.#pluginId = pluginId; + } + + async #extractCredentialsFromRequest(req: Request) { + const token = getTokenFromRequest(req); + if (!token) { + return await this.#auth.getNoneCredentials(); + } + + return await this.#auth.authenticate(token); + } + + async #extractLimitedCredentialsFromRequest(req: Request) { + const token = getTokenFromRequest(req); + if (token) { + return await this.#auth.authenticate(token, { + allowLimitedAccess: true, + }); + } + + const cookie = getCookieFromRequest(req); + if (cookie) { + return await this.#auth.authenticate(cookie, { + allowLimitedAccess: true, + }); + } + + return await this.#auth.getNoneCredentials(); + } + + async #getCredentials(req: RequestWithCredentials) { + return (req[credentialsSymbol] ??= + this.#extractCredentialsFromRequest(req)); + } + + async #getLimitedCredentials(req: RequestWithCredentials) { + return (req[limitedCredentialsSymbol] ??= + this.#extractLimitedCredentialsFromRequest(req)); + } + + async credentials( + req: Request, + options?: { + allow?: Array; + allowLimitedAccess?: boolean; + }, + ): Promise> { + // Limited and full credentials are treated as two separate cases, this lets + // us avoid internal dependencies between the AuthService and + // HttpAuthService implementations + const credentials = options?.allowLimitedAccess + ? await this.#getLimitedCredentials(req) + : await this.#getCredentials(req); + + const allowed = options?.allow; + if (!allowed) { + return credentials as any; + } + + if (this.#auth.isPrincipal(credentials, 'none')) { + if (allowed.includes('none' as TAllowed)) { + return credentials as any; + } + + throw new AuthenticationError('Missing credentials'); + } else if (this.#auth.isPrincipal(credentials, 'user')) { + if (allowed.includes('user' as TAllowed)) { + return credentials as any; + } + + throw new NotAllowedError( + `This endpoint does not allow 'user' credentials`, + ); + } else if (this.#auth.isPrincipal(credentials, 'service')) { + if (allowed.includes('service' as TAllowed)) { + return credentials as any; + } + + throw new NotAllowedError( + `This endpoint does not allow 'service' credentials`, + ); + } + + throw new NotAllowedError( + 'Unknown principal type, this should never happen', + ); + } + + async issueUserCookie( + res: Response, + options?: { credentials?: BackstageCredentials }, + ): Promise<{ expiresAt: Date }> { + if (res.headersSent) { + throw new Error('Failed to issue user cookie, headers were already sent'); + } + + let credentials: BackstageCredentials; + if (options?.credentials) { + if (this.#auth.isPrincipal(options.credentials, 'none')) { + res.clearCookie( + BACKSTAGE_AUTH_COOKIE, + await this.#getCookieOptions(res.req), + ); + return { expiresAt: new Date() }; + } + if (!this.#auth.isPrincipal(options.credentials, 'user')) { + throw new AuthenticationError( + 'Refused to issue cookie for non-user principal', + ); + } + credentials = options.credentials; + } else { + credentials = await this.credentials(res.req, { allow: ['user'] }); + } + + const existingExpiresAt = await this.#existingCookieExpiration(res.req); + if (existingExpiresAt && !willExpireSoon(existingExpiresAt)) { + return { expiresAt: existingExpiresAt }; + } + + const { token, expiresAt } = await this.#auth.getLimitedUserToken( + credentials, + ); + if (!token) { + throw new Error('User credentials is unexpectedly missing token'); + } + + res.cookie(BACKSTAGE_AUTH_COOKIE, token, { + ...(await this.#getCookieOptions(res.req)), + expires: expiresAt, + }); + + return { expiresAt }; + } + + async #getCookieOptions(_req: Request): Promise<{ + domain: string; + httpOnly: true; + secure: boolean; + priority: 'high'; + sameSite: 'none' | 'lax'; + }> { + // TODO: eventually we should read from `${req.protocol}://${req.hostname}` + // once https://github.com/backstage/backstage/issues/24169 has landed + const externalBaseUrlStr = await this.#discovery.getExternalBaseUrl( + this.#pluginId, + ); + const externalBaseUrl = new URL(externalBaseUrlStr); + + const secure = + externalBaseUrl.protocol === 'https:' || + externalBaseUrl.hostname === 'localhost'; + + return { + domain: externalBaseUrl.hostname, + httpOnly: true, + secure, + priority: 'high', + sameSite: secure ? 'none' : 'lax', + }; + } + + async #existingCookieExpiration(req: Request): Promise { + const existingCookie = getCookieFromRequest(req); + if (!existingCookie) { + return undefined; + } + + try { + const existingCredentials = await this.#auth.authenticate( + existingCookie, + { + allowLimitedAccess: true, + }, + ); + if (!this.#auth.isPrincipal(existingCredentials, 'user')) { + return undefined; + } + + return existingCredentials.expiresAt; + } catch (error) { + if (error.name === 'AuthenticationError') { + return undefined; + } + throw error; + } + } +} + +/** + * Authentication of HTTP requests. + * + * See {@link @backstage/code-plugin-api#HttpAuthService} + * and {@link https://backstage.io/docs/backend-system/core-services/http-auth | the service docs} + * for more information. + * + * @public + */ +export const httpAuthServiceFactory = createServiceFactory({ + service: coreServices.httpAuth, + deps: { + auth: coreServices.auth, + discovery: coreServices.discovery, + plugin: coreServices.pluginMetadata, + }, + async factory({ auth, discovery, plugin }) { + return new DefaultHttpAuthService(auth, discovery, plugin.getId()); + }, +}); diff --git a/packages/backend-defaults/src/entrypoints/httpAuth/index.ts b/packages/backend-defaults/src/entrypoints/httpAuth/index.ts new file mode 100644 index 0000000000..edd7e53026 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/httpAuth/index.ts @@ -0,0 +1,17 @@ +/* + * 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 { httpAuthServiceFactory } from './httpAuthServiceFactory'; diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createAuthIntegrationRouter.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createAuthIntegrationRouter.ts similarity index 99% rename from packages/backend-app-api/src/services/implementations/httpRouter/createAuthIntegrationRouter.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/createAuthIntegrationRouter.ts index 94650199f3..ef36e7ba2d 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/createAuthIntegrationRouter.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/createAuthIntegrationRouter.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { AuthService } from '@backstage/backend-plugin-api'; import express from 'express'; import Router from 'express-promise-router'; diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCookieAuthRefreshMiddleware.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/httpRouter/createCookieAuthRefreshMiddleware.test.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.test.ts diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCookieAuthRefreshMiddleware.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/httpRouter/createCookieAuthRefreshMiddleware.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.ts diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.test.ts similarity index 98% rename from packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.test.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.test.ts index a5246c91b2..124acf277b 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.test.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.test.ts @@ -20,7 +20,7 @@ import express from 'express'; import request from 'supertest'; import { createCredentialsBarrier } from './createCredentialsBarrier'; import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; -import { MiddlewareFactory } from '../../../http'; +import { MiddlewareFactory } from '../rootHttpRouter/http'; const errorMiddleware = MiddlewareFactory.create({ config: mockServices.rootConfig(), diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/httpRouter/createCredentialsBarrier.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.ts diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/createLifecycleMiddleware.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/httpRouter/createLifecycleMiddleware.test.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.test.ts diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts new file mode 100644 index 0000000000..3f8ee3ea69 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts @@ -0,0 +1,106 @@ +/* + * 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 { LifecycleService } from '@backstage/backend-plugin-api'; +import { ServiceUnavailableError } from '@backstage/errors'; +import { HumanDuration, durationToMilliseconds } from '@backstage/types'; +import { RequestHandler } from 'express'; + +export const DEFAULT_TIMEOUT = { seconds: 5 }; + +/** + * Options for {@link createLifecycleMiddleware}. + * @public + */ +export interface LifecycleMiddlewareOptions { + lifecycle: LifecycleService; + /** + * The maximum time that paused requests will wait for the service to start, before returning an error. + * + * Defaults to 5 seconds. + */ + startupRequestPauseTimeout?: HumanDuration; +} + +/** + * Creates a middleware that pauses requests until the service has started. + * + * @remarks + * + * Requests that arrive before the service has started will be paused until startup is complete. + * If the service does not start within the provided timeout, the request will be rejected with a + * {@link @backstage/errors#ServiceUnavailableError}. + * + * If the service is shutting down, all requests will be rejected with a + * {@link @backstage/errors#ServiceUnavailableError}. + * + * @public + */ +export function createLifecycleMiddleware( + options: LifecycleMiddlewareOptions, +): RequestHandler { + const { lifecycle, startupRequestPauseTimeout = DEFAULT_TIMEOUT } = options; + + let state: 'init' | 'up' | 'down' = 'init'; + const waiting = new Set<{ + next: (err?: Error) => void; + timeout: NodeJS.Timeout; + }>(); + + lifecycle.addStartupHook(async () => { + if (state === 'init') { + state = 'up'; + for (const item of waiting) { + clearTimeout(item.timeout); + item.next(); + } + waiting.clear(); + } + }); + + lifecycle.addShutdownHook(async () => { + state = 'down'; + + for (const item of waiting) { + clearTimeout(item.timeout); + item.next(new ServiceUnavailableError('Service is shutting down')); + } + waiting.clear(); + }); + + const timeoutMs = durationToMilliseconds(startupRequestPauseTimeout); + + return (_req, _res, next) => { + if (state === 'up') { + next(); + return; + } else if (state === 'down') { + next(new ServiceUnavailableError('Service is shutting down')); + return; + } + + const item = { + next, + timeout: setTimeout(() => { + if (waiting.delete(item)) { + next(new ServiceUnavailableError('Service has not started up yet')); + } + }, timeoutMs), + }; + + waiting.add(item); + }; +} diff --git a/packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts similarity index 100% rename from packages/backend-app-api/src/services/implementations/httpRouter/httpRouterServiceFactory.test.ts rename to packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.test.ts diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts new file mode 100644 index 0000000000..4a0dec49e6 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts @@ -0,0 +1,101 @@ +/* + * 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 { Handler } from 'express'; +import PromiseRouter from 'express-promise-router'; +import { + coreServices, + createServiceFactory, + HttpRouterServiceAuthPolicy, +} from '@backstage/backend-plugin-api'; +import { createLifecycleMiddleware } from './createLifecycleMiddleware'; +import { createCredentialsBarrier } from './createCredentialsBarrier'; +import { createAuthIntegrationRouter } from './createAuthIntegrationRouter'; +import { createCookieAuthRefreshMiddleware } from './createCookieAuthRefreshMiddleware'; + +/** + * @public + */ +export interface HttpRouterFactoryOptions { + /** + * A callback used to generate the path for each plugin, defaults to `/api/{pluginId}`. + */ + getPath?(pluginId: string): string; +} + +/** + * HTTP route registration for plugins. + * + * See {@link @backstage/code-plugin-api#HttpRouterService} + * and {@link https://backstage.io/docs/backend-system/core-services/http-router | the service docs} + * for more information. + * + * @public + */ +export const httpRouterServiceFactory = createServiceFactory( + (options?: HttpRouterFactoryOptions) => ({ + service: coreServices.httpRouter, + initialization: 'always', + deps: { + plugin: coreServices.pluginMetadata, + config: coreServices.rootConfig, + logger: coreServices.logger, + lifecycle: coreServices.lifecycle, + rootHttpRouter: coreServices.rootHttpRouter, + auth: coreServices.auth, + httpAuth: coreServices.httpAuth, + }, + async factory({ + auth, + httpAuth, + config, + logger, + plugin, + rootHttpRouter, + lifecycle, + }) { + if (options?.getPath) { + logger.warn( + `DEPRECATION WARNING: The 'getPath' option for HttpRouterService is deprecated. The ability to reconfigure the '/api/' path prefix for plugins will be removed in the future.`, + ); + } + const getPath = options?.getPath ?? (id => `/api/${id}`); + const path = getPath(plugin.getId()); + + const router = PromiseRouter(); + rootHttpRouter.use(path, router); + + const credentialsBarrier = createCredentialsBarrier({ + httpAuth, + config, + }); + + router.use(createAuthIntegrationRouter({ auth })); + router.use(createLifecycleMiddleware({ lifecycle })); + router.use(credentialsBarrier.middleware); + router.use(createCookieAuthRefreshMiddleware({ auth, httpAuth })); + + return { + use(handler: Handler): void { + router.use(handler); + }, + addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void { + credentialsBarrier.addAuthPolicy(policy); + }, + }; + }, + }), +); diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/index.ts b/packages/backend-defaults/src/entrypoints/httpRouter/index.ts new file mode 100644 index 0000000000..928a232131 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/httpRouter/index.ts @@ -0,0 +1,20 @@ +/* + * 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 { httpRouterServiceFactory } from './httpRouterServiceFactory'; +export type { HttpRouterFactoryOptions } from './httpRouterServiceFactory'; +export { createLifecycleMiddleware } from './createLifecycleMiddleware'; +export type { LifecycleMiddlewareOptions } from './createLifecycleMiddleware'; diff --git a/packages/backend-defaults/src/entrypoints/lifecycle/lifecycleServiceFactory.ts b/packages/backend-defaults/src/entrypoints/lifecycle/lifecycleServiceFactory.ts index 3eb43d6c6e..192886ca61 100644 --- a/packages/backend-defaults/src/entrypoints/lifecycle/lifecycleServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/lifecycle/lifecycleServiceFactory.ts @@ -85,7 +85,11 @@ export class BackendPluginLifecycleImpl implements LifecycleService { } /** - * Allows plugins to register shutdown hooks that are run when the process is about to exit. + * Registration of plugin startup and shutdown lifecycle hooks. + * + * See {@link @backstage/code-plugin-api#LifecycleService} + * and {@link https://backstage.io/docs/backend-system/core-services/lifecycle | the service docs} + * for more information. * * @public */ diff --git a/packages/backend-defaults/src/entrypoints/logger/index.ts b/packages/backend-defaults/src/entrypoints/logger/index.ts new file mode 100644 index 0000000000..ca52bf5193 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/logger/index.ts @@ -0,0 +1,17 @@ +/* + * 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 { loggerServiceFactory } from './loggerServiceFactory'; diff --git a/packages/backend-defaults/src/entrypoints/logger/loggerServiceFactory.ts b/packages/backend-defaults/src/entrypoints/logger/loggerServiceFactory.ts new file mode 100644 index 0000000000..4eff798e11 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/logger/loggerServiceFactory.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createServiceFactory, + coreServices, +} from '@backstage/backend-plugin-api'; + +/** + * Plugin-level logging. + * + * See {@link @backstage/code-plugin-api#LoggerService} + * and {@link https://backstage.io/docs/backend-system/core-services/logger | the service docs} + * for more information. + * + * @public + */ +export const loggerServiceFactory = createServiceFactory({ + service: coreServices.logger, + deps: { + rootLogger: coreServices.rootLogger, + plugin: coreServices.pluginMetadata, + }, + factory({ rootLogger, plugin }) { + return rootLogger.child({ plugin: plugin.getId() }); + }, +}); diff --git a/packages/backend-defaults/src/entrypoints/permissions/permissionsServiceFactory.ts b/packages/backend-defaults/src/entrypoints/permissions/permissionsServiceFactory.ts index f675dd6719..873d6a4fa0 100644 --- a/packages/backend-defaults/src/entrypoints/permissions/permissionsServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/permissions/permissionsServiceFactory.ts @@ -21,6 +21,12 @@ import { import { ServerPermissionClient } from '@backstage/plugin-permission-node'; /** + * Permission system integration for authorization of user actions. + * + * See {@link @backstage/code-plugin-api#PermissionsService} + * and {@link https://backstage.io/docs/backend-system/core-services/permissions | the service docs} + * for more information. + * * @public */ export const permissionsServiceFactory = createServiceFactory({ diff --git a/packages/backend-defaults/src/entrypoints/rootConfig/createConfigSecretEnumerator.test.ts b/packages/backend-defaults/src/entrypoints/rootConfig/createConfigSecretEnumerator.test.ts new file mode 100644 index 0000000000..1efb12ad03 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootConfig/createConfigSecretEnumerator.test.ts @@ -0,0 +1,74 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { loadConfigSchema } from '@backstage/config-loader'; +import { createConfigSecretEnumerator } from './createConfigSecretEnumerator'; +import { mockServices } from '@backstage/backend-test-utils'; + +describe('createConfigSecretEnumerator', () => { + it('should enumerate secrets', async () => { + const logger = mockServices.logger.mock(); + + const enumerate = await createConfigSecretEnumerator({ + logger, + }); + const secrets = enumerate( + mockServices.rootConfig({ + data: { + backend: { auth: { keys: [{ secret: 'my-secret-password' }] } }, + }, + }), + ); + expect(Array.from(secrets)).toEqual(['my-secret-password']); + }, 20_000); // Bit higher timeout since we're loading all config schemas in the repo + + it('should enumerate secrets with explicit schema', async () => { + const logger = mockServices.logger.mock(); + + const enumerate = await createConfigSecretEnumerator({ + logger, + schema: await loadConfigSchema({ + serialized: { + schemas: [ + { + value: { + type: 'object', + properties: { + secret: { + visibility: 'secret', + type: 'string', + }, + }, + }, + path: '/mock', + }, + ], + backstageConfigSchemaVersion: 1, + }, + }), + }); + + const secrets = enumerate( + mockServices.rootConfig({ + data: { + secret: 'my-secret', + other: 'not-secret', + }, + }), + ); + expect(Array.from(secrets)).toEqual(['my-secret']); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/rootConfig/createConfigSecretEnumerator.ts b/packages/backend-defaults/src/entrypoints/rootConfig/createConfigSecretEnumerator.ts new file mode 100644 index 0000000000..421b07c396 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootConfig/createConfigSecretEnumerator.ts @@ -0,0 +1,54 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 } from '@backstage/backend-plugin-api'; +import type { Config } from '@backstage/config'; +import { ConfigSchema, loadConfigSchema } from '@backstage/config-loader'; +import { getPackages } from '@manypkg/get-packages'; + +/** @public */ +export async function createConfigSecretEnumerator(options: { + logger: LoggerService; + dir?: string; + schema?: ConfigSchema; +}): Promise<(config: Config) => Iterable> { + const { logger, dir = process.cwd() } = options; + const { packages } = await getPackages(dir); + const schema = + options.schema ?? + (await loadConfigSchema({ + dependencies: packages.map(p => p.packageJson.name), + })); + + return (config: Config) => { + const [secretsData] = schema.process( + [{ data: config.getOptional() ?? {}, context: 'schema-enumerator' }], + { + visibility: ['secret'], + ignoreSchemaErrors: true, + }, + ); + const secrets = new Set(); + JSON.parse( + JSON.stringify(secretsData.data), + (_, v) => typeof v === 'string' && secrets.add(v), + ); + logger.info( + `Found ${secrets.size} new secrets in config that will be redacted`, + ); + return secrets; + }; +} diff --git a/packages/backend-defaults/src/entrypoints/rootConfig/index.ts b/packages/backend-defaults/src/entrypoints/rootConfig/index.ts index 1775ef2efc..66f5e8e15f 100644 --- a/packages/backend-defaults/src/entrypoints/rootConfig/index.ts +++ b/packages/backend-defaults/src/entrypoints/rootConfig/index.ts @@ -14,5 +14,8 @@ * limitations under the License. */ -export { rootConfigServiceFactory } from './rootConfigServiceFactory'; -export type { RootConfigFactoryOptions } from './rootConfigServiceFactory'; +export { createConfigSecretEnumerator } from './createConfigSecretEnumerator'; +export { + rootConfigServiceFactory, + type RootConfigFactoryOptions, +} from './rootConfigServiceFactory'; diff --git a/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts index 92d1a89c0f..5752a9c634 100644 --- a/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootConfig/rootConfigServiceFactory.ts @@ -24,6 +24,12 @@ import { } from '@backstage/config-loader'; /** + * Access to static configuration. + * + * See {@link @backstage/code-plugin-api#RootConfigService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-config | the service docs} + * for more information. + * * @public */ export interface RootConfigFactoryOptions { diff --git a/packages/backend-defaults/src/entrypoints/rootHealth/index.ts b/packages/backend-defaults/src/entrypoints/rootHealth/index.ts new file mode 100644 index 0000000000..35225b39c4 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHealth/index.ts @@ -0,0 +1,17 @@ +/* + * 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 { rootHealthServiceFactory } from './rootHealthServiceFactory'; diff --git a/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.test.ts new file mode 100644 index 0000000000..0eee5c18c6 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.test.ts @@ -0,0 +1,91 @@ +/* + * 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 } from '@backstage/backend-test-utils'; +import { DefaultRootHealthService } from './rootHealthServiceFactory'; + +describe('DefaultRootHealthService', () => { + describe('readiness', () => { + it(`should return a 500 response if the server hasn't started yet`, async () => { + const service = new DefaultRootHealthService({ + lifecycle: mockServices.rootLifecycle.mock(), + }); + await expect(service.getReadiness()).resolves.toEqual({ + status: 503, + payload: { + message: 'Backend has not started yet', + status: 'error', + }, + }); + }); + + it('should return 200 if the server has started', async () => { + let mockServerStartedFn = () => {}; + + const lifecycle = mockServices.rootLifecycle.mock({ + addStartupHook: jest.fn(fn => (mockServerStartedFn = fn)), + }); + + const service = new DefaultRootHealthService({ + lifecycle, + }); + + mockServerStartedFn(); + + await expect(service.getReadiness()).resolves.toEqual({ + status: 200, + payload: { status: 'ok' }, + }); + }); + + it(`should return a 500 response if the server has stopped`, async () => { + let mockServerStartedFn = () => {}; + let mockServerStoppedFn = () => {}; + + const lifecycle = mockServices.rootLifecycle.mock({ + addStartupHook: jest.fn(fn => (mockServerStartedFn = fn)), + addShutdownHook: jest.fn(fn => (mockServerStoppedFn = fn)), + }); + + const service = new DefaultRootHealthService({ + lifecycle, + }); + + mockServerStartedFn(); + mockServerStoppedFn(); + await expect(service.getReadiness()).resolves.toEqual({ + status: 503, + payload: { + message: 'Backend has not started yet', + status: 'error', + }, + }); + }); + }); + + describe('liveness', () => { + it('should return 200 if the server has started', async () => { + const service = new DefaultRootHealthService({ + lifecycle: mockServices.rootLifecycle.mock(), + }); + + await expect(service.getLiveness()).resolves.toEqual({ + status: 200, + payload: { status: 'ok' }, + }); + }); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.ts new file mode 100644 index 0000000000..c8b4ad5394 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.ts @@ -0,0 +1,64 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + RootHealthService, + RootLifecycleService, + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; + +/** @internal */ +export class DefaultRootHealthService implements RootHealthService { + #isRunning = false; + + constructor(readonly options: { lifecycle: RootLifecycleService }) { + options.lifecycle.addStartupHook(() => { + this.#isRunning = true; + }); + options.lifecycle.addShutdownHook(() => { + this.#isRunning = false; + }); + } + + async getLiveness(): Promise<{ status: number; payload?: any }> { + return { status: 200, payload: { status: 'ok' } }; + } + + async getReadiness(): Promise<{ status: number; payload?: any }> { + if (!this.#isRunning) { + return { + status: 503, + payload: { message: 'Backend has not started yet', status: 'error' }, + }; + } + + return { status: 200, payload: { status: 'ok' } }; + } +} + +/** + * @public + */ +export const rootHealthServiceFactory = createServiceFactory({ + service: coreServices.rootHealth, + deps: { + lifecycle: coreServices.rootLifecycle, + }, + async factory({ lifecycle }) { + return new DefaultRootHealthService({ lifecycle }); + }, +}); diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.test.ts new file mode 100644 index 0000000000..fc1de9b205 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.test.ts @@ -0,0 +1,124 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import express from 'express'; +import request from 'supertest'; +import { DefaultRootHttpRouter } from './DefaultRootHttpRouter'; + +describe('DefaultRootHttpRouter', () => { + it.each([ + [['/b'], '/a'], + [['/a'], '/aa/b'], + [['/aa'], '/a/b'], + [['/a/b'], '/aa'], + [['/b/a'], '/a'], + [['/a'], '/aa'], + ])(`with existing paths %s, adds %s without conflict`, (existing, added) => { + const router = DefaultRootHttpRouter.create(); + for (const path of existing) { + router.use(path, () => {}); + } + expect(() => router.use(added, () => {})).not.toThrow(); + }); + + it.each([ + [['/a'], '/a', '/a'], + [['/a'], '/a/b', '/a'], + [['/a/b'], '/a', '/a/b'], + ])( + `find conflict when existing paths %s, adds %s`, + (existing, added, conflict) => { + const router = DefaultRootHttpRouter.create(); + for (const path of existing) { + router.use(path, () => {}); + } + expect(() => router.use(added, () => {})).toThrow( + `Path ${added} conflicts with the existing path ${conflict}`, + ); + }, + ); + + it('should not be possible to supply an empty indexPath', () => { + expect(() => DefaultRootHttpRouter.create({ indexPath: '' })).toThrow( + 'indexPath option may not be an empty string', + ); + }); + + it('will always prioritize non-index paths', async () => { + const router = DefaultRootHttpRouter.create({ indexPath: '/x' }); + const app = express(); + app.use(router.handler()); + + const routerX = express.Router(); + routerX.get('/a', (_req, res) => res.status(201).end()); + + const routerY = express.Router(); + routerY.get('/a', (_req, res) => res.status(202).end()); + + await request(app).get('/').expect(404); + await request(app).get('/a').expect(404); + await request(app).get('/x/a').expect(404); + await request(app).get('/y/a').expect(404); + + router.use('/x', routerX); + + await request(app).get('/').expect(404); + await request(app).get('/a').expect(201); + await request(app).get('/x/a').expect(201); + await request(app).get('/y/a').expect(404); + + router.use('/y', routerY); + + await request(app).get('/').expect(404); + await request(app).get('/a').expect(201); + await request(app).get('/x/a').expect(201); + await request(app).get('/y/a').expect(202); + + expect('test').toBe('test'); + }); + + it('should treat unknown /api/ routes as 404', async () => { + const router = DefaultRootHttpRouter.create(); + const app = express(); + app.use(router.handler()); + + router.use('/api/app', (_req, res) => res.status(201).end()); + router.use('/api/catalog', (_req, res) => res.status(202).end()); + + await request(app).get('/').expect(201); + await request(app).get('/api/catalog').expect(202); + await request(app).get('/unknown').expect(201); + await request(app).get('/api/unknown').expect(404); + + expect('test').toBe('test'); + }); + + it('should treat unknown /api/ routes as 404 without an index path', async () => { + const router = DefaultRootHttpRouter.create({ indexPath: false }); + const app = express(); + app.use(router.handler()); + + router.use('/api/app', (_req, res) => res.status(201).end()); + router.use('/api/catalog', (_req, res) => res.status(202).end()); + + await request(app).get('/').expect(404); + await request(app).get('/api/catalog').expect(202); + await request(app).get('/unknown').expect(404); + await request(app).get('/api/unknown').expect(404); + + expect('test').toBe('test'); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.ts new file mode 100644 index 0000000000..9d7d1de120 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.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 { RootHttpRouterService } from '@backstage/backend-plugin-api'; +import { Handler, Router } from 'express'; +import trimEnd from 'lodash/trimEnd'; + +function normalizePath(path: string): string { + return `${trimEnd(path, '/')}/`; +} + +/** + * Options for the {@link DefaultRootHttpRouter} class. + * + * @public + */ +export interface DefaultRootHttpRouterOptions { + /** + * The path to forward all unmatched requests to. Defaults to '/api/app' if + * not given. Disables index path behavior if false is given. + */ + indexPath?: string | false; +} + +/** + * The default implementation of the {@link @backstage/backend-plugin-api#RootHttpRouterService} interface for + * {@link @backstage/backend-plugin-api#coreServices.rootHttpRouter}. + * + * @public + */ +export class DefaultRootHttpRouter implements RootHttpRouterService { + #indexPath?: string; + + #router = Router(); + #namedRoutes = Router(); + #indexRouter = Router(); + #existingPaths = new Array(); + + static create(options?: DefaultRootHttpRouterOptions) { + let indexPath; + if (options?.indexPath === false) { + indexPath = undefined; + } else if (options?.indexPath === undefined) { + indexPath = '/api/app'; + } else if (options?.indexPath === '') { + throw new Error('indexPath option may not be an empty string'); + } else { + indexPath = options.indexPath; + } + return new DefaultRootHttpRouter(indexPath); + } + + private constructor(indexPath?: string) { + this.#indexPath = indexPath; + this.#router.use(this.#namedRoutes); + + // Any request with a /api/ prefix will skip the index router, even if no named router matches + this.#router.use('/api/', (_req, _res, next) => { + next('router'); + }); + + if (this.#indexPath) { + this.#router.use(this.#indexRouter); + } + } + + use(path: string, handler: Handler) { + if (path.match(/^[/\s]*$/)) { + throw new Error(`Root router path may not be empty`); + } + const conflictingPath = this.#findConflictingPath(path); + if (conflictingPath) { + throw new Error( + `Path ${path} conflicts with the existing path ${conflictingPath}`, + ); + } + this.#existingPaths.push(path); + this.#namedRoutes.use(path, handler); + + if (this.#indexPath === path) { + this.#indexRouter.use(handler); + } + } + + handler(): Handler { + return this.#router; + } + + #findConflictingPath(newPath: string): string | undefined { + const normalizedNewPath = normalizePath(newPath); + for (const path of this.#existingPaths) { + const normalizedPath = normalizePath(path); + if (normalizedPath.startsWith(normalizedNewPath)) { + return path; + } + if (normalizedNewPath.startsWith(normalizedPath)) { + return path; + } + } + return undefined; + } +} diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts new file mode 100644 index 0000000000..13691ede28 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/createHealthRouter.ts @@ -0,0 +1,42 @@ +import { RootHealthService } from '@backstage/backend-plugin-api'; + +/* + * 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 Router from 'express-promise-router'; +import { Request, Response } from 'express'; + +export function createHealthRouter(options: { health: RootHealthService }) { + const router = Router(); + + router.get( + '.backstage/health/v1/readiness', + async (_request: Request, response: Response) => { + const { status, payload } = await options.health.getReadiness(); + response.status(status).json(payload); + }, + ); + + router.get( + '.backstage/health/v1/liveness', + async (_request: Request, response: Response) => { + const { status, payload } = await options.health.getLiveness(); + response.status(status).json(payload); + }, + ); + + return router; +} diff --git a/packages/backend-app-api/src/http/MiddlewareFactory.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.test.ts similarity index 100% rename from packages/backend-app-api/src/http/MiddlewareFactory.test.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.test.ts diff --git a/packages/backend-app-api/src/http/MiddlewareFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts similarity index 100% rename from packages/backend-app-api/src/http/MiddlewareFactory.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts diff --git a/packages/backend-app-api/src/http/applyInternalErrorFilter.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/applyInternalErrorFilter.ts similarity index 100% rename from packages/backend-app-api/src/http/applyInternalErrorFilter.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/applyInternalErrorFilter.ts diff --git a/packages/backend-app-api/src/http/config.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts similarity index 100% rename from packages/backend-app-api/src/http/config.test.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.test.ts diff --git a/packages/backend-app-api/src/http/config.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts similarity index 100% rename from packages/backend-app-api/src/http/config.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/config.ts diff --git a/packages/backend-app-api/src/http/createHttpServer.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts similarity index 100% rename from packages/backend-app-api/src/http/createHttpServer.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/createHttpServer.ts diff --git a/packages/backend-app-api/src/http/getGeneratedCertificate.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/getGeneratedCertificate.ts similarity index 100% rename from packages/backend-app-api/src/http/getGeneratedCertificate.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/getGeneratedCertificate.ts diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/index.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/index.ts new file mode 100644 index 0000000000..4a9ec14cf8 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/index.ts @@ -0,0 +1,30 @@ +/* + * 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 { readHttpServerOptions } from './config'; +export { createHttpServer } from './createHttpServer'; +export { MiddlewareFactory } from './MiddlewareFactory'; +export type { + MiddlewareFactoryErrorOptions, + MiddlewareFactoryOptions, +} from './MiddlewareFactory'; +export { readCorsOptions } from './readCorsOptions'; +export { readHelmetOptions } from './readHelmetOptions'; +export type { + ExtendedHttpServer, + HttpServerCertificateOptions, + HttpServerOptions, +} from './types'; diff --git a/packages/backend-app-api/src/http/readCorsOptions.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/readCorsOptions.test.ts similarity index 100% rename from packages/backend-app-api/src/http/readCorsOptions.test.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/readCorsOptions.test.ts diff --git a/packages/backend-app-api/src/http/readCorsOptions.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/readCorsOptions.ts similarity index 100% rename from packages/backend-app-api/src/http/readCorsOptions.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/readCorsOptions.ts diff --git a/packages/backend-app-api/src/http/readHelmetOptions.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/readHelmetOptions.test.ts similarity index 100% rename from packages/backend-app-api/src/http/readHelmetOptions.test.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/readHelmetOptions.test.ts diff --git a/packages/backend-app-api/src/http/readHelmetOptions.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/readHelmetOptions.ts similarity index 100% rename from packages/backend-app-api/src/http/readHelmetOptions.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/readHelmetOptions.ts diff --git a/packages/backend-app-api/src/http/types.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts similarity index 100% rename from packages/backend-app-api/src/http/types.ts rename to packages/backend-defaults/src/entrypoints/rootHttpRouter/http/types.ts diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/index.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/index.ts new file mode 100644 index 0000000000..9c2d96dab2 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/index.ts @@ -0,0 +1,26 @@ +/* + * 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 { + DefaultRootHttpRouter, + type DefaultRootHttpRouterOptions, +} from './DefaultRootHttpRouter'; +export * from './http'; +export { + rootHttpRouterServiceFactory, + type RootHttpRouterConfigureContext, + type RootHttpRouterFactoryOptions, +} from './rootHttpRouterServiceFactory'; diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts new file mode 100644 index 0000000000..22f5c2f310 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts @@ -0,0 +1,126 @@ +/* + * 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 { + RootConfigService, + coreServices, + createServiceFactory, + LifecycleService, + LoggerService, +} from '@backstage/backend-plugin-api'; +import express, { RequestHandler, Express } from 'express'; +import type { Server } from 'node:http'; +import { + createHttpServer, + MiddlewareFactory, + readHttpServerOptions, +} from './http'; +import { DefaultRootHttpRouter } from './DefaultRootHttpRouter'; +import { createHealthRouter } from './createHealthRouter'; + +/** + * @public + */ +export interface RootHttpRouterConfigureContext { + app: Express; + server: Server; + middleware: MiddlewareFactory; + routes: RequestHandler; + config: RootConfigService; + logger: LoggerService; + lifecycle: LifecycleService; + healthRouter: RequestHandler; + applyDefaults: () => void; +} + +/** + * HTTP route registration for root services. + * + * See {@link @backstage/code-plugin-api#RootHttpRouterService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-http-router | the service docs} + * for more information. + * + * @public + */ +export type RootHttpRouterFactoryOptions = { + /** + * The path to forward all unmatched requests to. Defaults to '/api/app' if + * not given. Disables index path behavior if false is given. + */ + indexPath?: string | false; + + configure?(context: RootHttpRouterConfigureContext): void; +}; + +function defaultConfigure({ applyDefaults }: RootHttpRouterConfigureContext) { + applyDefaults(); +} + +/** @public */ +export const rootHttpRouterServiceFactory = createServiceFactory( + (options?: RootHttpRouterFactoryOptions) => ({ + service: coreServices.rootHttpRouter, + deps: { + config: coreServices.rootConfig, + rootLogger: coreServices.rootLogger, + lifecycle: coreServices.rootLifecycle, + health: coreServices.rootHealth, + }, + async factory({ config, rootLogger, lifecycle, health }) { + const { indexPath, configure = defaultConfigure } = options ?? {}; + const logger = rootLogger.child({ service: 'rootHttpRouter' }); + const app = express(); + + const router = DefaultRootHttpRouter.create({ indexPath }); + const middleware = MiddlewareFactory.create({ config, logger }); + const routes = router.handler(); + + const healthRouter = createHealthRouter({ health }); + const server = await createHttpServer( + app, + readHttpServerOptions(config.getOptionalConfig('backend')), + { logger }, + ); + + configure({ + app, + server, + routes, + middleware, + config, + logger, + lifecycle, + healthRouter, + applyDefaults() { + app.use(middleware.helmet()); + app.use(middleware.cors()); + app.use(middleware.compression()); + app.use(middleware.logging()); + app.use(healthRouter); + app.use(routes); + app.use(middleware.notFound()); + app.use(middleware.error()); + }, + }); + + lifecycle.addShutdownHook(() => server.stop()); + + await server.start(); + + return router; + }, + }), +); diff --git a/packages/backend-defaults/src/entrypoints/rootLifecycle/rootLifecycleServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootLifecycle/rootLifecycleServiceFactory.ts index 197f99b97a..e724c2f5cb 100644 --- a/packages/backend-defaults/src/entrypoints/rootLifecycle/rootLifecycleServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootLifecycle/rootLifecycleServiceFactory.ts @@ -105,7 +105,11 @@ export class BackendLifecycleImpl implements RootLifecycleService { } /** - * Allows plugins to register shutdown hooks that are run when the process is about to exit. + * Registration of backend startup and shutdown lifecycle hooks. + * + * See {@link @backstage/code-plugin-api#RootLifecycleService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-lifecycle | the service docs} + * for more information. * * @public */ diff --git a/packages/backend-app-api/src/logging/WinstonLogger.test.ts b/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.test.ts similarity index 100% rename from packages/backend-app-api/src/logging/WinstonLogger.test.ts rename to packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.test.ts diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.ts b/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.ts new file mode 100644 index 0000000000..38d05f6511 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.ts @@ -0,0 +1,192 @@ +/* + * 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 { + LoggerService, + RootLoggerService, +} from '@backstage/backend-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { Format, TransformableInfo } from 'logform'; +import { + Logger, + format, + createLogger, + transports, + transport as Transport, +} from 'winston'; +import { MESSAGE } from 'triple-beam'; +import { escapeRegExp } from '../../lib/escapeRegExp'; + +/** + * @public + */ +export interface WinstonLoggerOptions { + meta?: JsonObject; + level?: string; + format?: Format; + transports?: Transport[]; +} + +/** + * A {@link @backstage/backend-plugin-api#LoggerService} implementation based on winston. + * + * @public + */ +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(); + const defaultFormatter = + process.env.NODE_ENV === 'production' + ? format.json() + : WinstonLogger.colorFormat(); + + let logger = createLogger({ + level: process.env.LOG_LEVEL || options.level || 'info', + format: format.combine( + options.format ?? defaultFormatter, + redacter.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; + + return { + format: format((obj: TransformableInfo) => { + if (!redactionPattern || !obj) { + return obj; + } + + obj[MESSAGE] = obj[MESSAGE]?.replace?.(redactionPattern, '***'); + + return obj; + })(), + 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/packages/backend-defaults/src/entrypoints/rootLogger/index.ts b/packages/backend-defaults/src/entrypoints/rootLogger/index.ts new file mode 100644 index 0000000000..96ed402520 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootLogger/index.ts @@ -0,0 +1,18 @@ +/* + * 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 { rootLoggerServiceFactory } from './rootLoggerServiceFactory'; +export { WinstonLogger, type WinstonLoggerOptions } from './WinstonLogger'; diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.ts new file mode 100644 index 0000000000..8454cf07d3 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.ts @@ -0,0 +1,58 @@ +/* + * 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 { + createServiceFactory, + coreServices, +} from '@backstage/backend-plugin-api'; +import { transports, format } from 'winston'; +import { WinstonLogger } from '../rootLogger/WinstonLogger'; +import { createConfigSecretEnumerator } from '../rootConfig/createConfigSecretEnumerator'; + +/** + * Root-level logging. + * + * See {@link @backstage/code-plugin-api#RootLoggerService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-logger | the service docs} + * for more information. + * + * @public + */ +export const rootLoggerServiceFactory = createServiceFactory({ + service: coreServices.rootLogger, + deps: { + config: coreServices.rootConfig, + }, + async factory({ config }) { + const logger = WinstonLogger.create({ + meta: { + service: 'backstage', + }, + level: process.env.LOG_LEVEL || 'info', + format: + process.env.NODE_ENV === 'production' + ? format.json() + : WinstonLogger.colorFormat(), + transports: [new transports.Console()], + }); + + const secretEnumerator = await createConfigSecretEnumerator({ logger }); + logger.addRedactions(secretEnumerator(config)); + config.subscribe?.(() => logger.addRedactions(secretEnumerator(config))); + + return logger; + }, +}); diff --git a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts index 62b36e024c..40aa9d521c 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts @@ -152,7 +152,7 @@ export class PluginTaskSchedulerImpl implements SchedulerService { export function parseDuration( frequency: SchedulerServiceTaskScheduleDefinition['frequency'], ): string { - if ('cron' in frequency) { + if (typeof frequency === 'object' && 'cron' in frequency) { return frequency.cron; } diff --git a/packages/backend-defaults/src/entrypoints/scheduler/schedulerServiceFactory.ts b/packages/backend-defaults/src/entrypoints/scheduler/schedulerServiceFactory.ts index 1105c86332..effa5c5925 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/schedulerServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/schedulerServiceFactory.ts @@ -21,7 +21,11 @@ import { import { DefaultSchedulerService } from './lib/DefaultSchedulerService'; /** - * The default service factory for {@link @backstage/backend-plugin-api#coreServices.scheduler}. + * Scheduling of distributed background tasks. + * + * See {@link @backstage/code-plugin-api#SchedulerService} + * and {@link https://backstage.io/docs/backend-system/core-services/scheduler | the service docs} + * for more information. * * @public */ diff --git a/packages/backend-defaults/src/entrypoints/urlReader/urlReaderServiceFactory.ts b/packages/backend-defaults/src/entrypoints/urlReader/urlReaderServiceFactory.ts index dae8d692cb..810882edf8 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/urlReaderServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/urlReaderServiceFactory.ts @@ -20,7 +20,15 @@ import { createServiceFactory, } from '@backstage/backend-plugin-api'; -/** @public */ +/** + * Reading content from external systems. + * + * See {@link @backstage/code-plugin-api#UrlReaderService} + * and {@link https://backstage.io/docs/backend-system/core-services/url-reader | the service docs} + * for more information. + * + * @public + */ export const urlReaderServiceFactory = createServiceFactory({ service: coreServices.urlReader, deps: { diff --git a/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts new file mode 100644 index 0000000000..b63b24fb18 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.test.ts @@ -0,0 +1,169 @@ +/* + * 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 { BackstageUserPrincipal } from '@backstage/backend-plugin-api'; +import { + mockServices, + setupRequestMockHandlers, +} from '@backstage/backend-test-utils'; +import { JsonObject } from '@backstage/types'; +import { SignJWT, base64url, importJWK } from 'jose'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { InternalBackstageCredentials } from '../auth/types'; +import { DefaultUserInfoService } from './DefaultUserInfoService'; + +describe('DefaultUserInfoService', () => { + const server = setupServer(); + setupRequestMockHandlers(server); + + const mockPublicKey = { + kty: 'EC', + x: 'GHlwg744e8JekzukPTdtix6R868D6fcWy0ooOx-NEZI', + y: 'Lyujcm0M6X9_yQi3l1eH09z0brU8K9cwrLml_fRFKro', + crv: 'P-256', + kid: 'mock', + alg: 'ES256', + }; + const mockPrivateKey = { + ...mockPublicKey, + d: 'KEn_mDqXYbZdRHb-JnCrW53LDOv5x4NL1FnlKcqBsFI', + }; + + function encodeData(data: JsonObject) { + return base64url.encode(JSON.stringify(data)); + } + + async function createToken(options: { + header: JsonObject; + payload: JsonObject; + signature?: string; + }) { + if (options.signature) { + const header = encodeData(options.header); + const payload = encodeData(options.payload); + + return `${header}.${payload}.${options.signature}`; + } + + return await new SignJWT(options.payload) + .setProtectedHeader({ ...options.header, alg: 'ES256' }) + .sign(await importJWK(mockPrivateKey)); + } + + const discovery = mockServices.discovery.mock({ + getBaseUrl: async pluginId => `https://example.com/api/${pluginId}`, + }); + + it('makes the expected call when no ent in the token', async () => { + const token = await createToken({ + header: { + typ: 'vnd.backstage.user', + alg: 'ES256', + kid: mockPublicKey.kid, + }, + payload: { + sub: 'user:default/alice', + }, + }); + const credentials = { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + token: token, + principal: { + type: 'user', + userEntityRef: 'user:default/alice', + }, + } as InternalBackstageCredentials; + + server.use( + rest.get('https://example.com/api/auth/v1/userinfo', (req, res, ctx) => { + expect(req.headers.get('authorization')).toBe(`Bearer ${token}`); + return res(ctx.json({ claims: { ent: ['group:default/my-team'] } })); + }), + ); + + const service = new DefaultUserInfoService({ discovery }); + await expect(service.getUserInfo(credentials)).resolves.toEqual({ + userEntityRef: 'user:default/alice', + ownershipEntityRefs: ['group:default/my-team'], + }); + }); + + it('uses the ent from the token when present', async () => { + const token = await createToken({ + header: { + typ: 'vnd.backstage.user', + alg: 'ES256', + kid: mockPublicKey.kid, + }, + payload: { + sub: 'user:default/alice', + ent: ['group:default/my-team'], + }, + }); + const credentials = { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + token: token, + principal: { + type: 'user', + userEntityRef: 'user:default/alice', + }, + } as InternalBackstageCredentials; + + const service = new DefaultUserInfoService({ discovery }); + await expect(service.getUserInfo(credentials)).resolves.toEqual({ + userEntityRef: 'user:default/alice', + ownershipEntityRefs: ['group:default/my-team'], + }); + }); + + it('passes on server errors', async () => { + const token = await createToken({ + header: { + typ: 'vnd.backstage.user', + alg: 'ES256', + kid: mockPublicKey.kid, + }, + payload: { + sub: 'user:default/alice', + }, + }); + const credentials = { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + token: token, + principal: { + type: 'user', + userEntityRef: 'user:default/alice', + }, + } as InternalBackstageCredentials; + + server.use( + rest.get('https://example.com/api/auth/v1/userinfo', (_req, res, ctx) => { + return res(ctx.status(404)); + }), + ); + + const service = new DefaultUserInfoService({ discovery }); + await expect( + service.getUserInfo(credentials), + ).rejects.toMatchInlineSnapshot( + `[ResponseError: Request failed with 404 Not Found]`, + ); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.ts b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.ts new file mode 100644 index 0000000000..83bbba89b7 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/userInfo/DefaultUserInfoService.ts @@ -0,0 +1,90 @@ +/* + * 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 { + UserInfoService, + BackstageUserInfo, + DiscoveryService, + BackstageCredentials, +} from '@backstage/backend-plugin-api'; +import { ResponseError } from '@backstage/errors'; +import { decodeJwt } from 'jose'; +import fetch from 'node-fetch'; +import { toInternalBackstageCredentials } from '../auth/helpers'; + +export type Options = { + discovery: DiscoveryService; +}; + +export class DefaultUserInfoService implements UserInfoService { + private readonly discovery: DiscoveryService; + + constructor(options: Options) { + this.discovery = options.discovery; + } + + async getUserInfo( + credentials: BackstageCredentials, + ): Promise { + const internalCredentials = toInternalBackstageCredentials(credentials); + if (internalCredentials.principal.type !== 'user') { + throw new Error('Only user credentials are supported'); + } + if (!internalCredentials.token) { + throw new Error('User credentials is unexpectedly missing token'); + } + const { sub: userEntityRef, ent: tokenEnt } = decodeJwt( + internalCredentials.token, + ); + + if (typeof userEntityRef !== 'string') { + throw new Error('User entity ref must be a string'); + } + + let ownershipEntityRefs = tokenEnt; + + if (!ownershipEntityRefs) { + const userInfoResp = await fetch( + `${await this.discovery.getBaseUrl('auth')}/v1/userinfo`, + { + headers: { + Authorization: `Bearer ${internalCredentials.token}`, + }, + }, + ); + + if (!userInfoResp.ok) { + throw await ResponseError.fromResponse(userInfoResp); + } + + const { + claims: { ent }, + } = await userInfoResp.json(); + ownershipEntityRefs = ent; + } + + if (!ownershipEntityRefs) { + throw new Error('Ownership entity refs can not be determined'); + } else if ( + !Array.isArray(ownershipEntityRefs) || + ownershipEntityRefs.some(ref => typeof ref !== 'string') + ) { + throw new Error('Ownership entity refs must be an array of strings'); + } + + return { userEntityRef, ownershipEntityRefs }; + } +} diff --git a/packages/backend-defaults/src/entrypoints/userInfo/index.ts b/packages/backend-defaults/src/entrypoints/userInfo/index.ts new file mode 100644 index 0000000000..13b42f053c --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/userInfo/index.ts @@ -0,0 +1,17 @@ +/* + * 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 { userInfoServiceFactory } from './userInfoServiceFactory'; diff --git a/packages/backend-defaults/src/entrypoints/userInfo/userInfoServiceFactory.ts b/packages/backend-defaults/src/entrypoints/userInfo/userInfoServiceFactory.ts new file mode 100644 index 0000000000..fe8c398bca --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/userInfo/userInfoServiceFactory.ts @@ -0,0 +1,40 @@ +/* + * 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 { + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { DefaultUserInfoService } from './DefaultUserInfoService'; + +/** + * Authenticated user information retrieval. + * + * See {@link @backstage/code-plugin-api#UserInfoService} + * and {@link https://backstage.io/docs/backend-system/core-services/user-info | the service docs} + * for more information. + * + * @public + */ +export const userInfoServiceFactory = createServiceFactory({ + service: coreServices.userInfo, + deps: { + discovery: coreServices.discovery, + }, + async factory({ discovery }) { + return new DefaultUserInfoService({ discovery }); + }, +}); diff --git a/packages/backend-app-api/src/lib/escapeRegExp.test.ts b/packages/backend-defaults/src/lib/escapeRegExp.test.ts similarity index 100% rename from packages/backend-app-api/src/lib/escapeRegExp.test.ts rename to packages/backend-defaults/src/lib/escapeRegExp.test.ts diff --git a/packages/backend-app-api/src/lib/escapeRegExp.ts b/packages/backend-defaults/src/lib/escapeRegExp.ts similarity index 100% rename from packages/backend-app-api/src/lib/escapeRegExp.ts rename to packages/backend-defaults/src/lib/escapeRegExp.ts diff --git a/packages/backend-common/src/urls.test.ts b/packages/backend-defaults/src/lib/urls.test.ts similarity index 100% rename from packages/backend-common/src/urls.test.ts rename to packages/backend-defaults/src/lib/urls.test.ts diff --git a/packages/backend-common/src/urls.ts b/packages/backend-defaults/src/lib/urls.ts similarity index 100% rename from packages/backend-common/src/urls.ts rename to packages/backend-defaults/src/lib/urls.ts diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index 51943e952d..4ec9489674 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,58 @@ # @backstage/backend-dynamic-feature-service +## 0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-scaffolder-node@0.4.7-next.0 + - @backstage/backend-app-api@0.7.9-next.0 + - @backstage/plugin-app-node@0.1.21-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-catalog-backend@1.23.2-next.0 + - @backstage/plugin-events-backend@0.3.8-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## 0.2.11 + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- Updated dependencies + - @backstage/cli-node@0.2.6 + - @backstage/backend-app-api@0.7.6 + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/backend-tasks@0.5.24 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/plugin-catalog-backend@1.23.0 + - @backstage/plugin-events-backend@0.3.6 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-events-node@0.3.5 + - @backstage/plugin-permission-node@0.7.30 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-scaffolder-node@0.4.5 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-app-node@0.1.19 + - @backstage/cli-common@0.1.14 + - @backstage/config-loader@1.8.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.11-next.3 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/api-report.md b/packages/backend-dynamic-feature-service/api-report.md index 57b2228975..20db7db71b 100644 --- a/packages/backend-dynamic-feature-service/api-report.md +++ b/packages/backend-dynamic-feature-service/api-report.md @@ -4,6 +4,7 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; +import { BackendFeatureCompat } from '@backstage/backend-plugin-api'; import { BackstagePackageJson } from '@backstage/cli-node'; import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; @@ -119,7 +120,7 @@ export const dynamicPluginsFeatureDiscoveryServiceFactory: () => ServiceFactory< >; // @public (undocumented) -export const dynamicPluginsFrontendSchemas: () => BackendFeature; +export const dynamicPluginsFrontendSchemas: BackendFeatureCompat; // @public (undocumented) export const dynamicPluginsRootLoggerServiceFactory: () => ServiceFactory< diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index fb2646f59b..60ff4d2d4e 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-dynamic-feature-service", "description": "Backstage dynamic feature service", - "version": "0.2.11-next.3", + "version": "0.2.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-dynamic-feature-service/src/manager/plugin-manager.test.ts b/packages/backend-dynamic-feature-service/src/manager/plugin-manager.test.ts index 340991b11f..8531624509 100644 --- a/packages/backend-dynamic-feature-service/src/manager/plugin-manager.test.ts +++ b/packages/backend-dynamic-feature-service/src/manager/plugin-manager.test.ts @@ -154,9 +154,9 @@ describe('backend-dynamic-feature-service', () => { const installer: NewBackendPluginInstaller = ( plugins[0] as BackendDynamicPlugin ).installer as NewBackendPluginInstaller; - expect(installer.install()).toEqual< - BackendFeature | BackendFeature[] - >({ $$type: '@backstage/BackendFeature' }); + expect((installer.install() as BackendFeature).$$type).toEqual( + '@backstage/BackendFeature', + ); }, }, { @@ -199,9 +199,9 @@ describe('backend-dynamic-feature-service', () => { const installer: NewBackendPluginInstaller = ( plugins[0] as BackendDynamicPlugin ).installer as NewBackendPluginInstaller; - expect(installer.install()).toEqual< - BackendFeature | BackendFeature[] - >({ $$type: '@backstage/BackendFeature' }); + expect((installer.install() as BackendFeature).$$type).toEqual( + '@backstage/BackendFeature', + ); }, }, { diff --git a/packages/backend-legacy/CHANGELOG.md b/packages/backend-legacy/CHANGELOG.md index 64a7e372db..9535ba1211 100644 --- a/packages/backend-legacy/CHANGELOG.md +++ b/packages/backend-legacy/CHANGELOG.md @@ -1,5 +1,89 @@ # example-backend-legacy +## 0.2.100-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.3-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.38-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-scaffolder-backend@1.23.0-next.0 + - @backstage/plugin-app-backend@0.3.70-next.0 + - @backstage/plugin-auth-backend@0.22.8-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-catalog-backend@1.23.2-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.19-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.8-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-devtools-backend@0.3.7-next.0 + - @backstage/plugin-events-backend@0.3.8-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/plugin-kubernetes-backend@0.18.2-next.0 + - @backstage/plugin-permission-backend@0.5.45-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/plugin-proxy-backend@0.5.2-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.22-next.0 + - @backstage/plugin-search-backend@1.5.13-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.27-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.2-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.27-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.31-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.26-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/plugin-signals-backend@0.1.7-next.0 + - @backstage/plugin-signals-node@0.1.7-next.0 + - @backstage/plugin-techdocs-backend@1.10.8-next.0 + - example-app@0.2.99-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-permission-common@0.7.14 + +## 0.2.99 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-tasks@0.5.24 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/plugin-auth-backend@0.22.6 + - @backstage/plugin-techdocs-backend@1.10.6 + - @backstage/plugin-devtools-backend@0.3.5 + - @backstage/plugin-catalog-backend@1.23.0 + - @backstage/plugin-search-backend@1.5.10 + - @backstage/plugin-proxy-backend@0.5.0 + - @backstage/plugin-app-backend@0.3.68 + - @backstage/integration@1.12.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.2.20 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.17 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.6 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.4.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.36 + - @backstage/plugin-search-backend-module-techdocs@0.1.24 + - @backstage/plugin-search-backend-module-catalog@0.1.25 + - @backstage/plugin-search-backend-module-explore@0.1.25 + - @backstage/plugin-search-backend-module-pg@0.5.28 + - @backstage/plugin-kubernetes-backend@0.18.0 + - @backstage/plugin-permission-backend@0.5.43 + - @backstage/plugin-scaffolder-backend@1.22.9 + - @backstage/plugin-signals-backend@0.1.5 + - @backstage/plugin-events-backend@0.3.6 + - @backstage/plugin-catalog-node@1.12.1 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-events-node@0.3.5 + - @backstage/plugin-permission-node@0.7.30 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-signals-node@0.1.5 + - example-app@0.2.98 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.2.99-next.3 ### Patch Changes diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index f19b5205ae..6b9bb3523a 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-legacy", - "version": "0.2.99-next.3", + "version": "0.2.100-next.0", "backstage": { "role": "backend" }, @@ -66,7 +66,7 @@ "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^19.0.3", "azure-devops-node-api": "^12.0.0", - "better-sqlite3": "^9.0.0", + "better-sqlite3": "^11.0.0", "dockerode": "^4.0.0", "example-app": "link:../app", "express": "^4.17.1", diff --git a/packages/backend-legacy/src/plugins/techdocs.ts b/packages/backend-legacy/src/plugins/techdocs.ts index 6e369f8f0f..21048d4bb9 100644 --- a/packages/backend-legacy/src/plugins/techdocs.ts +++ b/packages/backend-legacy/src/plugins/techdocs.ts @@ -14,14 +14,12 @@ * limitations under the License. */ -import { DockerContainerRunner } from '@backstage/backend-common'; import { createRouter, Generators, Preparers, Publisher, } from '@backstage/plugin-techdocs-backend'; -import Docker from 'dockerode'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; @@ -34,14 +32,9 @@ export default async function createPlugin( reader: env.reader, }); - // Docker client (conditionally) used by the generators, based on techdocs.generators config. - const dockerClient = new Docker(); - const containerRunner = new DockerContainerRunner({ dockerClient }); - // Generators are used for generating documentation sites. const generators = await Generators.fromConfig(env.config, { logger: env.logger, - containerRunner, }); // Publisher is used for diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index f7a6b90d54..0040eddc57 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/backend-openapi-utils +## 0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/errors@1.2.4 + +## 0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.19 + - @backstage/errors@1.2.4 + ## 0.1.12-next.2 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index 38121282c8..4b2551eb13 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-openapi-utils", "description": "OpenAPI typescript support.", - "version": "0.1.12-next.2", + "version": "0.1.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index c947a9627d..b36d7a996d 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,66 @@ # @backstage/backend-plugin-api +## 0.6.21-next.0 + +### Patch Changes + +- 53ced70: Added a new Root Health Service which adds new endpoints for health checks. +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- Updated dependencies + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.14 + +## 0.6.19 + +### Patch Changes + +- 78a0b08: **DEPRECATION**: You should no longer do a function call on backend features when adding them to backends. The support for doing that is deprecated, and you should remove all trailing `()` parentheses after plugins and modules where you add them to your backend or test backends (e.g. when using `startTestBackend`). + + The background for this is that `createBackendPlugin` and `createBackendModule` function now effectively return a `BackendFeature` rather than a `() => BackendFeature`. This is part of the cleanup efforts for New Backend System 1.0. In the short run this is non-breaking because the feature type has been given a callback signature that returns itself. But we strongly recommend that you remove all now-redundant calls made to feature objects, because that callback signature will be removed in a future release. + + Service factories are still callbacks at this point. + + Example change: + + ```diff + await startTestBackend({ + features: [ + eventsServiceFactory(), // service - stays unchanged + - catalogModuleBitbucketCloudEntityProvider(), // module - remove parentheses + + catalogModuleBitbucketCloudEntityProvider, + ``` + +- 9bdc3e8: In tests, return `null` rather than throwing an error when trying to get the `ExtensionPoint.T` property, so that tests asserting the property are not easily broken. +- 9e63318: Added an optional `accessRestrictions` to external access service tokens and service principals in general, such that you can limit their access to certain plugins or permissions. +- 3aa3fc7: Marked the `TokenManagerService` and `IdentityService` types as deprecated +- b2ee7f3: Deprecated all of the `UrlReader` related type names and replaced them with prefixed versions. Please update your imports. + + - `ReadTreeOptions` was renamed to `UrlReaderServiceReadTreeOptions` + - `ReadTreeResponse` was renamed to `UrlReaderServiceReadTreeResponse` + - `ReadTreeResponseDirOptions` was renamed to `UrlReaderServiceReadTreeResponseDirOptions` + - `ReadTreeResponseFile` was renamed to `UrlReaderServiceReadTreeResponseFile` + - `ReadUrlResponse` was renamed to `UrlReaderServiceReadUrlResponse` + - `ReadUrlOptions` was renamed to `UrlReaderServiceReadUrlOptions` + - `SearchOptions` was renamed to `UrlReaderServiceSearchOptions` + - `SearchResponse` was renamed to `UrlReaderServiceSearchResponse` + - `SearchResponseFile` was renamed to `UrlReaderServiceSearchResponseFile` + +- 9539a0b: Improved `coreServices` doc comments +- 6551b3d: Moved the declaration of the `SchedulerService` here, along with prefixed versions of all of the types it depends on, from `@backstage/backend-tasks` +- 0665b7e: Renamed `BackendPluginConfig`, `BackendModuleConfig`, and `ExtensionPointConfig` respectively to `CreateBackendPluginOptions`, `CreateBackendModuleOptions`, and `CreateExtensionPointOptions` to standardize frontend and backend factories signatures. +- 1779188: Start using the `isDatabaseConflictError` helper from the `@backstage/backend-plugin-api` package in order to avoid dependency with the soon to deprecate `@backstage/backend-common` package. +- Updated dependencies + - @backstage/plugin-auth-node@0.4.14 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.6.19-next.3 ### Patch Changes diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 140744b5de..e9762f652e 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -63,6 +63,12 @@ export interface BackendFeature { $$type: '@backstage/BackendFeature'; } +// @public @deprecated (undocumented) +export interface BackendFeatureCompat extends BackendFeature { + // @deprecated (undocumented) + (): this; +} + // @public @deprecated (undocumented) export type BackendModuleConfig = CreateBackendModuleOptions; @@ -188,6 +194,7 @@ export namespace coreServices { const rootConfig: ServiceRef; const database: ServiceRef; const discovery: ServiceRef; + const rootHealth: ServiceRef; const httpAuth: ServiceRef; const httpRouter: ServiceRef; const lifecycle: ServiceRef; @@ -208,7 +215,7 @@ export namespace coreServices { // @public export function createBackendModule( options: CreateBackendModuleOptions, -): () => BackendFeature; +): BackendFeatureCompat; // @public export interface CreateBackendModuleOptions { @@ -221,7 +228,7 @@ export interface CreateBackendModuleOptions { // @public export function createBackendPlugin( options: CreateBackendPluginOptions, -): () => BackendFeature; +): BackendFeatureCompat; // @public export interface CreateBackendPluginOptions { @@ -494,6 +501,18 @@ export function resolveSafeChildPath(base: string, path: string): string; // @public export interface RootConfigService extends Config {} +// @public (undocumented) +export interface RootHealthService { + getLiveness(): Promise<{ + status: number; + payload?: JsonValue; + }>; + getReadiness(): Promise<{ + status: number; + payload?: JsonValue; + }>; +} + // @public export interface RootHttpRouterService { use(path: string, handler: Handler): void; diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 6e3ad58fb5..dbb59f7991 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "0.6.19-next.3", + "version": "0.6.21-next.0", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" diff --git a/packages/backend-plugin-api/src/index.ts b/packages/backend-plugin-api/src/index.ts index c2e2a13a89..e6e57db1dc 100644 --- a/packages/backend-plugin-api/src/index.ts +++ b/packages/backend-plugin-api/src/index.ts @@ -21,6 +21,6 @@ */ export * from './services'; -export type { BackendFeature } from './types'; +export type { BackendFeature, BackendFeatureCompat } from './types'; export * from './paths'; export * from './wiring'; diff --git a/packages/backend-plugin-api/src/services/definitions/RootHealthService.ts b/packages/backend-plugin-api/src/services/definitions/RootHealthService.ts new file mode 100644 index 0000000000..e6c56e8654 --- /dev/null +++ b/packages/backend-plugin-api/src/services/definitions/RootHealthService.ts @@ -0,0 +1,31 @@ +/* + * 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 { JsonValue } from '@backstage/types'; + +/** + * @public + */ +export interface RootHealthService { + /** + * Get the liveness status of the backend. + */ + getLiveness(): Promise<{ status: number; payload?: JsonValue }>; + /** + * Get the readiness status of the backend. + */ + getReadiness(): Promise<{ status: number; payload?: JsonValue }>; +} diff --git a/packages/backend-plugin-api/src/services/definitions/SchedulerService.test.ts b/packages/backend-plugin-api/src/services/definitions/SchedulerService.test.ts index 7b20487af4..875e24786f 100644 --- a/packages/backend-plugin-api/src/services/definitions/SchedulerService.test.ts +++ b/packages/backend-plugin-api/src/services/definitions/SchedulerService.test.ts @@ -16,7 +16,6 @@ import { ConfigReader } from '@backstage/config'; import { HumanDuration } from '@backstage/types'; -import { Duration } from 'luxon'; import { readSchedulerServiceTaskScheduleDefinitionFromConfig } from './SchedulerService'; describe('readSchedulerServiceTaskScheduleDefinitionFromConfig', () => { @@ -35,7 +34,7 @@ describe('readSchedulerServiceTaskScheduleDefinitionFromConfig', () => { const result = readSchedulerServiceTaskScheduleDefinitionFromConfig(config); expect((result.frequency as { cron: string }).cron).toBe('0 30 * * * *'); - expect(result.timeout).toEqual(Duration.fromISO('PT3M')); + expect(result.timeout).toEqual({ minutes: 3 }); expect((result.initialDelay as HumanDuration).minutes).toEqual(20); expect(result.scope).toBe('global'); }); @@ -51,7 +50,7 @@ describe('readSchedulerServiceTaskScheduleDefinitionFromConfig', () => { const result = readSchedulerServiceTaskScheduleDefinitionFromConfig(config); expect((result.frequency as { cron: string }).cron).toBe('0 30 * * * *'); - expect(result.timeout).toEqual(Duration.fromISO('PT3M')); + expect(result.timeout).toEqual({ minutes: 3 }); expect(result.initialDelay).toBeUndefined(); expect(result.scope).toBeUndefined(); }); diff --git a/packages/backend-plugin-api/src/services/definitions/SchedulerService.ts b/packages/backend-plugin-api/src/services/definitions/SchedulerService.ts index 91edf27ad6..a7ec79a336 100644 --- a/packages/backend-plugin-api/src/services/definitions/SchedulerService.ts +++ b/packages/backend-plugin-api/src/services/definitions/SchedulerService.ts @@ -348,14 +348,14 @@ export interface SchedulerService { getScheduledTasks(): Promise; } -function readDuration(config: Config, key: string): Duration | HumanDuration { +function readDuration(config: Config, key: string): HumanDuration { if (typeof config.get(key) === 'string') { const value = config.getString(key); const duration = Duration.fromISO(value); if (!duration.isValid) { throw new Error(`Invalid duration: ${value}`); } - return duration; + return duration.toObject(); } return readDurationFromConfig(config, { key }); @@ -364,7 +364,7 @@ function readDuration(config: Config, key: string): Duration | HumanDuration { function readCronOrDuration( config: Config, key: string, -): { cron: string } | Duration | HumanDuration { +): { cron: string } | HumanDuration { const value = config.get(key); if (typeof value === 'object' && (value as { cron?: string }).cron) { return value as { cron: string }; diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index 4e02611f80..33d1da2903 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -23,7 +23,11 @@ import { createServiceRef } from '../system'; */ export namespace coreServices { /** - * The service reference for the plugin scoped {@link AuthService}. + * Handles token authentication and credentials management. + * + * See {@link AuthService} + * and {@link https://backstage.io/docs/backend-system/core-services/auth | the service docs} + * for more information. * * @public */ @@ -32,7 +36,11 @@ export namespace coreServices { }); /** - * The service reference for the plugin scoped {@link UserInfoService}. + * Authenticated user information retrieval. + * + * See {@link UserInfoService} + * and {@link https://backstage.io/docs/backend-system/core-services/user-info | the service docs} + * for more information. * * @public */ @@ -43,7 +51,11 @@ export namespace coreServices { }); /** - * The service reference for the plugin scoped {@link CacheService}. + * Key-value store for caching data. + * + * See {@link CacheService} + * and {@link https://backstage.io/docs/backend-system/core-services/cache | the service docs} + * for more information. * * @public */ @@ -52,7 +64,11 @@ export namespace coreServices { }); /** - * The service reference for the root scoped {@link RootConfigService}. + * Access to static configuration. + * + * See {@link RootConfigService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-config | the service docs} + * for more information. * * @public */ @@ -61,7 +77,11 @@ export namespace coreServices { >({ id: 'core.rootConfig', scope: 'root' }); /** - * The service reference for the plugin scoped {@link DatabaseService}. + * Database access and management via `knex`. + * + * See {@link DatabaseService} + * and {@link https://backstage.io/docs/backend-system/core-services/database | the service docs} + * for more information. * * @public */ @@ -70,7 +90,11 @@ export namespace coreServices { >({ id: 'core.database' }); /** - * The service reference for the plugin scoped {@link DiscoveryService}. + * Service discovery for inter-plugin communication. + * + * See {@link DiscoveryService} + * and {@link https://backstage.io/docs/backend-system/core-services/discovery | the service docs} + * for more information. * * @public */ @@ -79,7 +103,18 @@ export namespace coreServices { >({ id: 'core.discovery' }); /** - * The service reference for the plugin scoped {@link HttpAuthService}. + * The service reference for the plugin scoped {@link RootHealthService}. + */ + export const rootHealth = createServiceRef< + import('./RootHealthService').RootHealthService + >({ id: 'core.rootHealth', scope: 'root' }); + + /** + * Authentication of HTTP requests. + * + * See {@link HttpAuthService} + * and {@link https://backstage.io/docs/backend-system/core-services/http-auth | the service docs} + * for more information. * * @public */ @@ -88,7 +123,11 @@ export namespace coreServices { >({ id: 'core.httpAuth' }); /** - * The service reference for the plugin scoped {@link HttpRouterService}. + * HTTP route registration for plugins. + * + * See {@link HttpRouterService} + * and {@link https://backstage.io/docs/backend-system/core-services/http-router | the service docs} + * for more information. * * @public */ @@ -97,7 +136,11 @@ export namespace coreServices { >({ id: 'core.httpRouter' }); /** - * The service reference for the plugin scoped {@link LifecycleService}. + * Registration of plugin startup and shutdown lifecycle hooks. + * + * See {@link LifecycleService} + * and {@link https://backstage.io/docs/backend-system/core-services/lifecycle | the service docs} + * for more information. * * @public */ @@ -106,7 +149,11 @@ export namespace coreServices { >({ id: 'core.lifecycle' }); /** - * The service reference for the plugin scoped {@link LoggerService}. + * Plugin-level logging. + * + * See {@link LoggerService} + * and {@link https://backstage.io/docs/backend-system/core-services/logger | the service docs} + * for more information. * * @public */ @@ -115,7 +162,11 @@ export namespace coreServices { >({ id: 'core.logger' }); /** - * The service reference for the plugin scoped {@link PermissionsService}. + * Permission system integration for authorization of user actions. + * + * See {@link PermissionsService} + * and {@link https://backstage.io/docs/backend-system/core-services/permissions | the service docs} + * for more information. * * @public */ @@ -124,7 +175,11 @@ export namespace coreServices { >({ id: 'core.permissions' }); /** - * The service reference for the plugin scoped {@link PluginMetadataService}. + * Built-in service for accessing metadata about the current plugin. + * + * See {@link PluginMetadataService} + * and {@link https://backstage.io/docs/backend-system/core-services/plugin-metadata | the service docs} + * for more information. * * @public */ @@ -133,7 +188,11 @@ export namespace coreServices { >({ id: 'core.pluginMetadata' }); /** - * The service reference for the root scoped {@link RootHttpRouterService}. + * HTTP route registration for root services. + * + * See {@link RootHttpRouterService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-http-router | the service docs} + * for more information. * * @public */ @@ -142,7 +201,11 @@ export namespace coreServices { >({ id: 'core.rootHttpRouter', scope: 'root' }); /** - * The service reference for the root scoped {@link RootLifecycleService}. + * Registration of backend startup and shutdown lifecycle hooks. + * + * See {@link RootLifecycleService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-lifecycle | the service docs} + * for more information. * * @public */ @@ -151,7 +214,11 @@ export namespace coreServices { >({ id: 'core.rootLifecycle', scope: 'root' }); /** - * The service reference for the root scoped {@link RootLoggerService}. + * Root-level logging. + * + * See {@link RootLoggerService} + * and {@link https://backstage.io/docs/backend-system/core-services/root-logger | the service docs} + * for more information. * * @public */ @@ -160,7 +227,11 @@ export namespace coreServices { >({ id: 'core.rootLogger', scope: 'root' }); /** - * The service reference for the plugin scoped {@link SchedulerService}. + * Scheduling of distributed background tasks. + * + * See {@link SchedulerService} + * and {@link https://backstage.io/docs/backend-system/core-services/scheduler | the service docs} + * for more information. * * @public */ @@ -169,7 +240,11 @@ export namespace coreServices { >({ id: 'core.scheduler' }); /** - * The service reference for the plugin scoped {@link TokenManagerService}. + * Deprecated service authentication service, use the `auth` service instead. + * + * See {@link TokenManagerService} + * and {@link https://backstage.io/docs/backend-system/core-services/token-manager | the service docs} + * for more information. * * @public * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead @@ -179,7 +254,11 @@ export namespace coreServices { >({ id: 'core.tokenManager' }); /** - * The service reference for the plugin scoped {@link UrlReaderService}. + * Reading content from external systems. + * + * See {@link UrlReaderService} + * and {@link https://backstage.io/docs/backend-system/core-services/url-reader | the service docs} + * for more information. * * @public */ @@ -188,7 +267,11 @@ export namespace coreServices { >({ id: 'core.urlReader' }); /** - * The service reference for the plugin scoped {@link IdentityService}. + * Deprecated user authentication service, use the `auth` service instead. + * + * See {@link IdentityService} + * and {@link https://backstage.io/docs/backend-system/core-services/identity | the service docs} + * for more information. * * @public * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index 6f30c5f980..5e30d444fd 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -32,6 +32,7 @@ export type { export type { RootConfigService } from './RootConfigService'; export type { DatabaseService } from './DatabaseService'; export type { DiscoveryService } from './DiscoveryService'; +export type { RootHealthService } from './RootHealthService'; export type { HttpRouterService, HttpRouterServiceAuthPolicy, diff --git a/packages/backend-plugin-api/src/types.ts b/packages/backend-plugin-api/src/types.ts index 59f1106fab..31684b6a38 100644 --- a/packages/backend-plugin-api/src/types.ts +++ b/packages/backend-plugin-api/src/types.ts @@ -27,3 +27,14 @@ export interface BackendFeature { // NOTE: This type is opaque in order to simplify future API evolution. $$type: '@backstage/BackendFeature'; } + +/** + * @public + * @deprecated This type exists only as a helper for old code that relied on `createBackendFeature` and `createBackendPlugin` to return `() => BackendFeature` instead of `BackendFeature`. You should remove the `()` parentheses at the end of your usages. This type will be removed in a future release. + */ +export interface BackendFeatureCompat extends BackendFeature { + /** + * @deprecated You do not need to use this call signature; use the type directly instead by removing the `()` parentheses at the end. This call signature will be removed in a future release. + */ + (): this; +} diff --git a/packages/backend-plugin-api/src/wiring/factories.test.ts b/packages/backend-plugin-api/src/wiring/factories.test.ts index 9f11c9b40b..6d5c1f39cd 100644 --- a/packages/backend-plugin-api/src/wiring/factories.test.ts +++ b/packages/backend-plugin-api/src/wiring/factories.test.ts @@ -33,19 +33,25 @@ describe('createExtensionPoint', () => { describe('createBackendPlugin', () => { it('should create a BackendPlugin', () => { - const plugin = createBackendPlugin({ + const result = createBackendPlugin({ pluginId: 'x', register(r) { r.registerInit({ deps: {}, async init() {} }); }, }); - expect(plugin).toBeDefined(); - expect(plugin()).toEqual({ - $$type: '@backstage/BackendFeature', - version: 'v1', - getRegistrations: expect.any(Function), - }); - expect((plugin() as InternalBackendFeature).getRegistrations()).toEqual([ + + // legacy form + const legacy = result() as unknown as InternalBackendFeature; + expect(legacy.$$type).toEqual('@backstage/BackendFeature'); + expect(legacy.version).toEqual('v1'); + expect(legacy.getRegistrations).toEqual(expect.any(Function)); + + // new form + const plugin = result as unknown as InternalBackendFeature; + expect(plugin.$$type).toEqual('@backstage/BackendFeature'); + expect(plugin.version).toEqual('v1'); + expect(plugin.getRegistrations).toEqual(expect.any(Function)); + expect(plugin.getRegistrations()).toEqual([ { type: 'plugin', pluginId: 'x', @@ -56,6 +62,7 @@ describe('createBackendPlugin', () => { }, }, ]); + // @ts-expect-error expect(plugin({ a: 'a' })).toBeDefined(); }); @@ -63,21 +70,26 @@ describe('createBackendPlugin', () => { describe('createBackendModule', () => { it('should create a BackendModule', () => { - const mod = createBackendModule({ + const result = createBackendModule({ pluginId: 'x', moduleId: 'y', register(r) { r.registerInit({ deps: {}, async init() {} }); }, }); - expect(mod).toBeDefined(); - expect(mod()).toBeDefined(); - expect(mod()).toEqual({ - $$type: '@backstage/BackendFeature', - version: 'v1', - getRegistrations: expect.any(Function), - }); - expect((mod() as InternalBackendFeature).getRegistrations()).toEqual([ + + // legacy form + const legacy = result() as unknown as InternalBackendFeature; + expect(legacy.$$type).toEqual('@backstage/BackendFeature'); + expect(legacy.version).toEqual('v1'); + expect(legacy.getRegistrations).toEqual(expect.any(Function)); + + // new form + const module = result as unknown as InternalBackendFeature; + expect(module.$$type).toEqual('@backstage/BackendFeature'); + expect(module.version).toEqual('v1'); + expect(module.getRegistrations).toEqual(expect.any(Function)); + expect(module.getRegistrations()).toEqual([ { type: 'module', pluginId: 'x', @@ -89,7 +101,8 @@ describe('createBackendModule', () => { }, }, ]); + // @ts-expect-error - expect(mod({ a: 'a' })).toBeDefined(); + expect(module({ a: 'a' })).toBeDefined(); }); }); diff --git a/packages/backend-plugin-api/src/wiring/factories.ts b/packages/backend-plugin-api/src/wiring/factories.ts index 5442bab897..81e2247152 100644 --- a/packages/backend-plugin-api/src/wiring/factories.ts +++ b/packages/backend-plugin-api/src/wiring/factories.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { BackendFeature, BackendFeatureFactory } from '../types'; +import { BackendFeatureCompat } from '../types'; import { BackendModuleRegistrationPoints, BackendPluginRegistrationPoints, @@ -90,63 +90,57 @@ export interface CreateBackendPluginOptions { */ export function createBackendPlugin( options: CreateBackendPluginOptions, -): () => BackendFeature { - const factory: BackendFeatureFactory = () => { - let registrations: InternalBackendPluginRegistration[]; +): BackendFeatureCompat { + function getRegistrations() { + const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] = + []; + let init: InternalBackendPluginRegistration['init'] | undefined = undefined; - return { - $$type: '@backstage/BackendFeature', - version: 'v1', - getRegistrations() { - if (registrations) { - return registrations; + options.register({ + registerExtensionPoint(ext, impl) { + if (init) { + throw new Error('registerExtensionPoint called after registerInit'); } - const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] = - []; - let init: InternalBackendPluginRegistration['init'] | undefined = - undefined; - - options.register({ - registerExtensionPoint(ext, impl) { - if (init) { - throw new Error( - 'registerExtensionPoint called after registerInit', - ); - } - extensionPoints.push([ext, impl]); - }, - registerInit(regInit) { - if (init) { - throw new Error('registerInit must only be called once'); - } - init = { - deps: regInit.deps, - func: regInit.init, - }; - }, - }); - - if (!init) { - throw new Error( - `registerInit was not called by register in ${options.pluginId}`, - ); - } - - registrations = [ - { - type: 'plugin', - pluginId: options.pluginId, - extensionPoints, - init, - }, - ]; - return registrations; + extensionPoints.push([ext, impl]); }, - }; - }; - factory.$$type = '@backstage/BackendFeatureFactory'; + registerInit(regInit) { + if (init) { + throw new Error('registerInit must only be called once'); + } + init = { + deps: regInit.deps, + func: regInit.init, + }; + }, + }); - return factory; + if (!init) { + throw new Error( + `registerInit was not called by register in ${options.pluginId}`, + ); + } + + return [ + { + type: 'plugin', + pluginId: options.pluginId, + extensionPoints, + init, + }, + ]; + } + + function backendFeatureCompatWrapper() { + return backendFeatureCompatWrapper; + } + + Object.assign(backendFeatureCompatWrapper, { + $$type: '@backstage/BackendFeature' as const, + version: 'v1', + getRegistrations, + }); + + return backendFeatureCompatWrapper as BackendFeatureCompat; } /** @@ -180,62 +174,56 @@ export interface CreateBackendModuleOptions { */ export function createBackendModule( options: CreateBackendModuleOptions, -): () => BackendFeature { - const factory: BackendFeatureFactory = () => { - let registrations: InternalBackendModuleRegistration[]; +): BackendFeatureCompat { + function getRegistrations() { + const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] = + []; + let init: InternalBackendModuleRegistration['init'] | undefined = undefined; - return { - $$type: '@backstage/BackendFeature', - version: 'v1', - getRegistrations() { - if (registrations) { - return registrations; + options.register({ + registerExtensionPoint(ext, impl) { + if (init) { + throw new Error('registerExtensionPoint called after registerInit'); } - const extensionPoints: InternalBackendPluginRegistration['extensionPoints'] = - []; - let init: InternalBackendModuleRegistration['init'] | undefined = - undefined; - - options.register({ - registerExtensionPoint(ext, impl) { - if (init) { - throw new Error( - 'registerExtensionPoint called after registerInit', - ); - } - extensionPoints.push([ext, impl]); - }, - registerInit(regInit) { - if (init) { - throw new Error('registerInit must only be called once'); - } - init = { - deps: regInit.deps, - func: regInit.init, - }; - }, - }); - - if (!init) { - throw new Error( - `registerInit was not called by register in ${options.moduleId} module for ${options.pluginId}`, - ); - } - - registrations = [ - { - type: 'module', - pluginId: options.pluginId, - moduleId: options.moduleId, - extensionPoints, - init, - }, - ]; - return registrations; + extensionPoints.push([ext, impl]); }, - }; - }; - factory.$$type = '@backstage/BackendFeatureFactory'; + registerInit(regInit) { + if (init) { + throw new Error('registerInit must only be called once'); + } + init = { + deps: regInit.deps, + func: regInit.init, + }; + }, + }); - return factory; + if (!init) { + throw new Error( + `registerInit was not called by register in ${options.moduleId} module for ${options.pluginId}`, + ); + } + + return [ + { + type: 'module', + pluginId: options.pluginId, + moduleId: options.moduleId, + extensionPoints, + init, + }, + ]; + } + + function backendFeatureCompatWrapper() { + return backendFeatureCompatWrapper; + } + + Object.assign(backendFeatureCompatWrapper, { + $$type: '@backstage/BackendFeature' as const, + version: 'v1', + getRegistrations, + }); + + return backendFeatureCompatWrapper as BackendFeatureCompat; } diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index aa4c786b65..008ae3cb11 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/backend-tasks +## 0.5.26-next.0 + +### Patch Changes + +- 083eaf9: Fix bug where ISO durations could no longer be used for schedules +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.5.24 + +### Patch Changes + +- 736bc3c: Marked all exports as deprecated and pointed at `@backstage/backend-plugin-api` and `@backstage/backend-defaults` +- ed473cd: Updated the `TaskScheduleDefinitionConfig` deprecated comment to point to `SchedulerServiceTaskScheduleDefinitionConfig` +- 6a576dc: Deprecate the legacy `TaskScheduler.fromConfig` method and stop using the `getVoidlogger` in tests files to reduce the dependency on the soon-to-deprecate `backstage-common` package. +- 1897169: More detailed deprecation messages +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.5.24-next.3 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index f11d0c7788..2033be826c 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.5.24-next.3", + "version": "0.5.26-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.test.ts b/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.test.ts index c52d59b016..adeb134611 100644 --- a/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.test.ts +++ b/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.test.ts @@ -16,7 +16,6 @@ import { ConfigReader } from '@backstage/config'; import { HumanDuration } from '@backstage/types'; -import { Duration } from 'luxon'; import { readTaskScheduleDefinitionFromConfig } from './readTaskScheduleDefinitionFromConfig'; describe('readTaskScheduleDefinitionFromConfig', () => { @@ -35,7 +34,7 @@ describe('readTaskScheduleDefinitionFromConfig', () => { const result = readTaskScheduleDefinitionFromConfig(config); expect((result.frequency as { cron: string }).cron).toBe('0 30 * * * *'); - expect(result.timeout).toEqual(Duration.fromISO('PT3M')); + expect(result.timeout).toEqual({ minutes: 3 }); expect((result.initialDelay as HumanDuration).minutes).toEqual(20); expect(result.scope).toBe('global'); }); @@ -51,7 +50,7 @@ describe('readTaskScheduleDefinitionFromConfig', () => { const result = readTaskScheduleDefinitionFromConfig(config); expect((result.frequency as { cron: string }).cron).toBe('0 30 * * * *'); - expect(result.timeout).toEqual(Duration.fromISO('PT3M')); + expect(result.timeout).toEqual({ minutes: 3 }); expect(result.initialDelay).toBeUndefined(); expect(result.scope).toBeUndefined(); }); diff --git a/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.ts b/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.ts index 5a173f246b..e94d06d5c3 100644 --- a/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.ts +++ b/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.ts @@ -19,14 +19,14 @@ import { HumanDuration } from '@backstage/types'; import { TaskScheduleDefinition } from './types'; import { Duration } from 'luxon'; -function readDuration(config: Config, key: string): Duration | HumanDuration { +function readDuration(config: Config, key: string): HumanDuration { if (typeof config.get(key) === 'string') { const value = config.getString(key); const duration = Duration.fromISO(value); if (!duration.isValid) { throw new Error(`Invalid duration: ${value}`); } - return duration; + return duration.toObject(); } return readDurationFromConfig(config, { key }); diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 2e3051b85e..435d1f8abc 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/backend-test-utils +## 0.4.3-next.0 + +### Patch Changes + +- fce7887: Added mock for the Root Health Service in `mockServices`. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-defaults@0.3.3-next.0 + - @backstage/backend-app-api@0.7.9-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.4.0 + +### Minor Changes + +- 805cbe7: Added `TestCaches` that functions just like `TestDatabases` + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- 9e63318: Made it possible to give access restrictions to `mockCredentials.service` +- 006b3e8: The type `MockDirectoryOptions` was renamed to `CreateMockDirectoryOptions` so that it's clear these options are exclusive to the mock directory factory. +- 0634fdc: Refactored `TestDatabases` to no longer depend on `backend-common` +- 6a576dc: Fix the logger service mock to prevent returning `undefined` from the `child` method. +- 6c11f6e: Use imports from backend-defaults instead of the deprecated ones from backend-app-api +- Updated dependencies + - @backstage/backend-app-api@0.7.6 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/backend-defaults@0.3.0 + - @backstage/plugin-events-node@0.3.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.4.0-next.3 ### Patch Changes diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index cc30dc8f56..a2fb4b7674 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -22,7 +22,7 @@ import { EventsService } from '@backstage/plugin-events-node'; import { ExtendedHttpServer } from '@backstage/backend-app-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { HttpAuthService } from '@backstage/backend-plugin-api'; -import { HttpRouterFactoryOptions } from '@backstage/backend-app-api'; +import { HttpRouterFactoryOptions } from '@backstage/backend-defaults/httpRouter'; import { HttpRouterService } from '@backstage/backend-plugin-api'; import { IdentityService } from '@backstage/backend-plugin-api'; import { JsonObject } from '@backstage/types'; @@ -32,7 +32,8 @@ import { LifecycleService } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; import { PermissionsService } from '@backstage/backend-plugin-api'; import { RootConfigService } from '@backstage/backend-plugin-api'; -import { RootHttpRouterFactoryOptions } from '@backstage/backend-app-api'; +import { RootHealthService } from '@backstage/backend-plugin-api'; +import { RootHttpRouterFactoryOptions } from '@backstage/backend-defaults/rootHttpRouter'; import { RootHttpRouterService } from '@backstage/backend-plugin-api'; import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; @@ -280,6 +281,15 @@ export namespace mockServices { ) => ServiceFactory; } // (undocumented) + export namespace rootHealth { + const // (undocumented) + factory: () => ServiceFactory; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; + } + // (undocumented) export namespace rootHttpRouter { const // (undocumented) factory: ( diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 40523b1e04..540b4f9ee4 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "0.4.0-next.3", + "version": "0.4.3-next.0", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" @@ -46,6 +46,7 @@ }, "dependencies": { "@backstage/backend-app-api": "workspace:^", + "@backstage/backend-defaults": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", @@ -55,7 +56,7 @@ "@keyv/memcache": "^1.3.5", "@keyv/redis": "^2.5.3", "@types/keyv": "^4.2.0", - "better-sqlite3": "^9.0.0", + "better-sqlite3": "^11.0.0", "cookie": "^0.6.0", "express": "^4.17.1", "fs-extra": "^11.0.0", diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index 57621a9209..d56179d958 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -14,48 +14,49 @@ * limitations under the License. */ +import { cacheServiceFactory } from '@backstage/backend-defaults/cache'; +import { databaseServiceFactory } from '@backstage/backend-defaults/database'; import { - RootConfigService, - coreServices, - createServiceFactory, + HostDiscovery, + discoveryServiceFactory, +} from '@backstage/backend-defaults/discovery'; +import { httpRouterServiceFactory } from '@backstage/backend-defaults/httpRouter'; +import { lifecycleServiceFactory } from '@backstage/backend-defaults/lifecycle'; +import { loggerServiceFactory } from '@backstage/backend-defaults/logger'; +import { permissionsServiceFactory } from '@backstage/backend-defaults/permissions'; +import { rootHealthServiceFactory } from '@backstage/backend-defaults/rootHealth'; +import { rootHttpRouterServiceFactory } from '@backstage/backend-defaults/rootHttpRouter'; +import { rootLifecycleServiceFactory } from '@backstage/backend-defaults/rootLifecycle'; +import { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler'; +import { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader'; +import { + AuthService, + BackstageCredentials, + BackstageUserInfo, + DiscoveryService, + HttpAuthService, IdentityService, LoggerService, + RootConfigService, ServiceFactory, ServiceRef, TokenManagerService, - AuthService, - DiscoveryService, - HttpAuthService, - BackstageCredentials, - BackstageUserInfo, UserInfoService, + coreServices, + createServiceFactory, } from '@backstage/backend-plugin-api'; -import { - cacheServiceFactory, - databaseServiceFactory, - httpRouterServiceFactory, - lifecycleServiceFactory, - loggerServiceFactory, - permissionsServiceFactory, - rootHttpRouterServiceFactory, - rootLifecycleServiceFactory, - schedulerServiceFactory, - urlReaderServiceFactory, - discoveryServiceFactory, - HostDiscovery, -} from '@backstage/backend-app-api'; import { ConfigReader } from '@backstage/config'; -import { JsonObject } from '@backstage/types'; -import { MockIdentityService } from './MockIdentityService'; -import { MockRootLoggerService } from './MockRootLoggerService'; -import { MockAuthService } from './MockAuthService'; -import { MockHttpAuthService } from './MockHttpAuthService'; -import { mockCredentials } from './mockCredentials'; -import { MockUserInfoService } from './MockUserInfoService'; import { eventsServiceFactory, eventsServiceRef, } from '@backstage/plugin-events-node'; +import { JsonObject } from '@backstage/types'; +import { MockAuthService } from './MockAuthService'; +import { MockHttpAuthService } from './MockHttpAuthService'; +import { MockIdentityService } from './MockIdentityService'; +import { MockRootLoggerService } from './MockRootLoggerService'; +import { MockUserInfoService } from './MockUserInfoService'; +import { mockCredentials } from './mockCredentials'; /** @internal */ function createLoggerMock() { @@ -344,6 +345,14 @@ export namespace mockServices { })); } + export namespace rootHealth { + export const factory = rootHealthServiceFactory; + export const mock = simpleMock(coreServices.rootHealth, () => ({ + getLiveness: jest.fn(), + getReadiness: jest.fn(), + })); + } + export namespace httpRouter { export const factory = httpRouterServiceFactory; export const mock = simpleMock(coreServices.httpRouter, () => ({ diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts index a4b74b5ffa..ecba34290d 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts @@ -144,7 +144,7 @@ describe('TestBackend', () => { }); await startTestBackend({ - features: [testModule(), sf()], + features: [testModule, sf()], }); expect(testFn).toHaveBeenCalledWith('winning'); @@ -169,7 +169,7 @@ describe('TestBackend', () => { }); const backend = await startTestBackend({ - features: [testModule()], + features: [testModule], }); expect(shutdownSpy).not.toHaveBeenCalled(); @@ -212,7 +212,7 @@ describe('TestBackend', () => { }); await startTestBackend({ - features: [testPlugin()], + features: [testPlugin], }); }); @@ -233,7 +233,7 @@ describe('TestBackend', () => { }, }); - const { server } = await startTestBackend({ features: [testPlugin()] }); + const { server } = await startTestBackend({ features: [testPlugin] }); const res = await request(server) .get('/api/test/ping-me') diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts index e43353991f..f23883ba3e 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts @@ -133,7 +133,7 @@ function createExtensionPointTestModules( ref: ExtensionPoint, impl: unknown, ][], -): Array<() => BackendFeature> { +): Array { if (!extensionPointTuples) { return []; } diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 2a070cd28a..6e4257b62d 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,79 @@ # example-backend +## 0.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-defaults@0.3.3-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-scaffolder-backend@1.23.0-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.4.0-next.0 + - @backstage/plugin-notifications-backend@0.3.2-next.0 + - @backstage/plugin-app-backend@0.3.70-next.0 + - @backstage/plugin-auth-backend@0.22.8-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.1.18-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.7-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-catalog-backend@1.23.2-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.4-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.1.39-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.19-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.8-next.0 + - @backstage/plugin-devtools-backend@0.3.7-next.0 + - @backstage/plugin-kubernetes-backend@0.18.2-next.0 + - @backstage/plugin-permission-backend@0.5.45-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.18-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/plugin-proxy-backend@0.5.2-next.0 + - @backstage/plugin-search-backend@1.5.13-next.0 + - @backstage/plugin-search-backend-module-catalog@0.1.27-next.0 + - @backstage/plugin-search-backend-module-explore@0.1.27-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.26-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/plugin-signals-backend@0.1.7-next.0 + - @backstage/plugin-techdocs-backend@1.10.8-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-permission-common@0.7.14 + +## 0.0.27 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.19 + - @backstage/backend-tasks@0.5.24 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/plugin-auth-backend@0.22.6 + - @backstage/plugin-techdocs-backend@1.10.6 + - @backstage/plugin-scaffolder-backend-module-github@0.3.0 + - @backstage/plugin-devtools-backend@0.3.5 + - @backstage/plugin-catalog-backend@1.23.0 + - @backstage/plugin-search-backend@1.5.10 + - @backstage/plugin-proxy-backend@0.5.0 + - @backstage/plugin-app-backend@0.3.68 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.1.17 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.1.16 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.2.2 + - @backstage/plugin-auth-backend-module-github-provider@0.1.16 + - @backstage/plugin-auth-backend-module-guest-provider@0.1.5 + - @backstage/plugin-catalog-backend-module-unprocessed@0.4.6 + - @backstage/plugin-catalog-backend-module-openapi@0.1.37 + - @backstage/plugin-search-backend-module-techdocs@0.1.24 + - @backstage/plugin-search-backend-module-catalog@0.1.25 + - @backstage/plugin-search-backend-module-explore@0.1.25 + - @backstage/plugin-notifications-backend@0.3.0 + - @backstage/plugin-kubernetes-backend@0.18.0 + - @backstage/plugin-permission-backend@0.5.43 + - @backstage/plugin-scaffolder-backend@1.22.9 + - @backstage/plugin-signals-backend@0.1.5 + - @backstage/backend-defaults@0.3.0 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-permission-node@0.7.30 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/catalog-model@1.5.0 + ## 0.0.27-next.3 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 80a5f5b614..f81701a77d 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.27-next.3", + "version": "0.0.28-next.0", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index a4acd19cf2..1174b7bf6d 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -21,7 +21,6 @@ const backend = createBackend(); backend.add(import('@backstage/plugin-auth-backend')); backend.add(import('./authModuleGithubProvider')); backend.add(import('@backstage/plugin-auth-backend-module-guest-provider')); - backend.add(import('@backstage/plugin-app-backend/alpha')); backend.add(import('@backstage/plugin-catalog-backend-module-unprocessed')); backend.add( diff --git a/packages/cli-common/CHANGELOG.md b/packages/cli-common/CHANGELOG.md index 7eb1b29e29..29ffc4984c 100644 --- a/packages/cli-common/CHANGELOG.md +++ b/packages/cli-common/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/cli-common +## 0.1.14 + +### Patch Changes + +- 142abb0: The monorepo root check in `findPaths` will now accept a shorthand `workspaces` config in `package.json`, no longer requiring `workspaces.packages`. + ## 0.1.14-next.0 ### Patch Changes diff --git a/packages/cli-common/package.json b/packages/cli-common/package.json index 63b7d56d03..c316f15322 100644 --- a/packages/cli-common/package.json +++ b/packages/cli-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli-common", - "version": "0.1.14-next.0", + "version": "0.1.14", "description": "Common functionality used by cli, backend, and create-app", "backstage": { "role": "node-library" diff --git a/packages/cli-node/CHANGELOG.md b/packages/cli-node/CHANGELOG.md index 72608fb4c4..dcf9073277 100644 --- a/packages/cli-node/CHANGELOG.md +++ b/packages/cli-node/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/cli-node +## 0.2.6 + +### Patch Changes + +- a1ae9cc: Updated doc link. +- c328131: Added new plugin metadata fields to `BackstagePackageJson` type. +- 93be042: Upgraded @yarnpkg/parsers to stable 3.0 +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.6-next.2 ### Patch Changes diff --git a/packages/cli-node/package.json b/packages/cli-node/package.json index 38525c9854..56cf50a096 100644 --- a/packages/cli-node/package.json +++ b/packages/cli-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli-node", - "version": "0.2.6-next.2", + "version": "0.2.6", "description": "Node.js library for Backstage CLIs", "backstage": { "role": "node-library" diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 4d769a6772..0e65266410 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,55 @@ # @backstage/cli +## 0.26.10-next.0 + +### Patch Changes + +- e2e320c: - remove unused dependencies `winston` and `yn` from the template of backend plugins; + - update `msw` to version `2.3.1` in the template of backend plugins; + starting with v1 and switching later to v2 is tedious and not straight forward; it's easier to start with v2; +- 0540c5a: Updated the scaffolding output message for `plugin-common` in `backstage-cli`. Now, when executing `backstage-cli new` to create a new `plugin-common` package, the output message accurately reflects the action by displaying `Creating common plugin package...` instead of the previous, less accurate `Creating backend plugin...`. +- 7652db4: Only bootstrap global-agent if it's actually being used +- f0c0039: Fix issue with CLI that was preventing upgrading from 1.28 +- d228862: Update default backend plugin created by the cli to use non-deprecated error handling middleware +- da90cce: Updated dependency `esbuild` to `^0.21.0`. +- a60d73b: Fix a few minor issues with the backend template that were causing failing linting checks in the main repo. +- 0510d98: Subpath export `package.json` should be of a unique name to avoid typescript resolution issues +- Updated dependencies + - @backstage/integration@1.13.0-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.6 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.8.1 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## 0.26.7 + +### Patch Changes + +- 788eca7: Fix readme for new plugins created using cli +- 90c5268: Add `peerDependencies` to `devDependencies` in `package.json.hbs` templates. +- c00f7ee: Fix issue with `esm` loaded dependencies being different from the `cjs` import for Vite dependencies +- b0f66e9: Updated dependency `vite-plugin-node-polyfills` to `^0.22.0`. +- c328131: Added a new `--publish` flag to the `repo fix` command. This command will validate and if possible generate the metadata required for publishing packages with the Backstage CLI. In addition, a check has been added that the `backstage.pluginId` and `backstage.pluginPackage(s)` fields are present when packing a package for publishing. +- 5afbe1d: Export default module for `scaffolder-action` cli template +- 009da47: Fix `versions:check --fix` when `yarn.lock` has multiple joint versions in the same section +- 9ee948a: Bump `esbuild` target for package builds to `ES2022`. +- Updated dependencies + - @backstage/cli-node@0.2.6 + - @backstage/integration@1.12.0 + - @backstage/cli-common@0.1.14 + - @backstage/config-loader@1.8.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.26.7-next.3 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index bdaf29bc13..b458cf162f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli", - "version": "0.26.7-next.3", + "version": "0.26.10-next.0", "description": "CLI for developing Backstage plugins and apps", "backstage": { "role": "cli" @@ -90,7 +90,7 @@ "css-loader": "^6.5.1", "ctrlc-windows": "^2.1.0", "diff": "^5.0.0", - "esbuild": "^0.20.0", + "esbuild": "^0.21.0", "esbuild-loader": "^4.0.0", "eslint": "^8.6.0", "eslint-config-prettier": "^9.0.0", @@ -187,13 +187,13 @@ "nodemon": "^3.0.1", "vite": "^4.4.9", "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.21.0" + "vite-plugin-node-polyfills": "^0.22.0" }, "peerDependencies": { "@vitejs/plugin-react": "^4.0.4", "vite": "^4.4.9", "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.21.0" + "vite-plugin-node-polyfills": "^0.22.0" }, "peerDependenciesMeta": { "@vitejs/plugin-react": { diff --git a/packages/cli/src/commands/versions/bump.ts b/packages/cli/src/commands/versions/bump.ts index 1544240704..d6d5f424ba 100644 --- a/packages/cli/src/commands/versions/bump.ts +++ b/packages/cli/src/commands/versions/bump.ts @@ -14,6 +14,12 @@ * limitations under the License. */ +import { bootstrap } from 'global-agent'; + +if (shouldUseGlobalAgent()) { + bootstrap(); +} + import fs from 'fs-extra'; import chalk from 'chalk'; import ora from 'ora'; @@ -38,10 +44,22 @@ import { getManifestByVersion, ReleaseManifest, } from '@backstage/release-manifests'; -import 'global-agent/bootstrap'; import { PackageGraph } from '@backstage/cli-node'; import { migrateMovedPackages } from './migrate'; +function shouldUseGlobalAgent(): boolean { + // see https://www.npmjs.com/package/global-agent + const namespace = + process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE ?? 'GLOBAL_AGENT_'; + if ( + process.env[`${namespace}HTTP_PROXY`] || + process.env[`${namespace}HTTPS_PROXY`] + ) { + return true; + } + return false; +} + const DEP_TYPES = [ 'dependencies', 'devDependencies', diff --git a/packages/cli/src/lib/new/factories/pluginCommon.test.ts b/packages/cli/src/lib/new/factories/pluginCommon.test.ts index d85e490510..82c1c87169 100644 --- a/packages/cli/src/lib/new/factories/pluginCommon.test.ts +++ b/packages/cli/src/lib/new/factories/pluginCommon.test.ts @@ -67,7 +67,7 @@ describe('pluginCommon factory', () => { expect(modified).toBe(true); expectLogsToMatch(output, [ - 'Creating backend plugin backstage-plugin-test-common', + 'Creating common plugin package backstage-plugin-test-common', 'Checking Prerequisites:', `availability plugins${sep}test-common`, 'creating temp dir', diff --git a/packages/cli/src/lib/new/factories/pluginCommon.ts b/packages/cli/src/lib/new/factories/pluginCommon.ts index 560386c618..5f694124ea 100644 --- a/packages/cli/src/lib/new/factories/pluginCommon.ts +++ b/packages/cli/src/lib/new/factories/pluginCommon.ts @@ -46,7 +46,7 @@ export const pluginCommon = createFactory({ }); Task.log(); - Task.log(`Creating backend plugin ${chalk.cyan(name)}`); + Task.log(`Creating common plugin package ${chalk.cyan(name)}`); const targetDir = ctx.isMonoRepo ? paths.resolveTargetRoot('plugins', suffix) diff --git a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts index b43946228b..d83c2ce3f7 100644 --- a/packages/cli/src/lib/new/factories/scaffolderModule.test.ts +++ b/packages/cli/src/lib/new/factories/scaffolderModule.test.ts @@ -80,6 +80,7 @@ describe('scaffolderModule factory', () => { 'copying example.test.ts', 'copying example.ts', 'copying index.ts', + 'copying module.ts', 'Installing:', `moving plugins${sep}scaffolder-backend-module-test`, ]); diff --git a/packages/cli/src/lib/packager/productionPack.ts b/packages/cli/src/lib/packager/productionPack.ts index 6a59924a30..3c2b5aa89e 100644 --- a/packages/cli/src/lib/packager/productionPack.ts +++ b/packages/cli/src/lib/packager/productionPack.ts @@ -180,7 +180,9 @@ async function prepareExportsEntryPoints( await fs.writeJson( resolvePath(entryPointDir, PKG_PATH), { - name: pkg.name, + // Need a temporary name, as sharing the same name causes some typescript issues with caching of packages names + // And their defined `types` field. + name: `${pkg.name}__${entryPoint.name.toLocaleLowerCase('en-US')}`, version: pkg.version, ...(exp.default ? { main: posixPath.join('..', exp.default) } : {}), ...(exp.import ? { module: posixPath.join('..', exp.import) } : {}), diff --git a/packages/cli/src/lib/versioning/Lockfile.ts b/packages/cli/src/lib/versioning/Lockfile.ts index 6af115a4da..50d0a77cfd 100644 --- a/packages/cli/src/lib/versioning/Lockfile.ts +++ b/packages/cli/src/lib/versioning/Lockfile.ts @@ -98,24 +98,6 @@ export class Lockfile { return Lockfile.parse(lockfileContents); } - static #getRangesFromDataKey(key: string): string[] { - const [, name, ranges] = key.match(ENTRY_PATTERN) ?? []; - if (!name) { - throw new Error(`Failed to parse yarn.lock entry '${key}'`); - } - - return ranges.split(/\s*,\s*/).map(rangePart => { - let range = rangePart; - if (range.startsWith(`${name}@`)) { - range = range.slice(`${name}@`.length); - } - if (range.startsWith('npm:')) { - range = range.slice('npm:'.length); - } - return range; - }); - } - static parse(content: string) { const legacy = LEGACY_REGEX.test(content); @@ -131,7 +113,7 @@ export class Lockfile { for (const [key, value] of Object.entries(data)) { if (SPECIAL_OBJECT_KEYS.includes(key)) continue; - const [, name] = ENTRY_PATTERN.exec(key) ?? []; + const [, name, ranges] = ENTRY_PATTERN.exec(key) ?? []; if (!name) { throw new Error(`Failed to parse yarn.lock entry '${key}'`); } @@ -141,8 +123,13 @@ export class Lockfile { queries = []; packages.set(name, queries); } - const ranges = Lockfile.#getRangesFromDataKey(key); - for (const range of ranges) { + for (let range of ranges.split(/\s*,\s*/)) { + if (range.startsWith(`${name}@`)) { + range = range.slice(`${name}@`.length); + } + if (range.startsWith('npm:')) { + range = range.slice('npm:'.length); + } queries.push({ range, version: value.version, dataKey: key }); } } @@ -289,34 +276,9 @@ export class Lockfile { } remove(name: string, range: string): boolean { - const simpleQuery = `${name}@${range}`; - const query = this.getEntryOf(name, range); - + const query = `${name}@${range}`; const existed = Boolean(this.data[query]); - - if (simpleQuery === query) { - // Single-versioned entry, just delete - delete this.data[query]; - } else { - // Remove this version from the entry key. This modifies the key, so the - // package queries' needs to be updated too. - const newRanges = Lockfile.#getRangesFromDataKey(query).filter( - q => q !== simpleQuery, - ); - const newQuery = newRanges.join(', '); - - // Replace the entry with a new one without this particular range - const entry = this.data[query]; - delete this.data[query]; - this.data[newQuery] = entry; - - // Fix all package queries pointing to the old query - this.packages.get(name)?.forEach(q => { - if (q.dataKey === query) { - q.dataKey = newQuery; - } - }); - } + delete this.data[query]; const newEntries = this.packages.get(name)?.filter(e => e.range !== range); if (newEntries) { @@ -326,35 +288,19 @@ export class Lockfile { return existed; } - getEntryOf(name: string, range: string) { - const query = this.packages.get(name)?.find(q => q.range === range); - if (!query) { - throw new Error(`No entry data for ${name}@${range}`); - } - - return query.dataKey; - } - /** Modifies the lockfile by bumping packages to the suggested versions */ replaceVersions(results: AnalyzeResultNewVersion[]) { - // When replacing versions, we might replace the same version multiple times, - // as a query may contain multiple versions. This keeps the original version, - // to ensure we don't make mistakes. - const oldVersions = Object.fromEntries( - Object.entries(this.data).map(([key, val]) => [key, val.version]), - ); - for (const { name, range, oldVersion, newVersion } of results) { - const query = this.getEntryOf(name, range); + const query = `${name}@${range}`; // Update the backing data const entryData = this.data[query]; if (!entryData) { throw new Error(`No entry data for ${query}`); } - if (oldVersions[query] !== oldVersion) { + if (entryData.version !== oldVersion) { throw new Error( - `Expected existing version data for ${query} to be ${oldVersion}, was ${oldVersions[query]}`, + `Expected existing version data for ${query} to be ${oldVersion}, was ${entryData.version}`, ); } diff --git a/packages/cli/templates/default-backend-plugin/README.md.hbs b/packages/cli/templates/default-backend-plugin/README.md.hbs index 366ed27104..d519c3f459 100644 --- a/packages/cli/templates/default-backend-plugin/README.md.hbs +++ b/packages/cli/templates/default-backend-plugin/README.md.hbs @@ -11,4 +11,4 @@ start` in the root directory, and then navigating to [/{{id}}/health](http://loc 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. +It is only meant for local development, and the setup for it can be found inside the [/dev](./dev) directory. diff --git a/packages/cli/templates/default-backend-plugin/package.json.hbs b/packages/cli/templates/default-backend-plugin/package.json.hbs index 6b7aa915aa..3b808fc5e5 100644 --- a/packages/cli/templates/default-backend-plugin/package.json.hbs +++ b/packages/cli/templates/default-backend-plugin/package.json.hbs @@ -32,20 +32,19 @@ "@backstage/backend-defaults": "{{versionQuery '@backstage/backend-defaults'}}", "@backstage/backend-plugin-api": "{{versionQuery '@backstage/backend-plugin-api'}}", "@backstage/config": "{{versionQuery '@backstage/config'}}", - "@types/express": "{{versionQuery '@types/express' '4.17.6'}}", "express": "{{versionQuery 'express' '4.17.1'}}", "express-promise-router": "{{versionQuery 'express-promise-router' '4.1.0'}}", - "winston": "{{versionQuery 'winston' '3.2.1'}}", - "node-fetch": "{{versionQuery 'node-fetch' '2.6.7'}}", - "yn": "{{versionQuery 'yn' '4.0.0'}}" + "node-fetch": "{{versionQuery 'node-fetch' '2.6.7'}}" }, "devDependencies": { + "@backstage/backend-test-utils": "{{versionQuery '@backstage/backend-test-utils'}}", "@backstage/cli": "{{versionQuery '@backstage/cli'}}", "@backstage/plugin-auth-backend": "{{versionQuery '@backstage/plugin-auth-backend'}}", "@backstage/plugin-auth-backend-module-guest-provider": "{{versionQuery '@backstage/plugin-auth-backend-module-guest-provider'}}", + "@types/express": "{{versionQuery '@types/express' '4.17.6'}}", "@types/supertest": "{{versionQuery '@types/supertest' '2.0.12'}}", "supertest": "{{versionQuery 'supertest' '6.2.4'}}", - "msw": "{{versionQuery 'msw' '1.0.0'}}" + "msw": "{{versionQuery 'msw' '2.3.1'}}" }, "files": [ "dist" diff --git a/packages/cli/templates/default-backend-plugin/src/plugin.ts.hbs b/packages/cli/templates/default-backend-plugin/src/plugin.ts.hbs index 773bd4354f..bf04b43afe 100644 --- a/packages/cli/templates/default-backend-plugin/src/plugin.ts.hbs +++ b/packages/cli/templates/default-backend-plugin/src/plugin.ts.hbs @@ -16,14 +16,17 @@ export const {{pluginVar}} = createBackendPlugin({ deps: { httpRouter: coreServices.httpRouter, logger: coreServices.logger, + config: coreServices.rootConfig, }, async init({ httpRouter, logger, + config, }) { httpRouter.use( await createRouter({ logger, + config, }), ); httpRouter.addAuthPolicy({ diff --git a/packages/cli/templates/default-backend-plugin/src/service/router.test.ts b/packages/cli/templates/default-backend-plugin/src/service/router.test.ts index 4f5079744e..ed19d50d2b 100644 --- a/packages/cli/templates/default-backend-plugin/src/service/router.test.ts +++ b/packages/cli/templates/default-backend-plugin/src/service/router.test.ts @@ -1,4 +1,4 @@ -import { getVoidLogger } from '@backstage/backend-common'; +import { mockServices } from '@backstage/backend-test-utils'; import express from 'express'; import request from 'supertest'; @@ -9,7 +9,8 @@ describe('createRouter', () => { beforeAll(async () => { const router = await createRouter({ - logger: getVoidLogger(), + logger: mockServices.logger.mock(), + config: mockServices.rootConfig(), }); app = express().use(router); }); diff --git a/packages/cli/templates/default-backend-plugin/src/service/router.ts b/packages/cli/templates/default-backend-plugin/src/service/router.ts index ff7134e59d..312d7e252e 100644 --- a/packages/cli/templates/default-backend-plugin/src/service/router.ts +++ b/packages/cli/templates/default-backend-plugin/src/service/router.ts @@ -1,16 +1,18 @@ -import { errorHandler } from '@backstage/backend-common'; +import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter'; import { LoggerService } from '@backstage/backend-plugin-api'; +import { Config } from '@backstage/config'; import express from 'express'; import Router from 'express-promise-router'; export interface RouterOptions { logger: LoggerService; + config: Config; } export async function createRouter( options: RouterOptions, ): Promise { - const { logger } = options; + const { logger, config } = options; const router = Router(); router.use(express.json()); @@ -20,6 +22,8 @@ export async function createRouter( response.json({ status: 'ok' }); }); - router.use(errorHandler()); + const middleware = MiddlewareFactory.create({ logger, config }); + + router.use(middleware.error()); return router; } diff --git a/packages/cli/templates/scaffolder-module/src/actions/example/index.ts b/packages/cli/templates/scaffolder-module/src/actions/example/index.ts index e81099f333..06ce5befc0 100644 --- a/packages/cli/templates/scaffolder-module/src/actions/example/index.ts +++ b/packages/cli/templates/scaffolder-module/src/actions/example/index.ts @@ -1 +1,7 @@ +import { scaffolderModule } from './module'; + +/* + @deprecated - this way of importing modules will soon be unsupported, and you should use `backend.add(import(...))` instead. +*/ export { createAcmeExampleAction } from './example'; +export default scaffolderModule; diff --git a/packages/cli/templates/scaffolder-module/src/actions/example/module.ts b/packages/cli/templates/scaffolder-module/src/actions/example/module.ts new file mode 100644 index 0000000000..238268dcec --- /dev/null +++ b/packages/cli/templates/scaffolder-module/src/actions/example/module.ts @@ -0,0 +1,21 @@ +import { createBackendModule } from "@backstage/backend-plugin-api"; +import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; +import { createAcmeExampleAction } from "./example"; + +/** + * A backend module that registers the action into the scaffolder + */ +export const scaffolderModule = createBackendModule({ + moduleId: 'acme:example', + pluginId: 'scaffolder', + register({ registerInit }) { + registerInit({ + deps: { + scaffolderActions: scaffolderActionsExtensionPoint + }, + async init({ scaffolderActions}) { + scaffolderActions.addActions(createAcmeExampleAction()); + } + }); + }, +}) diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index 968fd850d3..2a47e34b54 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/codemods +## 0.1.49 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.14 + ## 0.1.49-next.0 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index a490369468..6bab6f3df8 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/codemods", - "version": "0.1.49-next.0", + "version": "0.1.49", "description": "A collection of codemods for Backstage projects", "backstage": { "role": "cli" diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index dc11c1f793..fb048e7237 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/config-loader +## 1.8.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.8.1-next.0 ### Patch Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index 1b8c25f14e..28718b8290 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/config-loader", - "version": "1.8.1-next.0", + "version": "1.8.1", "description": "Config loading functionality used by Backstage backend, and CLI", "backstage": { "role": "node-library" diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 53a9807c61..32edc95e49 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,64 @@ # @backstage/core-app-api +## 1.13.0-next.0 + +### Minor Changes + +- d3c39fc: Allow for the disabling of external routes through config, which was rendered impossible after the introduction of default targets. + + ```yaml + app: + routes: + bindings: + # This has the effect of removing the button for registering new + # catalog entities in the scaffolder template list view + scaffolder.registerComponent: false + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 1.12.6 + +### Patch Changes + +- 35fbe09: Added support for configuration of route bindings through static configuration, and default targets for external route refs. + + In addition to configuring route bindings through code, it is now also possible to configure route bindings under the `app.routes.bindings` key, for example: + + ```yaml + app: + routes: + bindings: + catalog.createComponent: catalog-import.importPage + ``` + + Each key in the route binding object is of the form `.`, where the route name is key used in the `externalRoutes` object passed to `createPlugin`. The value is of the same form, but with the name taken from the plugin `routes` option instead. + + The equivalent of the above configuration in code is the following: + + ```ts + const app = createApp({ + // ... + bindRoutes({ bind }) { + bind(catalogPlugin.externalRoutes, { + createComponent: catalogImportPlugin.routes.importPage, + }); + }, + }); + ``` + +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.12.6-next.0 ### Patch Changes diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 8c9c31946d..bdd6a1f663 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.12.6-next.0", + "version": "1.13.0-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/core-app-api/src/app/resolveRouteBindings.test.ts b/packages/core-app-api/src/app/resolveRouteBindings.test.ts index 9dfbbfd452..7d5c649a34 100644 --- a/packages/core-app-api/src/app/resolveRouteBindings.test.ts +++ b/packages/core-app-api/src/app/resolveRouteBindings.test.ts @@ -194,4 +194,35 @@ describe('collectRouteIds', () => { 'test.extRef': extRef, }); }); + + it('can disable external routes that have defaults', () => { + const source = createExternalRouteRef({ + id: 'test', + defaultTarget: 'test.target1', + }); + const target1 = createRouteRef({ id: 'test' }); + const plugin = createPlugin({ + id: 'test', + routes: { target1 }, + externalRoutes: { source }, + }); + + // resolves normally with no config + let result = resolveRouteBindings(() => {}, new MockConfigApi({}), [ + plugin, + ]); + + expect(result.get(source)).toBe(target1); + + // can be disabled + result = resolveRouteBindings( + () => {}, + new MockConfigApi({ + app: { routes: { bindings: { 'test.source': false } } }, + }), + [plugin], + ); + + expect(result.get(source)).toBe(undefined); + }); }); diff --git a/packages/core-app-api/src/app/resolveRouteBindings.ts b/packages/core-app-api/src/app/resolveRouteBindings.ts index 55e1139b29..07dfea43ee 100644 --- a/packages/core-app-api/src/app/resolveRouteBindings.ts +++ b/packages/core-app-api/src/app/resolveRouteBindings.ts @@ -102,11 +102,12 @@ export function resolveRouteBindings( const bindings = config .getOptionalConfig('app.routes.bindings') ?.get(); + const disabledExternalRefs = new Set(); if (bindings) { for (const [externalRefId, targetRefId] of Object.entries(bindings)) { - if (typeof targetRefId !== 'string' || targetRefId === '') { + if (!isValidTargetRefId(targetRefId)) { throw new Error( - `Invalid config at app.routes.bindings['${externalRefId}'], value must be a non-empty string`, + `Invalid config at app.routes.bindings['${externalRefId}'], value must be a non-empty string or false`, ); } @@ -116,23 +117,27 @@ export function resolveRouteBindings( `Invalid config at app.routes.bindings, '${externalRefId}' is not a valid external route`, ); } - if (result.has(externalRef)) { - continue; - } - const targetRef = routesById.routes.get(targetRefId); - if (!targetRef) { - throw new Error( - `Invalid config at app.routes.bindings['${externalRefId}'], '${targetRefId}' is not a valid route`, - ); - } - result.set(externalRef, targetRef); + if (targetRefId === false) { + disabledExternalRefs.add(externalRef); + + result.delete(externalRef); + } else if (!result.has(externalRef)) { + const targetRef = routesById.routes.get(targetRefId); + if (!targetRef) { + throw new Error( + `Invalid config at app.routes.bindings['${externalRefId}'], '${targetRefId}' is not a valid route`, + ); + } + + result.set(externalRef, targetRef); + } } } // Finally fall back to attempting to map defaults, at lowest priority for (const externalRef of routesById.externalRoutes.values()) { - if (!result.has(externalRef)) { + if (!result.has(externalRef) && !disabledExternalRefs.has(externalRef)) { const defaultRefId = 'getDefaultTarget' in externalRef ? (externalRef.getDefaultTarget as () => string | undefined)() @@ -148,3 +153,15 @@ export function resolveRouteBindings( return result; } + +function isValidTargetRefId(value: unknown): value is string | false { + if (value === false) { + return true; + } + + if (typeof value === 'string' && value) { + return true; + } + + return false; +} diff --git a/packages/core-compat-api/CHANGELOG.md b/packages/core-compat-api/CHANGELOG.md index 3c307d7a3b..8bcedca9c4 100644 --- a/packages/core-compat-api/CHANGELOG.md +++ b/packages/core-compat-api/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/core-compat-api +## 0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## 0.2.6 + +### Patch Changes + +- 35fbe09: Add support for forwarding default target from legacy external route refs. +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/frontend-plugin-api@0.6.6 + - @backstage/version-bridge@1.0.8 + ## 0.2.6-next.2 ### Patch Changes diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index a145668efd..954cd6deb3 100644 --- a/packages/core-compat-api/package.json +++ b/packages/core-compat-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/core-compat-api", - "version": "0.2.6-next.2", + "version": "0.2.7-next.0", "backstage": { "role": "web-library" }, diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index e10d4f3a1f..f42b6396ce 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/core-components +## 0.14.9-next.0 + +### Patch Changes + +- d4ffdbb: Fixed bug where `', () => { expect(input.textContent).toBe('test 1'); }); + it('display nothing when placeholder is empty string and items updated to none', () => { + const initialValue = 'initial'; + const initialItems = [{ label: initialValue, value: initialValue }]; + const { getByTestId, rerender } = render( + ); + + expect(getByTestId('select').textContent).toBe(''); + }); + it('display the placeholder value when selected props updated to undefined', async () => { const { getByTestId, rerender } = render( { + onChange(e.target.value); + }} + value={value} + autoComplete="off" + /> + + + + + ); +}; diff --git a/plugins/scaffolder-react/src/next/components/SecretWidget/SecretWidget.tsx b/plugins/scaffolder-react/src/next/components/SecretWidget/SecretWidget.tsx new file mode 100644 index 0000000000..e2d139f98b --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/SecretWidget/SecretWidget.tsx @@ -0,0 +1,53 @@ +/* + * 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 { WidgetProps } from '@rjsf/utils'; +import { useTemplateSecrets } from '@backstage/plugin-scaffolder-react'; +import InputLabel from '@material-ui/core/InputLabel'; +import Input from '@material-ui/core/Input'; +import React from 'react'; + +/** + * Secret Widget for overriding the default password input widget + * @alpha + */ +export const SecretWidget = ( + props: Pick, +) => { + const { setSecrets, secrets } = useTemplateSecrets(); + const { + name, + onChange, + schema: { title }, + } = props; + + return ( + <> + {title} + { + onChange(Array(e.target?.value.length).fill('*').join('')); + setSecrets({ [name]: e.target?.value }); + }} + value={secrets[name] ?? ''} + type="password" + autoComplete="off" + /> + + ); +}; diff --git a/plugins/scaffolder-react/src/next/components/SecretWidget/index.ts b/plugins/scaffolder-react/src/next/components/SecretWidget/index.ts new file mode 100644 index 0000000000..9f0964516c --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/SecretWidget/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 './SecretWidget'; diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 5bfdf1a44a..269b6a11d5 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -20,7 +20,6 @@ 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, { @@ -49,6 +48,8 @@ import { } from '@backstage/plugin-scaffolder-react'; import { ReviewStepProps } from '@backstage/plugin-scaffolder-react'; import { ErrorListTemplate } from './ErrorListTemplate'; +import { makeStyles } from '@material-ui/core/styles'; +import { PasswordWidget } from '../PasswordWidget/PasswordWidget'; const useStyles = makeStyles(theme => ({ backButton: { @@ -232,6 +233,7 @@ export const Stepper = (stepperProps: StepperProps) => { showErrorList="top" templates={{ ErrorListTemplate }} onChange={handleChange} + widgets={{ password: PasswordWidget }} experimental_defaultFormStateBehavior={{ allOf: 'populateDefaults', }} diff --git a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.test.tsx b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.test.tsx index 27fde2083f..3a2aa1469f 100644 --- a/plugins/scaffolder-react/src/next/components/Workflow/Workflow.test.tsx +++ b/plugins/scaffolder-react/src/next/components/Workflow/Workflow.test.tsx @@ -36,6 +36,7 @@ const scaffolderApiMock: jest.Mocked = { streamLogs: jest.fn(), listActions: jest.fn(), listTasks: jest.fn(), + autocomplete: jest.fn(), }; const catalogApiMock: jest.Mocked = { getEntityByRef: jest.fn(), diff --git a/plugins/scaffolder-react/src/next/components/index.ts b/plugins/scaffolder-react/src/next/components/index.ts index 119f983a9f..02f00bb1a8 100644 --- a/plugins/scaffolder-react/src/next/components/index.ts +++ b/plugins/scaffolder-react/src/next/components/index.ts @@ -26,3 +26,4 @@ export * from './TaskLogStream'; export * from './TemplateCategoryPicker'; export * from './ScaffolderPageContextMenu'; export * from './ScaffolderField'; +export * from './SecretWidget'; diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index f42ddfa0e1..55d7271807 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,108 @@ # @backstage/plugin-scaffolder +## 1.22.0-next.0 + +### Minor Changes + +- 52b6db0: Use virtualization with `EntityPicker` as done earlier with `MultiEntityPicker` to fix performance issues with large data sets. `VirtualizedListbox` extracted into reusable component. +- 3583ce5: Use virtualization with `MultiEntityPicker`. Fixes performance issues with large data sets. +- b5deed0: Add support for `bitbucketCloud` autocomplete in `RepoUrlPicker` + +### Patch Changes + +- 661b354: Fixed a bug where the `RepoUrlPicker` would still require the `owner` field for `azure` +- 89c44b3: Support `catalogFilter` array on `OwnedEntityPicker` +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-scaffolder-react@1.10.0-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-scaffolder-common@1.5.3 + +## 1.21.0 + +### Minor Changes + +- d57ebbc: Changed the way to display entities in EntityPicker to use entityPresentationApi instead of humanizeEntityRef +- 62bd9eb: Replace `ui:widget: password` with the a warning message stating that it's not secure and to use the build in `SecretField`. + + You can do this by updating your `template.yaml` files that have the reference `ui:widget: password` to `ui:field: Secret` instead. + + ```diff + apiVersion: backstage.io/v1alpha1 + kind: Template + metadata: + ... + + spec: + parameters: + - title: collect some information + schema: + type: object + properties: + password: + title: Password + type: string + - ui:widget: password + + ui:field: Secret + steps: + - id: collect-info + name: Collect some information + action: acme:do:something + input: + - password: ${{ parameters.password }} + + password: ${{ secrets.password }} + ``` + +- 60085dd: Added the following default targets for external routes: + + - `registerComponent` binds to the catalog import page. + - `viewTechDoc` binds to the TechDocs entity documentation page. + +### Patch Changes + +- cbebad1: Internal updates to allow reusing Backstage's `fetchApi` implementation for event source requests. This allows you to for example, override the `Authorization` header. +- 1ea7679: Removed waiting for the workspace and repository fields to be filled in before requesting user credentials +- d44a20a: Added additional plugin metadata to `package.json`. +- 6cb4886: Updated dependency `@rjsf/utils` to `5.18.4`. + Updated dependency `@rjsf/core` to `5.18.4`. + Updated dependency `@rjsf/material-ui` to `5.18.4`. + Updated dependency `@rjsf/validator-ajv8` to `5.18.4`. +- 75dcd7e: Fixing bug in `formData` type as it should be `optional` as it's possibly undefined +- bcec60f: updated the ContextMenu, ActionsPage, OngoingTask and TemplateCard frontend components to support the new scaffolder permissions: + + - `scaffolder.task.create` + - `scaffolder.task.cancel` + - `scaffolder.task.read` + +- 612a453: Change owner to project for azure host +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/core-compat-api@0.2.6 + - @backstage/integration@1.12.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-scaffolder-react@1.9.0 + - @backstage/plugin-scaffolder-common@1.5.3 + - @backstage/plugin-permission-react@0.4.23 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-catalog-react@1.12.1 + - @backstage/integration-react@1.1.28 + - @backstage/frontend-plugin-api@0.6.6 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.21.0-next.3 ### Minor Changes diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 5c766af890..f479b13ec4 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -502,6 +502,22 @@ export class ScaffolderClient implements ScaffolderApi_2 { useLongPollingLogs?: boolean; }); // (undocumented) + autocomplete({ + token, + resource, + provider, + context, + }: { + token: string; + provider: string; + resource: string; + context?: Record; + }): Promise<{ + results: { + title: string; + }[]; + }>; + // (undocumented) cancelTask(taskId: string): Promise; // (undocumented) dryRun( diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index a209ceb9f3..33cf7be16f 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder", - "version": "1.21.0-next.3", + "version": "1.22.0-next.0", "description": "The Backstage plugin that helps you create new things", "backstage": { "role": "frontend-plugin", @@ -81,10 +81,10 @@ "@material-ui/lab": "4.0.0-alpha.61", "@microsoft/fetch-event-source": "^2.0.1", "@react-hookz/web": "^24.0.0", - "@rjsf/core": "5.18.4", - "@rjsf/material-ui": "5.18.4", - "@rjsf/utils": "5.18.4", - "@rjsf/validator-ajv8": "5.18.4", + "@rjsf/core": "5.18.5", + "@rjsf/material-ui": "5.18.5", + "@rjsf/utils": "5.18.5", + "@rjsf/validator-ajv8": "5.18.5", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "@uiw/react-codemirror": "^4.9.3", "classnames": "^2.2.6", @@ -97,6 +97,7 @@ "luxon": "^3.0.0", "qs": "^6.9.4", "react-use": "^17.2.4", + "react-window": "^1.8.10", "yaml": "^2.0.0", "zen-observable": "^0.10.0", "zod": "^3.22.4", @@ -115,6 +116,7 @@ "@testing-library/user-event": "^14.0.0", "@types/humanize-duration": "^3.18.1", "@types/json-schema": "^7.0.9", + "@types/react-window": "^1.8.8", "msw": "^1.0.0", "swr": "^2.0.0" }, diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts index 6ef5fff588..1809ed4c15 100644 --- a/plugins/scaffolder/src/api.ts +++ b/plugins/scaffolder/src/api.ts @@ -337,4 +337,38 @@ export class ScaffolderClient implements ScaffolderApi { return await response.json(); } + + async autocomplete({ + token, + resource, + provider, + context, + }: { + token: string; + provider: string; + resource: string; + context?: Record; + }): Promise<{ results: { title: string }[] }> { + const baseUrl = await this.discoveryApi.getBaseUrl('scaffolder'); + + const url = `${baseUrl}/v2/autocomplete/${provider}/${resource}`; + + const response = await this.fetchApi.fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + token, + context: context ?? {}, + }), + }); + + if (!response.ok) { + throw await ResponseError.fromResponse(response); + } + + const { results } = await response.json(); + return { results }; + } } diff --git a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx index 614e3fcff0..b548bcbad4 100644 --- a/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx +++ b/plugins/scaffolder/src/components/ActionsPage/ActionsPage.test.tsx @@ -33,6 +33,7 @@ const scaffolderApiMock: jest.Mocked = { streamLogs: jest.fn(), listActions: jest.fn(), listTasks: jest.fn(), + autocomplete: jest.fn(), }; const apis = TestApiRegistry.from([scaffolderApiRef, scaffolderApiMock]); diff --git a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx index 176f6e9ce0..9eca3e85c5 100644 --- a/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/EntityPicker/EntityPicker.tsx @@ -43,6 +43,7 @@ import { EntityPickerUiOptions, EntityPickerFilterQuery, } from './schema'; +import { VirtualizedListbox } from '../VirtualizedListbox'; export { EntityPickerSchema } from './schema'; @@ -205,6 +206,7 @@ export const EntityPicker = (props: EntityPickerProps) => { entities?.entityRefToPresentation.get(stringifyEntityRef(option)) ?.primaryTitle!, })} + ListboxComponent={VirtualizedListbox} /> ); diff --git a/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx b/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx index 4ea26b4414..d800c9b372 100644 --- a/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/MultiEntityPicker/MultiEntityPicker.tsx @@ -43,6 +43,7 @@ import { MultiEntityPickerUiOptions, MultiEntityPickerFilterQuery, } from './schema'; +import { VirtualizedListbox } from '../VirtualizedListbox'; export { MultiEntityPickerSchema } from './schema'; @@ -177,6 +178,7 @@ export const MultiEntityPicker = (props: MultiEntityPickerProps) => { }} /> )} + ListboxComponent={VirtualizedListbox} /> ); diff --git a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx index d5351d54e5..02c437ceb6 100644 --- a/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx +++ b/plugins/scaffolder/src/components/fields/OwnedEntityPicker/OwnedEntityPicker.tsx @@ -90,17 +90,11 @@ function buildEntityPickerUISchema( uiSchema?.['ui:options'] || {}; const allowedKinds = uiOptions.allowedKinds; - const catalogFilter = { - ...uiOptions.catalogFilter, - ...(allowedKinds - ? { - kind: allowedKinds, - [`relations.${RELATION_OWNED_BY}`]: identityRefs || [], - } - : { - [`relations.${RELATION_OWNED_BY}`]: identityRefs || [], - }), - }; + const catalogFilter = asArray(uiOptions.catalogFilter).map(e => ({ + ...e, + ...(allowedKinds ? { kind: allowedKinds } : {}), + [`relations.${RELATION_OWNED_BY}`]: identityRefs || [], + })); return { 'ui:options': { @@ -108,3 +102,10 @@ function buildEntityPickerUISchema( }, }; } + +function asArray(catalogFilter: any): any[] { + if (catalogFilter) { + return Array.isArray(catalogFilter) ? catalogFilter : [catalogFilter]; + } + return [{}]; +} diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx index f799d68c2d..2ae89233ff 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.test.tsx @@ -16,18 +16,33 @@ import React from 'react'; import { BitbucketRepoPicker } from './BitbucketRepoPicker'; -import { render, fireEvent } from '@testing-library/react'; +import { render, fireEvent, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { TestApiProvider } from '@backstage/test-utils'; +import { + ScaffolderApi, + scaffolderApiRef, +} from '@backstage/plugin-scaffolder-react'; +import { act } from 'react-dom/test-utils'; describe('BitbucketRepoPicker', () => { + const scaffolderApiMock: Partial = { + autocomplete: jest.fn().mockImplementation(opts => ({ + results: [{ title: `${opts.resource}_example` }], + })), + }; + it('renders a select if there is a list of allowed owners', async () => { const allowedOwners = ['owner1', 'owner2']; const { findByText } = render( - , + + + , ); expect(await findByText('owner1')).toBeInTheDocument(); @@ -38,7 +53,13 @@ describe('BitbucketRepoPicker', () => { const state = { host: 'bitbucket.org', workspace: 'lolsWorkspace' }; const { getAllByRole } = render( - , + + + , ); expect(getAllByRole('textbox')).toHaveLength(2); @@ -51,7 +72,13 @@ describe('BitbucketRepoPicker', () => { }; const { getAllByRole } = render( - , + + + , ); expect(getAllByRole('textbox')).toHaveLength(1); @@ -61,16 +88,24 @@ describe('BitbucketRepoPicker', () => { it('calls onChange when the workspace changes', () => { const onChange = jest.fn(); const { getAllByRole } = render( - , + + + , ); const workspaceInput = getAllByRole('textbox')[0]; - fireEvent.change(workspaceInput, { target: { value: 'test-workspace' } }); + act(() => { + workspaceInput.focus(); + fireEvent.change(workspaceInput, { + target: { value: 'test-workspace' }, + }); + workspaceInput.blur(); + }); expect(onChange).toHaveBeenCalledWith({ workspace: 'test-workspace' }); }); @@ -80,27 +115,35 @@ describe('BitbucketRepoPicker', () => { it('calls onChange when the project changes', () => { const onChange = jest.fn(); const { getAllByRole } = render( - , + + + , ); const projectInput = getAllByRole('textbox')[1]; - fireEvent.change(projectInput, { target: { value: 'test-project' } }); + act(() => { + projectInput.focus(); + fireEvent.change(projectInput, { target: { value: 'test-project' } }); + projectInput.blur(); + }); expect(onChange).toHaveBeenCalledWith({ project: 'test-project' }); }); it('Does not render a select if the list of allowed projects does not exist', async () => { const { getAllByRole } = render( - , + + + , ); expect(getAllByRole('textbox')).toHaveLength(2); @@ -109,12 +152,14 @@ describe('BitbucketRepoPicker', () => { it('Does not render a select if the list of allowed projects is empty', async () => { const { getAllByRole } = render( - , + + + , ); expect(getAllByRole('textbox')).toHaveLength(2); @@ -124,16 +169,104 @@ describe('BitbucketRepoPicker', () => { it('Does render a select if there is a list of allowed projects', async () => { const allowedProjects = ['project1', 'project2']; const { findByText } = render( - , + + + , ); expect(await findByText('project1')).toBeInTheDocument(); expect(await findByText('project2')).toBeInTheDocument(); }); }); + + describe('autocompletion', () => { + it('should populate workspaces if host is set and accessToken is provided', async () => { + const onChange = jest.fn(); + + const { getAllByRole, getByText } = render( + + + , + ); + + // Open the Autcomplete dropdown + const workspaceInput = getAllByRole('textbox')[0]; + await userEvent.click(workspaceInput); + + // Verify that the available workspaces are shown + await waitFor(() => + expect(getByText('workspaces_example')).toBeInTheDocument(), + ); + + // Verify that selecting an option calls onChange + await userEvent.click(getByText('workspaces_example')); + expect(onChange).toHaveBeenCalledWith({ + workspace: 'workspaces_example', + }); + }); + + it('should populate projects if host and workspace are set and accessToken is provided', async () => { + const onChange = jest.fn(); + + const { getAllByRole, getByText } = render( + + + , + ); + + // Open the Autcomplete dropdown + const projectInput = getAllByRole('textbox')[1]; + await userEvent.click(projectInput); + + // Verify that the available projects are shown + await waitFor(() => + expect(getByText('projects_example')).toBeInTheDocument(), + ); + + // Verify that selecting an option calls onChange + await userEvent.click(getByText('projects_example')); + expect(onChange).toHaveBeenCalledWith({ project: 'projects_example' }); + }); + + it('should populate repositories if host, workspace and project are set and accessToken is provided', async () => { + const onChange = jest.fn(); + + render( + + + , + ); + + // Verify that the available repos are updated + await waitFor(() => + expect(onChange).toHaveBeenCalledWith({ + availableRepos: ['repositories_example'], + }), + ); + }); + }); }); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx index d070e3fee5..10d4a6e6c3 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/BitbucketRepoPicker.tsx @@ -13,13 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import FormControl from '@material-ui/core/FormControl'; import FormHelperText from '@material-ui/core/FormHelperText'; -import Input from '@material-ui/core/Input'; -import InputLabel from '@material-ui/core/InputLabel'; import { Select, SelectItem } from '@backstage/core-components'; import { RepoUrlPickerState } from './types'; +import Autocomplete from '@material-ui/lab/Autocomplete'; +import TextField from '@material-ui/core/TextField'; +import useDebounce from 'react-use/esm/useDebounce'; +import { useApi } from '@backstage/core-plugin-api'; +import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; /** * The underlying component that is rendered in the form for the `BitbucketRepoPicker` @@ -36,6 +39,7 @@ export const BitbucketRepoPicker = (props: { onChange: (state: RepoUrlPickerState) => void; state: RepoUrlPickerState; rawErrors: string[]; + accessToken?: string; }) => { const { allowedOwners = [], @@ -43,6 +47,7 @@ export const BitbucketRepoPicker = (props: { onChange, rawErrors, state, + accessToken, } = props; const { host, workspace, project } = state; const ownerItems: SelectItem[] = allowedOwners @@ -58,6 +63,100 @@ export const BitbucketRepoPicker = (props: { } }, [allowedOwners, host, onChange]); + const scaffolderApi = useApi(scaffolderApiRef); + + const [availableWorkspaces, setAvailableWorkspaces] = useState([]); + const [availableProjects, setAvailableProjects] = useState([]); + + // Update available workspaces when client is available + useDebounce( + () => { + const updateAvailableWorkspaces = async () => { + if ( + host === 'bitbucket.org' && + accessToken && + scaffolderApi.autocomplete + ) { + const { results } = await scaffolderApi.autocomplete({ + token: accessToken, + resource: 'workspaces', + context: {}, + provider: 'bitbucket-cloud', + }); + + setAvailableWorkspaces(results.map(r => r.title)); + } else { + setAvailableWorkspaces([]); + } + }; + + updateAvailableWorkspaces().catch(() => setAvailableWorkspaces([])); + }, + 500, + [host, accessToken], + ); + + // Update available projects when client is available and workspace changes + useDebounce( + () => { + const updateAvailableProjects = async () => { + if ( + host === 'bitbucket.org' && + accessToken && + workspace && + scaffolderApi.autocomplete + ) { + const { results } = await scaffolderApi.autocomplete({ + token: accessToken, + resource: 'projects', + context: { workspace }, + provider: 'bitbucket-cloud', + }); + + setAvailableProjects(results.map(r => r.title)); + } else { + setAvailableProjects([]); + } + }; + + updateAvailableProjects().catch(() => setAvailableProjects([])); + }, + 500, + [host, accessToken, workspace], + ); + + // Update available repositories when client is available and workspace or project changes + useDebounce( + () => { + const updateAvailableRepositories = async () => { + if ( + host === 'bitbucket.org' && + accessToken && + workspace && + project && + scaffolderApi.autocomplete + ) { + const { results } = await scaffolderApi.autocomplete({ + token: accessToken, + resource: 'repositories', + context: { workspace, project }, + provider: 'bitbucket-cloud', + }); + + onChange({ availableRepos: results.map(r => r.title) }); + } else { + onChange({ availableRepos: [] }); + } + }; + + updateAvailableRepositories().catch(() => + onChange({ availableRepos: [] }), + ); + }, + 500, + [host, accessToken, workspace, project], + ); + return ( <> {host === 'bitbucket.org' && ( @@ -78,14 +177,18 @@ export const BitbucketRepoPicker = (props: { items={ownerItems} /> ) : ( - <> - Workspace - onChange({ workspace: e.target.value })} - value={workspace} - /> - + { + onChange({ workspace: newValue || '' }); + }} + options={availableWorkspaces} + renderInput={params => ( + + )} + freeSolo + autoSelect + /> )} The Workspace that this repo will belong to @@ -109,14 +212,18 @@ export const BitbucketRepoPicker = (props: { items={projectItems} /> ) : ( - <> - Project - onChange({ project: e.target.value })} - value={project} - /> - + { + onChange({ project: newValue || '' }); + }} + options={availableProjects} + renderInput={params => ( + + )} + freeSolo + autoSelect + /> )} The Project that this repo will belong to diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx index 59c09c106c..002652cfab 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.test.tsx @@ -98,8 +98,15 @@ describe('RepoUrlPicker', () => { const [ownerInput, repoInput] = getAllByRole('textbox'); const submitButton = getByRole('button'); - fireEvent.change(ownerInput, { target: { value: 'backstage' } }); - fireEvent.change(repoInput, { target: { value: 'repo123' } }); + act(() => { + ownerInput.focus(); + fireEvent.change(ownerInput, { target: { value: 'backstage' } }); + ownerInput.blur(); + + repoInput.focus(); + fireEvent.change(repoInput, { target: { value: 'repo123' } }); + repoInput.blur(); + }); fireEvent.click(submitButton); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx index 85245639b0..e0d714ffda 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPicker.tsx @@ -203,6 +203,10 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { rawErrors={rawErrors} state={state} onChange={updateLocalState} + accessToken={ + uiSchema?.['ui:options']?.requestUserCredentials?.secretsKey && + secrets[uiSchema['ui:options'].requestUserCredentials.secretsKey] + } /> )} {hostType === 'azure' && ( @@ -228,6 +232,7 @@ export const RepoUrlPicker = (props: RepoUrlPickerProps) => { setState(prevState => ({ ...prevState, repoName: repo })) } rawErrors={rawErrors} + availableRepos={state.availableRepos} /> ); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.test.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.test.tsx index 4c392d646c..95407084c6 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.test.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.test.tsx @@ -16,6 +16,8 @@ import React from 'react'; import { RepoUrlPickerRepoName } from './RepoUrlPickerRepoName'; import { render, fireEvent } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { act } from 'react-dom/test-utils'; describe('RepoUrlPickerRepoName', () => { it('should call onChange with the first allowed repo if there is none set already', async () => { @@ -69,8 +71,39 @@ describe('RepoUrlPickerRepoName', () => { expect(textArea).toBeVisible(); - fireEvent.change(textArea, { target: { value: 'foo' } }); + act(() => { + textArea.focus(); + fireEvent.change(textArea, { target: { value: 'foo' } }); + textArea.blur(); + }); expect(onChange).toHaveBeenCalledWith('foo'); }); + + it('should autocomplete with provided availableRepos', async () => { + const availableRepos = ['foo', 'bar']; + + const onChange = jest.fn(); + + const { getByRole, getByText } = render( + , + ); + + // Open the Autocomplete dropdown + const input = getByRole('textbox'); + await userEvent.click(input); + + // Verify that available repos are shown + for (const repo of availableRepos) { + expect(getByText(repo)).toBeInTheDocument(); + } + + // Verify that selecting an option calls onChange + await userEvent.click(getByText(availableRepos[0])); + expect(onChange).toHaveBeenCalledWith(availableRepos[0]); + }); }); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.tsx b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.tsx index f2d68b08f3..01878cb619 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.tsx +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/RepoUrlPickerRepoName.tsx @@ -17,16 +17,17 @@ import React, { useEffect } from 'react'; import { Select, SelectItem } from '@backstage/core-components'; import FormControl from '@material-ui/core/FormControl'; import FormHelperText from '@material-ui/core/FormHelperText'; -import Input from '@material-ui/core/Input'; -import InputLabel from '@material-ui/core/InputLabel'; +import Autocomplete from '@material-ui/lab/Autocomplete'; +import TextField from '@material-ui/core/TextField'; export const RepoUrlPickerRepoName = (props: { repoName?: string; allowedRepos?: string[]; onChange: (host: string) => void; rawErrors: string[]; + availableRepos?: string[]; }) => { - const { repoName, allowedRepos, onChange, rawErrors } = props; + const { repoName, allowedRepos, onChange, rawErrors, availableRepos } = props; useEffect(() => { // If there is no repoName chosen currently @@ -61,14 +62,18 @@ export const RepoUrlPickerRepoName = (props: { items={repoItems} /> ) : ( - <> - Repository - onChange(String(e.target.value))} - value={repoName} - /> - + { + onChange(newValue || ''); + }} + options={availableRepos || []} + renderInput={params => ( + + )} + freeSolo + autoSelect + /> )} The name of the repository diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/types.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/types.ts index 5e979e789e..1430b10b84 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/types.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/types.ts @@ -20,4 +20,5 @@ export interface RepoUrlPickerState { organization?: string; workspace?: string; project?: string; + availableRepos?: string[]; } diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/validation.test.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/validation.test.ts index b9c481957c..2b59775d3a 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/validation.test.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/validation.test.ts @@ -36,6 +36,11 @@ describe('RepoPicker Validation', () => { host: 'server.bitbucket.com', }, ], + azure: [ + { + host: 'dev.azure.com', + }, + ], github: [ { host: 'github.com', @@ -201,4 +206,59 @@ describe('RepoPicker Validation', () => { 'Incomplete repository location provided, repo not provided', ); }); + + it('validates properly with proper input for azure', () => { + const mockFieldValidation = fieldValidator(); + + repoPickerValidation( + 'dev.azure.com?project=a&repo=b', + mockFieldValidation, + { + apiHolder: apiHolderMock, + }, + ); + + expect(mockFieldValidation.addError).not.toHaveBeenCalled(); + }); + + it('validates when no project or repo provided for azure', () => { + const mockFieldValidation = fieldValidator(); + + repoPickerValidation('dev.azure.com', mockFieldValidation, { + apiHolder: apiHolderMock, + }); + + expect(mockFieldValidation.addError).toHaveBeenNthCalledWith( + 1, + 'Incomplete repository location provided, project not provided', + ); + expect(mockFieldValidation.addError).toHaveBeenNthCalledWith( + 2, + 'Incomplete repository location provided, repo not provided', + ); + }); + + it('validates when no project provided for azure', () => { + const mockFieldValidation = fieldValidator(); + + repoPickerValidation('dev.azure.com?repo=r', mockFieldValidation, { + apiHolder: apiHolderMock, + }); + + expect(mockFieldValidation.addError).toHaveBeenCalledWith( + 'Incomplete repository location provided, project not provided', + ); + }); + + it('validates when no repo provided for azure', () => { + const mockFieldValidation = fieldValidator(); + + repoPickerValidation('dev.azure.com?project=p', mockFieldValidation, { + apiHolder: apiHolderMock, + }); + + expect(mockFieldValidation.addError).toHaveBeenCalledWith( + 'Incomplete repository location provided, repo not provided', + ); + }); }); diff --git a/plugins/scaffolder/src/components/fields/RepoUrlPicker/validation.ts b/plugins/scaffolder/src/components/fields/RepoUrlPicker/validation.ts index 55ba92abdc..06c2fd5684 100644 --- a/plugins/scaffolder/src/components/fields/RepoUrlPicker/validation.ts +++ b/plugins/scaffolder/src/components/fields/RepoUrlPicker/validation.ts @@ -48,13 +48,19 @@ export const repoPickerValidation = ( ); } + if (!searchParams.get('project')) { + validation.addError( + 'Incomplete repository location provided, project not provided', + ); + } + } else if (integrationApi?.byHost(host)?.type === 'azure') { if (!searchParams.get('project')) { validation.addError( 'Incomplete repository location provided, project not provided', ); } } - // For anything other than bitbucket and gerrit + // For anything other than bitbucket, azure, and gerrit else if (integrationApi?.byHost(host)?.type !== 'gerrit') { if (!searchParams.get('owner')) { validation.addError( diff --git a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx index aac0cf809a..a588286d97 100644 --- a/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx +++ b/plugins/scaffolder/src/components/fields/SecretInput/SecretInput.tsx @@ -14,18 +14,15 @@ * limitations under the License. */ 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 from '@material-ui/core/Input'; -import InputLabel from '@material-ui/core/InputLabel'; +import { + ScaffolderField, + SecretWidget, +} from '@backstage/plugin-scaffolder-react/alpha'; export const SecretInput = (props: ScaffolderRJSFFieldProps) => { - const { setSecrets, secrets } = useTemplateSecrets(); const { - name, - onChange, - schema: { title, description }, + schema: { description }, rawErrors, disabled, errors, @@ -40,18 +37,7 @@ export const SecretInput = (props: ScaffolderRJSFFieldProps) => { errors={errors} required={required} > - {title} - { - onChange(Array(e.target?.value.length).fill('*').join('')); - setSecrets({ [name]: e.target?.value }); - }} - value={secrets[name] ?? ''} - type="password" - autoComplete="off" - /> + ); }; diff --git a/plugins/scaffolder/src/components/fields/VirtualizedListbox.tsx b/plugins/scaffolder/src/components/fields/VirtualizedListbox.tsx new file mode 100644 index 0000000000..b0920b626a --- /dev/null +++ b/plugins/scaffolder/src/components/fields/VirtualizedListbox.tsx @@ -0,0 +1,50 @@ +/* + * 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 { FixedSizeList, ListChildComponentProps } from 'react-window'; + +const renderRow = (props: ListChildComponentProps) => { + const { data, index, style } = props; + return React.cloneElement(data[index], { style }); +}; + +export const VirtualizedListbox = React.forwardRef< + HTMLDivElement, + { children?: React.ReactNode } +>((props, ref) => { + const itemData = React.Children.toArray(props.children); + const itemCount = itemData.length; + + const itemSize = 36; + + const itemsToShow = Math.min(10, itemCount); + const height = Math.max(itemSize, itemsToShow * itemSize - 0.5 * itemSize); + + return ( +
+ + {renderRow} + +
+ ); +}); diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx index 269ff81271..2639e8149c 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.test.tsx @@ -51,6 +51,7 @@ const scaffolderApiMock: jest.Mocked = { streamLogs: jest.fn(), listActions: jest.fn(), listTasks: jest.fn(), + autocomplete: jest.fn(), }; const catalogApiMock: jest.Mocked = { diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index 880053dff5..e2d6440c94 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-search-backend-module-catalog +## 0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## 0.1.25 + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/backend-tasks@0.5.24 + - @backstage/plugin-catalog-node@1.12.1 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-search-common@1.2.12 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.25-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-catalog/api-report-alpha.md b/plugins/search-backend-module-catalog/api-report-alpha.md index f840884f68..a645532384 100644 --- a/plugins/search-backend-module-catalog/api-report-alpha.md +++ b/plugins/search-backend-module-catalog/api-report-alpha.md @@ -3,7 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; +import { BackendFeatureCompat } from '@backstage/backend-plugin-api'; import { CatalogCollatorEntityTransformer } from '@backstage/plugin-search-backend-module-catalog'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; @@ -16,7 +16,7 @@ export type CatalogCollatorExtensionPoint = { export const catalogCollatorExtensionPoint: ExtensionPoint; // @alpha -const _default: () => BackendFeature; +const _default: BackendFeatureCompat; export default _default; // (No @packageDocumentation comment for this package) diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index cf6a9a3e18..d46e220029 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-catalog", - "version": "0.1.25-next.3", + "version": "0.1.27-next.0", "description": "A module for the search backend that exports catalog modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-catalog/src/alpha.test.ts b/plugins/search-backend-module-catalog/src/alpha.test.ts index eb2a795ecc..94c585161b 100644 --- a/plugins/search-backend-module-catalog/src/alpha.test.ts +++ b/plugins/search-backend-module-catalog/src/alpha.test.ts @@ -28,7 +28,7 @@ describe('searchModuleCatalogCollator', () => { extensionPoints: [ [searchIndexRegistryExtensionPoint, extensionPointMock], ], - features: [searchModuleCatalogCollator()], + features: [searchModuleCatalogCollator], }); expect(extensionPointMock.addCollator).toHaveBeenCalledTimes(1); @@ -50,7 +50,7 @@ describe('searchModuleCatalogCollator', () => { ], ], features: [ - searchModuleCatalogCollator(), + searchModuleCatalogCollator, mockServices.rootConfig.factory({ data: { search: { diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index 81b6dfdeba..16cf473283 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.12 + +## 1.5.0 + +### Minor Changes + +- b186701: **BREAKING**: The ElasticSearch indexer will now delete stale indices matching the indexer's pattern. + The method `getAliases` of `ElasticSearchClientWrapper` has been deprecated and might be removed in future releases. + + An indexer using the `some-type-index__*` pattern will remove indices matching this pattern after indexation + to prevent stale indices leading to shards exhaustion. + + Before upgrading ensure that the index pattern doesn't match indices that are not managed by Backstage + and thus shouldn't be deleted. + + Note: The ElasticSearch indexer already uses wildcards patterns to remove aliases on these indices. + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- 6a576dc: Replace the usage of `getVoidLogger` with `mockServices.logger.mock` in order to remove the dependency with the soon-to-be-deprecated `backend-common` package. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-search-common@1.2.12 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + ## 1.4.2-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/api-report-alpha.md b/plugins/search-backend-module-elasticsearch/api-report-alpha.md index c0c30f7f2b..ca1858f9c8 100644 --- a/plugins/search-backend-module-elasticsearch/api-report-alpha.md +++ b/plugins/search-backend-module-elasticsearch/api-report-alpha.md @@ -3,12 +3,12 @@ > 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 { BackendFeatureCompat } from '@backstage/backend-plugin-api'; import { ElasticSearchQueryTranslator } from '@backstage/plugin-search-backend-module-elasticsearch'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; // @alpha -const _default: () => BackendFeature; +const _default: BackendFeatureCompat; export default _default; // @alpha (undocumented) diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index bf6c48910f..57414ec6e5 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", - "version": "1.4.2-next.3", + "version": "1.5.2-next.0", "description": "A module for the search backend that implements search using ElasticSearch", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index 9ce0c3ce31..4b75d163f9 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-search-backend-module-explore +## 0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.12 + +## 0.1.25 + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/backend-tasks@0.5.24 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-search-common@1.2.12 + - @backstage/config@1.2.0 + ## 0.1.25-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-explore/api-report-alpha.md b/plugins/search-backend-module-explore/api-report-alpha.md index e1ecb85886..052860b957 100644 --- a/plugins/search-backend-module-explore/api-report-alpha.md +++ b/plugins/search-backend-module-explore/api-report-alpha.md @@ -3,10 +3,10 @@ > 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 { BackendFeatureCompat } from '@backstage/backend-plugin-api'; // @alpha -const _default: () => BackendFeature; +const _default: BackendFeatureCompat; export default _default; // (No @packageDocumentation comment for this package) diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 88239e5853..13cba189e5 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-explore", - "version": "0.1.25-next.3", + "version": "0.1.27-next.0", "description": "A module for the search backend that exports explore modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-explore/src/alpha.test.ts b/plugins/search-backend-module-explore/src/alpha.test.ts index fa6ab8a909..2ba01ec478 100644 --- a/plugins/search-backend-module-explore/src/alpha.test.ts +++ b/plugins/search-backend-module-explore/src/alpha.test.ts @@ -35,7 +35,7 @@ describe('searchModuleExploreCollator', () => { [searchIndexRegistryExtensionPoint, extensionPointMock], ], features: [ - searchModuleExploreCollator(), + searchModuleExploreCollator, mockServices.rootConfig.factory({ data: { search: { diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index f02ea765b4..376d266f8f 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-search-backend-module-pg +## 0.5.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-app-api@0.7.9-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.12 + +## 0.5.28 + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- 6a576dc: Replace the usage of `getVoidLogger` with `mockServices.logger.mock` in order to remove the dependency with the soon-to-be-deprecated `backend-common` package. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-app-api@0.7.6 + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-search-common@1.2.12 + - @backstage/config@1.2.0 + ## 0.5.28-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-pg/api-report-alpha.md b/plugins/search-backend-module-pg/api-report-alpha.md index b021f6884f..ea2f6afece 100644 --- a/plugins/search-backend-module-pg/api-report-alpha.md +++ b/plugins/search-backend-module-pg/api-report-alpha.md @@ -3,10 +3,10 @@ > 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 { BackendFeatureCompat } from '@backstage/backend-plugin-api'; // @alpha -const _default: () => BackendFeature; +const _default: BackendFeatureCompat; export default _default; // (No @packageDocumentation comment for this package) diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 236adaac63..3319d85dbb 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-pg", - "version": "0.5.28-next.3", + "version": "0.5.31-next.0", "description": "A module for the search backend that implements search using PostgreSQL", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index 10705399e0..91652d5543 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.12 + +## 0.1.12 + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/backend-tasks@0.5.24 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-search-common@1.2.12 + - @backstage/config@1.2.0 + ## 0.1.12-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 d70b5f79fd..bf5ebb5408 100644 --- a/plugins/search-backend-module-stack-overflow-collator/api-report.md +++ b/plugins/search-backend-module-stack-overflow-collator/api-report.md @@ -5,7 +5,7 @@ ```ts /// -import { BackendFeature } from '@backstage/backend-plugin-api'; +import { BackendFeatureCompat } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { IndexableDocument } from '@backstage/plugin-search-common'; @@ -13,7 +13,7 @@ import { LoggerService } from '@backstage/backend-plugin-api'; import { Readable } from 'stream'; // @public -const searchStackOverflowCollatorModule: () => BackendFeature; +const searchStackOverflowCollatorModule: BackendFeatureCompat; export default searchStackOverflowCollatorModule; // @public diff --git a/plugins/search-backend-module-stack-overflow-collator/package.json b/plugins/search-backend-module-stack-overflow-collator/package.json index b35262a949..60b658a34a 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", - "version": "0.1.12-next.3", + "version": "0.1.14-next.0", "description": "A module for the search backend that exports stack overflow modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-stack-overflow-collator/src/module/SearchStackOverflowCollatorModule.test.ts b/plugins/search-backend-module-stack-overflow-collator/src/module/SearchStackOverflowCollatorModule.test.ts index a785ead6eb..4e9bc05b73 100644 --- a/plugins/search-backend-module-stack-overflow-collator/src/module/SearchStackOverflowCollatorModule.test.ts +++ b/plugins/search-backend-module-stack-overflow-collator/src/module/SearchStackOverflowCollatorModule.test.ts @@ -35,7 +35,7 @@ describe('searchStackOverflowCollatorModule', () => { [searchIndexRegistryExtensionPoint, extensionPointMock], ], features: [ - searchStackOverflowCollatorModule(), + searchStackOverflowCollatorModule, mockServices.rootConfig.factory({ data: { stackoverflow: { diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index d3173bcf2c..4e7e3c4baa 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/plugin-catalog-node@1.12.3-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/plugin-techdocs-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## 0.1.24 + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/backend-tasks@0.5.24 + - @backstage/plugin-techdocs-node@1.12.5 + - @backstage/plugin-catalog-node@1.12.1 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-search-common@1.2.12 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + ## 0.1.24-next.3 ### Patch Changes diff --git a/plugins/search-backend-module-techdocs/api-report-alpha.md b/plugins/search-backend-module-techdocs/api-report-alpha.md index df98623631..ed1e72b3bf 100644 --- a/plugins/search-backend-module-techdocs/api-report-alpha.md +++ b/plugins/search-backend-module-techdocs/api-report-alpha.md @@ -3,12 +3,12 @@ > 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 { BackendFeatureCompat } from '@backstage/backend-plugin-api'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { TechDocsCollatorEntityTransformer } from '@backstage/plugin-search-backend-module-techdocs'; // @alpha -const _default: () => BackendFeature; +const _default: BackendFeatureCompat; export default _default; // @alpha (undocumented) diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index 5646ac0b6d..1650012d93 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", - "version": "0.1.24-next.3", + "version": "0.1.26-next.0", "description": "A module for the search backend that exports techdocs modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-techdocs/src/alpha.test.ts b/plugins/search-backend-module-techdocs/src/alpha.test.ts index a278614b75..f1875a881b 100644 --- a/plugins/search-backend-module-techdocs/src/alpha.test.ts +++ b/plugins/search-backend-module-techdocs/src/alpha.test.ts @@ -35,7 +35,7 @@ describe('searchModuleTechDocsCollator', () => { [searchIndexRegistryExtensionPoint, extensionPointMock], ], features: [ - searchModuleTechDocsCollator(), + searchModuleTechDocsCollator, mockServices.rootConfig.factory({ data: { search: { diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 87f7db5616..5209cb8753 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-search-backend-node +## 1.2.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-tasks@0.5.26-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## 1.2.24 + +### Patch Changes + +- 6a576dc: Replace the usage of `getVoidLogger` with `mockServices.logger.mock` in order to remove the dependency with the soon-to-be-deprecated `backend-common` package. +- d44a20a: Added additional plugin metadata to `package.json`. +- 5b6f979: Split backend search plugin startup into "init" and "start" stages to ensure necessary initialization has happened before startup +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/backend-tasks@0.5.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.2.24-next.3 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index 932404902e..ef655ac566 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-node", - "version": "1.2.24-next.3", + "version": "1.2.26-next.0", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", "backstage": { "role": "node-library", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index f4e94b34b9..ea4142e583 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/plugin-search-backend +## 1.5.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-defaults@0.3.3-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/backend-openapi-utils@0.1.14-next.0 + - @backstage/plugin-permission-node@0.7.32-next.0 + - @backstage/plugin-search-backend-node@1.2.26-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + +## 1.5.10 + +### Patch Changes + +- 8869b8e: Updated local development setup. +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- d44a20a: Added additional plugin metadata to `package.json`. +- 5b6f979: Split backend search plugin startup into "init" and "start" stages to ensure necessary initialization has happened before startup +- 34dc47d: Move @backstage/repo-tools to devDependencies +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/backend-defaults@0.3.0 + - @backstage/plugin-search-backend-node@1.2.24 + - @backstage/plugin-permission-node@0.7.30 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-search-common@1.2.12 + - @backstage/backend-openapi-utils@0.1.12 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 1.5.10-next.3 ### Patch Changes diff --git a/plugins/search-backend/api-report-alpha.md b/plugins/search-backend/api-report-alpha.md index 548f4c6608..2e5de660cb 100644 --- a/plugins/search-backend/api-report-alpha.md +++ b/plugins/search-backend/api-report-alpha.md @@ -3,10 +3,10 @@ > 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 { BackendFeatureCompat } from '@backstage/backend-plugin-api'; // @alpha -const _default: () => BackendFeature; +const _default: BackendFeatureCompat; export default _default; // (No @packageDocumentation comment for this package) diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 1f44819562..c1d536d4d4 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend", - "version": "1.5.10-next.3", + "version": "1.5.13-next.0", "description": "The Backstage backend plugin that provides your backstage app with search", "backstage": { "role": "backend-plugin", diff --git a/plugins/search-backend/src/alpha.test.ts b/plugins/search-backend/src/alpha.test.ts index a18ab7e104..dfe80987d4 100644 --- a/plugins/search-backend/src/alpha.test.ts +++ b/plugins/search-backend/src/alpha.test.ts @@ -21,7 +21,7 @@ import searchPlugin from './alpha'; describe('searchPlugin', () => { it('should serve search results on query endpoint', async () => { const { server } = await startTestBackend({ - features: [searchPlugin()], + features: [searchPlugin], }); const response = await request(server).get('/api/search/query'); diff --git a/plugins/search-common/CHANGELOG.md b/plugins/search-common/CHANGELOG.md index e0c9991457..e034c62315 100644 --- a/plugins/search-common/CHANGELOG.md +++ b/plugins/search-common/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-search-common +## 1.2.12 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/plugin-permission-common@0.7.14 + - @backstage/types@1.1.1 + ## 1.2.12-next.0 ### Patch Changes diff --git a/plugins/search-common/package.json b/plugins/search-common/package.json index 19657dee23..61edfd13f3 100644 --- a/plugins/search-common/package.json +++ b/plugins/search-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-common", - "version": "1.2.12-next.0", + "version": "1.2.12", "description": "Common functionalities for Search, to be shared between various search-enabled plugins", "backstage": { "role": "common-library", diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index d0ca8d04f6..19ace29f0c 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-search-react +## 1.7.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.12 + +## 1.7.12 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-search-common@1.2.12 + - @backstage/frontend-plugin-api@0.6.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.7.12-next.2 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index bca09316da..25bc946bd4 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.7.12-next.2", + "version": "1.7.13-next.0", "backstage": { "role": "web-library", "pluginId": "search", diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 6d2bcc0418..effe205170 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-search +## 1.4.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.12 + +## 1.4.12 + +### Patch Changes + +- 4f92394: Migrate from identityApi to fetchApi in frontend plugins. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/core-compat-api@0.2.6 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-catalog-react@1.12.1 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-search-react@1.7.12 + - @backstage/frontend-plugin-api@0.6.6 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 1.4.12-next.3 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index ec5d704e87..f25bff3e26 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "1.4.12-next.3", + "version": "1.4.13-next.0", "description": "The Backstage plugin that provides your backstage app with search", "backstage": { "role": "frontend-plugin", diff --git a/plugins/signals-backend/CHANGELOG.md b/plugins/signals-backend/CHANGELOG.md index aed8136b7b..1e9c57e1da 100644 --- a/plugins/signals-backend/CHANGELOG.md +++ b/plugins/signals-backend/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-signals-backend +## 0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/plugin-signals-node@0.1.7-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.5 + +### Patch Changes + +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- 6a576dc: Replace the usage of `getVoidLogger` with `mockServices.logger.mock` in order to remove the dependency with the soon-to-be-deprecated `backend-common` package. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/plugin-events-node@0.3.5 + - @backstage/plugin-signals-node@0.1.5 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.1.5-next.3 ### Patch Changes diff --git a/plugins/signals-backend/api-report.md b/plugins/signals-backend/api-report.md index d59ca8e5ad..b85bbc4c03 100644 --- a/plugins/signals-backend/api-report.md +++ b/plugins/signals-backend/api-report.md @@ -4,7 +4,7 @@ ```ts import { AuthService } from '@backstage/backend-plugin-api'; -import { BackendFeature } from '@backstage/backend-plugin-api'; +import { BackendFeatureCompat } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { EventsService } from '@backstage/plugin-events-node'; import express from 'express'; @@ -38,7 +38,7 @@ export interface RouterOptions { } // @public -const signalsPlugin: () => BackendFeature; +const signalsPlugin: BackendFeatureCompat; export default signalsPlugin; // (No @packageDocumentation comment for this package) diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index 33fd9e5020..9501878d87 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-backend", - "version": "0.1.5-next.3", + "version": "0.1.7-next.0", "backstage": { "role": "backend-plugin", "pluginId": "signals", diff --git a/plugins/signals-node/CHANGELOG.md b/plugins/signals-node/CHANGELOG.md index 3563cbd5e2..28db4b57fa 100644 --- a/plugins/signals-node/CHANGELOG.md +++ b/plugins/signals-node/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-signals-node +## 0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-events-node@0.3.7-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.1.5 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/plugin-events-node@0.3.5 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.1.5-next.3 ### Patch Changes diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index eb40dc897a..8185c27d6b 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-node", - "version": "0.1.5-next.3", + "version": "0.1.7-next.0", "description": "Node.js library for the signals plugin", "backstage": { "role": "node-library", diff --git a/plugins/signals-react/CHANGELOG.md b/plugins/signals-react/CHANGELOG.md index 12810ba0b0..7d2af3c4d6 100644 --- a/plugins/signals-react/CHANGELOG.md +++ b/plugins/signals-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-signals-react +## 0.0.4 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + ## 0.0.4-next.1 ### Patch Changes diff --git a/plugins/signals-react/package.json b/plugins/signals-react/package.json index 7ea1bbafcd..b970c8e5dd 100644 --- a/plugins/signals-react/package.json +++ b/plugins/signals-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-react", - "version": "0.0.4-next.1", + "version": "0.0.4", "description": "Web library for the signals plugin", "backstage": { "role": "web-library", diff --git a/plugins/signals/CHANGELOG.md b/plugins/signals/CHANGELOG.md index 6c35f82895..f5992789c5 100644 --- a/plugins/signals/CHANGELOG.md +++ b/plugins/signals/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-signals +## 0.0.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + +## 0.0.7 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/types@1.1.1 + ## 0.0.7-next.2 ### Patch Changes diff --git a/plugins/signals/package.json b/plugins/signals/package.json index c19f9cd3dc..18345295b5 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals", - "version": "0.0.7-next.2", + "version": "0.0.8-next.0", "backstage": { "role": "frontend-plugin", "pluginId": "signals", diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 67c17b6e9d..93552868b9 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/plugin-techdocs@1.10.7-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/plugin-catalog@1.21.1-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/test-utils@1.5.7-next.0 + +## 1.0.33 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/plugin-techdocs@1.10.6 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-techdocs-react@1.2.5 + - @backstage/plugin-catalog-react@1.12.1 + - @backstage/plugin-search-react@1.7.12 + - @backstage/plugin-catalog@1.21.0 + - @backstage/core-app-api@1.12.6 + - @backstage/integration-react@1.1.28 + - @backstage/test-utils@1.5.6 + ## 1.0.33-next.2 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index b805b05ae7..a18bfea16f 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.33-next.2", + "version": "1.0.34-next.0", "backstage": { "role": "web-library", "pluginId": "techdocs-addons", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 05d8f1fd46..286ea77341 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/plugin-techdocs-backend +## 1.10.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.26-next.0 + - @backstage/plugin-techdocs-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/plugin-permission-common@0.7.14 + +## 1.10.6 + +### Patch Changes + +- e64bfb2: Allow defining custom build log transport for techdocs builder +- 8869b8e: Updated local development setup. +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- 2110d76: Removed `dockerode` dependency. +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-techdocs-node@1.12.5 + - @backstage/integration@1.12.0 + - @backstage/plugin-search-backend-module-techdocs@0.1.24 + - @backstage/plugin-permission-common@0.7.14 + - @backstage/plugin-catalog-common@1.0.24 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.10.6-next.3 ### Patch Changes diff --git a/plugins/techdocs-backend/api-report-alpha.md b/plugins/techdocs-backend/api-report-alpha.md index 311dafd9a8..241c1cdbd2 100644 --- a/plugins/techdocs-backend/api-report-alpha.md +++ b/plugins/techdocs-backend/api-report-alpha.md @@ -3,10 +3,10 @@ > 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 { BackendFeatureCompat } from '@backstage/backend-plugin-api'; // @alpha -const techdocsPlugin: () => BackendFeature; +const techdocsPlugin: BackendFeatureCompat; export default techdocsPlugin; // (No @packageDocumentation comment for this package) diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 1abf653784..01891b83d4 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "1.10.6-next.3", + "version": "1.10.8-next.0", "description": "The Backstage backend plugin that renders technical documentation for your components", "backstage": { "role": "backend-plugin", @@ -69,7 +69,6 @@ "@backstage/plugin-search-backend-module-techdocs": "workspace:^", "@backstage/plugin-techdocs-node": "workspace:^", "@types/express": "^4.17.6", - "dockerode": "^4.0.0", "express": "^4.17.1", "express-promise-router": "^4.1.0", "fs-extra": "^11.2.0", @@ -83,7 +82,6 @@ "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", - "@types/dockerode": "^3.3.0", "msw": "^1.0.0", "supertest": "^6.1.3" }, diff --git a/plugins/techdocs-backend/src/plugin.ts b/plugins/techdocs-backend/src/plugin.ts index 094335a0f0..fd0574fedc 100644 --- a/plugins/techdocs-backend/src/plugin.ts +++ b/plugins/techdocs-backend/src/plugin.ts @@ -16,7 +16,6 @@ import { cacheToPluginCacheManager, - DockerContainerRunner, loggerToWinstonLogger, } from '@backstage/backend-common'; import { @@ -30,13 +29,15 @@ import { PreparerBase, Preparers, Publisher, + PublisherBase, + PublisherType, RemoteProtocol, techdocsBuildsExtensionPoint, TechdocsGenerator, techdocsGeneratorExtensionPoint, techdocsPreparerExtensionPoint, + techdocsPublisherExtensionPoint, } from '@backstage/plugin-techdocs-node'; -import Docker from 'dockerode'; import { createRouter } from '@backstage/plugin-techdocs-backend'; import * as winston from 'winston'; @@ -87,6 +88,16 @@ export const techdocsPlugin = createBackendPlugin({ }, }); + let customTechdocsPublisher: PublisherBase | undefined; + env.registerExtensionPoint(techdocsPublisherExtensionPoint, { + registerPublisher(type: PublisherType, publisher: PublisherBase) { + if (customTechdocsPublisher) { + throw new Error(`Publisher for type ${type} is already registered`); + } + customTechdocsPublisher = publisher; + }, + }); + env.registerInit({ deps: { config: coreServices.rootConfig, @@ -118,14 +129,9 @@ export const techdocsPlugin = createBackendPlugin({ preparers.register(protocol, preparer); } - // Docker client (conditionally) used by the generators, based on techdocs.generators config. - const dockerClient = new Docker(); - const containerRunner = new DockerContainerRunner({ dockerClient }); - // Generators are used for generating documentation sites. const generators = await Generators.fromConfig(config, { logger: winstonLogger, - containerRunner, customGenerator: customTechdocsGenerator, }); @@ -135,6 +141,7 @@ export const techdocsPlugin = createBackendPlugin({ const publisher = await Publisher.fromConfig(config, { logger: winstonLogger, discovery: discovery, + customPublisher: customTechdocsPublisher, }); // checks if the publisher is working and logs the result diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index a5631f2492..da76210708 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/core-plugin-api@1.9.3 + +## 1.1.11 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/integration@1.12.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-techdocs-react@1.2.5 + - @backstage/integration-react@1.1.28 + ## 1.1.11-next.2 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 1b456ec300..f0b2301dfb 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", - "version": "1.1.11-next.2", + "version": "1.1.12-next.0", "description": "Plugin module for contributed TechDocs Addons", "backstage": { "role": "frontend-plugin-module", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 0c15e12faf..0093f6a1eb 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-techdocs-node +## 1.12.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.12 + +## 1.12.5 + +### Patch Changes + +- e64bfb2: Allow defining custom build log transport for techdocs builder +- 48c38f0: `TechdocsGenerator` won't require a `containerRunner` option anymore for generating TechDocs in docker. +- d44a20a: Added additional plugin metadata to `package.json`. +- 5db7536: Updated `getRepoUrlFromLocationAnnotation` to check for Harness SCM integration +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/integration@1.12.0 + - @backstage/plugin-search-common@1.2.12 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + ## 1.12.5-next.3 ### Patch Changes diff --git a/plugins/techdocs-node/api-report.md b/plugins/techdocs-node/api-report.md index 2d3ca90983..f03f9e1b0e 100644 --- a/plugins/techdocs-node/api-report.md +++ b/plugins/techdocs-node/api-report.md @@ -48,8 +48,8 @@ export type GeneratorBuilder = { // @public export type GeneratorOptions = { - containerRunner?: ContainerRunner; logger: Logger; + containerRunner?: ContainerRunner; }; // @public @@ -72,7 +72,7 @@ export class Generators implements GeneratorBuilder { config: Config, options: { logger: Logger; - containerRunner: ContainerRunner; + containerRunner?: ContainerRunner; customGenerator?: TechdocsGenerator; }, ): Promise; @@ -183,11 +183,15 @@ export class Preparers implements PreparerBuilder { } // @public -export class Publisher { +export class Publisher implements PublisherBuilder { static fromConfig( config: Config, options: PublisherFactory, ): Promise; + // (undocumented) + get(config: Config): PublisherBase; + // (undocumented) + register(type: PublisherType | 'techdocs', publisher: PublisherBase): void; } // @public @@ -202,10 +206,17 @@ export interface PublisherBase { publish(request: PublishRequest): Promise; } +// @public +export type PublisherBuilder = { + register(type: PublisherType, publisher: PublisherBase): void; + get(config: Config): PublisherBase; +}; + // @public export type PublisherFactory = { logger: Logger; discovery: PluginEndpointDiscovery; + customPublisher?: PublisherBase | undefined; }; // @public @@ -268,7 +279,7 @@ export class TechdocsGenerator implements GeneratorBase { config: Config; scmIntegrations: ScmIntegrationRegistry; }); - static readonly defaultDockerImage = 'spotify/techdocs:v1.2.3'; + static readonly defaultDockerImage = 'spotify/techdocs:v1.2.4'; static fromConfig( config: Config, options: GeneratorOptions, @@ -303,6 +314,15 @@ export interface TechdocsPreparerExtensionPoint { // @public export const techdocsPreparerExtensionPoint: ExtensionPoint; +// @public +export interface TechdocsPublisherExtensionPoint { + // (undocumented) + registerPublisher(type: PublisherType, publisher: PublisherBase): void; +} + +// @public +export const techdocsPublisherExtensionPoint: ExtensionPoint; + // @public export const transformDirLocation: ( entity: Entity, diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 7ef38c56ff..ae11fcb1df 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-node", - "version": "1.12.5-next.3", + "version": "1.12.7-next.0", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "backstage": { "role": "node-library", @@ -64,6 +64,7 @@ "@smithy/node-http-handler": "^2.1.7", "@trendyol-js/openstack-swift-sdk": "^0.0.7", "@types/express": "^4.17.6", + "dockerode": "^4.0.0", "express": "^4.17.1", "fs-extra": "^11.2.0", "git-url-parse": "^14.0.0", diff --git a/plugins/techdocs-node/src/extensions.ts b/plugins/techdocs-node/src/extensions.ts index 8e7c9ef244..c32a0d2db5 100644 --- a/plugins/techdocs-node/src/extensions.ts +++ b/plugins/techdocs-node/src/extensions.ts @@ -15,7 +15,13 @@ */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; import { DocsBuildStrategy } from './techdocsTypes'; -import { PreparerBase, RemoteProtocol, TechdocsGenerator } from './stages'; +import { + PreparerBase, + PublisherBase, + PublisherType, + RemoteProtocol, + TechdocsGenerator, +} from './stages'; import * as winston from 'winston'; /** @@ -75,3 +81,22 @@ export const techdocsPreparerExtensionPoint = createExtensionPoint({ id: 'techdocs.preparer', }); + +/** + * Extension point type for configuring a custom Techdocs publisher + * + * @public + */ +export interface TechdocsPublisherExtensionPoint { + registerPublisher(type: PublisherType, publisher: PublisherBase): void; +} + +/** + * Extension point for configuring a custom Techdocs publisher + * + * @public + */ +export const techdocsPublisherExtensionPoint = + createExtensionPoint({ + id: 'techdocs.publisher', + }); diff --git a/plugins/techdocs-node/src/index.ts b/plugins/techdocs-node/src/index.ts index b2efadf423..18f15f39ce 100644 --- a/plugins/techdocs-node/src/index.ts +++ b/plugins/techdocs-node/src/index.ts @@ -27,7 +27,9 @@ export { techdocsBuildsExtensionPoint, techdocsGeneratorExtensionPoint, techdocsPreparerExtensionPoint, + techdocsPublisherExtensionPoint, type TechdocsBuildsExtensionPoint, type TechdocsGeneratorExtensionPoint, type TechdocsPreparerExtensionPoint, + type TechdocsPublisherExtensionPoint, } from './extensions'; diff --git a/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.test.ts b/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.test.ts new file mode 100644 index 0000000000..4a9e364af3 --- /dev/null +++ b/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.test.ts @@ -0,0 +1,218 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fs from 'fs-extra'; +import Stream, { PassThrough } from 'stream'; +import { DockerContainerRunner, UserOptions } from './DockerContainerRunner'; +import { createMockDirectory } from '@backstage/backend-test-utils'; + +const mockPull = jest.fn(); +const mockRun = jest.fn(); +const mockPing = jest.fn(); + +jest.mock( + 'dockerode', + () => + function MockDocker() { + return { + pull: mockPull, + run: mockRun, + ping: mockPing, + }; + }, +); + +describe('DockerContainerRunner', () => { + let containerTaskApi: DockerContainerRunner; + + const inputDir = createMockDirectory(); + const outputDir = createMockDirectory(); + + beforeEach(() => { + inputDir.clear(); + outputDir.clear(); + + mockPull.mockImplementation( + ( + _repoTag: string, + _options: {}, + callback: (error?: any, result?: any) => void, + ) => { + const mockStream = new PassThrough(); + callback(undefined, mockStream); + mockStream.end(); + }, + ); + mockRun.mockResolvedValue([{ Error: null, StatusCode: 0 }]); + mockPing.mockResolvedValue(Buffer.from('OK', 'utf-8')); + + containerTaskApi = new DockerContainerRunner(); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + const imageName = 'dockerorg/image'; + const args = ['bash', '-c', 'echo test']; + const mountDirs = { + [inputDir.path]: '/input', + [outputDir.path]: '/output', + }; + const workingDir = inputDir.path; + const envVars = { HOME: '/tmp', LOG_LEVEL: 'debug' }; + const envVarsArray = ['HOME=/tmp', 'LOG_LEVEL=debug']; + + it('should pull the docker container', async () => { + await containerTaskApi.runContainer({ + imageName, + args, + }); + + expect(mockPull).toHaveBeenCalledWith(imageName, {}, expect.any(Function)); + + expect(mockRun).toHaveBeenCalled(); + }); + + it('should not pull the docker container when pullImage is false', async () => { + await containerTaskApi.runContainer({ + imageName, + args, + pullImage: false, + }); + + expect(mockPull).not.toHaveBeenCalled(); + expect(mockRun).toHaveBeenCalled(); + }); + + it('should call the dockerClient run command with the correct arguments passed through', async () => { + await containerTaskApi.runContainer({ + imageName, + args, + mountDirs, + envVars, + workingDir, + }); + + expect(mockRun).toHaveBeenCalledWith( + imageName, + args, + expect.any(Stream), + expect.objectContaining({ + Env: envVarsArray, + WorkingDir: workingDir, + HostConfig: { + AutoRemove: true, + Binds: expect.arrayContaining([ + `${await fs.realpath(inputDir.path)}:/input`, + `${await fs.realpath(outputDir.path)}:/output`, + ]), + }, + Volumes: { + '/input': {}, + '/output': {}, + }, + }), + ); + }); + + it('should ping docker to test availability', async () => { + await containerTaskApi.runContainer({ + imageName, + args, + }); + + expect(mockPing).toHaveBeenCalled(); + }); + + it('should pass through the user and group id from the host machine and set the home dir', async () => { + await containerTaskApi.runContainer({ + imageName, + args, + }); + + const userOptions: UserOptions = {}; + if (process.getuid && process.getgid) { + userOptions.User = `${process.getuid()}:${process.getgid()}`; + } + + expect(mockRun).toHaveBeenCalledWith( + imageName, + args, + expect.any(Stream), + expect.objectContaining({ + ...userOptions, + }), + ); + }); + + it('throws a correct error if the command fails in docker', async () => { + mockRun.mockResolvedValueOnce([ + { + Error: new Error('Something went wrong with docker'), + StatusCode: 0, + }, + ]); + + await expect( + containerTaskApi.runContainer({ + imageName, + args, + }), + ).rejects.toThrow(/Something went wrong with docker/); + }); + + describe('where docker is unavailable', () => { + const dockerError = 'a docker error'; + + beforeEach(() => { + mockPing.mockImplementationOnce(() => { + throw new Error(dockerError); + }); + }); + + it('should throw with a descriptive error message including the docker error message', async () => { + await expect( + containerTaskApi.runContainer({ + imageName, + args, + }), + ).rejects.toThrow(new RegExp(`.+: ${dockerError}`)); + }); + }); + + it('should pass through the log stream to the docker client', async () => { + const logStream = new PassThrough(); + await containerTaskApi.runContainer({ + imageName, + args, + logStream, + }); + + expect(mockRun).toHaveBeenCalledWith( + imageName, + args, + logStream, + expect.objectContaining({ + HostConfig: { + AutoRemove: true, + Binds: [], + }, + Volumes: {}, + }), + ); + }); +}); diff --git a/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts b/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts new file mode 100644 index 0000000000..b7cb7f1c86 --- /dev/null +++ b/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts @@ -0,0 +1,145 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Docker from 'dockerode'; +import fs from 'fs-extra'; +import { ForwardedError } from '@backstage/errors'; +import { PassThrough } from 'stream'; +import { pipeline as pipelineStream } from 'stream'; +import { promisify } from 'util'; +import { Writable } from 'stream'; + +const pipeline = promisify(pipelineStream); + +export type UserOptions = { + User?: string; +}; + +/** + * @internal + */ +export class DockerContainerRunner { + private readonly dockerClient: Docker; + + constructor() { + this.dockerClient = new Docker(); + } + + async runContainer(options: { + imageName: string; + command?: string | string[]; + args: string[]; + logStream?: Writable; + mountDirs?: Record; + workingDir?: string; + envVars?: Record; + pullImage?: boolean; + defaultUser?: boolean; + }) { + const { + imageName, + command, + args, + logStream = new PassThrough(), + mountDirs = {}, + workingDir, + envVars = {}, + pullImage = true, + defaultUser = false, + } = options; + + // Show a better error message when Docker is unavailable. + try { + await this.dockerClient.ping(); + } catch (e) { + throw new ForwardedError( + 'This operation requires Docker. Docker does not appear to be available. Docker.ping() failed with', + e, + ); + } + + if (pullImage) { + await new Promise((resolve, reject) => { + this.dockerClient.pull(imageName, {}, (err, stream) => { + if (err) { + reject(err); + return; + } + + pipeline(stream, logStream, { end: false }) + .then(resolve) + .catch(reject); + }); + }); + } + + const userOptions: UserOptions = {}; + if (!defaultUser && process.getuid && process.getgid) { + // Files that are created inside the Docker container will be owned by + // root on the host system on non Mac systems, because of reasons. Mainly the fact that + // volume sharing is done using NFS on Mac and actual mounts in Linux world. + // So we set the user in the container as the same user and group id as the host. + // On Windows we don't have process.getuid nor process.getgid + userOptions.User = `${process.getuid()}:${process.getgid()}`; + } + + // Initialize volumes to mount based on mountDirs map + const Volumes: { [T: string]: object } = {}; + for (const containerDir of Object.values(mountDirs)) { + Volumes[containerDir] = {}; + } + + // Create bind volumes + const Binds: string[] = []; + for (const [hostDir, containerDir] of Object.entries(mountDirs)) { + // Need to use realpath here as Docker mounting does not like + // symlinks for binding volumes + const realHostDir = await fs.realpath(hostDir); + Binds.push(`${realHostDir}:${containerDir}`); + } + + // Create docker environment variables array + const Env = []; + for (const [key, value] of Object.entries(envVars)) { + Env.push(`${key}=${value}`); + } + + const [{ Error: error, StatusCode: statusCode }] = + await this.dockerClient.run(imageName, args, logStream, { + Volumes, + HostConfig: { + AutoRemove: true, + Binds, + }, + ...(workingDir ? { WorkingDir: workingDir } : {}), + Entrypoint: command, + Env, + ...userOptions, + } as Docker.ContainerCreateOptions); + + if (error) { + throw new Error( + `Docker failed to run with the following error message: ${error}`, + ); + } + + if (statusCode !== 0) { + throw new Error( + `Docker container returned a non-zero exit code (${statusCode})`, + ); + } + } +} diff --git a/plugins/techdocs-node/src/stages/generate/generators.test.ts b/plugins/techdocs-node/src/stages/generate/generators.test.ts index 3e0571af54..f80f070796 100644 --- a/plugins/techdocs-node/src/stages/generate/generators.test.ts +++ b/plugins/techdocs-node/src/stages/generate/generators.test.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - ContainerRunner, - loggerToWinstonLogger, -} from '@backstage/backend-common'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { Generators } from './generators'; import { TechdocsGenerator } from './techdocs'; @@ -34,10 +31,6 @@ const mockEntity = { }; describe('generators', () => { - const containerRunner: jest.Mocked = { - runContainer: jest.fn(), - }; - it('should return error if no generator is registered', async () => { const generators = new Generators(); @@ -50,7 +43,6 @@ describe('generators', () => { const generators = new Generators(); const techdocs = TechdocsGenerator.fromConfig(new ConfigReader({}), { logger, - containerRunner, }); generators.register('techdocs', techdocs); diff --git a/plugins/techdocs-node/src/stages/generate/generators.ts b/plugins/techdocs-node/src/stages/generate/generators.ts index 603c714370..0c20ac1588 100644 --- a/plugins/techdocs-node/src/stages/generate/generators.ts +++ b/plugins/techdocs-node/src/stages/generate/generators.ts @@ -42,7 +42,7 @@ export class Generators implements GeneratorBuilder { config: Config, options: { logger: Logger; - containerRunner: ContainerRunner; + containerRunner?: ContainerRunner; customGenerator?: TechdocsGenerator; }, ): Promise { diff --git a/plugins/techdocs-node/src/stages/generate/techdocs.ts b/plugins/techdocs-node/src/stages/generate/techdocs.ts index c5130a3f8f..599457ee5a 100644 --- a/plugins/techdocs-node/src/stages/generate/techdocs.ts +++ b/plugins/techdocs-node/src/stages/generate/techdocs.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { ContainerRunner } from '@backstage/backend-common'; import { Config } from '@backstage/config'; import path from 'path'; import { Logger } from 'winston'; @@ -43,6 +42,8 @@ import { GeneratorRunOptions, } from './types'; import { ForwardedError } from '@backstage/errors'; +import { DockerContainerRunner } from './DockerContainerRunner'; +import { ContainerRunner } from '@backstage/backend-common'; /** * Generates documentation files @@ -53,7 +54,7 @@ export class TechdocsGenerator implements GeneratorBase { * The default docker image (and version) used to generate content. Public * and static so that techdocs-node consumers can use the same version. */ - public static readonly defaultDockerImage = 'spotify/techdocs:v1.2.3'; + public static readonly defaultDockerImage = 'spotify/techdocs:v1.2.4'; private readonly logger: Logger; private readonly containerRunner?: ContainerRunner; private readonly options: GeneratorConfig; @@ -155,13 +156,10 @@ export class TechdocsGenerator implements GeneratorBase { `Successfully generated docs from ${inputDir} into ${outputDir} using local mkdocs`, ); break; - case 'docker': - if (this.containerRunner === undefined) { - throw new Error( - "Invalid state: containerRunner cannot be undefined when runIn is 'docker'", - ); - } - await this.containerRunner.runContainer({ + case 'docker': { + const containerRunner = + this.containerRunner || new DockerContainerRunner(); + await containerRunner.runContainer({ imageName: this.options.dockerImage ?? TechdocsGenerator.defaultDockerImage, args: ['build', '-d', '/output'], @@ -178,6 +176,7 @@ export class TechdocsGenerator implements GeneratorBase { `Successfully generated docs from ${inputDir} into ${outputDir} using techdocs-container`, ); break; + } default: throw new Error( `Invalid config value "${this.options.runIn}" provided in 'techdocs.generators.techdocs'.`, diff --git a/plugins/techdocs-node/src/stages/generate/types.ts b/plugins/techdocs-node/src/stages/generate/types.ts index 149c3c2195..ca816d560f 100644 --- a/plugins/techdocs-node/src/stages/generate/types.ts +++ b/plugins/techdocs-node/src/stages/generate/types.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { ContainerRunner } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { Writable } from 'stream'; import { Logger } from 'winston'; import { ParsedLocationAnnotation } from '../../helpers'; +import { ContainerRunner } from '@backstage/backend-common'; // Determines where the generator will be run export type GeneratorRunInType = 'docker' | 'local'; @@ -28,8 +28,12 @@ export type GeneratorRunInType = 'docker' | 'local'; * @public */ export type GeneratorOptions = { - containerRunner?: ContainerRunner; logger: Logger; + /** + * @deprecated containerRunner is now instantiated in + * the generator and this option will be removed in the future + */ + containerRunner?: ContainerRunner; }; /** diff --git a/plugins/techdocs-node/src/stages/publish/index.ts b/plugins/techdocs-node/src/stages/publish/index.ts index c6f86f6bc1..f342ccf0ae 100644 --- a/plugins/techdocs-node/src/stages/publish/index.ts +++ b/plugins/techdocs-node/src/stages/publish/index.ts @@ -23,4 +23,5 @@ export type { MigrateRequest, ReadinessResponse, TechDocsMetadata, + PublisherBuilder, } from './types'; diff --git a/plugins/techdocs-node/src/stages/publish/publish.test.ts b/plugins/techdocs-node/src/stages/publish/publish.test.ts index 4059eccfeb..0063839e2f 100644 --- a/plugins/techdocs-node/src/stages/publish/publish.test.ts +++ b/plugins/techdocs-node/src/stages/publish/publish.test.ts @@ -25,6 +25,7 @@ import { AwsS3Publish } from './awsS3'; import { AzureBlobStoragePublish } from './azureBlobStorage'; import { OpenStackSwiftPublish } from './openStackSwift'; import { mockServices } from '@backstage/backend-test-utils'; +import { PublisherBase } from './types'; const logger = loggerToWinstonLogger(mockServices.logger.mock()); const discovery: jest.Mocked = { @@ -184,4 +185,20 @@ describe('Publisher', () => { }); expect(publisher).toBeInstanceOf(OpenStackSwiftPublish); }); + + it('registers a custom publisher if provided', async () => { + const mockConfig = new ConfigReader({}); + + const customPublisher = { + publish: jest.fn(), + } as unknown as PublisherBase; + + const publisher = await Publisher.fromConfig(mockConfig, { + logger, + discovery, + customPublisher, + }); + + expect(publisher).toBe(customPublisher); + }); }); diff --git a/plugins/techdocs-node/src/stages/publish/publish.ts b/plugins/techdocs-node/src/stages/publish/publish.ts index 732b161b42..09a6d9b375 100644 --- a/plugins/techdocs-node/src/stages/publish/publish.ts +++ b/plugins/techdocs-node/src/stages/publish/publish.ts @@ -20,14 +20,45 @@ import { AzureBlobStoragePublish } from './azureBlobStorage'; import { GoogleGCSPublish } from './googleStorage'; import { LocalPublish } from './local'; import { OpenStackSwiftPublish } from './openStackSwift'; -import { PublisherFactory, PublisherBase, PublisherType } from './types'; +import { + PublisherFactory, + PublisherBase, + PublisherType, + PublisherBuilder, +} from './types'; /** * Factory class to create a TechDocs publisher based on defined publisher type in app config. * Uses `techdocs.publisher.type`. * @public */ -export class Publisher { +export class Publisher implements PublisherBuilder { + private publishers: Map = + new Map(); + + register(type: PublisherType | 'techdocs', publisher: PublisherBase): void { + this.publishers.set(type, publisher); + } + + get(config: Config): PublisherBase { + const publisherType = (config.getOptionalString( + 'techdocs.publisher.type', + ) ?? 'local') as PublisherType; + + if (!publisherType) { + throw new Error('TechDocs publisher type not specified for the entity'); + } + + const publisher = this.publishers.get(publisherType); + if (!publisher) { + throw new Error( + `TechDocs publisher '${publisherType}' is not registered`, + ); + } + + return publisher; + } + /** * Returns a instance of TechDocs publisher * @param config - A Backstage configuration @@ -37,7 +68,14 @@ export class Publisher { config: Config, options: PublisherFactory, ): Promise { - const { logger, discovery } = options; + const { logger, discovery, customPublisher } = options; + + const publishers = new Publisher(); + + if (customPublisher) { + publishers.register('techdocs', customPublisher); + return customPublisher; + } const publisherType = (config.getOptionalString( 'techdocs.publisher.type', @@ -46,26 +84,51 @@ export class Publisher { switch (publisherType) { case 'googleGcs': logger.info('Creating Google Storage Bucket publisher for TechDocs'); - return GoogleGCSPublish.fromConfig(config, logger); + publishers.register( + publisherType, + GoogleGCSPublish.fromConfig(config, logger), + ); + break; case 'awsS3': logger.info('Creating AWS S3 Bucket publisher for TechDocs'); - return await AwsS3Publish.fromConfig(config, logger); + publishers.register( + publisherType, + await AwsS3Publish.fromConfig(config, logger), + ); + break; case 'azureBlobStorage': logger.info( 'Creating Azure Blob Storage Container publisher for TechDocs', ); - return AzureBlobStoragePublish.fromConfig(config, logger); + publishers.register( + publisherType, + AzureBlobStoragePublish.fromConfig(config, logger), + ); + break; case 'openStackSwift': logger.info( 'Creating OpenStack Swift Container publisher for TechDocs', ); - return OpenStackSwiftPublish.fromConfig(config, logger); + publishers.register( + publisherType, + OpenStackSwiftPublish.fromConfig(config, logger), + ); + break; case 'local': logger.info('Creating Local publisher for TechDocs'); - return LocalPublish.fromConfig(config, logger, discovery); + publishers.register( + publisherType, + LocalPublish.fromConfig(config, logger, discovery), + ); + break; default: logger.info('Creating Local publisher for TechDocs'); - return LocalPublish.fromConfig(config, logger, discovery); + publishers.register( + publisherType, + LocalPublish.fromConfig(config, logger, discovery), + ); } + + return publishers.get(config); } } diff --git a/plugins/techdocs-node/src/stages/publish/types.ts b/plugins/techdocs-node/src/stages/publish/types.ts index ff5b9acade..3acd48a468 100644 --- a/plugins/techdocs-node/src/stages/publish/types.ts +++ b/plugins/techdocs-node/src/stages/publish/types.ts @@ -17,6 +17,7 @@ import { Entity, CompoundEntityRef } from '@backstage/catalog-model'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { Logger } from 'winston'; import express from 'express'; +import { Config } from '@backstage/config'; /** * Options for building publishers @@ -25,6 +26,7 @@ import express from 'express'; export type PublisherFactory = { logger: Logger; discovery: PluginEndpointDiscovery; + customPublisher?: PublisherBase | undefined; }; /** @@ -157,3 +159,12 @@ export interface PublisherBase { */ migrateDocsCase?(migrateRequest: MigrateRequest): Promise; } + +/** + * Definition for a TechDocs publisher builder + * @public + */ +export type PublisherBuilder = { + register(type: PublisherType, publisher: PublisherBase): void; + get(config: Config): PublisherBase; +}; diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 8a681308d5..d07ed27eb0 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-techdocs-react +## 1.2.6-next.0 + +### Patch Changes + +- 8ac9ce5: Fixed a bug with the TechDocsReaderPageProvider not re-rendering when setShadowDom is called, meaning that the useShadowDom hooks were inconsistent. This issue caused the TextSize addon changes not to reapply during navigation. +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/version-bridge@1.0.8 + +## 1.2.5 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/version-bridge@1.0.8 + ## 1.2.5-next.2 ### Patch Changes diff --git a/plugins/techdocs-react/api-report.md b/plugins/techdocs-react/api-report.md index c158bbd81e..7d787c4da6 100644 --- a/plugins/techdocs-react/api-report.md +++ b/plugins/techdocs-react/api-report.md @@ -116,6 +116,8 @@ export type TechDocsReaderPageValue = { entityMetadata: AsyncState; shadowRoot?: ShadowRoot; setShadowRoot: Dispatch>; + shadowRootVersion: number; + incShadowRootVersion: () => void; title: string; setTitle: Dispatch>; subtitle: string; diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 233ec010bc..d002db68d1 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-react", - "version": "1.2.5-next.2", + "version": "1.2.6-next.0", "description": "Shared frontend utilities for TechDocs and Addons", "backstage": { "role": "web-library", diff --git a/plugins/techdocs-react/src/context.tsx b/plugins/techdocs-react/src/context.tsx index 43fdada98e..2e7cd9586d 100644 --- a/plugins/techdocs-react/src/context.tsx +++ b/plugins/techdocs-react/src/context.tsx @@ -25,6 +25,7 @@ import React, { } from 'react'; import useAsync, { AsyncState } from 'react-use/esm/useAsync'; import useAsyncRetry from 'react-use/esm/useAsyncRetry'; +import useCounter from 'react-use/esm/useCounter'; import { CompoundEntityRef, @@ -64,6 +65,8 @@ export type TechDocsReaderPageValue = { entityMetadata: AsyncState; shadowRoot?: ShadowRoot; setShadowRoot: Dispatch>; + shadowRootVersion: number; + incShadowRootVersion: () => void; title: string; setTitle: Dispatch>; subtitle: string; @@ -80,6 +83,8 @@ const defaultTechDocsReaderPageValue: TechDocsReaderPageValue = { setTitle: () => {}, setSubtitle: () => {}, setShadowRoot: () => {}, + shadowRootVersion: 0, + incShadowRootVersion: () => {}, metadata: { loading: true }, entityMetadata: { loading: true }, entityRef: { kind: '', name: '', namespace: '' }, @@ -134,6 +139,7 @@ export const TechDocsReaderPageProvider = memo( const [shadowRoot, setShadowRoot] = useState( defaultTechDocsReaderPageValue.shadowRoot, ); + const [shadowRootVersion, { inc: incShadowRootVersion }] = useCounter(0); useEffect(() => { if (shadowRoot && !metadata.value && !metadata.loading) { @@ -153,6 +159,8 @@ export const TechDocsReaderPageProvider = memo( entityMetadata, shadowRoot, setShadowRoot, + shadowRootVersion, + incShadowRootVersion, title, setTitle, subtitle, @@ -190,6 +198,5 @@ export const useTechDocsReaderPage = () => { if (context === undefined) { throw new Error('No context found for version 1.'); } - return context; }; diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 4065b4f341..fd35205da8 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,54 @@ # @backstage/plugin-techdocs +## 1.10.7-next.0 + +### Patch Changes + +- 8ac9ce5: Fixed a bug with the TechDocsReaderPageProvider not re-rendering when setShadowDom is called, meaning that the useShadowDom hooks were inconsistent. This issue caused the TextSize addon changes not to reapply during navigation. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/plugin-search-common@1.2.12 + +## 1.10.6 + +### Patch Changes + +- 654af4a: mkdocs-material have updated their CSS variable template, and a few are unset in Backstage. This patch adds the missing variables to ensure coverage. +- cbebad1: Internal updates to allow reusing Backstage's `fetchApi` implementation for event source requests. This allows you to for example, override the `Authorization` header. +- 96cd13e: `TechDocsIndexPage` now accepts an optional `ownerPickerMode` for toggling the behavior of the `EntityOwnerPicker`, exposing a new mode `` particularly suitable for larger catalogs. In this new mode, `EntityOwnerPicker` will display all the users and groups present in the catalog. +- e40bd9a: Fixed bug in `CopyToClipboardButton` component where positioning of the "Copy to clipboard" button in techdocs code snippets was broken in some cases. +- d44a20a: Added additional plugin metadata to `package.json`. +- 1256d88: Fixed an issue preventing the `TechDocsSearchBar` component from opening when clicking on the arrow icon. +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/core-compat-api@0.2.6 + - @backstage/integration@1.12.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-react@1.2.5 + - @backstage/plugin-catalog-react@1.12.1 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-search-react@1.7.12 + - @backstage/plugin-auth-react@0.1.3 + - @backstage/integration-react@1.1.28 + - @backstage/frontend-plugin-api@0.6.6 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 1.10.6-next.2 ### Patch Changes diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 2ec4ff38f0..8212246aab 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "1.10.6-next.2", + "version": "1.10.7-next.0", "description": "The Backstage plugin that renders technical documentation for your components", "backstage": { "role": "frontend-plugin", diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx index 3692ed22d3..00df73cab3 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/TechDocsReaderPageContent.tsx @@ -80,6 +80,7 @@ export const TechDocsReaderPageContent = withTechDocsReaderProvider( entityMetadata: { value: entityMetadata, loading: entityMetadataLoading }, entityRef, setShadowRoot, + incShadowRootVersion, } = useTechDocsReaderPage(); const dom = useTechDocsReaderDom(entityRef); const path = window.location.pathname; @@ -102,11 +103,12 @@ export const TechDocsReaderPageContent = withTechDocsReaderProvider( const handleAppend = useCallback( (newShadowRoot: ShadowRoot) => { setShadowRoot(newShadowRoot); + incShadowRootVersion(); if (onReady instanceof Function) { onReady(); } }, - [setShadowRoot, onReady], + [setShadowRoot, incShadowRootVersion, onReady], ); // No entity metadata = 404. Don't render content at all. diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts index d78f8222f8..78b73cb52a 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts @@ -74,6 +74,7 @@ export default ({ theme, sidebar }: RuleOptions) => ` } .md-sidebar .md-sidebar__scrollwrap { width: calc(12.1rem); + overflow-y: hidden; } .md-sidebar--secondary { right: ${theme.spacing(3)}px; @@ -234,7 +235,7 @@ export default ({ theme, sidebar }: RuleOptions) => ` #toggle-sidebar { display: none; } - + .md-content { margin: 0; width: 100%; diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index bddd6f9fb3..cbd2ab7536 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-user-settings-backend +## 0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.21-next.0 + - @backstage/backend-common@0.23.2-next.0 + - @backstage/plugin-auth-node@0.4.16-next.0 + - @backstage/plugin-signals-node@0.1.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.2.18 + +### Patch Changes + +- 8869b8e: Updated local development setup. +- 78a0b08: Internal refactor to handle `BackendFeature` contract change. +- d44a20a: Added additional plugin metadata to `package.json`. +- e6ec179: Use signals to update user settings across sessions +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/backend-plugin-api@0.6.19 + - @backstage/plugin-auth-node@0.4.14 + - @backstage/plugin-user-settings-common@0.0.1 + - @backstage/plugin-signals-node@0.1.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.18-next.3 ### Patch Changes diff --git a/plugins/user-settings-backend/api-report-alpha.md b/plugins/user-settings-backend/api-report-alpha.md index aa6b246616..d4b15a5717 100644 --- a/plugins/user-settings-backend/api-report-alpha.md +++ b/plugins/user-settings-backend/api-report-alpha.md @@ -3,10 +3,10 @@ > 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 { BackendFeatureCompat } from '@backstage/backend-plugin-api'; // @alpha -const _default: () => BackendFeature; +const _default: BackendFeatureCompat; export default _default; // (No @packageDocumentation comment for this package) diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index e08e63ad05..d8dc0770a5 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings-backend", - "version": "0.2.18-next.3", + "version": "0.2.20-next.0", "description": "The Backstage backend plugin to manage user settings", "backstage": { "role": "backend-plugin", diff --git a/plugins/user-settings-common/CHANGELOG.md b/plugins/user-settings-common/CHANGELOG.md index 768c2af894..652a308252 100644 --- a/plugins/user-settings-common/CHANGELOG.md +++ b/plugins/user-settings-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/plugin-user-settings-common +## 0.0.1 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- e6ec179: Use signals to update user settings across sessions + ## 0.0.1-next.0 ### Patch Changes diff --git a/plugins/user-settings-common/package.json b/plugins/user-settings-common/package.json index f9a6b32d93..82c5db84f1 100644 --- a/plugins/user-settings-common/package.json +++ b/plugins/user-settings-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings-common", - "version": "0.0.1-next.0", + "version": "0.0.1", "description": "Common functionalities for the user-settings plugin", "backstage": { "role": "common-library", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index e373503785..20ef229a2d 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-user-settings +## 0.8.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-app-api@1.13.0-next.0 + - @backstage/plugin-catalog-react@1.12.2-next.0 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.8.7 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- e6ec179: Use signals to update user settings across sessions +- Updated dependencies + - @backstage/core-components@0.14.8 + - @backstage/core-compat-api@0.2.6 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-user-settings-common@0.0.1 + - @backstage/plugin-catalog-react@1.12.1 + - @backstage/plugin-signals-react@0.0.4 + - @backstage/core-app-api@1.12.6 + - @backstage/frontend-plugin-api@0.6.6 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.8.7-next.2 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 1d2fd3131c..3257de8072 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings", - "version": "0.8.7-next.2", + "version": "0.8.8-next.0", "description": "A Backstage plugin that provides a settings page", "backstage": { "role": "frontend-plugin", diff --git a/yarn.lock b/yarn.lock index 9513149eaa..6f4f365ea1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -385,69 +385,58 @@ __metadata: languageName: node linkType: hard -"@aws-crypto/crc32c@npm:3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/crc32c@npm:3.0.0" +"@aws-crypto/crc32@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/crc32@npm:5.2.0" dependencies: - "@aws-crypto/util": ^3.0.0 + "@aws-crypto/util": ^5.2.0 "@aws-sdk/types": ^3.222.0 - tslib: ^1.11.1 - checksum: 0a116b5d1c5b09a3dde65aab04a07b32f543e87b68f2d175081e3f4a1a17502343f223d691dd883ace1ddce65cd40093673e7c7415dcd99062202ba87ffb4038 + tslib: ^2.6.2 + checksum: 1ddf7ec3fccf106205ff2476d90ae1d6625eabd47752f689c761b71e41fe451962b7a1c9ed25fe54e17dd747a62fbf4de06030fe56fe625f95285f6f70b96c57 languageName: node linkType: hard -"@aws-crypto/ie11-detection@npm:^3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/ie11-detection@npm:3.0.0" +"@aws-crypto/crc32c@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/crc32c@npm:5.2.0" dependencies: - tslib: ^1.11.1 - checksum: 299b2ddd46eddac1f2d54d91386ceb37af81aef8a800669281c73d634ed17fd855dcfb8b3157f2879344b93a2666a6d602550eb84b71e4d7868100ad6da8f803 + "@aws-crypto/util": ^5.2.0 + "@aws-sdk/types": ^3.222.0 + tslib: ^2.6.2 + checksum: 0b399de8607c59e1e46c05d2b24a16b56d507944fdac925c611f0ba7302f5555c098139806d7da1ebef1f89bf4e4b5d4dec74d4809ce0f18238b72072065effe languageName: node linkType: hard -"@aws-crypto/sha1-browser@npm:3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/sha1-browser@npm:3.0.0" +"@aws-crypto/sha1-browser@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/sha1-browser@npm:5.2.0" dependencies: - "@aws-crypto/ie11-detection": ^3.0.0 - "@aws-crypto/supports-web-crypto": ^3.0.0 - "@aws-crypto/util": ^3.0.0 + "@aws-crypto/supports-web-crypto": ^5.2.0 + "@aws-crypto/util": ^5.2.0 "@aws-sdk/types": ^3.222.0 "@aws-sdk/util-locate-window": ^3.0.0 - "@aws-sdk/util-utf8-browser": ^3.0.0 - tslib: ^1.11.1 - checksum: 78c379e105a0c4e7b2ed745dffd8f55054d7dde8b350b61de682bbc3cd081a50e2f87861954fa9cd53c7ea711ebca1ca0137b14cb36483efc971f60f573cf129 + "@smithy/util-utf8": ^2.0.0 + tslib: ^2.6.2 + checksum: 8b04af601d945c5ef0f5f733b55681edc95b81c02ce5067b57f1eb4ee718e45485cf9aeeb7a84da9131656d09e1c4bc78040ec759f557a46703422d8df098d59 languageName: node linkType: hard -"@aws-crypto/sha256-browser@npm:3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/sha256-browser@npm:3.0.0" +"@aws-crypto/sha256-browser@npm:5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/sha256-browser@npm:5.2.0" dependencies: - "@aws-crypto/ie11-detection": ^3.0.0 - "@aws-crypto/sha256-js": ^3.0.0 - "@aws-crypto/supports-web-crypto": ^3.0.0 - "@aws-crypto/util": ^3.0.0 + "@aws-crypto/sha256-js": ^5.2.0 + "@aws-crypto/supports-web-crypto": ^5.2.0 + "@aws-crypto/util": ^5.2.0 "@aws-sdk/types": ^3.222.0 "@aws-sdk/util-locate-window": ^3.0.0 - "@aws-sdk/util-utf8-browser": ^3.0.0 - tslib: ^1.11.1 - checksum: ca89456bf508db2e08060a7f656460db97ac9a15b11e39d6fa7665e2b156508a1758695bff8e82d0a00178d6ac5c36f35eb4bcfac2e48621265224ca14a19bd2 + "@smithy/util-utf8": ^2.0.0 + tslib: ^2.6.2 + checksum: 773f12f2026d82a6bb4a23a8f491894a6d32525bd9b8bfbc12896526cf11882a7607a671c478c45f9cd7d6ba1caaed48a62b67c6f725244bd83a1275108f46c7 languageName: node linkType: hard -"@aws-crypto/sha256-js@npm:3.0.0, @aws-crypto/sha256-js@npm:^3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/sha256-js@npm:3.0.0" - dependencies: - "@aws-crypto/util": ^3.0.0 - "@aws-sdk/types": ^3.222.0 - tslib: ^1.11.1 - checksum: 644ded32ea310237811afae873d3c7320739cb6f6cc39dced9c94801379e68e5ee2cca0c34f0384793fa9e750a7e0a5e2468f95754bd08e6fd72ab833c8fe23c - languageName: node - linkType: hard - -"@aws-crypto/sha256-js@npm:^5.0.0": +"@aws-crypto/sha256-js@npm:5.2.0, @aws-crypto/sha256-js@npm:^5.0.0, @aws-crypto/sha256-js@npm:^5.2.0": version: 5.2.0 resolution: "@aws-crypto/sha256-js@npm:5.2.0" dependencies: @@ -458,12 +447,12 @@ __metadata: languageName: node linkType: hard -"@aws-crypto/supports-web-crypto@npm:^3.0.0": - version: 3.0.0 - resolution: "@aws-crypto/supports-web-crypto@npm:3.0.0" +"@aws-crypto/supports-web-crypto@npm:^5.2.0": + version: 5.2.0 + resolution: "@aws-crypto/supports-web-crypto@npm:5.2.0" dependencies: - tslib: ^1.11.1 - checksum: 35479a1558db9e9a521df6877a99f95670e972c602f2a0349303477e5d638a5baf569fb037c853710e382086e6fd77e8ed58d3fb9b49f6e1186a9d26ce7be006 + tslib: ^2.6.2 + checksum: 6ffc21de48b2b2c3e918193101d7e8fe949d47b37688892e1c39eaedaa938be80c0f404fe1c874c30cce16781026777a53bf47d5d90143ca91d0feb7c4a6f830 languageName: node linkType: hard @@ -500,665 +489,674 @@ __metadata: linkType: hard "@aws-sdk/client-codecommit@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-codecommit@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-codecommit@npm:3.600.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 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 09a7393ba36cf0eaf527041580e468b62346634768ee1ced243e5e894d6a532f96332642ddc1965c9e2078cbe4183c84bc6003a427a05e6ea781ceff5c143e0d + checksum: 1a8197ffcf74b27a4b6159d8b4923db0f5c27b3d5daacb321ef956c49b0250800ce904c1c03264c67366c14244a8ba7a067849700b382979da19f7bc4c20a3fd 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" +"@aws-sdk/client-cognito-identity@npm:3.600.0": + version: 3.600.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.600.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 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 964ee562d41df0fc3d71a739ef86846dddbfa8742df74831926dd629de0111ace69faed4869d9b7a50cd5eb8d2c1ac09da2126b7071e9d69f8ba8e8d85d24323 + checksum: ad01c387061da6d46767e209f3d422281e6af97d60ed61af687980990c7600ecbd88e2f430d975f029648d4475bf84234f710f4099edd2d61f90fef3444ee4a0 languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-eks@npm:3.556.0" + version: 3.605.0 + resolution: "@aws-sdk/client-eks@npm:3.605.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 - "@smithy/util-waiter": ^2.2.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 + "@smithy/util-waiter": ^3.0.1 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: c36a0f23d3f01ed9fcbeec286b5e919cacc2ecb0bb3e880844e9b84018d81935c4b8f3dc33a3392c808a6e001659f5ca0c99889d830491c48040b9df3d474cc8 + checksum: 6cd87756d631fd18b12d21a89a938612ba17446cdc1de06c3c3a0ee488ffd8c9de4af3d27567524eb0e17155d423394e374002cb5a45d4376df6d82255abe870 languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-organizations@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-organizations@npm:3.600.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 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: e747d1f2f75a9985944765ac920408bffe5fc79dfb700c56b1633fec4e6f480b9568e30f72a6c80f09dcb7998480f158fa5c40646e8af4fed4a68e694d78c4f8 + checksum: b403a51e298fec8ec93553ac8a22a452408b0634b3a01d6c61ce271d7af69b1cef8907a9dce31fad79fa2cfc01fd6912d848e9b656b7a16f973e986b00bd727c languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-s3@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-s3@npm:3.600.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.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 + "@aws-crypto/sha1-browser": 5.2.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-bucket-endpoint": 3.598.0 + "@aws-sdk/middleware-expect-continue": 3.598.0 + "@aws-sdk/middleware-flexible-checksums": 3.598.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-location-constraint": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-sdk-s3": 3.598.0 + "@aws-sdk/middleware-signing": 3.598.0 + "@aws-sdk/middleware-ssec": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/signature-v4-multi-region": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@aws-sdk/xml-builder": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/eventstream-serde-browser": ^3.0.2 + "@smithy/eventstream-serde-config-resolver": ^3.0.1 + "@smithy/eventstream-serde-node": ^3.0.2 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-blob-browser": ^3.1.0 + "@smithy/hash-node": ^3.0.1 + "@smithy/hash-stream-node": ^3.1.0 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/md5-js": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-stream": ^3.0.2 + "@smithy/util-utf8": ^3.0.0 + "@smithy/util-waiter": ^3.0.1 tslib: ^2.6.2 - checksum: e5b04013a9270b438b196ccf60bedba14187ee059fbd3fd42a8bac927c7935226ba031c1a5312befa6e37e4ea8cd075fe28b8b524fe51b5b372bf5543dd46216 + checksum: be9940ac1a9bff2e8efbf6f0ac782b0bcd66ab229639dc46d60aa71e041b3ef16a327e37c92397691a16c982cf5e529ab2ffd60351a9d9730bf4947bb391ced4 languageName: node linkType: hard "@aws-sdk/client-ses@npm:^3.550.0": - version: 3.556.0 - resolution: "@aws-sdk/client-ses@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-ses@npm:3.600.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 - "@smithy/util-waiter": ^2.2.0 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 + "@smithy/util-waiter": ^3.0.1 tslib: ^2.6.2 - checksum: 913108e79061185faae51711b121df99da624f988f530af23c3e4270299be60771be83f507dc8ed4af4051765077ea038edab19e4d0d32e159c4e67faf5fc9f8 + checksum: f0c042db4e20b8165f7da42ba2026ee6c32944c10c6a3508c021efbc0a3474fd0ef888367db47f54dc89a6bbad482858b0c816f6d3ec4ac84bfc156d315b2381 languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/client-sqs@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/client-sqs@npm:3.600.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-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 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-sdk-sqs": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/md5-js": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: fe14caaffe9115b430d7c89895b193b2415532862b6cb70918ea0790f01017ca4bbf998ed221bf7fb4285b7eb6090c156bca4c8ccf49f61f2c34f96fd57e7ed4 + checksum: e0ec11d0d89539ae1964cc2f0655af7367c0c43153ab16fe9542e303cd1b69c5f0e9f3d912c52ff7bbfc5f557733d52e187e72563f0bfed3a21ed6249ae37c8a languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.556.0" +"@aws-sdk/client-sso-oidc@npm:3.600.0": + version: 3.600.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.600.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/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 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - peerDependencies: - "@aws-sdk/credential-provider-node": ^3.556.0 - checksum: d932569016b811e14bd977e2e198556e3e4bf156108b098eb8850f83486cf361e23e17cc2fbae2ae7ebb1c2268f312a64c90dafb9f19e8dd6e9a817397e79552 + checksum: ef7a40ce69de30b25a8a7a5ee035f17e87edc1060c128b3b50f30f19b681aaa7b99b564ffc348cd74fe0e1079bd46087a6784674266d743c45564bcd4d5221b3 languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/client-sso@npm:3.556.0" +"@aws-sdk/client-sso@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/client-sso@npm:3.598.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.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 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: bf0f2d449983c650e25befbee80dd48508464c1814e5b412a8f5e725e88e0764ac75a1b959df509c746b638dbbb571f51617be4c02f7b0ef8185c045255f6c52 + checksum: b570f54643ac0ab0f300bf074e77c2fbba70206a11d2aed1f6ecd361027f2f6a1d62719627e905bcb44dd73d481a29ef5a70878c676386afe2a133f479a445d4 languageName: node linkType: hard -"@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" +"@aws-sdk/client-sts@npm:3.600.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.600.0 + resolution: "@aws-sdk/client-sts@npm:3.600.0" dependencies: - "@aws-crypto/sha256-browser": 3.0.0 - "@aws-crypto/sha256-js": 3.0.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 + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/client-sso-oidc": 3.600.0 + "@aws-sdk/core": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/middleware-host-header": 3.598.0 + "@aws-sdk/middleware-logger": 3.598.0 + "@aws-sdk/middleware-recursion-detection": 3.598.0 + "@aws-sdk/middleware-user-agent": 3.598.0 + "@aws-sdk/region-config-resolver": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@aws-sdk/util-user-agent-browser": 3.598.0 + "@aws-sdk/util-user-agent-node": 3.598.0 + "@smithy/config-resolver": ^3.0.2 + "@smithy/core": ^2.2.1 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/hash-node": ^3.0.1 + "@smithy/invalid-dependency": ^3.0.1 + "@smithy/middleware-content-length": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/middleware-retry": ^3.0.4 + "@smithy/middleware-serde": ^3.0.1 + "@smithy/middleware-stack": ^3.0.1 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/url-parser": ^3.0.1 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-body-length-browser": ^3.0.0 + "@smithy/util-body-length-node": ^3.0.0 + "@smithy/util-defaults-mode-browser": ^3.0.4 + "@smithy/util-defaults-mode-node": ^3.0.4 + "@smithy/util-endpoints": ^2.0.2 + "@smithy/util-middleware": ^3.0.1 + "@smithy/util-retry": ^3.0.1 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - peerDependencies: - "@aws-sdk/credential-provider-node": ^3.556.0 - checksum: 81ce40440de0c3012b6e21d7f9b748bc46982e72ffaccc763efeed34d79eee519ed9a95e2cb37b2e411460cced2897f409d90e42a5b012344358839c717fa435 + checksum: 47d6d145d481c8dc285b68baccf36ab76b92ed1fbf5a58a0900bbe913a7caf3eddc84414428b013e58c91242e7ffd5a55b0620217dc295c75c2729ccb89b9ae8 languageName: node linkType: hard -"@aws-sdk/core@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/core@npm:3.556.0" +"@aws-sdk/core@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/core@npm:3.598.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 + "@smithy/core": ^2.2.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/signature-v4": ^3.1.0 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 fast-xml-parser: 4.2.5 tslib: ^2.6.2 - checksum: 9b446f0939f8573289b598282194aeff81b3e8c9aa76b29d6e865fe40f38b301f041fab39d565f975ed6e8a3ba4d4b9b43444aaab7dbf2c7ea84e67d370a2695 + checksum: e58944a6571808b53d21f012b9671ffec597d2a826a9c0f1fbcbe160189a3c47f5b4671ac92b7437c349f19b8a8df7e12255c57795ab0224c318ed69a0d23229 languageName: node linkType: hard -"@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" +"@aws-sdk/credential-provider-cognito-identity@npm:3.600.0": + version: 3.600.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.600.0" dependencies: - "@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 + "@aws-sdk/client-cognito-identity": 3.600.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 4c66b780f9f8c3e5df9d5e397069e0bbd31596bfb93b5ac76baa39cb0ef7bebc848a879b940dbcdda7c40cb78beeb46e0b10fab94e71ea317e0512e49c9b6f80 + checksum: 9e7e325fde26192fbd7f542ad0ff69d193b5edb65b0361cdeb13f538b1b563de999e82da34493921351ea599643c4884bd17fdc16eba423d3343e681f346072f languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.535.0" +"@aws-sdk/credential-provider-env@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: ec7d011051d69643efd26fe7f3767b1301c6e6bdba12640dad542b60efb2b5fe31df01f8137703d814cf857a69485cc928d0de49ab56c5d05f79815dce19bdbf + checksum: 517f06dd47b7aa4c8d5a9fe82698150237c28c46ed9f82cd1d92d1453690b9d6139b65519d92dea611d319c4418fe4540e7d52c03d3897e7e471731fb0156afb languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.552.0": - version: 3.552.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.552.0" +"@aws-sdk/credential-provider-http@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/types": 3.598.0 + "@smithy/fetch-http-handler": ^3.0.2 + "@smithy/node-http-handler": ^3.0.1 + "@smithy/property-provider": ^3.1.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/util-stream": ^3.0.2 tslib: ^2.6.2 - checksum: 86be07b2a0c73b5c1140557e00b08c091303da1908ff40a29bcc69b73bf4ad175a5ad945e0d45d5c76b02bee3f15a947abb18838b2771ad71feb795a5309a446 + checksum: e2f6208491a6e58b7ac7368c2247dee55080be740511ded01cc3454920ef29d0b7712930571651a8d0ec2aea4e0a107c7d5dd6ecd01bd4de3c264c54e32959b3 languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.556.0" +"@aws-sdk/credential-provider-ini@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/credential-provider-env": 3.598.0 + "@aws-sdk/credential-provider-http": 3.598.0 + "@aws-sdk/credential-provider-process": 3.598.0 + "@aws-sdk/credential-provider-sso": 3.598.0 + "@aws-sdk/credential-provider-web-identity": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/credential-provider-imds": ^3.1.1 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 24b7dc1349f80090455bde95856955aef824752bff8b91dbad1dea784dc03b48b9671650aa2002de8427bd1df832c33be52b5bf157ad2759ad65a6d37247e339 + peerDependencies: + "@aws-sdk/client-sts": ^3.598.0 + checksum: 9fab1e9c312e20150c96daf15e0347b79f0589cc44eb299c15e80c7d5380e8966805fa8893d3c906f99b7eb3c0f872f0795415f75921204580a30d869dd87f54 languageName: node linkType: hard -"@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" +"@aws-sdk/credential-provider-node@npm:3.600.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.600.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.600.0" dependencies: - "@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 + "@aws-sdk/credential-provider-env": 3.598.0 + "@aws-sdk/credential-provider-http": 3.598.0 + "@aws-sdk/credential-provider-ini": 3.598.0 + "@aws-sdk/credential-provider-process": 3.598.0 + "@aws-sdk/credential-provider-sso": 3.598.0 + "@aws-sdk/credential-provider-web-identity": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/credential-provider-imds": ^3.1.1 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: c4b83c36426941caff81a25393eec101cf2d21264c29c69e5a7a940ae8af1f4b2a8f0a26f47c2294a32f381d53eed9ba2dc2cbbcd053585aa9016acb79e98ad8 + checksum: 480c7c36a8558667a25617e6f7f2292b4362b0e894bc204ce62f565dc8e8cc46c713dc04621321336ce715b493590b3b854b33dc6d5123ed39a17643158d94fc languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.535.0" +"@aws-sdk/credential-provider-process@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: af5fad70513e8d0bc10013f220588e45e83d488e0780873d7e76bf5b7099e70c9b4e49b6409d16add64ae212c53a472b12a2178e8bafd7878fdf121d6e2fd112 + checksum: cd1f0dbbc38b137a0e9c2cfa9bb9e55eed1da5166e13576295205d276ab313e9d4a2f97a566d576abc85c6f4e9e84ad676ca5c32f90de17e027d6a1372fb00e6 languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.556.0" +"@aws-sdk/credential-provider-sso@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/client-sso": 3.598.0 + "@aws-sdk/token-providers": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: ea6c9bd7f183abedf79ff7959fdc31c16cb250afece2304d3005343aae4a203d04f2421ac1dd0a815a6d1823c721b277449d0ab27dc17fe8c75b211e44a31667 + checksum: 16828609b9ac17772eecd89deb9ac9b98a1decad42ca1f8cf6a57e6873eeb3563db00bfb67684cbb08108d5ee6b8f98ec23047d7f6750cb67c1342cd8b96ac1c languageName: node linkType: hard -"@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" +"@aws-sdk/credential-provider-web-identity@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.598.0" dependencies: - "@aws-sdk/client-sts": 3.556.0 - "@aws-sdk/types": 3.535.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 79d3277db07130b201b5788a76e8a71c2816be1e190ce7f96d174c2c8153fdcfb6adbf17575d8fd5c928452327a37872f18a48e563805997247bdc3cda2b9cac + peerDependencies: + "@aws-sdk/client-sts": ^3.598.0 + checksum: e62352ae7f408ae8969d22fd42a502ec078536952be1253f184bf96c57f3c88589fd431762b2300b494159df4eb4af975358645772ac36f2cc722c86a88ff85e languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/credential-providers@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/credential-providers@npm:3.600.0" dependencies: - "@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 + "@aws-sdk/client-cognito-identity": 3.600.0 + "@aws-sdk/client-sso": 3.598.0 + "@aws-sdk/client-sts": 3.600.0 + "@aws-sdk/credential-provider-cognito-identity": 3.600.0 + "@aws-sdk/credential-provider-env": 3.598.0 + "@aws-sdk/credential-provider-http": 3.598.0 + "@aws-sdk/credential-provider-ini": 3.598.0 + "@aws-sdk/credential-provider-node": 3.600.0 + "@aws-sdk/credential-provider-process": 3.598.0 + "@aws-sdk/credential-provider-sso": 3.598.0 + "@aws-sdk/credential-provider-web-identity": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/credential-provider-imds": ^3.1.1 + "@smithy/property-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 6d00b6ab7fbd0e0ca83ecd2823b446290be20d68f7c2b26128b8f678ab9d6e0f7fb423adf94bb12903abdeb324b4aa7ce8dd81e0b17f5b3322f6b14e634552e0 + checksum: d957d851a9d4aba30e941c12515ce08fda66cadf2623fa329a2f651e2229e901a7845b139cd15404c8a714985e9b358747f1a8aacf0951e9b05331c5ae92af7c languageName: node linkType: hard @@ -1184,34 +1182,34 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.556.0 - resolution: "@aws-sdk/lib-storage@npm:3.556.0" + version: 3.600.0 + resolution: "@aws-sdk/lib-storage@npm:3.600.0" dependencies: - "@smithy/abort-controller": ^2.2.0 - "@smithy/middleware-endpoint": ^2.5.1 - "@smithy/smithy-client": ^2.5.1 + "@smithy/abort-controller": ^3.0.1 + "@smithy/middleware-endpoint": ^3.0.2 + "@smithy/smithy-client": ^3.1.2 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-s3": ^3.0.0 - checksum: 361e87ce38f566e7ffe0da2bd436bfda5dfce1c9e4f86f4fbab9e157ba24a47e169824dd9723f02eab8cd682b381a765453bd8d4c5fa0ae3c5273ff6d3a166e5 + "@aws-sdk/client-s3": ^3.600.0 + checksum: 3fc04712f61289ac47f9502f0f33351a50e581d7999398575e84713750c77261b20ef8ac4f0a68514737c9950b313a563752b6856f63acaff23d128a4b4a9f4b languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.535.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-arn-parser": 3.568.0 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 + "@smithy/util-config-provider": ^3.0.0 tslib: ^2.6.2 - checksum: d72dfd197dc9aa1ed8ea3de6fb0a18363688fa8e18f6a9d01cb2f425087c5b72aa4bfd0955715c84da86adf9a46029755cff55a02a6ffbf4459009982a5a5415 + checksum: 45a4adc3427a70f7129675439c9396073dc418e9e5ede4acd0dc0620d76610e8adf3f1c863120f7714bc67053a194289ac55ce6814a79960c4746cbd45f7116f languageName: node linkType: hard @@ -1228,108 +1226,108 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.535.0" +"@aws-sdk/middleware-expect-continue@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: fdac9bc59833ca9688155f115f85c31f690df5ef690e9a8921b94b87c4faac3eb3ff10641699822faaaf9a6cc4ce4c67e693a7b4befe8baf8138a9d276d6714d + checksum: 1038945711d48d661cbf21343fd78968240f43b18f5b7fade7e41a7bf5308a65f37859f2b349e5fb038dded0136e0ea734e38e52085178b6a546a6ac48c630e9 languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.535.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.598.0" dependencies: - "@aws-crypto/crc32": 3.0.0 - "@aws-crypto/crc32c": 3.0.0 - "@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 + "@aws-crypto/crc32": 5.2.0 + "@aws-crypto/crc32c": 5.2.0 + "@aws-sdk/types": 3.598.0 + "@smithy/is-array-buffer": ^3.0.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 14c04cd932bdb9029466079b248c1fa8222183de4c288bf12ad661cdc7717938485fdb973b7948da729e5be218573cfd2cbe74b51a1bc2bd27131ca7d67909c1 + checksum: 1311849976b0631055d2d79f991647a87cae742bba23a94f01d18164612ba303ff3bed629744ba58c04bfde371b69ad4eb29e266a7b022ea8529b9a7f6a18415 languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.535.0" +"@aws-sdk/middleware-host-header@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 13a22a5b19912a86fe872c9c0f6ba9ab758ba9483ce9a2e73fa68acae498b68404e38e7fc1e3962639a6c3f80ebe19ea5c5340e1024e11ab417998696c8a5dca + checksum: c505de5bf4f39051a55011b9b2da0b673bda668def00a9b3b4696a3146bfbf0e5509d3bde28ef238648158b863816ce85fbf5829228bb97450c826b7d24d40d0 languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.535.0" +"@aws-sdk/middleware-location-constraint@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 4e89b6c5d4253568e599f0e8be37e80cf12a755ba89b89d9c9ae2ced75213850c41922fa1871a9c92345057e15d5db956a353841eb63353d8f2bb69a61d4a10d + checksum: ab1ae3ad3dc7fad76688c039136d602abe25ebd6b98b6fb61a86f02dbec4414a74334169d12581aae720fe9d372549e9b9dfb56ee87388602264b697db09ff9f languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-logger@npm:3.535.0" +"@aws-sdk/middleware-logger@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-logger@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: e264d05aa88fadd94d17000b1df79bf1931c5fbc2c871616de9b836bab7254d8c21e0fc2ac509a07af578bd823b795efafaf48daca805bc4493986288ed0c4ab + checksum: 8c90bf68b65fe82ae08bf0c665bfea335fef757f8be7ddac6f9059f9f149c9bebc68e034bc225d131d168a61d61a409936d4f4d260c4b2aa2251385238df765a languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.535.0" +"@aws-sdk/middleware-recursion-detection@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: b6b518243a10dcdcea7c1fd4790cf2e1e0e3d4363ebce51ac364c9b15631a6f3d1db44d00e7c75cbdf1d558a0d868583d6e1853e571e15e23d0d2901f168e2e4 + checksum: 161247dbbc8aa31d77c8d4c9c55264c775b5f9996e58451574605435c4a0ff6b9fce28be6f133ddce9f93a24f08c7af6fde59ef93ecb2cc4cd170a4db72b4833 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.556.0" +"@aws-sdk/middleware-sdk-s3@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-arn-parser": 3.568.0 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/signature-v4": ^3.1.0 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/util-config-provider": ^3.0.0 tslib: ^2.6.2 - checksum: a50d96f898a8e6f7cfa0bc61c888240e1fd7aa55cb9fd9376d720f43d30a83d7ad4bd9d828224c125f62b362d77ccfc7fbd64c5c4563f97790f9683ea87abe93 + checksum: 2953ae0f2729ffc4ca68e51e8f3247d447004e5d3d787b333351f2972cc94b49f8379f3403d153c3c5940bda47e1930b0386b77c448ca81bc54bf40f7cb4111f languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.552.0": - version: 3.552.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.552.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/types": 3.598.0 + "@smithy/smithy-client": ^3.1.2 + "@smithy/types": ^3.1.0 + "@smithy/util-hex-encoding": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: a2dfeab25b89b8c0f3204195df58bf5deefb261883db936c6701e70d5a1f6e2a0e8e3a756fea6a4f0e3a1dc4023d820c6b8b3717f759622ffa7cd8851cd9ed59 + checksum: 5b31bc50ffb2973a1a5108ca0a9a2fbf3cc96a403fd06e58994eb9e98e5804cb8fd2d2db977214d92ce30a5a256b54df156b285f7a89e286e7d0ceb3d9f69414 languageName: node linkType: hard @@ -1343,42 +1341,42 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/middleware-signing@npm:3.556.0" +"@aws-sdk/middleware-signing@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-signing@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/protocol-http": ^4.0.1 + "@smithy/signature-v4": ^3.1.0 + "@smithy/types": ^3.1.0 + "@smithy/util-middleware": ^3.0.1 tslib: ^2.6.2 - checksum: b72c0223cc531d9eaac41124c3dcf60d974dbe0a5698fa6cf2ec877d73d83ff02ae310636478054ba5f7d1c3240ff277831c5144955ddb59e513b3de7cb4f272 + checksum: c952da22635dbca7b91c47e43df43a9f4826bbebc36e5851ce325e07f43451de015232145df32eed3190b23d3b051469bf4c381b94ab4eb367ca8f22de4a4670 languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.537.0": - version: 3.537.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.537.0" +"@aws-sdk/middleware-ssec@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 7a963134cab4c9056d249113f6d5e2847be28847fc8c39b943c487ff5d22b9b1d91092e801694e2da95929a4820c45f6b5afc22c655a6dcfb5eb82e44952de14 + checksum: 600afb96254d1085c402fec6c5b7f260ca64126104c4cf3ff6da9811c5cdf0dab5f34fadf68e449ec61f89a165479e1cfab8cd3135c720a2e7a678be4572c215 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.540.0": - version: 3.540.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.540.0" +"@aws-sdk/middleware-user-agent@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@aws-sdk/util-endpoints": 3.540.0 - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@aws-sdk/util-endpoints": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 7ee609fb2b669f93657a87c291dff17f8315973ddbbeee36c54a0233b4911091916880f6e27da93fef01e5fd53654b3834a68cf74256b88b1c4dbe5880a4c14f + checksum: 11dcf64badadf8c6b3283b3cec4cb684467eaf57206782c68a9b758e6f7a4f1b632d5ed89bb6ffbc855bf6d3fb855f0a56858bda640a67c0812ced08cd19959f languageName: node linkType: hard @@ -1426,31 +1424,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.535.0" +"@aws-sdk/region-config-resolver@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/types": 3.598.0 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/types": ^3.1.0 + "@smithy/util-config-provider": ^3.0.0 + "@smithy/util-middleware": ^3.0.1 tslib: ^2.6.2 - checksum: 7b556e47c721c0829ae635203a1dbcab7040e2885d2bdc37898eb3139dabb5f6da580b860202e3b7737330bfc02de5084a98ff8f8b5c36adcfe8e076b82d3487 + checksum: 649115771cb6b77e793088f3ee6eec346c1379f9f5d0e925f71103ad55c5f4a1132fca7e859a6b75ff46ecd1cc165a4eb260227596e4a2871118e6918602a726 languageName: node linkType: hard -"@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" +"@aws-sdk/signature-v4-multi-region@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/middleware-sdk-s3": 3.598.0 + "@aws-sdk/types": 3.598.0 + "@smithy/protocol-http": ^4.0.1 + "@smithy/signature-v4": ^3.1.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 0a23fbb8f99e1b8ab6c7523d5584864749a2ad5b244b78667d88d4a0eb0f74127e22fff4b44a9b694c235e70a66520ee72e0e57b129847d9405c6d907abf5e81 + checksum: 6e0aa7adfe98c452eaa269ea9dc68d2b914a3c5bdc00b5923c0a9003e54899b7d3b9ce14d305b5229200e658a18fdebb93977437f029e9a576c9fe9a3cded0b1 languageName: node linkType: hard @@ -1470,17 +1468,18 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.556.0": - version: 3.556.0 - resolution: "@aws-sdk/token-providers@npm:3.556.0" +"@aws-sdk/token-providers@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/token-providers@npm:3.598.0" dependencies: - "@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 + "@aws-sdk/types": 3.598.0 + "@smithy/property-provider": ^3.1.1 + "@smithy/shared-ini-file-loader": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 15726af45c8a52837eb3291391c23e5b66a153218275c4fcc228a80f63169b401270ff736271401b6d4c301944bc20620d63dfb14a87bbe743a50e3157e68c7e + peerDependencies: + "@aws-sdk/client-sso-oidc": ^3.598.0 + checksum: 24197672226e1e953fa57ca10c6adae9c3f6b571fbf40f517609e028d8ea6ab45c3afd285bd999bc35c0690b3427be04d4af3f677ced6778b0a716e0dd4e5280 languageName: node linkType: hard @@ -1494,13 +1493,13 @@ __metadata: languageName: node linkType: hard -"@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" +"@aws-sdk/types@npm:3.598.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0": + version: 3.598.0 + resolution: "@aws-sdk/types@npm:3.598.0" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 3f735c78ea3a6f37d05387286f6d18b0e5deb41442095bd2f7c27b000659962872d1c801fa8484a6ac4b7d2725b2e176dc628c3fa2a903a3141d4be76488d48f + checksum: 9b2bd50d6935422dd1046e6eaa48c4c774d06aa1374bf4600a3af2c7a52432b5e25ec111cf49976b07b03d7cb5f4fa6fd44b7ce8a67dd0b3a4cee4abaf9e6fa5 languageName: node linkType: hard @@ -1515,12 +1514,12 @@ __metadata: languageName: node linkType: hard -"@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" +"@aws-sdk/util-arn-parser@npm:3.568.0, @aws-sdk/util-arn-parser@npm:^3.310.0": + version: 3.568.0 + resolution: "@aws-sdk/util-arn-parser@npm:3.568.0" dependencies: tslib: ^2.6.2 - checksum: 0e4c4ea080c7c6da00d359c337a1f9d961eac20c35cebad9cb6bb9b618f981955643990de7bfd6b53c29367a6d33550fe27b2a7539efdff08e01bdd303f0c5c2 + checksum: e3c45e5d524a772954d0a33614d397414185b9eb635423d01253cad1c1b9add625798ed9cf23343d156fae89c701f484bc062ab673f67e2e2edfe362fde6d170 languageName: node linkType: hard @@ -1534,15 +1533,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.540.0": - version: 3.540.0 - resolution: "@aws-sdk/util-endpoints@npm:3.540.0" +"@aws-sdk/util-endpoints@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/util-endpoints@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 - "@smithy/util-endpoints": ^1.2.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 + "@smithy/util-endpoints": ^2.0.2 tslib: ^2.6.2 - checksum: 62312773965480f8df5edb62ecf82ab3e54d5aa1b1f7eebdad78a2925eab47218b0268bc25a5d03598ac4d0c08935733031a2e3e1ce72531535ed1ea8a9b56c3 + checksum: 6fb92e8c99b6ce96cda21c9d1744a290c683bae8d82394c1b1fe7ed7d3cb0a18d4025b8863532680db3f550ad130e54d528c64a0a32f398f3c00c5ce2e043ecd languageName: node linkType: hard @@ -1594,32 +1593,32 @@ __metadata: languageName: node linkType: hard -"@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" +"@aws-sdk/util-user-agent-browser@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/types": ^3.1.0 bowser: ^2.11.0 tslib: ^2.6.2 - checksum: 148b82900e4b9efd24f5fc4152a8d6010c90eb019517fa3c00c3ac42205055f7611ef3834fb63397def40e600ea20f901177a7dd5b6aefa2aef4208e994f7d90 + checksum: c53afc0fe7a07838ad22ae1e9ed6834d56a69cb0ad623d4912deeaa715af479b64266965fce30e7210e576118f80ceb525f79f504dc459fe0294fd15e694752e languageName: node linkType: hard -"@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" +"@aws-sdk/util-user-agent-node@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.598.0" dependencies: - "@aws-sdk/types": 3.535.0 - "@smithy/node-config-provider": ^2.3.0 - "@smithy/types": ^2.12.0 + "@aws-sdk/types": 3.598.0 + "@smithy/node-config-provider": ^3.1.1 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: f214c406fccde14591d1df25fed662e573510cdf1d5829d22e7a93e517ea4a3905acd123eaaeafdb8b217400e8c8e159231d37be02b67307922023996b398f42 + checksum: 1560fabf19b236cfbce42769e1ef7e46bdad881b8a4b0ce069401d9a6edd5e1b195f45cb2847abf9ef1453d2e69447e7a3dabc92b037d9a41fe58960538db1ae languageName: node linkType: hard @@ -1642,13 +1641,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:3.535.0": - version: 3.535.0 - resolution: "@aws-sdk/xml-builder@npm:3.535.0" +"@aws-sdk/xml-builder@npm:3.598.0": + version: 3.598.0 + resolution: "@aws-sdk/xml-builder@npm:3.598.0" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.1.0 tslib: ^2.6.2 - checksum: 9320f6600c7852b681ed4171f1521eda166321ef7ffea5a6b99a1d328835bb12f7423431ea23a696c678ec4fc8e6dbb2f979d941289f6e0cb55c3da7d5eee140 + checksum: 6b9fa385f749219d0a0654445e5deba54c7753d3e0da795dfc2bfdbaeb59fbfc8ef0e3f477c6aff6181a12a11ac87e3f84dedbbd1d1adb2c32941b149401abcf languageName: node linkType: hard @@ -1661,7 +1660,16 @@ __metadata: languageName: node linkType: hard -"@azure/core-auth@npm:^1.3.0, @azure/core-auth@npm:^1.4.0, @azure/core-auth@npm:^1.5.0": +"@azure/abort-controller@npm:^2.0.0": + version: 2.1.2 + resolution: "@azure/abort-controller@npm:2.1.2" + dependencies: + tslib: ^2.6.2 + checksum: 22176c04ea01498311c6bbd336669f6e3faffad1cbb0c9ebc6ee9c1ff2cf958fd17ce73c7354b99d8bda9fcd311325ece7bee248875279174e3fc460e8b1a63d + languageName: node + linkType: hard + +"@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: @@ -1672,40 +1680,29 @@ __metadata: languageName: node linkType: hard -"@azure/core-client@npm:^1.4.0": - version: 1.7.3 - resolution: "@azure/core-client@npm:1.7.3" +"@azure/core-client@npm:^1.3.0, @azure/core-client@npm:^1.6.2, @azure/core-client@npm:^1.9.2": + version: 1.9.2 + resolution: "@azure/core-client@npm:1.9.2" dependencies: - "@azure/abort-controller": ^1.0.0 + "@azure/abort-controller": ^2.0.0 "@azure/core-auth": ^1.4.0 "@azure/core-rest-pipeline": ^1.9.1 "@azure/core-tracing": ^1.0.0 - "@azure/core-util": ^1.0.0 + "@azure/core-util": ^1.6.1 "@azure/logger": ^1.0.0 - tslib: ^2.2.0 - checksum: 155a188b75b2d5ea783d5fde50479337c41796736f0fced1576466c8251e429195c229f2aff0bf897761f15c19d8fd0deea9a54aab514bd3584e37140e3f0cdc + tslib: ^2.6.2 + checksum: 961b829dfda4f734a763e9480a2ea622a7031ba2da4126d0add6e351a9f73ddc5782bf2b766735d976b61da3857014e0a90223d1f85d1c68468747a7a56851c3 languageName: node linkType: hard -"@azure/core-http@npm:^3.0.0": - version: 3.0.2 - resolution: "@azure/core-http@npm:3.0.2" +"@azure/core-http-compat@npm:^2.0.0": + version: 2.1.2 + resolution: "@azure/core-http-compat@npm:2.1.2" dependencies: - "@azure/abort-controller": ^1.0.0 - "@azure/core-auth": ^1.3.0 - "@azure/core-tracing": 1.0.0-preview.13 - "@azure/core-util": ^1.1.1 - "@azure/logger": ^1.0.0 - "@types/node-fetch": ^2.5.0 - "@types/tunnel": ^0.0.3 - form-data: ^4.0.0 - node-fetch: ^2.6.7 - process: ^0.11.10 - tslib: ^2.2.0 - tunnel: ^0.0.6 - uuid: ^8.3.0 - xml2js: ^0.5.0 - checksum: 01b5a75e09533476dbb69c672dcd00d48298cf81db5015cd261c510c5be377176db8e3dc4809e6952459bfbe214f52f8a1ed84a116ac31b8a7388b2025098f66 + "@azure/abort-controller": ^2.0.0 + "@azure/core-client": ^1.3.0 + "@azure/core-rest-pipeline": ^1.3.0 + checksum: 387d0187607d95a6876f63d4b689210bce6ad243f48e56413136ba3875a8a9c4e238813307fb0cf0c53298f4b9d0893d04321c9331812bc74cf0f4e3e6872069 languageName: node linkType: hard @@ -1730,30 +1727,19 @@ __metadata: languageName: node linkType: hard -"@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" +"@azure/core-rest-pipeline@npm:^1.1.0, @azure/core-rest-pipeline@npm:^1.10.1, @azure/core-rest-pipeline@npm:^1.3.0, @azure/core-rest-pipeline@npm:^1.9.1": + version: 1.16.1 + resolution: "@azure/core-rest-pipeline@npm:1.16.1" dependencies: - "@azure/abort-controller": ^1.0.0 + "@azure/abort-controller": ^2.0.0 "@azure/core-auth": ^1.4.0 "@azure/core-tracing": ^1.0.1 - "@azure/core-util": ^1.3.0 + "@azure/core-util": ^1.9.0 "@azure/logger": ^1.0.0 - form-data: ^4.0.0 - http-proxy-agent: ^5.0.0 - https-proxy-agent: ^5.0.0 - tslib: ^2.2.0 - checksum: a774ab2e87ff56d7f3ef1844a814bbd76264ea1c33534081d38ce6df1098d803d0b13b15912f9053d0695ca2669b0dd104c8feec8dbf24df80a3608ea784fc9e - languageName: node - linkType: hard - -"@azure/core-tracing@npm:1.0.0-preview.13": - version: 1.0.0-preview.13 - resolution: "@azure/core-tracing@npm:1.0.0-preview.13" - dependencies: - "@opentelemetry/api": ^1.0.1 - tslib: ^2.2.0 - checksum: bc3ea8dce1fc6bb6e4cb2e82ec0c361b3e6f6e18e162f352eb347e6991c6461ebc249f5d1b36402cc0d295e2a6bcbaa68014445d7f4293c0792a698c430f145e + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.0 + tslib: ^2.6.2 + checksum: ab2c5b715c4ebb9f6554f12d8e804833be29db0f23868adc092f4841aa8c7f140a6821dbcd9fa046bfb31e435085f171a87dab3f97d851cf9a62127d042fa75e languageName: node linkType: hard @@ -1766,23 +1752,33 @@ __metadata: languageName: node linkType: hard -"@azure/core-util@npm:^1.0.0, @azure/core-util@npm:^1.1.0, @azure/core-util@npm:^1.1.1, @azure/core-util@npm:^1.2.0, @azure/core-util@npm:^1.3.0": - version: 1.6.1 - resolution: "@azure/core-util@npm:1.6.1" +"@azure/core-util@npm:^1.1.0, @azure/core-util@npm:^1.2.0, @azure/core-util@npm:^1.3.0, @azure/core-util@npm:^1.6.1, @azure/core-util@npm:^1.9.0": + version: 1.9.0 + resolution: "@azure/core-util@npm:1.9.0" dependencies: - "@azure/abort-controller": ^1.0.0 - tslib: ^2.2.0 - checksum: 1f8cd130993f161c98925070af863510cbcc79e0471864e4b16852afc2ee7413c9c7fabe72f20f3e521ee75c3cd7e3085661fdc8d5d0a643a6e1b1b7bf691ddd + "@azure/abort-controller": ^2.0.0 + tslib: ^2.6.2 + checksum: 9246dc5bd246e7b94883ea8130fce04e2f22abd1e94afcff7a3e92a4c2da5e9b382dbf89a606b21d70bc8b01c7c89c84e803ca9da27f78d87f72bdff91ec7380 + languageName: node + linkType: hard + +"@azure/core-xml@npm:^1.3.2": + version: 1.4.2 + resolution: "@azure/core-xml@npm:1.4.2" + dependencies: + fast-xml-parser: ^4.3.2 + tslib: ^2.6.2 + checksum: f3815db55f0280db6080a3fc5b6187ad45cacf5c3842ea806a5565886edf2ebf2fa9fc1175407cf58d462341962a8396513943543b332b37b313ac3a79dc28fa languageName: node linkType: hard "@azure/identity@npm:^4.0.0": - version: 4.2.1 - resolution: "@azure/identity@npm:4.2.1" + version: 4.3.0 + resolution: "@azure/identity@npm:4.3.0" dependencies: "@azure/abort-controller": ^1.0.0 "@azure/core-auth": ^1.5.0 - "@azure/core-client": ^1.4.0 + "@azure/core-client": ^1.9.2 "@azure/core-rest-pipeline": ^1.1.0 "@azure/core-tracing": ^1.0.0 "@azure/core-util": ^1.3.0 @@ -1794,7 +1790,7 @@ __metadata: open: ^8.0.0 stoppable: ^1.1.0 tslib: ^2.2.0 - checksum: 2dbd7b0fa6b92904b7b8f828374d7316384cc4e00c71cdac3a2f2544b9e02c7287fe7ad58149bb8794c57913d77a927f5a7b5d1367e05abe82b0f2e1b162415c + checksum: 7f4256b39c4e27bf072c33f02dd63bd50dcf54ad578e3e483dcf89283546a6086b1640adfe4c93a537cbe483dd2e3a29f6d7b837e51f333229f7bbbc448966b3 languageName: node linkType: hard @@ -1842,18 +1838,23 @@ __metadata: linkType: hard "@azure/storage-blob@npm:^12.5.0": - version: 12.17.0 - resolution: "@azure/storage-blob@npm:12.17.0" + version: 12.23.0 + resolution: "@azure/storage-blob@npm:12.23.0" dependencies: "@azure/abort-controller": ^1.0.0 - "@azure/core-http": ^3.0.0 + "@azure/core-auth": ^1.4.0 + "@azure/core-client": ^1.6.2 + "@azure/core-http-compat": ^2.0.0 "@azure/core-lro": ^2.2.0 "@azure/core-paging": ^1.1.1 - "@azure/core-tracing": 1.0.0-preview.13 + "@azure/core-rest-pipeline": ^1.10.1 + "@azure/core-tracing": ^1.0.0 + "@azure/core-util": ^1.6.1 + "@azure/core-xml": ^1.3.2 "@azure/logger": ^1.0.0 events: ^3.0.0 tslib: ^2.2.0 - checksum: 2e5d3f26577f698498bba7ff7b7cfeb942709a713d9c72864b80633bee28e2b369370afc55f18e49ccc02b4dad9d1de3a4602caa99dce1f8d8196c8472a8add1 + checksum: 7f09b4bfae0d73f7cf8f383038edeaf8bc8610960bc24a9b8c140f4084bb3afd62971fb56e2ff5e013168165dcfff7b9a545f6cc837fe2669618184e4b77c107 languageName: node linkType: hard @@ -3457,6 +3458,7 @@ __metadata: resolution: "@backstage/backend-app-api@workspace:packages/backend-app-api" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -3496,6 +3498,7 @@ __metadata: minimist: ^1.2.5 morgan: ^1.10.0 msw: ^1.0.0 + node-fetch: ^2.6.7 node-forge: ^1.3.1 path-to-regexp: ^6.2.1 selfsigned: ^2.0.0 @@ -3546,7 +3549,10 @@ __metadata: "@types/fs-extra": ^11.0.0 "@types/http-errors": ^2.0.0 "@types/luxon": ^3.0.0 + "@types/morgan": ^1.9.0 + "@types/node-forge": ^1.3.0 "@types/pg": ^8.6.6 + "@types/stoppable": ^1.1.0 "@types/supertest": ^2.0.8 "@types/tar": ^6.1.1 "@types/webpack-env": ^1.15.2 @@ -3554,7 +3560,7 @@ __metadata: archiver: ^6.0.0 aws-sdk-client-mock: ^4.0.0 base64-stream: ^1.0.0 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 compression: ^1.7.4 concat-stream: ^2.0.0 cors: ^2.8.5 @@ -3573,14 +3579,21 @@ __metadata: logform: ^2.3.2 luxon: ^3.0.0 minimatch: ^9.0.0 + minimist: ^1.2.5 + morgan: ^1.10.0 msw: ^1.0.0 mysql2: ^3.0.0 node-fetch: ^2.6.7 + node-forge: ^1.3.1 p-limit: ^3.1.0 + path-to-regexp: ^6.2.1 pg: ^8.11.3 raw-body: ^2.4.1 + selfsigned: ^2.0.0 + stoppable: ^1.1.0 supertest: ^6.1.3 tar: ^6.1.12 + triple-beam: ^1.4.1 uuid: ^9.0.0 winston: ^3.2.1 winston-transport: ^4.5.0 @@ -3605,47 +3618,76 @@ __metadata: "@aws-sdk/types": ^3.347.0 "@aws-sdk/util-stream-node": ^3.350.0 "@backstage/backend-app-api": "workspace:^" + "@backstage/backend-common": "workspace:^" "@backstage/backend-dev-utils": "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/integration": "workspace:^" "@backstage/integration-aws-node": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" "@backstage/plugin-events-node": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" "@backstage/types": "workspace:^" "@google-cloud/storage": ^7.0.0 "@keyv/memcache": ^1.3.5 "@keyv/redis": ^2.5.3 + "@manypkg/get-packages": ^1.1.3 "@octokit/rest": ^19.0.3 "@opentelemetry/api": ^1.3.0 + "@types/cors": ^2.8.6 + "@types/express": ^4.17.6 + "@types/http-errors": ^2.0.0 + "@types/morgan": ^1.9.0 + "@types/node-forge": ^1.3.0 + "@types/stoppable": ^1.1.0 archiver: ^6.0.0 aws-sdk-client-mock: ^4.0.0 base64-stream: ^1.0.0 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 + compression: ^1.7.4 concat-stream: ^2.0.0 + cookie: ^0.6.0 + cors: ^2.8.5 cron: ^3.0.0 + express: ^4.17.1 + express-promise-router: ^4.1.0 fs-extra: ^11.2.0 git-url-parse: ^14.0.0 + helmet: ^6.0.0 + http-errors: ^2.0.0 isomorphic-git: ^1.23.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: ^9.0.0 + minimist: ^1.2.5 + morgan: ^1.10.0 msw: ^1.0.0 mysql2: ^3.0.0 node-fetch: ^2.6.7 + node-forge: ^1.3.1 p-limit: ^3.1.0 + path-to-regexp: ^6.2.1 pg: ^8.11.3 pg-connection-string: ^2.3.0 raw-body: ^2.4.1 + selfsigned: ^2.0.0 + stoppable: ^1.1.0 + supertest: ^6.1.3 tar: ^6.1.12 + triple-beam: ^1.4.1 uuid: ^9.0.0 wait-for-expect: ^3.0.2 + winston: ^3.2.1 + winston-transport: ^4.5.0 yauzl: ^3.0.0 yn: ^4.0.0 zod: ^3.22.4 @@ -3765,6 +3807,7 @@ __metadata: resolution: "@backstage/backend-test-utils@workspace:packages/backend-test-utils" dependencies: "@backstage/backend-app-api": "workspace:^" + "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" @@ -3776,7 +3819,7 @@ __metadata: "@keyv/redis": ^2.5.3 "@types/keyv": ^4.2.0 "@types/supertest": ^2.0.8 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 cookie: ^0.6.0 express: ^4.17.1 fs-extra: ^11.0.0 @@ -3929,7 +3972,7 @@ __metadata: ctrlc-windows: ^2.1.0 del: ^7.0.0 diff: ^5.0.0 - esbuild: ^0.20.0 + esbuild: ^0.21.0 esbuild-loader: ^4.0.0 eslint: ^8.6.0 eslint-config-prettier: ^9.0.0 @@ -3989,7 +4032,7 @@ __metadata: util: ^0.12.3 vite: ^4.4.9 vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.21.0 + vite-plugin-node-polyfills: ^0.22.0 webpack: ^5.70.0 webpack-dev-server: ^5.0.0 webpack-node-externals: ^3.0.0 @@ -4001,7 +4044,7 @@ __metadata: "@vitejs/plugin-react": ^4.0.4 vite: ^4.4.9 vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.21.0 + vite-plugin-node-polyfills: ^0.22.0 peerDependenciesMeta: "@vitejs/plugin-react": optional: true @@ -4184,14 +4227,14 @@ __metadata: languageName: node linkType: hard -"@backstage/core-components@npm:^0.14.4, @backstage/core-components@npm:^0.14.7": - version: 0.14.7 - resolution: "@backstage/core-components@npm:0.14.7" +"@backstage/core-components@npm:^0.14.4, @backstage/core-components@npm:^0.14.8": + version: 0.14.8 + resolution: "@backstage/core-components@npm:0.14.8" dependencies: "@backstage/config": ^1.2.0 - "@backstage/core-plugin-api": ^1.9.2 + "@backstage/core-plugin-api": ^1.9.3 "@backstage/errors": ^1.2.4 - "@backstage/theme": ^0.5.4 + "@backstage/theme": ^0.5.6 "@backstage/version-bridge": ^1.0.8 "@date-io/core": ^1.3.13 "@material-table/core": ^3.1.0 @@ -4229,7 +4272,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: e3906347c197d741dbff24d20af5cd0117e4bf1667c34a4a3a70d8c0f3c0c92bd768b53c417ca78f8b87560a3623f497938f531be86c8727f83822a11e9aa4e5 + checksum: b833e833c83f72e0cc695fe2726cbf01b58819ad062ed9ab1e604514bb398ade20e1abb208d2e39ab1f746fdbd4547486e3935bacb44b457a47070f9c77895dc languageName: node linkType: hard @@ -4304,25 +4347,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@npm:^1.8.2, @backstage/core-plugin-api@npm:^1.9.2": - version: 1.9.2 - resolution: "@backstage/core-plugin-api@npm:1.9.2" - dependencies: - "@backstage/config": ^1.2.0 - "@backstage/errors": ^1.2.4 - "@backstage/types": ^1.1.1 - "@backstage/version-bridge": ^1.0.8 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.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: 2df505c14853b3b35b8644d66f3e58d235bc6ee7f7b81785ec163aa9f089fc03a6c03e3b191d001b247f19d97063e02e585d67661720a8b6a13ab67a2403c218 - 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@^1.9.3, @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: @@ -4469,12 +4494,12 @@ __metadata: languageName: unknown linkType: soft -"@backstage/frontend-plugin-api@npm:^0.6.5": - version: 0.6.5 - resolution: "@backstage/frontend-plugin-api@npm:0.6.5" +"@backstage/frontend-plugin-api@npm:^0.6.6": + version: 0.6.6 + resolution: "@backstage/frontend-plugin-api@npm:0.6.6" dependencies: - "@backstage/core-components": ^0.14.7 - "@backstage/core-plugin-api": ^1.9.2 + "@backstage/core-components": ^0.14.8 + "@backstage/core-plugin-api": ^1.9.3 "@backstage/types": ^1.1.1 "@backstage/version-bridge": ^1.0.8 "@material-ui/core": ^4.12.4 @@ -4485,7 +4510,7 @@ __metadata: peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: be880b5a3bb86d4e2c32a90ca64265b529901dabcdcbf5a87b5cbdfd68fc347297359550da195034e671e074db9db7c659d663d4fd46ed3836896bd1878fae2f + checksum: c2af07bb73751f050937ba0f34941cc21639defdf13c6e219069ff4143324404229113874caef28f41b9a92a00121991da2a88782595e5221b48910e2f8be7c7 languageName: node linkType: hard @@ -4552,13 +4577,13 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@npm:^1.1.27": - version: 1.1.27 - resolution: "@backstage/integration-react@npm:1.1.27" +"@backstage/integration-react@npm:^1.1.28": + version: 1.1.28 + resolution: "@backstage/integration-react@npm:1.1.28" dependencies: "@backstage/config": ^1.2.0 - "@backstage/core-plugin-api": ^1.9.2 - "@backstage/integration": ^1.11.0 + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/integration": ^1.12.0 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@types/react": ^16.13.1 || ^17.0.0 @@ -4566,7 +4591,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: 136bdfeb7c4ba91eb2405a82ae99fd5d935056d7fe77064bf799a8d375a2b5c645e0df7deaee7e1e0ad6fb48dcac94c82e4b29e3d3a00f80555116b1902102b2 + checksum: 15443a7ebc457114715651e652a40472085ca18ec10da078bad1e71e3aa9cac33d10704b164d09108f6195a9cb4d2eae11751d853598ef0dd0e4c160858f782d languageName: node linkType: hard @@ -4594,9 +4619,9 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration@npm:^1.11.0": - version: 1.11.0 - resolution: "@backstage/integration@npm:1.11.0" +"@backstage/integration@npm:^1.12.0": + version: 1.12.0 + resolution: "@backstage/integration@npm:1.12.0" dependencies: "@azure/identity": ^4.0.0 "@backstage/config": ^1.2.0 @@ -4607,7 +4632,7 @@ __metadata: git-url-parse: ^14.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - checksum: 57ea46e57da004cdab41e82f558105f78f84f65d58163e93363dc775d42ab29401d3a38390ace012bf388eec57350d432a415d8fed27e57419e21522044fcc33 + checksum: 603c08058dadfe54b5d1788db87bab951b53ea4d1b19f609873717e0ab514859cc8608d0d60755c91eaea000ad71f817c5dd50892a3215443d7eed5a1d24a849 languageName: node linkType: hard @@ -5520,6 +5545,19 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-catalog-backend-module-logs@workspace:plugins/catalog-backend-module-logs": + version: 0.0.0-use.local + resolution: "@backstage/plugin-catalog-backend-module-logs@workspace:plugins/catalog-backend-module-logs" + dependencies: + "@backstage/backend-plugin-api": "workspace:^" + "@backstage/backend-test-utils": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/plugin-catalog-backend": "workspace:^" + "@backstage/plugin-events-backend-test-utils": "workspace:^" + "@backstage/plugin-events-node": "workspace:^" + languageName: unknown + linkType: soft + "@backstage/plugin-catalog-backend-module-msgraph@workspace:plugins/catalog-backend-module-msgraph": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-msgraph@workspace:plugins/catalog-backend-module-msgraph" @@ -5657,7 +5695,7 @@ __metadata: "@types/lodash": ^4.14.151 "@types/supertest": ^2.0.8 "@types/uuid": ^9.0.0 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 codeowners-utils: ^1.0.2 core-js: ^3.6.5 express: ^4.17.1 @@ -5683,18 +5721,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@npm:^1.0.20, @backstage/plugin-catalog-common@npm:^1.0.23": - version: 1.0.23 - resolution: "@backstage/plugin-catalog-common@npm:1.0.23" - dependencies: - "@backstage/catalog-model": ^1.5.0 - "@backstage/plugin-permission-common": ^0.7.13 - "@backstage/plugin-search-common": ^1.2.11 - checksum: 071456b301689b9b349bdb1bea0d81cc41b0e8055e68096655a0abd198ea21afdc27bda7135d5c800ba8074fbc20d2d8d3a2244578fa8f6547205bee57c31c3d - languageName: node - linkType: hard - -"@backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@^1.0.24, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-common@workspace:plugins/catalog-common" dependencies: @@ -5804,19 +5831,19 @@ __metadata: linkType: soft "@backstage/plugin-catalog-react@npm:^1.11.3, @backstage/plugin-catalog-react@npm:^1.9.3": - version: 1.12.0 - resolution: "@backstage/plugin-catalog-react@npm:1.12.0" + version: 1.12.1 + resolution: "@backstage/plugin-catalog-react@npm:1.12.1" dependencies: "@backstage/catalog-client": ^1.6.5 "@backstage/catalog-model": ^1.5.0 - "@backstage/core-components": ^0.14.7 - "@backstage/core-plugin-api": ^1.9.2 + "@backstage/core-components": ^0.14.8 + "@backstage/core-plugin-api": ^1.9.3 "@backstage/errors": ^1.2.4 - "@backstage/frontend-plugin-api": ^0.6.5 - "@backstage/integration-react": ^1.1.27 - "@backstage/plugin-catalog-common": ^1.0.23 - "@backstage/plugin-permission-common": ^0.7.13 - "@backstage/plugin-permission-react": ^0.4.22 + "@backstage/frontend-plugin-api": ^0.6.6 + "@backstage/integration-react": ^1.1.28 + "@backstage/plugin-catalog-common": ^1.0.24 + "@backstage/plugin-permission-common": ^0.7.14 + "@backstage/plugin-permission-react": ^0.4.23 "@backstage/types": ^1.1.1 "@backstage/version-bridge": ^1.0.8 "@material-ui/core": ^4.12.2 @@ -5835,7 +5862,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: 8079c6c1f4c5b07df5cfb2873f4c3ba16759a3a1ac36a1e1ff61fb428cece5baca40b5c2bc41a2d402ad9a60e73fd545c0a95eec274189423f40a04551a5f337 + checksum: adbf967e978fa6bb4798d0620853e41f64cc08c39dd0056fc01b2146ca427d1bfab401b8972d7b551d4188b90f80f69db9254799bca095608b7079cec73da9c5 languageName: node linkType: hard @@ -6197,7 +6224,7 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@rjsf/utils": 5.18.4 + "@rjsf/utils": 5.18.5 "@types/react": ^16.13.1 || ^17.0.0 "@types/react-grid-layout": ^1.3.2 peerDependencies: @@ -6228,10 +6255,10 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@rjsf/core": 5.18.4 - "@rjsf/material-ui": 5.18.4 - "@rjsf/utils": 5.18.4 - "@rjsf/validator-ajv8": 5.18.4 + "@rjsf/core": 5.18.5 + "@rjsf/material-ui": 5.18.5 + "@rjsf/utils": 5.18.5 + "@rjsf/validator-ajv8": 5.18.5 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 @@ -6682,21 +6709,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-common@npm:^0.7.13": - version: 0.7.13 - resolution: "@backstage/plugin-permission-common@npm:0.7.13" - dependencies: - "@backstage/config": ^1.2.0 - "@backstage/errors": ^1.2.4 - "@backstage/types": ^1.1.1 - cross-fetch: ^4.0.0 - uuid: ^9.0.0 - zod: ^3.22.4 - checksum: 3abea60e1016d352b99700d331af39b8c2b6f84ce7e19e02026f909e53a709b23c1ac9fadc591658252c458bb4d381545574ca66374db0912efe6640c8d58020 - languageName: node - linkType: hard - -"@backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@^0.7.14, @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: @@ -6734,24 +6747,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-react@npm:^0.4.22": - version: 0.4.22 - resolution: "@backstage/plugin-permission-react@npm:0.4.22" - dependencies: - "@backstage/config": ^1.2.0 - "@backstage/core-plugin-api": ^1.9.2 - "@backstage/plugin-permission-common": ^0.7.13 - "@types/react": ^16.13.1 || ^17.0.0 || ^18.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: c91ad5a336358ae3a2e6030e7ea7a8584735544a14aa6ada061ca0c01ee32b2e16bd2fe24c9327cbdb959eec185bac045b1211b0a03a5c9d45b350f0a6c031ca - languageName: node - linkType: hard - -"@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@^0.4.23, @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: @@ -6829,6 +6825,7 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" + "@backstage/plugin-bitbucket-cloud-common": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" "@backstage/plugin-scaffolder-node-test-utils": "workspace:^" fs-extra: ^11.2.0 @@ -6923,6 +6920,22 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-scaffolder-backend-module-gcp@workspace:plugins/scaffolder-backend-module-gcp": + version: 0.0.0-use.local + resolution: "@backstage/plugin-scaffolder-backend-module-gcp@workspace:plugins/scaffolder-backend-module-gcp" + dependencies: + "@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:^" + "@google-cloud/storage": ^7.0.0 + raw-body: ^2.4.1 + languageName: unknown + linkType: soft + "@backstage/plugin-scaffolder-backend-module-gerrit@workspace:^, @backstage/plugin-scaffolder-backend-module-gerrit@workspace:plugins/scaffolder-backend-module-gerrit": version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend-module-gerrit@workspace:plugins/scaffolder-backend-module-gerrit" @@ -7082,6 +7095,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-scaffolder-backend@workspace:plugins/scaffolder-backend" dependencies: + "@backstage/backend-app-api": "workspace:^" "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" @@ -7093,6 +7107,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-bitbucket-cloud-common": "workspace:^" "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" @@ -7116,7 +7131,7 @@ __metadata: "@types/supertest": ^2.0.8 "@types/zen-observable": ^0.8.0 concat-stream: ^2.0.0 - esbuild: ^0.20.0 + esbuild: ^0.21.0 express: ^4.17.1 express-promise-router: ^4.1.0 fs-extra: ^11.2.0 @@ -7184,11 +7199,13 @@ __metadata: "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-common": "workspace:^" "@backstage/types": "workspace:^" + concat-stream: ^2.0.0 fs-extra: ^11.2.0 globby: ^11.0.0 isomorphic-git: ^1.23.0 jsonschema: ^1.2.6 p-limit: ^3.1.0 + tar: ^6.1.12 winston: ^3.2.1 zod: ^3.22.4 zod-to-json-schema: ^3.20.4 @@ -7219,10 +7236,10 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.18.4 - "@rjsf/material-ui": 5.18.4 - "@rjsf/utils": 5.18.4 - "@rjsf/validator-ajv8": 5.18.4 + "@rjsf/core": 5.18.5 + "@rjsf/material-ui": 5.18.5 + "@rjsf/utils": 5.18.5 + "@rjsf/validator-ajv8": 5.18.5 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 @@ -7285,10 +7302,10 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@microsoft/fetch-event-source": ^2.0.1 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.18.4 - "@rjsf/material-ui": 5.18.4 - "@rjsf/utils": 5.18.4 - "@rjsf/validator-ajv8": 5.18.4 + "@rjsf/core": 5.18.5 + "@rjsf/material-ui": 5.18.5 + "@rjsf/utils": 5.18.5 + "@rjsf/validator-ajv8": 5.18.5 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 @@ -7296,6 +7313,7 @@ __metadata: "@types/humanize-duration": ^3.18.1 "@types/json-schema": ^7.0.9 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react-window": ^1.8.8 "@uiw/react-codemirror": ^4.9.3 classnames: ^2.2.6 git-url-parse: ^14.0.0 @@ -7308,6 +7326,7 @@ __metadata: msw: ^1.0.0 qs: ^6.9.4 react-use: ^17.2.4 + react-window: ^1.8.10 swr: ^2.0.0 yaml: ^2.0.0 zen-observable: ^0.10.0 @@ -7499,16 +7518,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-search-common@npm:^1.2.11": - version: 1.2.11 - resolution: "@backstage/plugin-search-common@npm:1.2.11" - dependencies: - "@backstage/plugin-permission-common": ^0.7.13 - "@backstage/types": ^1.1.1 - checksum: 861ba64fd733511bad58d2b3f6b2af60426d71b8e8d74838b85a15a5870d54c0de984681a33f5adb8e97284da9167655982bcf5e543436d0f4160a2c0cbece1f - languageName: node - linkType: hard - "@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" @@ -7727,9 +7736,7 @@ __metadata: "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-search-backend-module-techdocs": "workspace:^" "@backstage/plugin-techdocs-node": "workspace:^" - "@types/dockerode": ^3.3.0 "@types/express": ^4.17.6 - dockerode: ^4.0.0 express: ^4.17.1 express-promise-router: ^4.1.0 fs-extra: ^11.2.0 @@ -7801,6 +7808,7 @@ __metadata: "@types/recursive-readdir": ^2.2.0 "@types/supertest": ^2.0.8 aws-sdk-client-mock: ^4.0.0 + dockerode: ^4.0.0 express: ^4.17.1 fs-extra: ^11.2.0 git-url-parse: ^14.0.0 @@ -8060,23 +8068,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/theme@npm:^0.5.0, @backstage/theme@npm:^0.5.4": - version: 0.5.5 - resolution: "@backstage/theme@npm:0.5.5" - 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 || ^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: a5ba7b39d41773a4a73a07d1a9a6bcf0815835a196a31c1ec1d5eac61ec801bfe875f31823a6ae6aa5033b21bd04b4fa692fd3fddc71a12e2126b1d222738b34 - languageName: node - linkType: hard - -"@backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": +"@backstage/theme@^0.5.0, @backstage/theme@^0.5.6, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": version: 0.0.0-use.local resolution: "@backstage/theme@workspace:packages/theme" dependencies: @@ -8208,8 +8200,8 @@ __metadata: linkType: hard "@changesets/cli@npm:^2.14.0": - version: 2.27.5 - resolution: "@changesets/cli@npm:2.27.5" + version: 2.27.6 + resolution: "@changesets/cli@npm:2.27.6" dependencies: "@babel/runtime": ^7.20.1 "@changesets/apply-release-plan": ^7.0.3 @@ -8235,7 +8227,7 @@ __metadata: external-editor: ^3.1.0 fs-extra: ^7.0.1 human-id: ^1.0.2 - meow: ^6.0.0 + mri: ^1.2.0 outdent: ^0.5.0 p-limit: ^2.2.0 preferred-pm: ^3.0.0 @@ -8243,10 +8235,9 @@ __metadata: semver: ^7.5.3 spawndamnit: ^2.0.0 term-size: ^2.1.0 - tty-table: ^4.1.5 bin: changeset: bin.js - checksum: 7e0d0aadabcf3028abbb2e079b58135b8e39f78bc174f4fa669cf94482ca3a4ec873e4b4ff9a7e071d83aee592780f0c47bd36a3a12282ab5f13a493c796663f + checksum: efb3c7b569debb2bb0baae2d7bafee4ae19d3c7f0023ea97fa0b6518198c85ba16c2a66609561c9dd0f0601c3390d5933b00e3ad3cb962b4b0e7fcb4de929dfa languageName: node linkType: hard @@ -8504,13 +8495,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.23.0": - version: 6.26.3 - resolution: "@codemirror/view@npm:6.26.3" + version: 6.28.2 + resolution: "@codemirror/view@npm:6.28.2" dependencies: "@codemirror/state": ^6.4.0 style-mod: ^4.1.0 w3c-keyname: ^2.2.4 - checksum: fdee35fb5e0bbba7b6f1a9b43a865880911bbfafd30360da5dda21b35f81ba2d080ff66b6c3d94dbe946b6b7ec98a76208786360b8f030ef10bcb054b816de05 + checksum: d2d36d7bbb1fc094fb421251b96144b67a932f43d12092bd2318ced283db0081e6e78cc99c5cecf9eedd24278d39fe41deaa490fcc03637d85c5cf332af58fec languageName: node linkType: hard @@ -8809,6 +8800,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/aix-ppc64@npm:0.21.5" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm64@npm:0.18.20" @@ -8823,6 +8821,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm64@npm:0.21.5" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm@npm:0.18.20" @@ -8837,6 +8842,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm@npm:0.21.5" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-x64@npm:0.18.20" @@ -8851,6 +8863,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-x64@npm:0.21.5" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-arm64@npm:0.18.20" @@ -8865,6 +8884,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-arm64@npm:0.21.5" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-x64@npm:0.18.20" @@ -8879,6 +8905,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-x64@npm:0.21.5" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-arm64@npm:0.18.20" @@ -8893,6 +8926,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-arm64@npm:0.21.5" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-x64@npm:0.18.20" @@ -8907,6 +8947,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-x64@npm:0.21.5" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm64@npm:0.18.20" @@ -8921,6 +8968,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm64@npm:0.21.5" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm@npm:0.18.20" @@ -8935,6 +8989,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm@npm:0.21.5" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ia32@npm:0.18.20" @@ -8949,6 +9010,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ia32@npm:0.21.5" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-loong64@npm:0.18.20" @@ -8963,6 +9031,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-loong64@npm:0.21.5" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-mips64el@npm:0.18.20" @@ -8977,6 +9052,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-mips64el@npm:0.21.5" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ppc64@npm:0.18.20" @@ -8991,6 +9073,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ppc64@npm:0.21.5" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-riscv64@npm:0.18.20" @@ -9005,6 +9094,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-riscv64@npm:0.21.5" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-s390x@npm:0.18.20" @@ -9019,6 +9115,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-s390x@npm:0.21.5" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-x64@npm:0.18.20" @@ -9033,6 +9136,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-x64@npm:0.21.5" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/netbsd-x64@npm:0.18.20" @@ -9047,6 +9157,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/netbsd-x64@npm:0.21.5" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/openbsd-x64@npm:0.18.20" @@ -9061,6 +9178,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/openbsd-x64@npm:0.21.5" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/sunos-x64@npm:0.18.20" @@ -9075,6 +9199,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/sunos-x64@npm:0.21.5" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-arm64@npm:0.18.20" @@ -9089,6 +9220,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-arm64@npm:0.21.5" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-ia32@npm:0.18.20" @@ -9103,6 +9241,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-ia32@npm:0.21.5" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-x64@npm:0.18.20" @@ -9117,6 +9262,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-x64@npm:0.21.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" @@ -9316,11 +9468,11 @@ __metadata: linkType: hard "@google-cloud/container@npm:^5.0.0": - version: 5.12.0 - resolution: "@google-cloud/container@npm:5.12.0" + version: 5.15.0 + resolution: "@google-cloud/container@npm:5.15.0" dependencies: google-gax: ^4.0.3 - checksum: bf22c6754d67b133f272522b41f9f383e960a3288847d345407a171cce593856527cd3ee3df13bb4b09091bfce03f3404d24559ce2c28733ce71866068fb5277 + checksum: e31332b17816688f0cf831c66ef1ccc24c7600e4ec798fdeed33b66ed934372b1a962e92c665903bae661db5aaf872d79becc7d67b3f9c6a55b403acdfd534ec languageName: node linkType: hard @@ -9361,8 +9513,8 @@ __metadata: linkType: hard "@google-cloud/storage@npm:^7.0.0": - version: 7.10.1 - resolution: "@google-cloud/storage@npm:7.10.1" + version: 7.11.2 + resolution: "@google-cloud/storage@npm:7.11.2" dependencies: "@google-cloud/paginator": ^5.0.0 "@google-cloud/projectify": ^4.0.0 @@ -9370,16 +9522,16 @@ __metadata: abort-controller: ^3.0.0 async-retry: ^1.3.3 duplexify: ^4.1.3 - ent: ^2.2.0 fast-xml-parser: ^4.3.0 gaxios: ^6.0.2 google-auth-library: ^9.6.3 + html-entities: ^2.5.2 mime: ^3.0.0 p-limit: ^3.0.1 retry-request: ^7.0.0 teeny-request: ^9.0.0 uuid: ^8.0.0 - checksum: 0605f8abf67cde98bc48b05c749b569416af821fcc3eb8ed3fac6dc5ade9c1f2f3210404c85e30525260ea4f34785d7436f7684e6eacd083613237669badff25 + checksum: 763cd560245006e11a060fdbd5edff5d6bfe22b0c0b06dfe88af43b7b14458598c00a71c4e1b079e9ab09096d7d262bdc27fa77d76a8969af0765f23c93f8405 languageName: node linkType: hard @@ -10073,11 +10225,11 @@ __metadata: linkType: hard "@jest-mock/express@npm:^2.0.1": - version: 2.0.2 - resolution: "@jest-mock/express@npm:2.0.2" + version: 2.1.0 + resolution: "@jest-mock/express@npm:2.1.0" dependencies: - "@types/express": ^4.17.17 - checksum: 558feb47e7e9620a5e53b83c51b3802782ecf7ab32b8d81077b16f641b7e1a6dc6fffa652d2ab48b28ba0f0634fa6387bd21b08f62b92bd730dfca167a4c2795 + "@types/express": ^4.17.21 + checksum: 305b72c214c1e80ed16271aa48e4d6d906346f5221a4e873d1e8ae48c32c2316cb88bed819b195c934c339b9ab41d4b34c4e41ac66feefe980d2cd16bc0b6d20 languageName: node linkType: hard @@ -11019,23 +11171,23 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.15": - version: 5.15.15 - resolution: "@mui/core-downloads-tracker@npm:5.15.15" - checksum: 3e99a04e03f66d5fa5f0c23cdce0f9fa2331ba08c99a75dc2347ccaa1c6ed520153e04aaeb0d613c9dca099a3e6242558a6284c33d93f95cc65e3243b17860bc +"@mui/core-downloads-tracker@npm:^5.15.20": + version: 5.15.20 + resolution: "@mui/core-downloads-tracker@npm:5.15.20" + checksum: 8cc71169ce1201c5a37fad6c5c58739850694e90c7bda636c692d47a79fd4c7884eab2c24b0084d6732a3d28c9a4a6d222dd5747f9d91f5075614700a3a3282a languageName: node linkType: hard "@mui/material@npm:^5.12.2": - version: 5.15.15 - resolution: "@mui/material@npm:5.15.15" + version: 5.15.20 + resolution: "@mui/material@npm:5.15.20" dependencies: "@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/core-downloads-tracker": ^5.15.20 + "@mui/system": ^5.15.20 "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 + "@mui/utils": ^5.15.20 "@types/react-transition-group": ^4.4.10 clsx: ^2.1.0 csstype: ^3.1.3 @@ -11055,16 +11207,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: ee0dc22fc4d617f7cf69f2451b6d5139978e6c5319e3056e7719159aff786ee3b80abd07691e230371811d9b5b574aef4559d7855bfe2f8493d596d960a91ab7 + checksum: 0d0e29682fa8f4ff03746efabb4b480da9dfe004e68982a36662ff0d40d76f5840ebf8ef3b0f9629056afb3030145dd5eb3bd2b0ab96d201fac7a300fef155b0 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/private-theming@npm:5.15.14" +"@mui/private-theming@npm:^5.15.20": + version: 5.15.20 + resolution: "@mui/private-theming@npm:5.15.20" dependencies: "@babel/runtime": ^7.23.9 - "@mui/utils": ^5.15.14 + "@mui/utils": ^5.15.20 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -11072,7 +11224,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 1b1ef54e8281c9b13fcc58f4c39682efc610946a68402283c19fcfbce8a7d7a231d61b536d6df9bf7a59a1426591bd403a453a59eb8efb9689437fb58554dc8c + checksum: 5c70a9ebca3827cea11d67b3f8ed24d18a10c44f30f14d8d1c37b3f1e74d7a5e91cec5ffb7f24e8b2d974b38e4d046a93473c20a0cd7c7a880580e5df3d1afb7 languageName: node linkType: hard @@ -11098,14 +11250,14 @@ __metadata: linkType: hard "@mui/styles@npm:^5.14.18": - version: 5.15.15 - resolution: "@mui/styles@npm:5.15.15" + version: 5.15.20 + resolution: "@mui/styles@npm:5.15.20" dependencies: "@babel/runtime": ^7.23.9 "@emotion/hash": ^0.9.1 - "@mui/private-theming": ^5.15.14 + "@mui/private-theming": ^5.15.20 "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 + "@mui/utils": ^5.15.20 clsx: ^2.1.0 csstype: ^3.1.3 hoist-non-react-statics: ^3.3.2 @@ -11124,19 +11276,19 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 5e436a8a22ae9a2e6fcb63ead3a6eff2092cc9731fce0b22d04ab9c67639a173a0e27fb617628e7720592862118a32248be458bedfabaf1de5448543a97b0307 + checksum: bdc19d66caf3fb3272dd1c67d6a40b0e77bca2c3c7a5b9112ebed2cf3d6795932401bcb9ddfb9daba9c3e293455cf9cb2c24975eff15c75a2ce3d40ed30d59d7 languageName: node linkType: hard -"@mui/system@npm:^5.15.15": - version: 5.15.15 - resolution: "@mui/system@npm:5.15.15" +"@mui/system@npm:^5.15.20": + version: 5.15.20 + resolution: "@mui/system@npm:5.15.20" dependencies: "@babel/runtime": ^7.23.9 - "@mui/private-theming": ^5.15.14 + "@mui/private-theming": ^5.15.20 "@mui/styled-engine": ^5.15.14 "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 + "@mui/utils": ^5.15.20 clsx: ^2.1.0 csstype: ^3.1.3 prop-types: ^15.8.1 @@ -11152,7 +11304,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 9ca96d5f66b2a9d6471909cc98c671eea5ec0a6d58a7ec071073b9e5200b95c3f017f0ca5cc946abc7f83074bd11830ca18f5e30bc98e25cd6ca217bd1b3a26f + checksum: e9e79b6a905845aef87939de8ac7990d73a2f92bba02e41905dcb9f44e53727bdfa52a978cf59a2a2cfa73d2512df78c4351eb130d7c25af1880bb8b7ebfc686 languageName: node linkType: hard @@ -11168,9 +11320,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/utils@npm:5.15.14" +"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.14, @mui/utils@npm:^5.15.20": + version: 5.15.20 + resolution: "@mui/utils@npm:5.15.20" dependencies: "@babel/runtime": ^7.23.9 "@types/prop-types": ^15.7.11 @@ -11182,7 +11334,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 36543ba7e3b65fb3219ed27e8f1455aff15b47a74c9b642c63e60774e22baa6492a196079e72bcfa5a570421dab32160398f892110bd444428bcf8b266b11893 + checksum: 8f8c7f9129e0eb1bf55c1d675c647da1fa4acf1c7f50e0ce2ce750cc0603e62fdc21b76e8ef8ff9bf06bce054e9cf97210ed737f55887b0ef939bd6605b4e537 languageName: node linkType: hard @@ -12331,7 +12483,7 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/api@npm:^1.0.0, @opentelemetry/api@npm:^1.0.1, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.0": +"@opentelemetry/api@npm:^1.0.0, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.0": version: 1.8.0 resolution: "@opentelemetry/api@npm:1.8.0" checksum: 0e32079975f05bee6de2ad8ade097f0afdc63f462c76550150fce2444c73ab92aaf851ac85e638b6e3b269da6640ac7e63f33913a0fd7df9f9beec2e100759df @@ -13584,13 +13736,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.44.1 - resolution: "@playwright/test@npm:1.44.1" + version: 1.45.0 + resolution: "@playwright/test@npm:1.45.0" dependencies: - playwright: 1.44.1 + playwright: 1.45.0 bin: playwright: cli.js - checksum: 90507b77e388aa984deb92db56f7bb3b305c6be441e1d0087ca046989cfdda068bbc26d75bd29c20ad3dbb2434e69a8ff0d6b30003b88c9234cd3aa6a9f7deb9 + checksum: 55fb72f393b05f6684b5098e0681712f71e1fe25aa6a00bd636133f9ccc26d096d61ee30f569b83368e4bf6a1288d2f8f6fd5364da5d396eab180f89f61b7164 languageName: node linkType: hard @@ -14329,9 +14481,9 @@ __metadata: languageName: node linkType: hard -"@rjsf/core@npm:5.18.4": - version: 5.18.4 - resolution: "@rjsf/core@npm:5.18.4" +"@rjsf/core@npm:5.18.5": + version: 5.18.5 + resolution: "@rjsf/core@npm:5.18.5" dependencies: lodash: ^4.17.21 lodash-es: ^4.17.21 @@ -14341,26 +14493,26 @@ __metadata: peerDependencies: "@rjsf/utils": ^5.18.x react: ^16.14.0 || >=17 - checksum: 8c3f49914be396595ce67dc4c36ac25c5cb6673917ec82c47f79321f5bb78d02741e8dca39287d0435270e7c9ccb06f7d40e396bdf71a3e9eb1371ef16954817 + checksum: 7b986ec075d5b2de503d01172abdb3e3d33d04e5298fbf80842400e682f0aecdabfe4bb8482dde8a6aed90a35f4f5574cb7b24a11d689566c0cc0599485b334a languageName: node linkType: hard -"@rjsf/material-ui@npm:5.18.4": - version: 5.18.4 - resolution: "@rjsf/material-ui@npm:5.18.4" +"@rjsf/material-ui@npm:5.18.5": + version: 5.18.5 + resolution: "@rjsf/material-ui@npm:5.18.5" peerDependencies: "@material-ui/core": ^4.12.3 "@material-ui/icons": ^4.11.2 "@rjsf/core": ^5.18.x "@rjsf/utils": ^5.18.x react: ^16.14.0 || >=17 - checksum: 2bb0eeb0603bd11b034785ac1902cfcf3630cb4d04161728adff86b2629ca4d21bbb42beb9e6acdd4c9a6a4d84cce1ca325413a9bd1fd94eda47f58d62eb3164 + checksum: 61337141bcd7bcb46013d81ae6b618919eff3f55319800511443e524876bf5c84089970e14148716de203d5def341aa15c4d102243f0b694f120f05189a3adb7 languageName: node linkType: hard -"@rjsf/utils@npm:5.18.4": - version: 5.18.4 - resolution: "@rjsf/utils@npm:5.18.4" +"@rjsf/utils@npm:5.18.5": + version: 5.18.5 + resolution: "@rjsf/utils@npm:5.18.5" dependencies: json-schema-merge-allof: ^0.8.1 jsonpointer: ^5.0.1 @@ -14369,13 +14521,13 @@ __metadata: react-is: ^18.2.0 peerDependencies: react: ^16.14.0 || >=17 - checksum: d7cf514527ec50a94751c5ec1f9e5eafd89d0c56441a22ae28a4e667aaa7c60447e1e1ccf8355c5be5b97e9a1163853c116816b13307e3463433d50f6b89bb3e + checksum: 8da3ce82a0ec83e78806461db7226fd20489f6e8c41906ccde9d55c554aec3f50b8b8bac8c35e3cdf12d788c18fdad71c992f0d8b44f6161a1bf9e13598ded99 languageName: node linkType: hard -"@rjsf/validator-ajv8@npm:5.18.4": - version: 5.18.4 - resolution: "@rjsf/validator-ajv8@npm:5.18.4" +"@rjsf/validator-ajv8@npm:5.18.5": + version: 5.18.5 + resolution: "@rjsf/validator-ajv8@npm:5.18.5" dependencies: ajv: ^8.12.0 ajv-formats: ^2.1.1 @@ -14383,7 +14535,7 @@ __metadata: lodash-es: ^4.17.21 peerDependencies: "@rjsf/utils": ^5.18.x - checksum: edf3b24e07babe972e57645d396467c6404ff3f95a79118667f2d62082aa28e4ee7df5fad81e28071cd24b5455fe687a9f9bcf714718d4fd6036912b04c69a84 + checksum: 350d1f8043b7bbd88cf5d7fa28560062f4141e1ef9ef004c2997b63d0281d4a1af04be4b951c2c9c4d1c56d10f0e2fbab665c7176b38e87dd6da6d5303e1c84e languageName: node linkType: hard @@ -14851,177 +15003,187 @@ __metadata: languageName: node linkType: hard -"@smithy/chunked-blob-reader-native@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/chunked-blob-reader-native@npm:2.2.0" +"@smithy/abort-controller@npm:^3.0.1, @smithy/abort-controller@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/abort-controller@npm:3.1.0" dependencies: - "@smithy/util-base64": ^2.3.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: ac619f18844e8a8288672c40b8967a82b78f5398119638b3e4fcadf451a3356139307c2d9f24c8c041530238f1ce6e0f90ce82adfcb050d08afefa2f0541c2d0 + checksum: 78643bddda2bcb68e00bb95ae866741407236b92b1834796c0855710950386ae1e5e67d72fb42ec444e8a4dc4357a1527c4f331324a2fad156468f5a0cccf128 languageName: node linkType: hard -"@smithy/chunked-blob-reader@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/chunked-blob-reader@npm:2.2.0" +"@smithy/chunked-blob-reader-native@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/chunked-blob-reader-native@npm:3.0.0" dependencies: + "@smithy/util-base64": ^3.0.0 tslib: ^2.6.2 - checksum: f5acb1e812f97d7c233ccf955557ac10c7e94c8c9610d2fad715d1010fe30ee686a93a5d6e589ce8ae4eb7cf201d5eab61cee5e8646bbebdfa8a5f23693d7a5a + checksum: f97c0c0ce5e9bd2350883df3c232311aa82eb87eb387125f685900326f86fc3aca208e9004291f742f6978abf91a0c1112cc9a803cd0caf0dffbcfa9b6d0239e languageName: node linkType: hard -"@smithy/config-resolver@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/config-resolver@npm:2.2.0" +"@smithy/chunked-blob-reader@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/chunked-blob-reader@npm:3.0.0" dependencies: - "@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 + checksum: 6f520884ade14f1073adb640db2f03eb22a9920f342f37958df3e98327890b741cd909b16cbbc6f70c6c8dd250d6b3a8d76841b685d4871b0403f309267def4f languageName: node linkType: hard -"@smithy/core@npm:^1.4.2": - version: 1.4.2 - resolution: "@smithy/core@npm:1.4.2" +"@smithy/config-resolver@npm:^3.0.2, @smithy/config-resolver@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/config-resolver@npm:3.0.3" dependencies: - "@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 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/types": ^3.2.0 + "@smithy/util-config-provider": ^3.0.0 + "@smithy/util-middleware": ^3.0.2 tslib: ^2.6.2 - checksum: 414ec1c392ab5346f2b833f310078d7e850df8b9e5db6fedbce65116146c2fda116d56db841401ba05b5e7399a5f5c426870d324bf6fd060143ce66e2f3eafbb + checksum: 7a7baf23e64ed85d4229bfd320a3ea96087c57ce1b94638a89bab5f92dcc24ec22c11740d90f2fab38eb39eeb860463ae98b24598555c2b55a01bd79c20ef99b languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/credential-provider-imds@npm:2.3.0" +"@smithy/core@npm:^2.2.1": + version: 2.2.3 + resolution: "@smithy/core@npm:2.2.3" dependencies: - "@smithy/node-config-provider": ^2.3.0 - "@smithy/property-provider": ^2.2.0 - "@smithy/types": ^2.12.0 - "@smithy/url-parser": ^2.2.0 + "@smithy/middleware-endpoint": ^3.0.3 + "@smithy/middleware-retry": ^3.0.6 + "@smithy/middleware-serde": ^3.0.2 + "@smithy/protocol-http": ^4.0.2 + "@smithy/smithy-client": ^3.1.4 + "@smithy/types": ^3.2.0 + "@smithy/util-middleware": ^3.0.2 tslib: ^2.6.2 - checksum: dd57e09e60bd51ed103f7a5363a43e1373470ea3cee04ace66f5bbaafab005355ffbfa3e137e2ecac34aa28911fb5b6ecac60845846c6a4a5432f3e57a74b837 + checksum: 6addaede7f4699c48d690872647bbc86efc5bf9adb088557cfd4263e629e6bd7d45a1de983824a7c5ff608ec2cd42d7c6f61854d3d33b8ded352df550789b34b languageName: node linkType: hard -"@smithy/eventstream-codec@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-codec@npm:2.2.0" +"@smithy/credential-provider-imds@npm:^3.1.1, @smithy/credential-provider-imds@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/credential-provider-imds@npm:3.1.2" dependencies: - "@aws-crypto/crc32": 3.0.0 - "@smithy/types": ^2.12.0 - "@smithy/util-hex-encoding": ^2.2.0 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/property-provider": ^3.1.2 + "@smithy/types": ^3.2.0 + "@smithy/url-parser": ^3.0.2 tslib: ^2.6.2 - checksum: ae59067964e19c6728b1be74a6e19793e4d3decdcbcea546bd40f77c3cc1eacc48c30272ef68927ba477c2b6450d023474f2dec516dfd93e204150ba18cab697 + checksum: bf0ce9f7c510f5f7e05d08c2b1d861f133016457e3872bfc5e4ac9b22f26123adcf773a562189971e2ce97bdad2f576a4eefb764808df2ae1833e77be86358f2 languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-serde-browser@npm:2.2.0" +"@smithy/eventstream-codec@npm:^3.1.1": + version: 3.1.1 + resolution: "@smithy/eventstream-codec@npm:3.1.1" dependencies: - "@smithy/eventstream-serde-universal": ^2.2.0 - "@smithy/types": ^2.12.0 + "@aws-crypto/crc32": 5.2.0 + "@smithy/types": ^3.2.0 + "@smithy/util-hex-encoding": ^3.0.0 tslib: ^2.6.2 - checksum: c00bd592365f42ddafcad83f06d3c85ce8ee21bd806de903043ef132de9acca8bf1592ed811b11daba1742332928fc73a66c9032b06df2f6526da0339918f8d5 + checksum: fdc7a2bcf99f7c830ba24b5745877ec26556613423a025c6b122b167ef92a76a860f7dffe21f25667f12c2736a121f4e2064050dcf768406a60ce3ebc029e402 languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-serde-config-resolver@npm:2.2.0" +"@smithy/eventstream-serde-browser@npm:^3.0.2": + version: 3.0.3 + resolution: "@smithy/eventstream-serde-browser@npm:3.0.3" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/eventstream-serde-universal": ^3.0.3 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: a35dbcbc14ad1825ce22a9e7daac93067d8ade6173a3ce33b819eed61390f8d93ea63b70945f6d1bced175fad58def3d09a14ee3043c63a798ecef407b2d1701 + checksum: 3e41fb32f06dc266ab41185482e441068c1e84ac5637462fc107511a495a7338972f10568bb57970e22eef2d14e024f93e0991b30b54545bca5b5189add5d41e languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-serde-node@npm:2.2.0" +"@smithy/eventstream-serde-config-resolver@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/eventstream-serde-config-resolver@npm:3.0.2" dependencies: - "@smithy/eventstream-serde-universal": ^2.2.0 - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 1d4971b99654c4672716608a63e668ccefd78cc1806c0ea4df5c3cc0ca0208b7647f7914d2c77a37d0a29b31b66cff660ce2ab2f46f56d997c9a58ea6b6241b2 + checksum: 5c2113b6acc65df61f6fc844054c5a85825305e1d9f47987a5f350b603e304c8d90ad2c62cb7a098f10b7243c4f466fa413264821d261a3b69dc12c33fa976d4 languageName: node linkType: hard -"@smithy/eventstream-serde-universal@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/eventstream-serde-universal@npm:2.2.0" +"@smithy/eventstream-serde-node@npm:^3.0.2": + version: 3.0.3 + resolution: "@smithy/eventstream-serde-node@npm:3.0.3" dependencies: - "@smithy/eventstream-codec": ^2.2.0 - "@smithy/types": ^2.12.0 + "@smithy/eventstream-serde-universal": ^3.0.3 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: c28038c2f57deed7b5e0e5f8ab8150d4a7947f2971241da96ef1d53b45d83dfa661717065f059099c420ee66ae2455818ae124bb8601b609558040d4a7509227 + checksum: 29e2323b92a87302518ecfd75096e856c77a3d39ffa2680ff56e11c2c01b4434f56f86940e13c636e207af7cadf867f824f5c60249c53e1c27faa1cf932b6eb9 languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^2.5.0": - version: 2.5.0 - resolution: "@smithy/fetch-http-handler@npm:2.5.0" +"@smithy/eventstream-serde-universal@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/eventstream-serde-universal@npm:3.0.3" dependencies: - "@smithy/protocol-http": ^3.3.0 - "@smithy/querystring-builder": ^2.2.0 - "@smithy/types": ^2.12.0 - "@smithy/util-base64": ^2.3.0 + "@smithy/eventstream-codec": ^3.1.1 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 91a58ac32c6b4afc6d7fb2b9ac3e3b817171f76e09b013a6506308b044455054444a92e1acbd8f98bdd159b15fdd44b1e3fb52c21cbb2e69be8e3698d2206021 + checksum: 6c0c3602e3e79bb0abe47f1d7b8c277f58879ab613cda99d80cf0e825653055f892daee313e6d40e5096932e004838e3c9f674e440b97921520257f80337bed8 languageName: node linkType: hard -"@smithy/hash-blob-browser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/hash-blob-browser@npm:2.2.0" +"@smithy/fetch-http-handler@npm:^3.0.2, @smithy/fetch-http-handler@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/fetch-http-handler@npm:3.1.0" dependencies: - "@smithy/chunked-blob-reader": ^2.2.0 - "@smithy/chunked-blob-reader-native": ^2.2.0 - "@smithy/types": ^2.12.0 + "@smithy/protocol-http": ^4.0.2 + "@smithy/querystring-builder": ^3.0.2 + "@smithy/types": ^3.2.0 + "@smithy/util-base64": ^3.0.0 tslib: ^2.6.2 - checksum: 1b748b4449ccee723c8b47a412491283fa7b5a2a6c27b0b73e03d905c2af70b56b74d63a658d8ef0bd330cc4617bc11431c86e24a4932b4722aad08e1b25e576 + checksum: 7b9b928e8a094e41a9c7516aa2fcfd3bb88b0271737e1d4fa301973a49f577094fa967ba481a0cf6e5c977be6bb8b2898d868b3269a476cae2aaaed582277733 languageName: node linkType: hard -"@smithy/hash-node@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/hash-node@npm:2.2.0" +"@smithy/hash-blob-browser@npm:^3.1.0": + version: 3.1.1 + resolution: "@smithy/hash-blob-browser@npm:3.1.1" dependencies: - "@smithy/types": ^2.12.0 - "@smithy/util-buffer-from": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@smithy/chunked-blob-reader": ^3.0.0 + "@smithy/chunked-blob-reader-native": ^3.0.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 3305b5778fa99558375b16629ad98fd00a1fb33ea905037977b0a7c93d92c8de1481756ef7dbc004e45210b23f983dec04bcd13d43c98f36a5f47291cbed9d89 + checksum: 9a54f0b7d48d5a411c2e3361f8a946d71b75d54965bc3d2a0524d0fe01fc032c2ee2a4e105104daefa14e3e02f0e38b9e83faf0b40d3933a33b87d8b8b142c8f languageName: node linkType: hard -"@smithy/hash-stream-node@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/hash-stream-node@npm:2.2.0" +"@smithy/hash-node@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/hash-node@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 - "@smithy/util-utf8": ^2.3.0 + "@smithy/types": ^3.2.0 + "@smithy/util-buffer-from": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 191d76fd1df705c32d24463794f8b8b391061c7ca7265591cd4f070259fa80395c2f115fd3d37f6bb3a4a2303b3811a31509ea767d0c3d0a9644789ae8283118 + checksum: 2b7b678d429b9806a28f18472f8beec45f5a2e1d004b084cc4b591c1239565c46435b278c7f76be09790d6d6eabc617e7d0f3aef11c375721b78600506d62856 languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/invalid-dependency@npm:2.2.0" +"@smithy/hash-stream-node@npm:^3.1.0": + version: 3.1.1 + resolution: "@smithy/hash-stream-node@npm:3.1.1" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: ed17980ccdf4c564cfcb517f3959dfeb7c7dbddd76eaf2c9e10031ebd19e78e56609df3377626215e51a6c4b98db03cfa88ad46f15ba26bb55c34351f3182a98 + checksum: 21d4d8ffca488a1aa83d97eb418197ca4b9c25329ce2d67a5978cd4b74ee7e609ebcb510fce3a271ce240b5e421073cda516e23cde7d9fedbb682ee02d7b7c9f + languageName: node + linkType: hard + +"@smithy/invalid-dependency@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/invalid-dependency@npm:3.0.2" + dependencies: + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: 21f0f2669989d9b8ffdc86e80fa8d0a39b5ada187a21c61bc4405936a31fa054a59577fa8fde4de707de559cc3e08c80aaac0205aaacf0eaf3a2ff620fa12830 languageName: node linkType: hard @@ -15034,93 +15196,102 @@ __metadata: languageName: node linkType: hard -"@smithy/md5-js@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/md5-js@npm:2.2.0" +"@smithy/is-array-buffer@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/is-array-buffer@npm:3.0.0" dependencies: - "@smithy/types": ^2.12.0 - "@smithy/util-utf8": ^2.3.0 tslib: ^2.6.2 - checksum: ae343c198a8d8c6689bcb1d7f766e29578d370e8d79180db9b6183b5c74ac091829e8abe3053df0589f53324c01a79c7f9e889e5cd92094e3b5c4be96fb7b970 + checksum: ce7440fcb1ce3c46722cff11c33e2f62a9df86d74fa2054a8e6b540302a91211cf6e4e3b1b7aac7030c6c8909158c1b6867c394201fa8afc6b631979956610e5 languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/middleware-content-length@npm:2.2.0" +"@smithy/md5-js@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/md5-js@npm:3.0.2" dependencies: - "@smithy/protocol-http": ^3.3.0 - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 1eae8d2b6f432ce9a849e741d4f2426baee8a51f22a5262c11802e125078ee33d9d8f4183fb142043ba9d1371adad9c835c784333a394d865fb248339f7482e6 + checksum: cc8857d043b53234ce280776ac7592ed6287c911d7ac45d3b9836adbf01b9e814a1f164b8a8c5b654bde14e8ce4baed17494b983d4cfee61584da623f9b794e5 languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^2.5.1": - version: 2.5.1 - resolution: "@smithy/middleware-endpoint@npm:2.5.1" +"@smithy/middleware-content-length@npm:^3.0.1": + version: 3.0.2 + resolution: "@smithy/middleware-content-length@npm:3.0.2" dependencies: - "@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 + "@smithy/protocol-http": ^4.0.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 7ac2a35a6f52c33d868fc4b73330ae34fecfc43c59b8d501ee9fb81924c6747494700b55b3025b83fe7bea3d4e323c8853ec5b117c17cccf06cc27bbc4f492b2 + checksum: 67758207c3a26eb6d44fd922d178299418fc42a07937813364a17a76547bf736df75d279cb493fca9ac5c3897c0c8d24c6e124f3edc143c991a26b44521eb423 languageName: node linkType: hard -"@smithy/middleware-retry@npm:^2.3.1": - version: 2.3.1 - resolution: "@smithy/middleware-retry@npm:2.3.1" +"@smithy/middleware-endpoint@npm:^3.0.2, @smithy/middleware-endpoint@npm:^3.0.3": + version: 3.0.3 + resolution: "@smithy/middleware-endpoint@npm:3.0.3" dependencies: - "@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 + "@smithy/middleware-serde": ^3.0.2 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/shared-ini-file-loader": ^3.1.2 + "@smithy/types": ^3.2.0 + "@smithy/url-parser": ^3.0.2 + "@smithy/util-middleware": ^3.0.2 + tslib: ^2.6.2 + checksum: 15a37293aa590bd0c8ab59430e967f786500603bca92dbde655480c3b7c1812a8cbcd267ff31691c2d8ea596f7917769ef91fa4033e07ec9971bf252fc12ebcd + languageName: node + linkType: hard + +"@smithy/middleware-retry@npm:^3.0.4, @smithy/middleware-retry@npm:^3.0.6": + version: 3.0.6 + resolution: "@smithy/middleware-retry@npm:3.0.6" + dependencies: + "@smithy/node-config-provider": ^3.1.2 + "@smithy/protocol-http": ^4.0.2 + "@smithy/service-error-classification": ^3.0.2 + "@smithy/smithy-client": ^3.1.4 + "@smithy/types": ^3.2.0 + "@smithy/util-middleware": ^3.0.2 + "@smithy/util-retry": ^3.0.2 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 5eebf9d26fccc6c8c517924463e93d244edebe52d120b28d5d705904f83773da1734296b8d57b4f30a15cbf36690e508f5946dfd56749cbcda501d08cb778933 + checksum: c17ac5665e0dd2315e996c219b5aa2327c9270a49ca7dc64b8d81c80261f9d0098d3725641f2e4c87aac293c283d709fb062b5c7be6912e72f9042492a3e91d9 languageName: node linkType: hard -"@smithy/middleware-serde@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/middleware-serde@npm:2.3.0" +"@smithy/middleware-serde@npm:^3.0.1, @smithy/middleware-serde@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/middleware-serde@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 5393370c0f8a820d8ca36eccecff5b6434c4f81fbaad8800088fb4c8dad5312bf3eb47f67533784de959807bbb3379c23d81a1bcbaf8824254034dd2b83fd76b + checksum: 16c933ecb8061ff9fcf49ecabcc54b6d56de0e02464e5dd995ac729ad06e70be7a341c329b0b7cc1b33c8dbaa31372e337130e9eb6aac4c2df63ce37cb36d54f languageName: node linkType: hard -"@smithy/middleware-stack@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/middleware-stack@npm:2.2.0" +"@smithy/middleware-stack@npm:^3.0.1, @smithy/middleware-stack@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/middleware-stack@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 293d76764e327a5ada4ea7de268f451e62a6a56983ba7dcdbc63fdbb0427c01071a9a81d7807b16586977df829ce5d9587facbd9367b089841bbc9fc329ce6af + checksum: 70ec59d020ae6d8c53aefecb039fb511cfa67a57ce00ba1e41d2c3da346265cc18bdf1e0724b0df10f1ef838807e151e93f6da6e886fafbac51d2ed962b795d1 languageName: node linkType: hard -"@smithy/node-config-provider@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/node-config-provider@npm:2.3.0" +"@smithy/node-config-provider@npm:^3.1.1, @smithy/node-config-provider@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/node-config-provider@npm:3.1.2" dependencies: - "@smithy/property-provider": ^2.2.0 - "@smithy/shared-ini-file-loader": ^2.4.0 - "@smithy/types": ^2.12.0 + "@smithy/property-provider": ^3.1.2 + "@smithy/shared-ini-file-loader": ^3.1.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 9c1dc6d97e0379d947498e7d64e593ea183d5f2c89dace4561c1c613850bf264581b597105c15d64ceabdea954e57ad8e6bf9e42642ddc3f737464f350ffbb5b + checksum: 596e7a6b92fa68f6c172969bde6a04aadf35634f78a601351642b44bc271f3ad5444588a8c3dea8f7cdbe65a2d69e1c1d93291bf8d240736a035ac8db4e96ce3 languageName: node linkType: hard -"@smithy/node-http-handler@npm:^2.1.7, @smithy/node-http-handler@npm:^2.5.0": +"@smithy/node-http-handler@npm:^2.1.7": version: 2.5.0 resolution: "@smithy/node-http-handler@npm:2.5.0" dependencies: @@ -15133,13 +15304,26 @@ __metadata: languageName: node linkType: hard -"@smithy/property-provider@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/property-provider@npm:2.2.0" +"@smithy/node-http-handler@npm:^3.0.1, @smithy/node-http-handler@npm:^3.1.0": + version: 3.1.0 + resolution: "@smithy/node-http-handler@npm:3.1.0" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/abort-controller": ^3.1.0 + "@smithy/protocol-http": ^4.0.2 + "@smithy/querystring-builder": ^3.0.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 8d257cbc5222baf6706e288c3b51196588f135878141f8af76fcb3f0abafc027ed46cf4bb938266d1906111175082ee85f73806d5a2b1c929aee16ec8b5283e6 + checksum: 915cc2876cfe5b2330e868aa512930d4c126192d7695354dc2a88aab1c6639968ace36c1e8778c8a647a8b6f3f3faac2a14870607043cba972e05ee94491738a + languageName: node + linkType: hard + +"@smithy/property-provider@npm:^3.1.1, @smithy/property-provider@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/property-provider@npm:3.1.2" + dependencies: + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: 9ec0cce2728dd4a0d327fef523ca5bddcba9a7750e6e5a614293d6ba4c12d6b86c32020689481a529b4797d07315fd84647f13ea0dbe91f1da7932c954b08421 languageName: node linkType: hard @@ -15153,6 +15337,16 @@ __metadata: languageName: node linkType: hard +"@smithy/protocol-http@npm:^4.0.1, @smithy/protocol-http@npm:^4.0.2": + version: 4.0.2 + resolution: "@smithy/protocol-http@npm:4.0.2" + dependencies: + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: e1b419e0324f20300c490491cbc32b9d151579a6ce11f708b76ed265ef3499d404d9c0e3443692984514a0f8042b456f5c7e1a62694d42c7dc9bc64bfcff0301 + languageName: node + linkType: hard + "@smithy/querystring-builder@npm:^2.2.0": version: 2.2.0 resolution: "@smithy/querystring-builder@npm:2.2.0" @@ -15164,61 +15358,72 @@ __metadata: languageName: node linkType: hard -"@smithy/querystring-parser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/querystring-parser@npm:2.2.0" +"@smithy/querystring-builder@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/querystring-builder@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 + "@smithy/util-uri-escape": ^3.0.0 tslib: ^2.6.2 - checksum: 9b27751c329fecc84bdfe7f128ab766c7e5f1d4bdda6184699a0df8999e95aef21fafc6179d6c693e519c78874e738fd9afb5ac4679901cb68d092a86a612419 + checksum: c6f6fc8681879daed9c85b3fd2d81cbbf553addbdc1d6ab2660687d967af40eba0112e40cf1157bdd4c42784bc22977a3da9ed9dde674b7ede5e70720a0b38af 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" +"@smithy/querystring-parser@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/querystring-parser@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 - checksum: 00ac54110a258c7a47c62d4f655d4998bd40e5adb47e10281b28df7a585f2f1e960dc35325eac006636280e7fb2b81dbeb32b89e08bac87acc136c4d29a4dc53 + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: 7f18281e8d73c70dc020e1a8719a8322d88130c24e8c8cffa39ffe83e9f18d28bb9d420e6026ddb17d60ac950b0fb5b9465a4ba8493086e6186f60a9573b2ad8 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" +"@smithy/service-error-classification@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/service-error-classification@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 - tslib: ^2.6.2 - checksum: b0c9e045bfe2150e07f4b31ae7d69d3646679337df9fec1e1201b845cc64ea2250c37db8e8d0e7573fc3c11188164adba43bbaf32275fa8a9f70e8bbc77146bf + "@smithy/types": ^3.2.0 + checksum: f7cfd6438286942ec1f7f059c4bdac517c64833fcbea27198880106c7e55d0c2083f0c8e22c8fe5a68f0d86e5bd33a78f644898b48008b2f14c0c13d46f0923c languageName: node linkType: hard -"@smithy/signature-v4@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/signature-v4@npm:2.3.0" +"@smithy/shared-ini-file-loader@npm:^3.1.1, @smithy/shared-ini-file-loader@npm:^3.1.2": + version: 3.1.2 + resolution: "@smithy/shared-ini-file-loader@npm:3.1.2" 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 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 96050956b86876d0137af9b003d0a30005766bffc730495d7c106bd2eb05c8ada2da23ceac51d56e04f98b304e0ea55d698e1a10c99cda3ade44b3ac30166a00 + checksum: bbb7ceaefdcbe4e43e5a65cf424e41f6a70e44fc9b05b7f8c968bd6134253e04af4455ad0fa91fda18f55695b7992c8bfc5281aa201be2a69f7733014fd84042 languageName: node linkType: hard -"@smithy/smithy-client@npm:^2.5.1": - version: 2.5.1 - resolution: "@smithy/smithy-client@npm:2.5.1" +"@smithy/signature-v4@npm:^3.1.0": + version: 3.1.1 + resolution: "@smithy/signature-v4@npm:3.1.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 + "@smithy/is-array-buffer": ^3.0.0 + "@smithy/types": ^3.2.0 + "@smithy/util-hex-encoding": ^3.0.0 + "@smithy/util-middleware": ^3.0.2 + "@smithy/util-uri-escape": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 10d51793aab8f6e0ba0890a2a101216ffc3a1c43664f8ed9688dcbc174ca0f83f2d1c8d7af484c84491174067af3d6b235b765a58b12f2308a6bfe42b1d74f59 + checksum: f7eca9889ac4252e8fff76bf31a75bbc8afebc7ac690e3fddffadaccde64fd05305b6e22ad00f8d8da3bb3ca8739d310d6abe70350a4c12c996fb0335a8bd975 + languageName: node + linkType: hard + +"@smithy/smithy-client@npm:^3.1.2, @smithy/smithy-client@npm:^3.1.4": + version: 3.1.4 + resolution: "@smithy/smithy-client@npm:3.1.4" + dependencies: + "@smithy/middleware-endpoint": ^3.0.3 + "@smithy/middleware-stack": ^3.0.2 + "@smithy/protocol-http": ^4.0.2 + "@smithy/types": ^3.2.0 + "@smithy/util-stream": ^3.0.4 + tslib: ^2.6.2 + checksum: be1ce3523d5b49d1c2fb75695201dcc3748583050675efc7910b0a8bc9444c781daf435bec711166e6d2f0238ed301187283362c33aa31aefd2c21b09fb305a5 languageName: node linkType: hard @@ -15240,43 +15445,52 @@ __metadata: languageName: node linkType: hard -"@smithy/url-parser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/url-parser@npm:2.2.0" +"@smithy/types@npm:^3.1.0, @smithy/types@npm:^3.2.0": + version: 3.2.0 + resolution: "@smithy/types@npm:3.2.0" dependencies: - "@smithy/querystring-parser": ^2.2.0 - "@smithy/types": ^2.12.0 tslib: ^2.6.2 - checksum: f21f1e44bc2a4634220465990651f5ee0708cb6759b3685b8a8c00cc2cd64bbbc7807f66cd79ec6e654f7245867d4fb4ced406ad5c14612ebc47eae3f34e63c5 + checksum: f07caa63cd2f1ed9a14612a9493fcc9c0aca974593e16c1328daecc7f36af2ece5e5e79c24212966180f88a183abf078bfbcd98cf362a8d8f95f3f8642d41389 languageName: node linkType: hard -"@smithy/util-base64@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/util-base64@npm:2.3.0" +"@smithy/url-parser@npm:^3.0.1, @smithy/url-parser@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/url-parser@npm:3.0.2" dependencies: - "@smithy/util-buffer-from": ^2.2.0 - "@smithy/util-utf8": ^2.3.0 + "@smithy/querystring-parser": ^3.0.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 2ce995c5d12037e9518bb2732f24090bc493d48118dfd6519faa41e19cd91863895bc0b5958b790d2cdeb919a8c410790dcffa3a452d560f0eeab73dc0c92cbd + checksum: a0dac1ff3eac440d3dba7f2ad80eb3cfb46cf912ceb4a533b0bd87ad5b5f1e9b641ca9a247844129c33dc2901cbe753c89185b70c6d323b781b83451a738702e languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-body-length-browser@npm:2.2.0" +"@smithy/util-base64@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-base64@npm:3.0.0" dependencies: + "@smithy/util-buffer-from": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: e9c1d16b3b95d529011476e6154eaf282d3a983204b29dcf1e7ef04a9f5c2deae30167e06190f315771c813c768f19f486d3139fe9fcaf34d12c2333350f3412 + checksum: 413f26046a7e98b2661a078f218a8d040c820fc5a02f5e364aff58c3957e28fde1ac4048c2ebbad5d87b9da4b9aa98a8d4a7fb0d2ce97def33738bd7d8d79aa0 languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/util-body-length-node@npm:2.3.0" +"@smithy/util-body-length-browser@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-body-length-browser@npm:3.0.0" dependencies: tslib: ^2.6.2 - checksum: 5d5c31b071e0b3222dcfe863ea2d179253f0dfaa30d03f40ebfa352ed292e00a451053cc523e27527e61094d5ed475069d2287ef19a857c6da0364ca71cfdf3c + checksum: b01d8258b9a25b262734fc49cefefe48583ba193c3eefd49a6f7fd5922c3015d23dda88b52f3dd9a16827cad16b5b9425eef01e91bd0c71bb5abc469d2952c07 + languageName: node + linkType: hard + +"@smithy/util-body-length-node@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-body-length-node@npm:3.0.0" + dependencies: + tslib: ^2.6.2 + checksum: da1baf4790609d3dc28c88385c7274fdf9b91a641fe3c5af22b78e18156df17bd470181348f43b2c739680936b1dafb1526158dfd817c3d9ecb71e653b4cbe3f languageName: node linkType: hard @@ -15290,97 +15504,107 @@ __metadata: languageName: node linkType: hard -"@smithy/util-config-provider@npm:^2.3.0": - version: 2.3.0 - resolution: "@smithy/util-config-provider@npm:2.3.0" +"@smithy/util-buffer-from@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-buffer-from@npm:3.0.0" dependencies: + "@smithy/is-array-buffer": ^3.0.0 tslib: ^2.6.2 - checksum: 0f3f113c2658bd5a79f98dc28d53ca9c0adf8ec3c8c86c7dd91d2cd37149b4cf83d85cc89d5fe67ffe5cd319ec85f139ef229844eb039017193b307a4c315399 + checksum: 1bfc4ab093fe98132bbc1ccd36a0b9ad75a31ed26bac4b7e9350205513a2481eb190ae44679ab4fecc5e10d367b5e6592bbfbf792671579d17d17bd7f7f233f5 languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^2.2.1": - version: 2.2.1 - resolution: "@smithy/util-defaults-mode-browser@npm:2.2.1" +"@smithy/util-config-provider@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-config-provider@npm:3.0.0" dependencies: - "@smithy/property-provider": ^2.2.0 - "@smithy/smithy-client": ^2.5.1 - "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: fc0f5f57d30261cf3a6693d8e338b9d269332c478ee18d905309a769844188190caf0564855d7e84f6c61e56aa556195dda89f65e8c30791951cf4999e4a70e7 + languageName: node + linkType: hard + +"@smithy/util-defaults-mode-browser@npm:^3.0.4": + version: 3.0.6 + resolution: "@smithy/util-defaults-mode-browser@npm:3.0.6" + dependencies: + "@smithy/property-provider": ^3.1.2 + "@smithy/smithy-client": ^3.1.4 + "@smithy/types": ^3.2.0 bowser: ^2.11.0 tslib: ^2.6.2 - checksum: 286337d9165181e1df3d28d348210e88f20662ec63a9d6c1bcfce3342003de130a218dab42ce64aa4399ef345e2528414f73f399f8f4c8e9a6fcbc8e48250f98 + checksum: 753e21d8b6c9cbfb874dd9468823bce7ebfa979da8972fb5c67a31333513cebe09072fcb9ae803219bf41775569c8277e49f83abd96041042d3c487d299c7a0a languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^2.3.1": - version: 2.3.1 - resolution: "@smithy/util-defaults-mode-node@npm:2.3.1" +"@smithy/util-defaults-mode-node@npm:^3.0.4": + version: 3.0.6 + resolution: "@smithy/util-defaults-mode-node@npm:3.0.6" dependencies: - "@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 + "@smithy/config-resolver": ^3.0.3 + "@smithy/credential-provider-imds": ^3.1.2 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/property-provider": ^3.1.2 + "@smithy/smithy-client": ^3.1.4 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 7fb9d0ac8b5919955399284c1801f49a1f5275f6cf240894ba0a91a8825248bb167938647a983d89905d6bfa7b226789781e85d2ff7f27c58cdd32c2e68600ae + checksum: d64efd2b5bd7b4b3b1a668725d34018bd8cae00b8a59991eadabf122e590ad153be4f9beda58b063b451d9f03371575c9a8e2806bcc0b7790e63fc9d839f5c95 languageName: node linkType: hard -"@smithy/util-endpoints@npm:^1.2.0": - version: 1.2.0 - resolution: "@smithy/util-endpoints@npm:1.2.0" +"@smithy/util-endpoints@npm:^2.0.2": + version: 2.0.3 + resolution: "@smithy/util-endpoints@npm:2.0.3" dependencies: - "@smithy/node-config-provider": ^2.3.0 - "@smithy/types": ^2.12.0 + "@smithy/node-config-provider": ^3.1.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 19a59b1c9b214457371d4d7109b190c237de5ebd06f5b4f3665dddc5fe0879dbb19bcdc5dec23d1825cd04388b7f9bf7fddf354e1a23e84d9c690ad21e71cb86 + checksum: f8b77a7f68bd99b73362b29a56e35270b509f76ed82c003e82dae1468f46c2c986060aea1fcb78f3d9346830f62c1c3f3e0aa4de856b8897ba183efabc22969d 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" +"@smithy/util-hex-encoding@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-hex-encoding@npm:3.0.0" dependencies: tslib: ^2.6.2 - checksum: 7d14589bc4a44eebf878595290c53ee4d90cc6b5445b5fe130608d6dea477c292730b85e4e08190a1555ef7664214f0f00dc478ba725516787a49fff658e725e + checksum: dd32fd71e915825987a18bf7c0f8f0c4956d0b17a0ee71592b5563bb20e04f24dbf81d36161aac07caab3bb5e535cc609fce20aa4a38f66b457c4c6f5c7748d9 languageName: node linkType: hard -"@smithy/util-middleware@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-middleware@npm:2.2.0" +"@smithy/util-middleware@npm:^3.0.1, @smithy/util-middleware@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/util-middleware@npm:3.0.2" dependencies: - "@smithy/types": ^2.12.0 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 312dc86e5415a12e2580a02311750b350aec8fb9da5a60c3010c10694990ded869b7ca5b87aa20e5facbacdd233e928e418b7765d7797019cd48177052aedd03 + checksum: 8a6183d3fd4a7c01787fbfd1dd901b1cdf0937f3c5e73646e8377b1e3322782e191cb7c1c9278e6c84d7462d4b0e70bcac9cfca52367728b3357914db96f90cc languageName: node linkType: hard -"@smithy/util-retry@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-retry@npm:2.2.0" +"@smithy/util-retry@npm:^3.0.1, @smithy/util-retry@npm:^3.0.2": + version: 3.0.2 + resolution: "@smithy/util-retry@npm:3.0.2" dependencies: - "@smithy/service-error-classification": ^2.1.5 - "@smithy/types": ^2.12.0 + "@smithy/service-error-classification": ^3.0.2 + "@smithy/types": ^3.2.0 tslib: ^2.6.2 - checksum: 1a8071c8ac5a2646b3d3894e3bd9c36a9db045f52eadb194f32b02d2fdedd69fb267a2b02bcef9f91d0f8f3fe061754ac075d07ac166d90894acb27d68c62a41 + checksum: 68846a52a6c71658db40f54681afad8c9bdb4687dc3c12fd13c27cf9aa3b96c57469a4d5658d4caabc9c710d95f920c0a3faafc9503fb99fb6466f51072fe852 languageName: node linkType: hard -"@smithy/util-stream@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-stream@npm:2.2.0" +"@smithy/util-stream@npm:^3.0.2, @smithy/util-stream@npm:^3.0.4": + version: 3.0.4 + resolution: "@smithy/util-stream@npm:3.0.4" 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 + "@smithy/fetch-http-handler": ^3.1.0 + "@smithy/node-http-handler": ^3.1.0 + "@smithy/types": ^3.2.0 + "@smithy/util-base64": ^3.0.0 + "@smithy/util-buffer-from": ^3.0.0 + "@smithy/util-hex-encoding": ^3.0.0 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: f0febd1a7558201d9178c0018478f89729800e9b8962dc735ec99f41ce01d1128373e3bd6008f0b4ff79b25ee4476db4fd5fa18d6feeb8b5b715d416da7027c3 + checksum: ba4a785d30606e82cbf80e644be05fad7a1813e19226ec8893a91993e0c943bc222643ab9c70625f72ee760b4f4d1632e74af586e028e7d3dc8197b1927e580b languageName: node linkType: hard @@ -15393,7 +15617,16 @@ __metadata: languageName: node linkType: hard -"@smithy/util-utf8@npm:^2.0.0, @smithy/util-utf8@npm:^2.3.0": +"@smithy/util-uri-escape@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-uri-escape@npm:3.0.0" + dependencies: + tslib: ^2.6.2 + checksum: d7ee01c978e2b08d0a89a3b678f5d5e5d5bb4ab4ab85567a238b1a6195dff1bdaf9ae62497e7f32ff5121b3dc007c370bcb6e8ef79b01fe5acdec5bbce8c7ce4 + languageName: node + linkType: hard + +"@smithy/util-utf8@npm:^2.0.0": version: 2.3.0 resolution: "@smithy/util-utf8@npm:2.3.0" dependencies: @@ -15403,14 +15636,24 @@ __metadata: languageName: node linkType: hard -"@smithy/util-waiter@npm:^2.2.0": - version: 2.2.0 - resolution: "@smithy/util-waiter@npm:2.2.0" +"@smithy/util-utf8@npm:^3.0.0": + version: 3.0.0 + resolution: "@smithy/util-utf8@npm:3.0.0" dependencies: - "@smithy/abort-controller": ^2.2.0 - "@smithy/types": ^2.12.0 + "@smithy/util-buffer-from": ^3.0.0 tslib: ^2.6.2 - checksum: 303f56beb9ba4afada862eff4950a17d904a4fdfc01bd8acb932b0457e457730981162777004414252e700014c554d894a1ce9d32e0bad75e1a4a2ca6492429e + checksum: d97be1748963263a1161ba80417d82318b977b38542f3fdf0379b0162461188be680e5bfb66a89d65652f0fad6ecf2ab23a43205979216e50602488f73434da3 + languageName: node + linkType: hard + +"@smithy/util-waiter@npm:^3.0.1": + version: 3.1.1 + resolution: "@smithy/util-waiter@npm:3.1.1" + dependencies: + "@smithy/abort-controller": ^3.1.0 + "@smithy/types": ^3.2.0 + tslib: ^2.6.2 + checksum: dda2666bc0c91a158fdcd04eab41f01130b5d34a9d8a86ea5ed9a8d1c87829caf381fda34a0595bf4748e99365a36842afe12fbf045f532c55f0d14f49c6a448 languageName: node linkType: hard @@ -16600,21 +16843,19 @@ __metadata: version: 0.0.0-use.local resolution: "@techdocs/cli@workspace:packages/techdocs-cli" dependencies: - "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" "@backstage/config": "workspace:^" "@backstage/plugin-techdocs-node": "workspace:^" "@types/commander": ^2.12.2 - "@types/dockerode": ^3.3.0 "@types/fs-extra": ^11.0.0 "@types/http-proxy": ^1.17.4 "@types/node": ^18.17.8 "@types/serve-handler": ^6.1.0 "@types/webpack-env": ^1.15.3 commander: ^12.0.0 - dockerode: ^4.0.0 find-process: ^1.4.5 fs-extra: ^11.0.0 global-agent: ^3.0.0 @@ -17301,14 +17542,14 @@ __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.19.3 - resolution: "@types/express-serve-static-core@npm:4.19.3" + version: 4.19.5 + resolution: "@types/express-serve-static-core@npm:4.19.5" dependencies: "@types/node": "*" "@types/qs": "*" "@types/range-parser": "*" "@types/send": "*" - checksum: fff38a7f43baeb6a62380682d39846c9d92047e0dce1737d76ebd944528619abc18addc4f0548bf43dbf4514090a1bd5140ba36695024656f941a87424b8ed7d + checksum: 72076c2f8df55e89136d4343fc874050d56c0f4afd885772a8aa506b98c3f4f3ddc7dcba42295a8b931c61000234fd679aec79ef50db15f376bf37d46234939a languageName: node linkType: hard @@ -17321,7 +17562,7 @@ __metadata: languageName: node linkType: hard -"@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": +"@types/express@npm:*, @types/express@npm:^4.17.14, @types/express@npm:^4.17.21, @types/express@npm:^4.17.6": version: 4.17.21 resolution: "@types/express@npm:4.17.21" dependencies: @@ -17360,6 +17601,13 @@ __metadata: languageName: node linkType: hard +"@types/global-agent@npm:^2.1.3": + version: 2.1.3 + resolution: "@types/global-agent@npm:2.1.3" + checksum: 6129b6d5ba871b9d111ddf91e6f9a1725d3f28bf2aa6869ec83bebd14c688cde4275ebea6fa45b0b1c00d78109d022c935f952e9e4876d76289d4706484776c3 + languageName: node + linkType: hard + "@types/google-protobuf@npm:^3.7.2": version: 3.15.12 resolution: "@types/google-protobuf@npm:3.15.12" @@ -17897,7 +18145,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.12": version: 2.6.11 resolution: "@types/node-fetch@npm:2.6.11" dependencies: @@ -17971,13 +18219,6 @@ __metadata: languageName: node linkType: hard -"@types/normalize-package-data@npm:^2.4.0": - version: 2.4.1 - resolution: "@types/normalize-package-data@npm:2.4.1" - checksum: e87bccbf11f95035c89a132b52b79ce69a1e3652fe55962363063c9c0dae0fe2477ebc585e03a9652adc6f381d24ba5589cc5e51849df4ced3d3e004a7d40ed5 - languageName: node - linkType: hard - "@types/npm-packlist@npm:^3.0.0": version: 3.0.0 resolution: "@types/npm-packlist@npm:3.0.0" @@ -18264,7 +18505,7 @@ __metadata: languageName: node linkType: hard -"@types/react-window@npm:^1.8.5": +"@types/react-window@npm:^1.8.5, @types/react-window@npm:^1.8.8": version: 1.8.8 resolution: "@types/react-window@npm:1.8.8" dependencies: @@ -18625,15 +18866,6 @@ __metadata: languageName: node linkType: hard -"@types/tunnel@npm:^0.0.3": - version: 0.0.3 - resolution: "@types/tunnel@npm:0.0.3" - dependencies: - "@types/node": "*" - checksum: 53e23a1f9fb14a491c00425b2a4fc443817564d77be5e1b95fcbeb6d009551b62ea82ffc3e5ca0c6b9f6b186824ca6ec46e7450c1bcd6674a46d1325f0116e24 - languageName: node - linkType: hard - "@types/unist@npm:*, @types/unist@npm:^2.0.0": version: 2.0.6 resolution: "@types/unist@npm:2.0.6" @@ -20728,7 +20960,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flat@npm:^1.2.3, array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": version: 1.3.2 resolution: "array.prototype.flat@npm:1.3.2" dependencies: @@ -20764,16 +20996,16 @@ __metadata: languageName: node linkType: hard -"array.prototype.tosorted@npm:^1.1.3": - version: 1.1.3 - resolution: "array.prototype.tosorted@npm:1.1.3" +"array.prototype.tosorted@npm:^1.1.4": + version: 1.1.4 + resolution: "array.prototype.tosorted@npm:1.1.4" dependencies: - call-bind: ^1.0.5 + call-bind: ^1.0.7 define-properties: ^1.2.1 - es-abstract: ^1.22.3 - es-errors: ^1.1.0 + es-abstract: ^1.23.3 + es-errors: ^1.3.0 es-shim-unscopables: ^1.0.2 - checksum: 555e8808086bbde9e634c5dc5a8c0a2f1773075447b43b2fa76ab4f94f4e90f416d2a4f881024e1ce1a2931614caf76cd6b408af901c9d7cd13061d0d268f5af + checksum: e4142d6f556bcbb4f393c02e7dbaea9af8f620c040450c2be137c9cbbd1a17f216b9c688c5f2c08fbb038ab83f55993fa6efdd9a05881d84693c7bcb5422127a languageName: node linkType: hard @@ -20793,13 +21025,6 @@ __metadata: languageName: node linkType: hard -"arrify@npm:^1.0.1": - version: 1.0.1 - resolution: "arrify@npm:1.0.1" - checksum: 745075dd4a4624ff0225c331dacb99be501a515d39bcb7c84d24660314a6ec28e68131b137e6f7e16318170842ce97538cd298fc4cd6b2cc798e0b957f2747e7 - languageName: node - linkType: hard - "arrify@npm:^2.0.0, arrify@npm:^2.0.1": version: 2.0.1 resolution: "arrify@npm:2.0.1" @@ -21476,14 +21701,14 @@ __metadata: languageName: node linkType: hard -"better-sqlite3@npm:^9.0.0": - version: 9.6.0 - resolution: "better-sqlite3@npm:9.6.0" +"better-sqlite3@npm:^11.0.0": + version: 11.0.0 + resolution: "better-sqlite3@npm:11.0.0" dependencies: bindings: ^1.5.0 node-gyp: latest prebuild-install: ^7.1.1 - checksum: be3a1d2a3f6f9b5141be6607a38c0a51fa5849495b071955e507bc0c2a2fb08430852c1bf03796eec1a53344b25645807db48dcb51c71b0662b74c5a70420bb0 + checksum: 7bf02ea6ba3253f53cb36bd872f86379ebf1a66cb103d39b91c610995c4396dde2b976bdf866f07eb7d67eb6f5433aa5490a6a4f4264244f83a53562f68832dc languageName: node linkType: hard @@ -21699,15 +21924,6 @@ __metadata: languageName: node linkType: hard -"breakword@npm:^1.0.5": - version: 1.0.5 - resolution: "breakword@npm:1.0.5" - dependencies: - wcwidth: ^1.0.1 - checksum: 8ca7b10bbbbfe1c45c12c9119c4bc1e585452ddd58c5da93020a0c1deac3cf6bb335632675c9c705ba7b644065ae1d6623a25e79b7a48e0ee0ff42cb6e94b357 - languageName: node - linkType: hard - "brorand@npm:^1.0.1, brorand@npm:^1.1.0": version: 1.1.0 resolution: "brorand@npm:1.1.0" @@ -22137,17 +22353,6 @@ __metadata: languageName: node linkType: hard -"camelcase-keys@npm:^6.2.2": - version: 6.2.2 - resolution: "camelcase-keys@npm:6.2.2" - dependencies: - camelcase: ^5.3.1 - map-obj: ^4.0.0 - quick-lru: ^4.0.1 - checksum: 43c9af1adf840471e54c68ab3e5fe8a62719a6b7dbf4e2e86886b7b0ff96112c945736342b837bd2529ec9d1c7d1934e5653318478d98e0cf22c475c04658e2a - languageName: node - linkType: hard - "camelcase@npm:5.0.0": version: 5.0.0 resolution: "camelcase@npm:5.0.0" @@ -22155,7 +22360,7 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": +"camelcase@npm:^5.3.1": version: 5.3.1 resolution: "camelcase@npm:5.3.1" checksum: e6effce26b9404e3c0f301498184f243811c30dfe6d0b9051863bd8e4034d09c8c2923794f280d6827e5aa055f6c434115ff97864a16a963366fb35fd673024b @@ -22577,17 +22782,6 @@ __metadata: languageName: node linkType: hard -"cliui@npm:^6.0.0": - version: 6.0.0 - resolution: "cliui@npm:6.0.0" - dependencies: - string-width: ^4.2.0 - strip-ansi: ^6.0.0 - wrap-ansi: ^6.2.0 - checksum: 4fcfd26d292c9f00238117f39fc797608292ae36bac2168cfee4c85923817d0607fe21b3329a8621e01aedf512c99b7eaa60e363a671ffd378df6649fb48ae42 - languageName: node - linkType: hard - "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -23967,39 +24161,6 @@ __metadata: languageName: node linkType: hard -"csv-generate@npm:^3.4.3": - version: 3.4.3 - resolution: "csv-generate@npm:3.4.3" - checksum: 868dc630e8bcabf42d3d1ef22c09fb783de72d7e5929854aad0323f44059b1747edf8a2724e32fdc5008396e2ea38d5c45df0b0e3a1b506e3ab34f76f3e2fb3a - languageName: node - linkType: hard - -"csv-parse@npm:^4.16.3": - version: 4.16.3 - resolution: "csv-parse@npm:4.16.3" - checksum: 5ad7790fc31c32ca1623bad1a54906134ba44fa109e8dd2dfda440bf7e9fd93610d9076a78f45c872701bfafdf7f93c9b75500c09d7efd6611d863f1d45ec69f - languageName: node - linkType: hard - -"csv-stringify@npm:^5.6.5": - version: 5.6.5 - resolution: "csv-stringify@npm:5.6.5" - checksum: f93e1444857416081de3d86765b62e4c4f7c110974ad6bbcb0031d7db39b6624847ac9ee5705726e7011346f32f3696f27299b74b23a6c2b083adff0dd2755fe - languageName: node - linkType: hard - -"csv@npm:^5.5.0": - version: 5.5.3 - resolution: "csv@npm:5.5.3" - dependencies: - csv-generate: ^3.4.3 - csv-parse: ^4.16.3 - csv-stringify: ^5.6.5 - stream-transform: ^2.1.3 - checksum: 0decc2d0d7a0abf127f4556d6f3cef5a54015b78d348608b5e8f42256c2bd0a021f34f1efc9723b2cd162680917de4c0b3967bfb65a07305eca0827654ca727e - languageName: node - linkType: hard - "ctrlc-windows@npm:^2.1.0": version: 2.1.0 resolution: "ctrlc-windows@npm:2.1.0" @@ -24286,23 +24447,6 @@ __metadata: languageName: node linkType: hard -"decamelize-keys@npm:^1.1.0": - version: 1.1.0 - resolution: "decamelize-keys@npm:1.1.0" - dependencies: - decamelize: ^1.1.0 - map-obj: ^1.0.0 - checksum: 8bc5d32e035a072f5dffc1f1f3d26ca7ab1fb44a9cade34c97ab6cd1e62c81a87e718101e96de07d78cecda20a3fdb955df958e46671ccad01bb8dcf0de2e298 - languageName: node - linkType: hard - -"decamelize@npm:^1.1.0, decamelize@npm:^1.2.0": - version: 1.2.0 - resolution: "decamelize@npm:1.2.0" - checksum: ad8c51a7e7e0720c70ec2eeb1163b66da03e7616d7b98c9ef43cce2416395e84c1e9548dd94f5f6ffecfee9f8b94251fc57121a8b021f2ff2469b2bae247b8aa - 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" @@ -25282,13 +25426,6 @@ __metadata: languageName: node linkType: hard -"ent@npm:^2.2.0": - version: 2.2.0 - resolution: "ent@npm:2.2.0" - checksum: f588b5707d6fef36011ea10d530645912a69530a1eb0831f8708c498ac028363a7009f45cfadd28ceb4dafd9ac17ec15213f88d09ce239cd033cfe1328dd7d7d - languageName: node - linkType: hard - "entities@npm:^2.0.0": version: 2.2.0 resolution: "entities@npm:2.2.0" @@ -25427,7 +25564,7 @@ __metadata: languageName: node linkType: hard -"es-errors@npm:^1.1.0, es-errors@npm:^1.2.1, es-errors@npm:^1.3.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 @@ -25733,6 +25870,86 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.21.0": + version: 0.21.5 + resolution: "esbuild@npm:0.21.5" + dependencies: + "@esbuild/aix-ppc64": 0.21.5 + "@esbuild/android-arm": 0.21.5 + "@esbuild/android-arm64": 0.21.5 + "@esbuild/android-x64": 0.21.5 + "@esbuild/darwin-arm64": 0.21.5 + "@esbuild/darwin-x64": 0.21.5 + "@esbuild/freebsd-arm64": 0.21.5 + "@esbuild/freebsd-x64": 0.21.5 + "@esbuild/linux-arm": 0.21.5 + "@esbuild/linux-arm64": 0.21.5 + "@esbuild/linux-ia32": 0.21.5 + "@esbuild/linux-loong64": 0.21.5 + "@esbuild/linux-mips64el": 0.21.5 + "@esbuild/linux-ppc64": 0.21.5 + "@esbuild/linux-riscv64": 0.21.5 + "@esbuild/linux-s390x": 0.21.5 + "@esbuild/linux-x64": 0.21.5 + "@esbuild/netbsd-x64": 0.21.5 + "@esbuild/openbsd-x64": 0.21.5 + "@esbuild/sunos-x64": 0.21.5 + "@esbuild/win32-arm64": 0.21.5 + "@esbuild/win32-ia32": 0.21.5 + "@esbuild/win32-x64": 0.21.5 + 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: 2911c7b50b23a9df59a7d6d4cdd3a4f85855787f374dce751148dbb13305e0ce7e880dde1608c2ab7a927fc6cec3587b80995f7fc87a64b455f8b70b55fd8ec1 + languageName: node + linkType: hard + "esbuild@npm:esbuild-wasm@^0.15.15": version: 0.15.18 resolution: "esbuild-wasm@npm:0.15.18" @@ -25983,14 +26200,14 @@ __metadata: linkType: hard "eslint-plugin-react@npm:^7.28.0": - version: 7.34.2 - resolution: "eslint-plugin-react@npm:7.34.2" + version: 7.34.3 + resolution: "eslint-plugin-react@npm:7.34.3" dependencies: array-includes: ^3.1.8 array.prototype.findlast: ^1.2.5 array.prototype.flatmap: ^1.3.2 array.prototype.toreversed: ^1.1.2 - array.prototype.tosorted: ^1.1.3 + array.prototype.tosorted: ^1.1.4 doctrine: ^2.1.0 es-iterator-helpers: ^1.0.19 estraverse: ^5.3.0 @@ -26006,7 +26223,7 @@ __metadata: string.prototype.matchall: ^4.0.11 peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: aed331239f3a64fcd884380534ece4b8716f1eca4899c8636d04306879e6b4e7339e28e427bdd571d372b78b713025e0767e5f5b5486a8d19bff82616ebe8959 + checksum: 1a519b9792ab9392a5157f2543ce98ab1218c62f4a31c4c3ceb5dd3e7997def4aa07ab39f7276af0fe116ef002db29d97216a15b7aa3b200e55b641cf77d6292 languageName: node linkType: hard @@ -26364,7 +26581,7 @@ __metadata: react-use: ^17.2.4 vite: ^4.4.9 vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.21.0 + vite-plugin-node-polyfills: ^0.22.0 zen-observable: ^0.10.0 languageName: unknown linkType: soft @@ -26438,7 +26655,7 @@ __metadata: react-use: ^17.2.4 vite: ^4.4.9 vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.21.0 + vite-plugin-node-polyfills: ^0.22.0 zen-observable: ^0.10.0 languageName: unknown linkType: soft @@ -26490,7 +26707,7 @@ __metadata: "@types/express-serve-static-core": ^4.17.5 "@types/luxon": ^3.0.0 azure-devops-node-api: ^12.0.0 - better-sqlite3: ^9.0.0 + better-sqlite3: ^11.0.0 dockerode: ^4.0.0 example-app: "link:../app" express: ^4.17.1 @@ -26948,14 +27165,14 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:^4.3.0": - version: 4.3.2 - resolution: "fast-xml-parser@npm:4.3.2" +"fast-xml-parser@npm:^4.3.0, fast-xml-parser@npm:^4.3.2": + version: 4.4.0 + resolution: "fast-xml-parser@npm:4.4.0" dependencies: strnum: ^1.0.5 bin: fxparser: src/cli/cli.js - checksum: d507ce2efa5fd13d0a5ba28bd76dd68f2fc30ad8748357c37b70f360d19417866d79e35a688af067d5bceaaa796033fa985206aef9692f7a421e1326b6e73309 + checksum: ad33a4b5165a0ffcb6e17ae78825bd4619a8298844a8a8408f2ea141a0d2d9439d18865dc5254162f09fe54d510ff18e5d5c0a190869cab21fc745ee66be816b languageName: node linkType: hard @@ -27056,15 +27273,6 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:8.0.0": - version: 8.0.0 - resolution: "file-entry-cache@npm:8.0.0" - dependencies: - flat-cache: ^4.0.0 - checksum: f67802d3334809048c69b3d458f672e1b6d26daefda701761c81f203b80149c35dea04d78ea4238969dd617678e530876722a0634c43031a0957f10cc3ed190f - languageName: node - linkType: hard - "file-entry-cache@npm:^6.0.1": version: 6.0.1 resolution: "file-entry-cache@npm:6.0.1" @@ -27262,16 +27470,6 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^4.0.0": - version: 4.0.1 - resolution: "flat-cache@npm:4.0.1" - dependencies: - flatted: ^3.2.9 - keyv: ^4.5.4 - checksum: 899fc86bf6df093547d76e7bfaeb900824b869d7d457d02e9b8aae24836f0a99fbad79328cfd6415ee8908f180699bf259dc7614f793447cb14f707caf5996f6 - languageName: node - linkType: hard - "flatstr@npm:^1.0.12": version: 1.0.12 resolution: "flatstr@npm:1.0.12" @@ -27279,7 +27477,7 @@ __metadata: languageName: node linkType: hard -"flatted@npm:3.3.1, flatted@npm:^3.1.0, flatted@npm:^3.2.9": +"flatted@npm:3.3.1, flatted@npm:^3.1.0": version: 3.3.1 resolution: "flatted@npm:3.3.1" checksum: 85ae7181650bb728c221e7644cbc9f4bf28bc556f2fc89bb21266962bdf0ce1029cc7acc44bb646cd469d9baac7c317f64e841c4c4c00516afa97320cdac7f94 @@ -27790,7 +27988,7 @@ __metadata: languageName: node linkType: hard -"get-caller-file@npm:^2.0.1, get-caller-file@npm:^2.0.5": +"get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" checksum: b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 @@ -28470,13 +28668,6 @@ __metadata: languageName: node linkType: hard -"hard-rejection@npm:^2.1.0": - version: 2.1.0 - resolution: "hard-rejection@npm:2.1.0" - checksum: 7baaf80a0c7fff4ca79687b4060113f1529589852152fa935e6787a2bc96211e784ad4588fb3048136ff8ffc9dfcf3ae385314a5b24db32de20bea0d1597f9dc - languageName: node - linkType: hard - "harmony-reflect@npm:^1.4.6": version: 1.6.1 resolution: "harmony-reflect@npm:1.6.1" @@ -28701,13 +28892,6 @@ __metadata: languageName: node linkType: hard -"hosted-git-info@npm:^2.1.4": - version: 2.8.9 - resolution: "hosted-git-info@npm:2.8.9" - checksum: c955394bdab888a1e9bb10eb33029e0f7ce5a2ac7b3f158099dc8c486c99e73809dca609f5694b223920ca2174db33d32b12f9a2a47141dc59607c29da5a62dd - languageName: node - linkType: hard - "hosted-git-info@npm:^4.0.1": version: 4.1.0 resolution: "hosted-git-info@npm:4.1.0" @@ -28761,10 +28945,10 @@ __metadata: languageName: node linkType: hard -"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 +"html-entities@npm:^2.1.0, html-entities@npm:^2.4.0, html-entities@npm:^2.5.2": + version: 2.5.2 + resolution: "html-entities@npm:2.5.2" + checksum: b23f4a07d33d49ade1994069af4e13d31650e3fb62621e92ae10ecdf01d1a98065c78fd20fdc92b4c7881612210b37c275f2c9fba9777650ab0d6f2ceb3b99b6 languageName: node linkType: hard @@ -29002,7 +29186,7 @@ __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.4, https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": version: 7.0.4 resolution: "https-proxy-agent@npm:7.0.4" dependencies: @@ -29973,13 +30157,6 @@ __metadata: languageName: node linkType: hard -"is-plain-obj@npm:^1.1.0": - version: 1.1.0 - resolution: "is-plain-obj@npm:1.1.0" - checksum: 0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 - languageName: node - linkType: hard - "is-plain-obj@npm:^3.0.0": version: 3.0.0 resolution: "is-plain-obj@npm:3.0.0" @@ -31497,7 +31674,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.1.2, json5@npm:^2.1.3, json5@npm:^2.2.3": +"json5@npm:^2.1.2, json5@npm:^2.1.3, json5@npm:^2.2.2, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" bin: @@ -31802,7 +31979,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:*, keyv@npm:^4.0.0, keyv@npm:^4.5.2, keyv@npm:^4.5.4": +"keyv@npm:*, keyv@npm:^4.0.0, keyv@npm:^4.5.2": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -31820,7 +31997,7 @@ __metadata: languageName: node linkType: hard -"kind-of@npm:^6.0.2, kind-of@npm:^6.0.3": +"kind-of@npm:^6.0.2": version: 6.0.3 resolution: "kind-of@npm:6.0.3" checksum: 3ab01e7b1d440b22fe4c31f23d8d38b4d9b91d9f291df683476576493d5dfd2e03848a8b05813dd0c3f0e835bc63f433007ddeceb71f05cb25c45ae1b19c6d3b @@ -31834,7 +32011,7 @@ __metadata: languageName: node linkType: hard -"kleur@npm:^4.0.3, kleur@npm:^4.1.4": +"kleur@npm:^4.0.3": version: 4.1.5 resolution: "kleur@npm:4.1.5" checksum: 1dc476e32741acf0b1b5b0627ffd0d722e342c1b0da14de3e8ae97821327ca08f9fb944542fb3c126d90ac5f27f9d804edbe7c585bf7d12ef495d115e0f22c12 @@ -31881,15 +32058,14 @@ __metadata: linkType: hard "knip@npm:^5.0.0": - version: 5.19.0 - resolution: "knip@npm:5.19.0" + version: 5.23.1 + resolution: "knip@npm:5.23.1" dependencies: "@ericcornelissen/bash-parser": 0.5.3 "@nodelib/fs.walk": 2.0.0 "@snyk/github-codeowners": 1.1.0 easy-table: 1.2.0 fast-glob: ^3.3.2 - file-entry-cache: 8.0.0 jiti: ^1.21.0 js-yaml: ^4.1.0 minimist: ^1.2.8 @@ -31900,6 +32076,7 @@ __metadata: smol-toml: ^1.1.4 strip-json-comments: 5.0.1 summary: 2.1.0 + tsconfig-paths: ^4.2.0 zod: ^3.22.4 zod-validation-error: ^3.0.3 peerDependencies: @@ -31908,7 +32085,7 @@ __metadata: bin: knip: bin/knip.js knip-bun: bin/knip-bun.js - checksum: de4c564e1242fff2d005ee5626c509b8ccf3b0b7e2402766363ac193b607d5742e7a336e321b964c38c143832839b3e361ef6cb8d83add7163ee48902dd6995c + checksum: d3c39f266907b2c8f241e4d7d7c4b3a4fa1500c57f7e60f86bd3e9cd2684696e4c84b823d2a461b23cdc729a310ad571eec6ac22acacb5a4b17130d19ef5b866 languageName: node linkType: hard @@ -32829,13 +33006,6 @@ __metadata: languageName: node linkType: hard -"map-obj@npm:^1.0.0": - version: 1.0.1 - resolution: "map-obj@npm:1.0.1" - checksum: 9949e7baec2a336e63b8d4dc71018c117c3ce6e39d2451ccbfd3b8350c547c4f6af331a4cbe1c83193d7c6b786082b6256bde843db90cb7da2a21e8fcc28afed - languageName: node - linkType: hard - "map-obj@npm:^2.0.0": version: 2.0.0 resolution: "map-obj@npm:2.0.0" @@ -32843,13 +33013,6 @@ __metadata: languageName: node linkType: hard -"map-obj@npm:^4.0.0": - version: 4.3.0 - resolution: "map-obj@npm:4.3.0" - checksum: fbc554934d1a27a1910e842bc87b177b1a556609dd803747c85ece420692380827c6ae94a95cce4407c054fa0964be3bf8226f7f2cb2e9eeee432c7c1985684e - languageName: node - linkType: hard - "markdown-it@npm:^12.2.0": version: 12.3.2 resolution: "markdown-it@npm:12.3.2" @@ -33206,25 +33369,6 @@ __metadata: languageName: node linkType: hard -"meow@npm:^6.0.0": - version: 6.1.1 - resolution: "meow@npm:6.1.1" - dependencies: - "@types/minimist": ^1.2.0 - camelcase-keys: ^6.2.2 - decamelize-keys: ^1.1.0 - hard-rejection: ^2.1.0 - minimist-options: ^4.0.2 - normalize-package-data: ^2.5.0 - read-pkg-up: ^7.0.1 - redent: ^3.0.0 - trim-newlines: ^3.0.0 - type-fest: ^0.13.1 - yargs-parser: ^18.1.3 - checksum: 77b569781145ad030be77130623d9f74d6eef0af5e0a349419d3df39bcf6d88cc25be046a7757062162a88160fb5d8604e540b5177b371d2bbc2aaf73ec01479 - languageName: node - linkType: hard - "merge-descriptors@npm:1.0.1": version: 1.0.1 resolution: "merge-descriptors@npm:1.0.1" @@ -33828,17 +33972,6 @@ __metadata: languageName: node linkType: hard -"minimist-options@npm:^4.0.2": - version: 4.1.0 - resolution: "minimist-options@npm:4.1.0" - dependencies: - arrify: ^1.0.1 - is-plain-obj: ^1.1.0 - kind-of: ^6.0.3 - checksum: 8c040b3068811e79de1140ca2b708d3e203c8003eb9a414c1ab3cd467fc5f17c9ca02a5aef23bedc51a7f8bfbe77f87e9a7e31ec81fba304cda675b019496f4e - languageName: node - linkType: hard - "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": version: 1.2.8 resolution: "minimist@npm:1.2.8" @@ -33988,13 +34121,6 @@ __metadata: languageName: node linkType: hard -"mixme@npm:^0.5.1": - version: 0.5.4 - resolution: "mixme@npm:0.5.4" - checksum: cec5f6127c92455bc86d592f0a0628e188c7ccf3909bd106703a1d939f0e2f451ddaac6da0d77c5f14d53dd2d58f64f5b2f8ff55a68ec68be95a73d290e4d430 - languageName: node - linkType: hard - "mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": version: 0.5.3 resolution: "mkdirp-classic@npm:0.5.3" @@ -34132,7 +34258,7 @@ __metadata: languageName: node linkType: hard -"mri@npm:^1.1.0": +"mri@npm:^1.1.0, mri@npm:^1.2.0": version: 1.2.0 resolution: "mri@npm:1.2.0" checksum: 83f515abbcff60150873e424894a2f65d68037e5a7fcde8a9e2b285ee9c13ac581b63cfc1e6826c4732de3aeb84902f7c1e16b7aff46cd3f897a0f757a894e85 @@ -34684,8 +34810,8 @@ __metadata: linkType: hard "node-mocks-http@npm:^1.0.0": - version: 1.14.1 - resolution: "node-mocks-http@npm:1.14.1" + version: 1.15.0 + resolution: "node-mocks-http@npm:1.15.0" dependencies: "@types/express": ^4.17.21 "@types/node": ^20.10.6 @@ -34699,7 +34825,7 @@ __metadata: parseurl: ^1.3.3 range-parser: ^1.2.0 type-is: ^1.6.18 - checksum: cc37618fb5f44a6049f8fcfc73373c4b42943e35e4b0f7463939d3f219663fe647e00e6eb9c3b8aedd48e88e10e1542993ac1a7ff8442ee2c3f6b97f23ced0e0 + checksum: 9be3ef4eec1b283800bbae50d7615fb633c7d28a0bedcf13e2ddfaa7ed4aa865d00c1d26e929ee8d617b3734958d8c19345f615760004f1940a8268c9bbacf07 languageName: node linkType: hard @@ -34763,15 +34889,15 @@ __metadata: linkType: hard "nodemailer@npm:^6.9.13": - version: 6.9.13 - resolution: "nodemailer@npm:6.9.13" - checksum: 1b591ef480be2ff69480127cbff819e6593b1ef263b6f920e1a4e83e40280582daf7a14a809ef92f9828e2a70bdb3ce22b11924e209f2afe4975f9ff37e08e9d + version: 6.9.14 + resolution: "nodemailer@npm:6.9.14" + checksum: 4037a45e24dbca47c0ea9a962d2c316deef7afe6ebf73c7da3a84942a8d501d85aae7f36dc1c5dac58dec7275f7cb1c92fd4f9c7c19f037225019ad2f402a9dc languageName: node linkType: hard "nodemon@npm:^3.0.1": - version: 3.1.3 - resolution: "nodemon@npm:3.1.3" + version: 3.1.4 + resolution: "nodemon@npm:3.1.4" dependencies: chokidar: ^3.5.2 debug: ^4 @@ -34785,7 +34911,7 @@ __metadata: undefsafe: ^2.0.5 bin: nodemon: bin/nodemon.js - checksum: ac2fa8865ab292b7ddf66731487acca4b4282b2728361e0de633c0c74cd705d6a0852b52f785c09469d959241d038ba824f50375622e687a2a318be747d9cd9d + checksum: 3f003fc2c7bdaba559108320f188b7cb063220455e5da218ff3bf4f7468ad7059852da6e35a52b8c690cc27f6e36a433a9ad1f1bdb8096ec1ee3d930629cbeca languageName: node linkType: hard @@ -34822,18 +34948,6 @@ __metadata: languageName: node linkType: hard -"normalize-package-data@npm:^2.5.0": - version: 2.5.0 - resolution: "normalize-package-data@npm:2.5.0" - dependencies: - hosted-git-info: ^2.1.4 - resolve: ^1.10.0 - semver: 2 || 3 || 4 || 5 - validate-npm-package-license: ^3.0.1 - checksum: 7999112efc35a6259bc22db460540cae06564aa65d0271e3bdfa86876d08b0e578b7b5b0028ee61b23f1cae9fc0e7847e4edc0948d3068a39a2a82853efc8499 - languageName: node - linkType: hard - "normalize-path@npm:^2.1.1": version: 2.1.1 resolution: "normalize-path@npm:2.1.1" @@ -36526,27 +36640,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.44.1": - version: 1.44.1 - resolution: "playwright-core@npm:1.44.1" +"playwright-core@npm:1.45.0": + version: 1.45.0 + resolution: "playwright-core@npm:1.45.0" bin: playwright-core: cli.js - checksum: ebc6fa0ff77792fe52648fda06cc4474d4e9746db6dc5750d262b7fe2caf9f9e2327a71f1fb365e862213403a9daf95361c5040a9b0fd462928d7eb4fdc760e1 + checksum: e81a55eeefa997fcb559527127c9cefbbabe81f196de486224e6c2a3a66852dab883379ff28a05b8008fb0ad4992840ad53c2415cee27e2d1778836210d9248e languageName: node linkType: hard -"playwright@npm:1.44.1": - version: 1.44.1 - resolution: "playwright@npm:1.44.1" +"playwright@npm:1.45.0": + version: 1.45.0 + resolution: "playwright@npm:1.45.0" dependencies: fsevents: 2.3.2 - playwright-core: 1.44.1 + playwright-core: 1.45.0 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: c2e8ff0a855e4a9e665ae5ffa0ff90423289546157be55e83f78916d17075c5910a7244773739c2a973da884a4ff0b3cf9b6e6b543de112e43b12169a9208e86 + checksum: 2a5f827fdcc90f1ec0ea4d9e4f2021ae894df88d3c0577677a81f72a09d91fb15584346e63ec2f85bfc24f872976ff2a76cee6ca7d7f29a8cc3159ced4f25b50 languageName: node linkType: hard @@ -37283,12 +37397,12 @@ __metadata: linkType: hard "prom-client@npm:^15.0.0": - version: 15.1.2 - resolution: "prom-client@npm:15.1.2" + version: 15.1.3 + resolution: "prom-client@npm:15.1.3" dependencies: "@opentelemetry/api": ^1.4.0 tdigest: ^0.1.1 - checksum: b9b2f439588a462c0aec840e8aa857bb0a77284174d6587ca042eb13ea6ac36ba13277f45ae6ed3696b3007a1020c5ee2c5ee46b23be033a7bb45207a5365c21 + checksum: 9a57f3c16f39aa9a03da021883a4231c0bb56fc9d02f6ef9c28f913379f275640a5a33b98d9946ebf53c71011a29b580e9d2d6e3806cb1c229a3f59c65993968 languageName: node linkType: hard @@ -37644,13 +37758,6 @@ __metadata: languageName: node linkType: hard -"quick-lru@npm:^4.0.1": - version: 4.0.1 - resolution: "quick-lru@npm:4.0.1" - checksum: bea46e1abfaa07023e047d3cf1716a06172c4947886c053ede5c50321893711577cb6119360f810cc3ffcd70c4d7db4069c3cee876b358ceff8596e062bd1154 - languageName: node - linkType: hard - "quick-lru@npm:^5.1.1": version: 5.1.1 resolution: "quick-lru@npm:5.1.1" @@ -38492,7 +38599,7 @@ __metadata: languageName: node linkType: hard -"react-window@npm:^1.8.6": +"react-window@npm:^1.8.10, react-window@npm:^1.8.6": version: 1.8.10 resolution: "react-window@npm:1.8.10" dependencies: @@ -38542,29 +38649,6 @@ __metadata: languageName: node linkType: hard -"read-pkg-up@npm:^7.0.1": - version: 7.0.1 - resolution: "read-pkg-up@npm:7.0.1" - dependencies: - find-up: ^4.1.0 - read-pkg: ^5.2.0 - type-fest: ^0.8.1 - checksum: e4e93ce70e5905b490ca8f883eb9e48b5d3cebc6cd4527c25a0d8f3ae2903bd4121c5ab9c5a3e217ada0141098eeb661313c86fa008524b089b8ed0b7f165e44 - languageName: node - linkType: hard - -"read-pkg@npm:^5.2.0": - version: 5.2.0 - resolution: "read-pkg@npm:5.2.0" - dependencies: - "@types/normalize-package-data": ^2.4.0 - normalize-package-data: ^2.5.0 - parse-json: ^5.0.0 - type-fest: ^0.6.0 - checksum: eb696e60528b29aebe10e499ba93f44991908c57d70f2d26f369e46b8b9afc208ef11b4ba64f67630f31df8b6872129e0a8933c8c53b7b4daf0eace536901222 - languageName: node - linkType: hard - "read-tls-client-hello@npm:^1.0.0": version: 1.0.1 resolution: "read-tls-client-hello@npm:1.0.1" @@ -39068,13 +39152,6 @@ __metadata: languageName: node linkType: hard -"require-main-filename@npm:^2.0.0": - version: 2.0.0 - resolution: "require-main-filename@npm:2.0.0" - checksum: e9e294695fea08b076457e9ddff854e81bffbe248ed34c1eec348b7abbd22a0d02e8d75506559e2265e96978f3c4720bd77a6dad84755de8162b357eb6c778c7 - languageName: node - linkType: hard - "requires-port@npm:^1.0.0": version: 1.0.0 resolution: "requires-port@npm:1.0.0" @@ -39140,7 +39217,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.8, resolve@npm:~1.22.1": +"resolve@npm:^1.1.6, 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.8, resolve@npm:~1.22.1": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -39176,7 +39253,7 @@ __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.8#~builtin, resolve@patch:resolve@~1.22.1#~builtin": +"resolve@patch:resolve@^1.1.6#~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.8#~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=c3c19d" dependencies: @@ -39582,6 +39659,7 @@ __metadata: "@spotify/eslint-plugin": ^15.0.0 "@spotify/prettier-config": ^15.0.0 "@techdocs/cli": "workspace:*" + "@types/global-agent": ^2.1.3 "@types/node": ^18.17.8 "@types/webpack": ^5.28.0 "@useoptic/optic": ^0.50.10 @@ -39915,15 +39993,6 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.5.0, semver@npm:^5.6.0": - version: 5.7.2 - resolution: "semver@npm:5.7.2" - bin: - semver: bin/semver - checksum: fb4ab5e0dd1c22ce0c937ea390b4a822147a9c53dbd2a9a0132f12fe382902beef4fbf12cf51bb955248d8d15874ce8cd89532569756384f994309825f10b686 - languageName: node - linkType: hard - "semver@npm:7.5.4, semver@npm:~7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" @@ -39935,6 +40004,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^5.5.0, semver@npm:^5.6.0": + version: 5.7.2 + resolution: "semver@npm:5.7.2" + bin: + semver: bin/semver + checksum: fb4ab5e0dd1c22ce0c937ea390b4a822147a9c53dbd2a9a0132f12fe382902beef4fbf12cf51bb955248d8d15874ce8cd89532569756384f994309825f10b686 + languageName: node + linkType: hard + "semver@npm:^6.0.0, semver@npm:^6.2.0, semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -40425,22 +40503,6 @@ __metadata: languageName: node linkType: hard -"smartwrap@npm:^2.0.2": - version: 2.0.2 - resolution: "smartwrap@npm:2.0.2" - dependencies: - array.prototype.flat: ^1.2.3 - breakword: ^1.0.5 - grapheme-splitter: ^1.0.4 - strip-ansi: ^6.0.0 - wcwidth: ^1.0.1 - yargs: ^15.1.0 - bin: - smartwrap: src/terminal-adapter.js - checksum: 1a6833eb1c3d8488b036df66dcab37dcdda5270bb9629c471155785c09ee1b591177a9774c588c43f8fa28833204500019265da2ffed28ac7bbf4589b943d2fa - languageName: node - linkType: hard - "smol-toml@npm:^1.1.4": version: 1.2.1 resolution: "smol-toml@npm:1.2.1" @@ -40646,40 +40708,6 @@ __metadata: languageName: node linkType: hard -"spdx-correct@npm:^3.0.0": - version: 3.1.1 - resolution: "spdx-correct@npm:3.1.1" - dependencies: - spdx-expression-parse: ^3.0.0 - spdx-license-ids: ^3.0.0 - checksum: 77ce438344a34f9930feffa61be0eddcda5b55fc592906ef75621d4b52c07400a97084d8701557b13f7d2aae0cb64f808431f469e566ef3fe0a3a131dcb775a6 - languageName: node - linkType: hard - -"spdx-exceptions@npm:^2.1.0": - version: 2.3.0 - resolution: "spdx-exceptions@npm:2.3.0" - checksum: cb69a26fa3b46305637123cd37c85f75610e8c477b6476fa7354eb67c08128d159f1d36715f19be6f9daf4b680337deb8c65acdcae7f2608ba51931540687ac0 - languageName: node - linkType: hard - -"spdx-expression-parse@npm:^3.0.0": - version: 3.0.1 - resolution: "spdx-expression-parse@npm:3.0.1" - dependencies: - spdx-exceptions: ^2.1.0 - spdx-license-ids: ^3.0.0 - checksum: a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde - languageName: node - linkType: hard - -"spdx-license-ids@npm:^3.0.0": - version: 3.0.12 - resolution: "spdx-license-ids@npm:3.0.12" - checksum: 92a4dddce62ce1db6fe54a7a839cf85e06abc308fc83b776a55b44e4f1906f02e7ebd506120847039e976bbbad359ea8bdfafb7925eae5cd7e73255f02e0b7d6 - languageName: node - linkType: hard - "spdy-transport@npm:^3.0.0": version: 3.0.0 resolution: "spdy-transport@npm:3.0.0" @@ -41034,15 +41062,6 @@ __metadata: languageName: node linkType: hard -"stream-transform@npm:^2.1.3": - version: 2.1.3 - resolution: "stream-transform@npm:2.1.3" - dependencies: - mixme: ^0.5.1 - checksum: 26ce872a6812d5c784fa1f042bfd403644bc1c019f64627b5012c4544830a5570bef98b47225b38120c5878b326f3d1a213cd999a2285c98b536e5e202ca5bdf - languageName: node - linkType: hard - "streamsearch@npm:^1.1.0": version: 1.1.0 resolution: "streamsearch@npm:1.1.0" @@ -42340,13 +42359,6 @@ __metadata: languageName: node linkType: hard -"trim-newlines@npm:^3.0.0": - version: 3.0.1 - resolution: "trim-newlines@npm:3.0.1" - checksum: b530f3fadf78e570cf3c761fb74fef655beff6b0f84b29209bac6c9622db75ad1417f4a7b5d54c96605dcd72734ad44526fef9f396807b90839449eb543c6206 - languageName: node - linkType: hard - "triple-beam@npm:^1.3.0, triple-beam@npm:^1.4.1": version: 1.4.1 resolution: "triple-beam@npm:1.4.1" @@ -42495,6 +42507,17 @@ __metadata: languageName: node linkType: hard +"tsconfig-paths@npm:^4.2.0": + version: 4.2.0 + resolution: "tsconfig-paths@npm:4.2.0" + dependencies: + json5: ^2.2.2 + minimist: ^1.2.6 + strip-bom: ^3.0.0 + checksum: 28c5f7bbbcabc9dabd4117e8fdc61483f6872a1c6b02a4b1c4d68c5b79d06896c3cc9547610c4c3ba64658531caa2de13ead1ea1bf321c7b53e969c4752b98c7 + languageName: node + linkType: hard + "tslib@npm:2.6.2, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.4.1 || ^1.9.3, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" @@ -42534,23 +42557,6 @@ __metadata: languageName: node linkType: hard -"tty-table@npm:^4.1.5": - version: 4.1.6 - resolution: "tty-table@npm:4.1.6" - dependencies: - chalk: ^4.1.2 - csv: ^5.5.0 - kleur: ^4.1.4 - smartwrap: ^2.0.2 - strip-ansi: ^6.0.0 - wcwidth: ^1.0.1 - yargs: ^17.1.1 - bin: - tty-table: adapters/terminal-adapter.js - checksum: 0f689b7d79ad6b9e608299e667a493309901fe802f1c4d66627a90cacb6fe11e0521e1a2dc5a75f793750ecdd849e98292d4874e5e6e988edd928b67045eb847 - languageName: node - linkType: hard - "tunnel-agent@npm:^0.6.0": version: 0.6.0 resolution: "tunnel-agent@npm:0.6.0" @@ -42641,20 +42647,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.6.0": - version: 0.6.0 - resolution: "type-fest@npm:0.6.0" - checksum: b2188e6e4b21557f6e92960ec496d28a51d68658018cba8b597bd3ef757721d1db309f120ae987abeeda874511d14b776157ff809f23c6d1ce8f83b9b2b7d60f - languageName: node - linkType: hard - -"type-fest@npm:^0.8.1": - version: 0.8.1 - resolution: "type-fest@npm:0.8.1" - checksum: d61c4b2eba24009033ae4500d7d818a94fd6d1b481a8111612ee141400d5f1db46f199c014766b9fa9b31a6a7374d96fc748c6d688a78a3ce5a33123839becb7 - languageName: node - linkType: hard - "type-fest@npm:^2.19.0": version: 2.19.0 resolution: "type-fest@npm:2.19.0" @@ -43575,16 +43567,6 @@ __metadata: languageName: node linkType: hard -"validate-npm-package-license@npm:^3.0.1": - version: 3.0.4 - resolution: "validate-npm-package-license@npm:3.0.4" - dependencies: - spdx-correct: ^3.0.0 - spdx-expression-parse: ^3.0.0 - checksum: 35703ac889d419cf2aceef63daeadbe4e77227c39ab6287eeb6c1b36a746b364f50ba22e88591f5d017bc54685d8137bc2d328d0a896e4d3fd22093c0f32a9ad - languageName: node - linkType: hard - "validate-npm-package-name@npm:^3.0.0": version: 3.0.0 resolution: "validate-npm-package-name@npm:3.0.0" @@ -43753,15 +43735,15 @@ __metadata: languageName: node linkType: hard -"vite-plugin-node-polyfills@npm:^0.21.0": - version: 0.21.0 - resolution: "vite-plugin-node-polyfills@npm:0.21.0" +"vite-plugin-node-polyfills@npm:^0.22.0": + version: 0.22.0 + resolution: "vite-plugin-node-polyfills@npm:0.22.0" dependencies: "@rollup/plugin-inject": ^5.0.5 node-stdlib-browser: ^1.2.0 peerDependencies: vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 - checksum: 923379f0205911d13ffdcdc841a6565a191a6fe199eb7c0d38b6ea1f53bbdf3d42ad12a9ae8d5f49c14e3f4e2cb56fc7ea8c24a51eeedfbe64c6ebbca4a2966a + checksum: c08d3df0d5cc3102280483d3f7b216f92a18e0708fcb9f67f78f01ab865474254756bacee17caa90b3f46afe5834cb9d8de0dd0e58c1bbbdae1b949edc1e6b57 languageName: node linkType: hard @@ -44219,13 +44201,6 @@ __metadata: languageName: node linkType: hard -"which-module@npm:^2.0.0": - version: 2.0.0 - resolution: "which-module@npm:2.0.0" - checksum: 809f7fd3dfcb2cdbe0180b60d68100c88785084f8f9492b0998c051d7a8efe56784492609d3f09ac161635b78ea29219eb1418a98c15ce87d085bce905705c9c - languageName: node - linkType: hard - "which-pm@npm:2.0.0": version: 2.0.0 resolution: "which-pm@npm:2.0.0" @@ -44429,8 +44404,8 @@ __metadata: 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.16.0, ws@npm:^8.17.0, ws@npm:^8.8.0": - version: 8.17.0 - resolution: "ws@npm:8.17.0" + version: 8.17.1 + resolution: "ws@npm:8.17.1" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -44439,7 +44414,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 147ef9eab0251364e1d2c55338ad0efb15e6913923ccbfdf20f7a8a6cb8f88432bcd7f4d8f66977135bfad35575644f9983201c1a361019594a4e53977bf6d4e + checksum: 442badcce1f1178ec87a0b5372ae2e9771e07c4929a3180321901f226127f252441e8689d765aa5cfba5f50ac60dd830954afc5aeae81609aefa11d3ddf5cecf languageName: node linkType: hard @@ -44459,8 +44434,8 @@ __metadata: linkType: hard "ws@npm:^7, ws@npm:^7.4.6, ws@npm:^7.5.5": - version: 7.5.9 - resolution: "ws@npm:7.5.9" + version: 7.5.10 + resolution: "ws@npm:7.5.10" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ^5.0.2 @@ -44469,7 +44444,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138 + checksum: f9bb062abf54cc8f02d94ca86dcd349c3945d63851f5d07a3a61c2fcb755b15a88e943a63cf580cbdb5b74436d67ef6b67f745b8f7c0814e411379138e1863cb languageName: node linkType: hard @@ -44615,13 +44590,6 @@ __metadata: languageName: node linkType: hard -"y18n@npm:^4.0.0": - version: 4.0.3 - resolution: "y18n@npm:4.0.3" - checksum: 014dfcd9b5f4105c3bb397c1c8c6429a9df004aa560964fb36732bfb999bfe83d45ae40aeda5b55d21b1ee53d8291580a32a756a443e064317953f08025b1aa4 - languageName: node - linkType: hard - "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" @@ -44688,16 +44656,6 @@ __metadata: 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" - dependencies: - camelcase: ^5.0.0 - decamelize: ^1.2.0 - checksum: 60e8c7d1b85814594d3719300ecad4e6ae3796748b0926137bfec1f3042581b8646d67e83c6fc80a692ef08b8390f21ddcacb9464476c39bbdf52e34961dd4d9 - languageName: node - linkType: hard - "yargs-parser@npm:^20.2.2": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" @@ -44712,25 +44670,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^15.1.0": - version: 15.4.1 - resolution: "yargs@npm:15.4.1" - dependencies: - cliui: ^6.0.0 - decamelize: ^1.2.0 - find-up: ^4.1.0 - get-caller-file: ^2.0.1 - require-directory: ^2.1.1 - require-main-filename: ^2.0.0 - set-blocking: ^2.0.0 - string-width: ^4.2.0 - which-module: ^2.0.0 - y18n: ^4.0.0 - yargs-parser: ^18.1.2 - checksum: 40b974f508d8aed28598087720e086ecd32a5fd3e945e95ea4457da04ee9bdb8bdd17fd91acff36dc5b7f0595a735929c514c40c402416bbb87c03f6fb782373 - languageName: node - linkType: hard - "yargs@npm:^16.2.0": version: 16.2.0 resolution: "yargs@npm:16.2.0"