diff --git a/.changeset/all-camels-agree.md b/.changeset/all-camels-agree.md new file mode 100644 index 0000000000..44d8a4f2c9 --- /dev/null +++ b/.changeset/all-camels-agree.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fix broken external links in Backstage UI Header component. diff --git a/.changeset/angry-sites-fold.md b/.changeset/angry-sites-fold.md deleted file mode 100644 index 8124ddaf47..0000000000 --- a/.changeset/angry-sites-fold.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Added the configuration flag `auth.omitIdentityTokenOwnershipClaim` that causes issued user tokens to no longer contain the `ent` claim that represents the ownership references of the user. - -The benefit of this new flag is that issued user tokens will be much smaller in -size, but they will no longer be self-contained. This means that any consumers -of the token that require access to the ownership claims now need to call the -`/api/auth/v1/userinfo` endpoint instead. Within the Backstage ecosystem this is -done automatically, as clients will still receive the full set of claims during -authentication, while plugin backends will need to use the `UserInfoService` -which already calls the user info endpoint if necessary. - -When enabling this flag, it is important that any custom sign-in resolvers directly return the result of the sign-in method. For example, the following would not work: - -```ts -const { token } = await ctx.issueToken({ - claims: { sub: entityRef, ent: [entityRef] }, -}); -return { token }; // WARNING: This will not work with the flag enabled -``` - -Instead, the sign-in resolver should directly return the result: - -```ts -return ctx.issueToken({ - claims: { sub: entityRef, ent: [entityRef] }, -}); -``` diff --git a/.changeset/beige-kiwis-flow.md b/.changeset/beige-kiwis-flow.md deleted file mode 100644 index 500095b44b..0000000000 --- a/.changeset/beige-kiwis-flow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-node': minor ---- - -**BREAKING**: The `PinnipedHelper` class now expects a regular `LoggerService` instance from the new backend system, instead of a Winston logger. diff --git a/.changeset/better-hats-cross.md b/.changeset/better-hats-cross.md new file mode 100644 index 0000000000..99444b7fbf --- /dev/null +++ b/.changeset/better-hats-cross.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Adjusted the log line wording of task worker starting diff --git a/.changeset/better-steaks-act.md b/.changeset/better-steaks-act.md new file mode 100644 index 0000000000..b3ce601245 --- /dev/null +++ b/.changeset/better-steaks-act.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +The templates executed with the `yarn new` command now supports templating filenames. diff --git a/.changeset/brave-donuts-sink.md b/.changeset/brave-donuts-sink.md deleted file mode 100644 index 47827345a5..0000000000 --- a/.changeset/brave-donuts-sink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/test-utils': patch ---- - -Added support for interpolating JSX elements with the `MockTranslationApi`. diff --git a/.changeset/brave-eggs-mate.md b/.changeset/brave-eggs-mate.md deleted file mode 100644 index 73eb8e363a..0000000000 --- a/.changeset/brave-eggs-mate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/theme': patch ---- - -Show arrow when MuiTableSortLabel receives focus diff --git a/.changeset/brave-pandas-beam.md b/.changeset/brave-pandas-beam.md deleted file mode 100644 index 8dd525d749..0000000000 --- a/.changeset/brave-pandas-beam.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@backstage/core-app-api': minor ---- - -Support custom `AuthConnector` for `OAuth2`. - -A user can pass their own `AuthConnector` implementation in `OAuth2` constructor. -In which case the session manager will use that instead of the `DefaultAuthConnector` to interact with the -authentication provider. - -A custom `AuthConnector` may call the authentication provider from the front-end, store and retrieve tokens -in the session storage, for example, and otherwise send custom requests to the authentication provider and -handle its responses. - -Note, that if the custom `AuthConnector` transforms scopes returned from the authentication provider, -the transformation must be the same as `OAuth2CreateOptions#scopeTransform` passed to `OAuth2` constructor. -See creating `DefaultAuthConnector` in `OAuth2#create(...)` for an example. diff --git a/.changeset/brave-toes-switch.md b/.changeset/brave-toes-switch.md deleted file mode 100644 index 27b39cccd3..0000000000 --- a/.changeset/brave-toes-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': minor ---- - -Add new `userGroupMember.path`, `user.path` and, `group.path` option to each query type to allow more complex msgraph queries diff --git a/.changeset/breezy-hotels-deny.md b/.changeset/breezy-hotels-deny.md deleted file mode 100644 index 13c8b47a7f..0000000000 --- a/.changeset/breezy-hotels-deny.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/integration': patch ---- - -Added missing `organizations` property to `azure` section in `config.d.ts` file diff --git a/.changeset/breezy-times-ring.md b/.changeset/breezy-times-ring.md new file mode 100644 index 0000000000..f65dd6ff55 --- /dev/null +++ b/.changeset/breezy-times-ring.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Updated knip-reports to detect dependencies in dev/alpha pattern diff --git a/.changeset/bright-ears-send.md b/.changeset/bright-ears-send.md new file mode 100644 index 0000000000..5104f2377b --- /dev/null +++ b/.changeset/bright-ears-send.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +Enable YAML merge keys in yamlPlaceholderResolver diff --git a/.changeset/bright-moles-sort.md b/.changeset/bright-moles-sort.md deleted file mode 100644 index 9796729d1a..0000000000 --- a/.changeset/bright-moles-sort.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-dynamic-feature-service': minor ---- - -**BREAKING** Removed support for the legacy backend, please migrate to the new backend system diff --git a/.changeset/bumpy-showers-design.md b/.changeset/bumpy-showers-design.md deleted file mode 100644 index 2db5006944..0000000000 --- a/.changeset/bumpy-showers-design.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gitlab': patch ---- - -If the commit action is not `create` log a more appropriate error message to the end user advising that the files they're trying to modify might not exist diff --git a/.changeset/busy-badgers-hang.md b/.changeset/busy-badgers-hang.md deleted file mode 100644 index fc4b0e907e..0000000000 --- a/.changeset/busy-badgers-hang.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Removed `lerna-debug.log*` pattern from `.gitignore` as Lerna was removed from the package in version `@backstage/create-app@0.5.19`. diff --git a/.changeset/busy-goats-create.md b/.changeset/busy-goats-create.md new file mode 100644 index 0000000000..78b8f65571 --- /dev/null +++ b/.changeset/busy-goats-create.md @@ -0,0 +1,10 @@ +--- +'@backstage/plugin-search-backend-module-elasticsearch': patch +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-signals-backend': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-signals': patch +--- + +Removed/moved unused dependencies diff --git a/.changeset/calm-toys-occur.md b/.changeset/calm-toys-occur.md deleted file mode 100644 index ea03aaf4f8..0000000000 --- a/.changeset/calm-toys-occur.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -'@backstage/plugin-bitbucket-cloud-common': minor ---- - -Update Bitbucket Cloud schema and models. - -The latest schema was fetched from Bitbucket Cloud and stored locally. -Based on the updated schema, the models got regenerated. - -**BREAKING:** - -Due to the schema changes, the model update includes one breaking change: - -- `Account.username` was removed. - -Additionally, there were a couple of compatible changes including the addition of -`BaseCommit.committer` and others. diff --git a/.changeset/chatty-months-grow.md b/.changeset/chatty-months-grow.md deleted file mode 100644 index 1495e7732e..0000000000 --- a/.changeset/chatty-months-grow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -Use correct colour token for TextField clear button icon, prevent layout shift whenever it is hidden or shown and properly size focus area around it. Also stop leading icon shrinking when used together with clear button. diff --git a/.changeset/chatty-showers-cheat.md b/.changeset/chatty-showers-cheat.md deleted file mode 100644 index 24c2720fb6..0000000000 --- a/.changeset/chatty-showers-cheat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': minor ---- - -**BREAKING ALPHA**: You can no longer import the catalog plugin from the `/alpha` export; please use the regular root default export instead. diff --git a/.changeset/chilly-trams-cheer.md b/.changeset/chilly-trams-cheer.md deleted file mode 100644 index 0e14423ef8..0000000000 --- a/.changeset/chilly-trams-cheer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-react': patch ---- - -Add headlamp formatter diff --git a/.changeset/chubby-cougars-run.md b/.changeset/chubby-cougars-run.md deleted file mode 100644 index deb954ef6b..0000000000 --- a/.changeset/chubby-cougars-run.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -This patch addresses an issue identified in Backstage when configured with a MySQL database. If an entity of type location -(e..all.yaml) has more than 70 referenced entities, clicking "Refresh" does not update the referenced entities as expected. This occurs because the TEXT type in MySQL has a limit of 65,535 bytes, which is insufficient to store all the referenced entities, causing the refresh operation to fail. diff --git a/.changeset/chubby-needles-vanish.md b/.changeset/chubby-needles-vanish.md deleted file mode 100644 index 2cd664dcdd..0000000000 --- a/.changeset/chubby-needles-vanish.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -Fix Canon missing dependencies diff --git a/.changeset/clean-otters-allow.md b/.changeset/clean-otters-allow.md deleted file mode 100644 index 5e0aeb598f..0000000000 --- a/.changeset/clean-otters-allow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -fix: enable `lazyCompilation` and `refreshOptions` for rspack diff --git a/.changeset/clever-boats-clap.md b/.changeset/clever-boats-clap.md new file mode 100644 index 0000000000..6b40f05a76 --- /dev/null +++ b/.changeset/clever-boats-clap.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-search-react': minor +'@backstage/plugin-techdocs': minor +'@backstage/plugin-catalog': minor +'@backstage/plugin-search': minor +--- + +Add support for customizable icons in `SearchResultListItemBlueprint` and related components diff --git a/.changeset/common-goats-raise.md b/.changeset/common-goats-raise.md deleted file mode 100644 index c2d797b719..0000000000 --- a/.changeset/common-goats-raise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': patch ---- - -Use action context logger in Octokit client diff --git a/.changeset/cool-bikes-push.md b/.changeset/cool-bikes-push.md deleted file mode 100644 index 00825c1ad0..0000000000 --- a/.changeset/cool-bikes-push.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-app-api': patch ---- - -Updated `I18nextTranslationApi` to support interpolation of JSX elements. diff --git a/.changeset/cool-cities-grab.md b/.changeset/cool-cities-grab.md deleted file mode 100644 index 372ca9887f..0000000000 --- a/.changeset/cool-cities-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -`LogViewer` now supports a `textWrap` prop that wraps log lines to the next line for overflowing content instead of using horizontal scroll diff --git a/.changeset/cool-colts-float.md b/.changeset/cool-colts-float.md deleted file mode 100644 index c001f81ade..0000000000 --- a/.changeset/cool-colts-float.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Support passing additional properties to OpenAPI server generator diff --git a/.changeset/cool-groups-fail.md b/.changeset/cool-groups-fail.md deleted file mode 100644 index 459358676b..0000000000 --- a/.changeset/cool-groups-fail.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -`GithubUrlReader`'s search detects glob-patterns supported by `minimatch`, instead of just detecting -`*` and `?` characters. - -For example, this allows to search for patterns like `{C,c}atalog-info.yaml`. diff --git a/.changeset/cool-knives-design.md b/.changeset/cool-knives-design.md deleted file mode 100644 index 63197edd16..0000000000 --- a/.changeset/cool-knives-design.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch ---- - -The `id` option of `createFrontendPlugin` has been renamed to `pluginId` in order to better align with similar APIs in the frontend and backend systems. - -The old `id` option is deprecated and will be removed in a future release. diff --git a/.changeset/crazy-chefs-sin.md b/.changeset/crazy-chefs-sin.md deleted file mode 100644 index 8d33add929..0000000000 --- a/.changeset/crazy-chefs-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-notifications-backend-module-slack': patch ---- - -Fix slack notification processor to handle a notification with an empty description diff --git a/.changeset/create-app-1745936753.md b/.changeset/create-app-1745936753.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1745936753.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/create-app-1747144256.md b/.changeset/create-app-1747144256.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1747144256.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/create-app-1745325336.md b/.changeset/create-app-1761312116.md similarity index 100% rename from .changeset/create-app-1745325336.md rename to .changeset/create-app-1761312116.md diff --git a/.changeset/cruel-items-dig.md b/.changeset/cruel-items-dig.md new file mode 100644 index 0000000000..65f07956ac --- /dev/null +++ b/.changeset/cruel-items-dig.md @@ -0,0 +1,27 @@ +--- +'@backstage/ui': minor +--- + +**BREAKING**: Migrated Avatar component from Base UI to custom implementation with size changes: + +- Base UI-specific props are no longer supported +- Size values have been updated: + - New `x-small` size added (1.25rem / 20px) + - `small` size unchanged (1.5rem / 24px) + - `medium` size unchanged (2rem / 32px, default) + - `large` size **changed from 3rem to 2.5rem** (40px) + - New `x-large` size added (3rem / 48px) + +Migration: + +```diff +# Remove Base UI-specific props +- ++ + +# Update large size usage to x-large for same visual size +- ++ +``` + +Added `purpose` prop for accessibility control (`'informative'` or `'decoration'`). diff --git a/.changeset/cruel-lights-sip.md b/.changeset/cruel-lights-sip.md deleted file mode 100644 index b38ab052a9..0000000000 --- a/.changeset/cruel-lights-sip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend-module-github-provider': patch ---- - -Added missing types package diff --git a/.changeset/cruel-plums-talk.md b/.changeset/cruel-plums-talk.md new file mode 100644 index 0000000000..bc7a30b048 --- /dev/null +++ b/.changeset/cruel-plums-talk.md @@ -0,0 +1,58 @@ +--- +'@backstage/ui': minor +--- + +**BREAKING**: Migrated Checkbox component from Base UI to React Aria Components. + +API changes required: + +- `checked` → `isSelected` +- `defaultChecked` → `defaultSelected` +- `disabled` → `isDisabled` +- `required` → `isRequired` +- `label` prop removed - use `children` instead +- CSS: `bui-CheckboxLabel` class removed +- Data attribute: `data-checked` → `data-selected` +- Use without label is no longer supported + +Migration examples: + +Before: + +```tsx + +``` + +After: + +```tsx + + Accept terms + +``` + +Before: + +```tsx + +``` + +After: + +```tsx +Option +``` + +Before: + +```tsx + +``` + +After: + +```tsx + + Accessible label + +``` diff --git a/.changeset/cyan-pots-appear.md b/.changeset/cyan-pots-appear.md deleted file mode 100644 index f82f4548c3..0000000000 --- a/.changeset/cyan-pots-appear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-unprocessed': minor ---- - -**BREAKING** Removed support for the legacy backend and removed references to `@backstage/backend-common`, please [migrate to the new backend system](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating) diff --git a/.changeset/deep-gifts-slide.md b/.changeset/deep-gifts-slide.md new file mode 100644 index 0000000000..f3be77e74d --- /dev/null +++ b/.changeset/deep-gifts-slide.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fixed CSS issues in Select component including popover width constraints, focus outline behavior, and overflow handling. diff --git a/.changeset/deep-ties-move.md b/.changeset/deep-ties-move.md deleted file mode 100644 index 57f6c7772c..0000000000 --- a/.changeset/deep-ties-move.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-ldap': patch ---- - -Improves error reporting for missing metadata.name in LDAP catalog provider. diff --git a/.changeset/dirty-grapes-vanish.md b/.changeset/dirty-grapes-vanish.md deleted file mode 100644 index b78660d21e..0000000000 --- a/.changeset/dirty-grapes-vanish.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/backend-defaults': minor ---- - -**BREAKING**: The `DefaultSchedulerService` constructor options now requires `RootLifecycleService`, `HttpRouterService`, and `PluginMetadataService` fields. - -The scheduler will register a REST API for listing and triggering tasks. Please see [the scheduler documentation](https://backstage.io/docs/backend-system/core-services/scheduler) for more details about this API. diff --git a/.changeset/dry-carpets-hope.md b/.changeset/dry-carpets-hope.md deleted file mode 100644 index 569e089a66..0000000000 --- a/.changeset/dry-carpets-hope.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-backstage-openapi': patch ---- - -Do not swallow errors; instead allow them to bubble up to the task scheduler for better tracking and logging. diff --git a/.changeset/dry-shirts-film.md b/.changeset/dry-shirts-film.md deleted file mode 100644 index 35ada3969a..0000000000 --- a/.changeset/dry-shirts-film.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Added the Catalog presentation API to the HomePageRecentlyVisited and HomePageTopVisited components diff --git a/.changeset/dull-doodles-trade.md b/.changeset/dull-doodles-trade.md deleted file mode 100644 index eb9399fcc7..0000000000 --- a/.changeset/dull-doodles-trade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Changed logging of cluster details to debug to minimise log clutter. diff --git a/.changeset/early-colts-accept.md b/.changeset/early-colts-accept.md deleted file mode 100644 index ff583144f0..0000000000 --- a/.changeset/early-colts-accept.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-dynamic-feature-service': patch ---- - -Fixed various typos. -`FrontendRemoteResolver`'s misspelled `getAdditionaRemoteInfo` has been deprecated. Use the correct spelling `getAdditionalRemoteInfo` instead. diff --git a/.changeset/early-dryers-teach.md b/.changeset/early-dryers-teach.md deleted file mode 100644 index d747fbc730..0000000000 --- a/.changeset/early-dryers-teach.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-node': minor ---- - -Added `parseEntityYaml` from `@backstage/plugin-catalog-backend`, to make it more easily usable by custom plugins and modules diff --git a/.changeset/easy-hands-grow.md b/.changeset/easy-hands-grow.md new file mode 100644 index 0000000000..fc3cfd96e1 --- /dev/null +++ b/.changeset/easy-hands-grow.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog-backend': minor +'@backstage/plugin-catalog-node': minor +--- + +Make YAML merge (<<:) support configurable in the Backstage Catalog instead of always being enabled diff --git a/.changeset/eight-toys-feel.md b/.changeset/eight-toys-feel.md deleted file mode 100644 index c0f5a12c40..0000000000 --- a/.changeset/eight-toys-feel.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Added a configuration to permit backend plugin module failures on startup: - -```yaml -backend: - ... - startup: - plugins: - plugin-x: - modules: - module-y: - onPluginModuleBootFailure: continue -``` - -This configuration permits `plugin-x` with `module-y` to fail on startup. Omitting the -`onPluginModuleBootFailure` configuration matches the previous behavior, wherein any -individual plugin module failure is forwarded to the plugin and aborts backend startup. - -The default can also be changed, so that continuing on failure is the default -unless otherwise specified: - -```yaml -backend: - startup: - default: - onPluginModuleBootFailure: continue - plugins: - catalog: - modules: - github: - onPluginModuleBootFailure: abort -``` diff --git a/.changeset/eighty-results-prove.md b/.changeset/eighty-results-prove.md new file mode 100644 index 0000000000..6df2d2f11a --- /dev/null +++ b/.changeset/eighty-results-prove.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-app-visualizer': patch +--- + +Improve tree visualizer to use a horizontal layout and fill the content space. diff --git a/.changeset/eleven-beans-relax.md b/.changeset/eleven-beans-relax.md deleted file mode 100644 index fd01394d2d..0000000000 --- a/.changeset/eleven-beans-relax.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/release-manifests': patch ---- - -This expands the configurability of `release-manifests` to pave the road for more configuration options in the `cli`. - -Specifically it allows the specification of mirrored, proxied, or air-gapped hosts when upgrading across releases when -working in restricted or heavily governed development environments (common in large enterprises and government -entities). diff --git a/.changeset/eleven-carpets-win.md b/.changeset/eleven-carpets-win.md new file mode 100644 index 0000000000..69d677786a --- /dev/null +++ b/.changeset/eleven-carpets-win.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Fix a bug in the Gitlab URL reader where `search` did not handle multiple globs diff --git a/.changeset/eleven-ghosts-strive.md b/.changeset/eleven-ghosts-strive.md deleted file mode 100644 index ac48c19524..0000000000 --- a/.changeset/eleven-ghosts-strive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Full support in EntityPicker (and derivatives) for default EntityPresentationApi diff --git a/.changeset/every-ants-count.md b/.changeset/every-ants-count.md new file mode 100644 index 0000000000..963c3a521a --- /dev/null +++ b/.changeset/every-ants-count.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-test-utils': minor +--- + +Added support for Postgres 18 to the available `TestDatabases`. + +Note that the set of _default_ databases to test against for users of the `TestDatabases` class was also updated to include Postgres 14 and 18, instead of 13 and 17. If you need to override this, you can pass in an explicit `ids` argument, for example `ids: ['POSTGRES_17', 'POSTGRES_13', 'SQLITE_3']`. diff --git a/.changeset/every-bottles-grow.md b/.changeset/every-bottles-grow.md deleted file mode 100644 index a61a7b42b9..0000000000 --- a/.changeset/every-bottles-grow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -"Added a note clarifying that `entity-fetch` audit events are not visible by default in the logs and are only displayed when the log severity level is adjusted." diff --git a/.changeset/every-clocks-arrive.md b/.changeset/every-clocks-arrive.md new file mode 100644 index 0000000000..d2061913e3 --- /dev/null +++ b/.changeset/every-clocks-arrive.md @@ -0,0 +1,5 @@ +--- +'@backstage/dev-utils': patch +--- + +Fixed styling of the dev app by adding a lazy import of `@backstage/ui/css/styles.css`. diff --git a/.changeset/famous-cities-stand.md b/.changeset/famous-cities-stand.md deleted file mode 100644 index 86ba727997..0000000000 --- a/.changeset/famous-cities-stand.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-auth-node': patch ---- - -Added the `identity` property to `BackstageSignInResult`. - -The `prepareBackstageIdentityResponse` function will now also forward the `identity` to the response if present in the provided sign-in result. diff --git a/.changeset/fancy-frogs-like.md b/.changeset/fancy-frogs-like.md deleted file mode 100644 index ed3a9fbf81..0000000000 --- a/.changeset/fancy-frogs-like.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Internal code cleanup diff --git a/.changeset/fast-tools-mate.md b/.changeset/fast-tools-mate.md new file mode 100644 index 0000000000..2e212ce1b3 --- /dev/null +++ b/.changeset/fast-tools-mate.md @@ -0,0 +1,10 @@ +--- +'@backstage/plugin-notifications-backend': patch +--- + +Show default settings for notifications even before receiving first notification. + +Previously, it was not possible for the users to see or modify their notification settings until they had received at +least one notification from specific origin or topic. +This update ensures that default settings are displayed from the outset, +allowing users to customize their preferences immediately. diff --git a/.changeset/fine-hands-return.md b/.changeset/fine-hands-return.md new file mode 100644 index 0000000000..d3bf69c9b9 --- /dev/null +++ b/.changeset/fine-hands-return.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fix default text color in Backstage UI diff --git a/.changeset/five-seas-jam.md b/.changeset/five-seas-jam.md new file mode 100644 index 0000000000..4aa481422f --- /dev/null +++ b/.changeset/five-seas-jam.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications-backend-module-email': patch +--- + +Updated `AWS SES` client to version 2 to support `nodemailer` version 7. diff --git a/.changeset/fix-text-truncate-prop.md b/.changeset/fix-text-truncate-prop.md new file mode 100644 index 0000000000..26aee3280c --- /dev/null +++ b/.changeset/fix-text-truncate-prop.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fixed Text component to prevent `truncate` prop from being spread to the underlying DOM element. diff --git a/.changeset/flat-paws-do.md b/.changeset/flat-paws-do.md new file mode 100644 index 0000000000..13d78c1423 --- /dev/null +++ b/.changeset/flat-paws-do.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-openapi': patch +--- + +fix wrong dereferencing for AsyncApi 3 documents diff --git a/.changeset/floppy-days-tell.md b/.changeset/floppy-days-tell.md deleted file mode 100644 index 2eb184f6fe..0000000000 --- a/.changeset/floppy-days-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -For improved a11y, clicking a Select component label now focuses the Select trigger element, and the TextField component's label is now styled to indicate it's interactive. diff --git a/.changeset/four-peaches-talk.md b/.changeset/four-peaches-talk.md deleted file mode 100644 index 4b0d2e8a47..0000000000 --- a/.changeset/four-peaches-talk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Internal refactor of opaque type handling. diff --git a/.changeset/four-snails-argue.md b/.changeset/four-snails-argue.md deleted file mode 100644 index 905e52a559..0000000000 --- a/.changeset/four-snails-argue.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -'@backstage/integration': minor ---- - -Added support for federated credentials using managed identities in the Azure DevOps integration. Federated credentials are only available for Azure DevOps organizations that have been configured to use Entra ID for authentication. - -```diff -integrations: - azure: - - host: dev.azure.com - credentials: -+ - clientId: ${APP_REGISTRATION_CLIENT_ID} -+ managedIdentityClientId: system-assigned -+ tenantId: ${AZURE_TENANT_ID} -``` - -This also adds support for automatically using the system-assigned managed identity of an Azure resource by specifying `system-assigned` as the client ID of the managed identity. - -```diff -integrations: - azure: - - host: dev.azure.com - credentials: -- - clientId: ${AZURE_CLIENT_ID} -+ - clientId: system-assigned -``` diff --git a/.changeset/fruity-bags-flow.md b/.changeset/fruity-bags-flow.md deleted file mode 100644 index bc6034a489..0000000000 --- a/.changeset/fruity-bags-flow.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -'@backstage/plugin-catalog-unprocessed-entities': patch -'@backstage/frontend-test-utils': patch -'@backstage/core-compat-api': patch -'@backstage/plugin-app-visualizer': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-catalog-graph': patch -'@backstage/plugin-notifications': patch -'@backstage/plugin-user-settings': patch -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-api-docs': patch -'@backstage/plugin-devtools': patch -'@backstage/plugin-techdocs': patch -'@backstage/plugin-catalog': patch -'@backstage/plugin-signals': patch -'@backstage/plugin-search': patch -'@backstage/plugin-home': patch -'@backstage/plugin-app': patch -'@backstage/plugin-org': patch ---- - -Internal update to use the new `pluginId` option of `createFrontendPlugin`. diff --git a/.changeset/fruity-snails-laugh.md b/.changeset/fruity-snails-laugh.md new file mode 100644 index 0000000000..3b7775efac --- /dev/null +++ b/.changeset/fruity-snails-laugh.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': minor +--- + +fix scaffolder action createDeployToken to allow usage of oauth tokens diff --git a/.changeset/funny-papayas-tell.md b/.changeset/funny-papayas-tell.md deleted file mode 100644 index 98beaf89e0..0000000000 --- a/.changeset/funny-papayas-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': minor ---- - -Show the pagination text for the offset-paginated catalog table, and remove the pagination bar from the top of the `CatalogTable` when pagination is enabled. diff --git a/.changeset/funny-stars-open.md b/.changeset/funny-stars-open.md new file mode 100644 index 0000000000..336e68bac1 --- /dev/null +++ b/.changeset/funny-stars-open.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Fix inconsistent behavior in the `new` command for the `@internal` scope: it now consistently defaults to the `backstage-plugin-` infix whether the `--scope` option is not set or it's set to `internal`. diff --git a/.changeset/gentle-bikes-relax.md b/.changeset/gentle-bikes-relax.md new file mode 100644 index 0000000000..7a4aeda5f8 --- /dev/null +++ b/.changeset/gentle-bikes-relax.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-module-addons-contrib': patch +--- + +ExpandableCollapse Techdocs Addon was breaking native sidebar collapse on Firefox diff --git a/.changeset/giant-lamps-happen.md b/.changeset/giant-lamps-happen.md new file mode 100644 index 0000000000..1bc4ae6eab --- /dev/null +++ b/.changeset/giant-lamps-happen.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Improved the Link component structure in Backstage UI. diff --git a/.changeset/good-islands-drive.md b/.changeset/good-islands-drive.md deleted file mode 100644 index 5b909dc84f..0000000000 --- a/.changeset/good-islands-drive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Added `info` object to the context of the alpha CLI. diff --git a/.changeset/green-trainers-float.md b/.changeset/green-trainers-float.md deleted file mode 100644 index 537fe01736..0000000000 --- a/.changeset/green-trainers-float.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Fix EntityPicker field to render description as markdown, matching other form components in the system. diff --git a/.changeset/grumpy-phones-kiss.md b/.changeset/grumpy-phones-kiss.md deleted file mode 100644 index 96b6ff05d9..0000000000 --- a/.changeset/grumpy-phones-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-elasticsearch': patch ---- - -Fixed an issue where the `search.elasticsearch.queryOptions` config were not picked up by the `ElasticSearchSearchEngine`. diff --git a/.changeset/grumpy-planes-bet.md b/.changeset/grumpy-planes-bet.md new file mode 100644 index 0000000000..bf7d36be41 --- /dev/null +++ b/.changeset/grumpy-planes-bet.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Fixed a bug in the Scaffolder's template parsing in the `useTemplateSchema` hook by removing the title instead of setting it to `undefined` diff --git a/.changeset/heavy-baths-rule.md b/.changeset/heavy-baths-rule.md deleted file mode 100644 index 09f26e8b57..0000000000 --- a/.changeset/heavy-baths-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-github': minor ---- - -**BREAKING** The `GithubLocationAnalyzer` now requires the `AuthService` and the `CatalogService` when being constructed and the `TokenManger` has been removed. diff --git a/.changeset/heavy-cars-wash.md b/.changeset/heavy-cars-wash.md new file mode 100644 index 0000000000..87da5a6d95 --- /dev/null +++ b/.changeset/heavy-cars-wash.md @@ -0,0 +1,70 @@ +--- +'@backstage/plugin-catalog-backend-module-ldap': minor +--- + +Moved from `ldapjs` dependency to `ldapts` + +### Breaking Changes + +**Type Migration** + +Custom transformers must now accept `Entry` from ldapts instead of `SearchEntry` +from ldapjs The Entry type provides direct property access without need for +`.object()` or `.raw()` methods. + +If you have custom user or group transformers, update the signature from: + +```typescript +(vendor: LdapVendor, config: UserConfig, entry: SearchEntry) => + Promise; +``` + +to + +```typescript +(vendor: LdapVendor, config: UserConfig, entry: Entry) => + Promise; +``` + +**Search Options** + +Updated LDAP search configuration `typesOnly: false` → `attributeValues: true` +This inverts the boolean logic: ldapjs used negative form while ldapts uses +positive form. Both achieve the same result: retrieving attribute values rather +than just attribute names. + +Update LDAP search options in configuration from + +```yaml +options: + typesOnly: false +``` + +to + +```yaml +options: + attributeValues: true +``` + +**API Changes** Removed `LdapClient.searchStreaming()` method. Users should +migrate to `LdapClient.search()` instead + +If you're using `searchStreaming` directly: + +```typescript +// Before +await client.searchStreaming(dn, options, async entry => { + // process each entry +}); + +// After +const entries = await client.search(dn, options); +for (const entry of entries) { + // process each entry +} +``` + +> **_NOTE:_**: Both methods have always loaded all entries into memory. The +> searchStreaming method was only needed internally to handle ldapjs's +> event-based API. diff --git a/.changeset/heavy-onions-swim.md b/.changeset/heavy-onions-swim.md deleted file mode 100644 index 42ba056c1e..0000000000 --- a/.changeset/heavy-onions-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -Added `workspace:template` and `workspace:template:file` actions to complement respective `fetch:*` actions diff --git a/.changeset/honest-lamps-occur.md b/.changeset/honest-lamps-occur.md new file mode 100644 index 0000000000..27b2eb44f5 --- /dev/null +++ b/.changeset/honest-lamps-occur.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fixed dialog backdrop appearance in dark mode. diff --git a/.changeset/honest-pandas-win.md b/.changeset/honest-pandas-win.md new file mode 100644 index 0000000000..a9dc5d7e9d --- /dev/null +++ b/.changeset/honest-pandas-win.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': minor +--- + +Promote `instanceMetadata` service to main entrypoint. diff --git a/.changeset/honest-states-repeat.md b/.changeset/honest-states-repeat.md deleted file mode 100644 index 06b459b673..0000000000 --- a/.changeset/honest-states-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Added optional title prop to `customHomePageGrid` diff --git a/.changeset/honest-teams-shave.md b/.changeset/honest-teams-shave.md deleted file mode 100644 index 6afbf37039..0000000000 --- a/.changeset/honest-teams-shave.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/plugin-home-react': patch -'@backstage/plugin-home': patch ---- - -Export ContentModal from `@backstage/plugin-home-react` so people can use this in other scenarios. -Renamed `CatalogReactComponentsNameToClassKey` to `PluginHomeComponentsNameToClassKey` in `overridableComponents.ts` - -Made QuickStartCard `docsLinkTitle` prop more flexible to allow for any React.JSX.Element instead of just a string. -Added QuickStartCard prop `additionalContent` which can eventually replace the prop `video`. diff --git a/.changeset/huge-olives-do.md b/.changeset/huge-olives-do.md deleted file mode 100644 index 61eb37559f..0000000000 --- a/.changeset/huge-olives-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-events-backend-module-gitlab': patch ---- - -Adds support for `object_kind` field with priority over `event_name` on Gitlab webhook event types diff --git a/.changeset/huge-taxis-grab.md b/.changeset/huge-taxis-grab.md new file mode 100644 index 0000000000..a021fcb82c --- /dev/null +++ b/.changeset/huge-taxis-grab.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Migrated CellProfile component from Base UI Avatar to Backstage UI Avatar component. diff --git a/.changeset/icy-mugs-glow.md b/.changeset/icy-mugs-glow.md deleted file mode 100644 index 553daff24a..0000000000 --- a/.changeset/icy-mugs-glow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-bitbucket-cloud-common': patch ---- - -Add support for `repo:updated` events as `Events.RepoUpdatedEvent`. diff --git a/.changeset/itchy-bars-smell.md b/.changeset/itchy-bars-smell.md new file mode 100644 index 0000000000..b82779502e --- /dev/null +++ b/.changeset/itchy-bars-smell.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': minor +--- + +Fixing styles on SearchField in Backstage UI after migration to CSS modules. `SearchField` has now its own set of class names. We previously used class names from `TextField` but this approach was creating some confusion so going forward in your theme you'll be able to theme `TextField` and `SearchField` separately. diff --git a/.changeset/khaki-grapes-sink.md b/.changeset/khaki-grapes-sink.md deleted file mode 100644 index d96521e029..0000000000 --- a/.changeset/khaki-grapes-sink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -Added new icon and onClear props to the TextField to make it easier to accessorize inputs. diff --git a/.changeset/large-experts-sort.md b/.changeset/large-experts-sort.md deleted file mode 100644 index 6d58836db7..0000000000 --- a/.changeset/large-experts-sort.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-events-backend-module-github': minor ---- - -**BREAKING**: Removed the `createGithubSignatureValidator` export. - -Added support webhook validation based on `integrations.github.[].apps.[].webhookSecret`. diff --git a/.changeset/large-lemons-clap.md b/.changeset/large-lemons-clap.md deleted file mode 100644 index cf1a3eed5d..0000000000 --- a/.changeset/large-lemons-clap.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch -'@backstage/backend-defaults': patch -'@backstage/integration': patch ---- - -update documentation diff --git a/.changeset/lazy-tires-show.md b/.changeset/lazy-tires-show.md deleted file mode 100644 index 3ccf5f155e..0000000000 --- a/.changeset/lazy-tires-show.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-permission-backend': minor -'@backstage/plugin-permission-common': minor -'@backstage/plugin-permission-node': minor ---- - -Fixed an issue causing the `PermissionClient` to exhaust the request body size limit too quickly when making many requests. diff --git a/.changeset/legal-weeks-walk.md b/.changeset/legal-weeks-walk.md new file mode 100644 index 0000000000..2068ff40b2 --- /dev/null +++ b/.changeset/legal-weeks-walk.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Added `@backstage/plugin-app-visualizer` to the app in the `--next` template. diff --git a/.changeset/lemon-spies-sleep.md b/.changeset/lemon-spies-sleep.md new file mode 100644 index 0000000000..15ec451f62 --- /dev/null +++ b/.changeset/lemon-spies-sleep.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Apply default ordering of templates diff --git a/.changeset/long-humans-sink.md b/.changeset/long-humans-sink.md new file mode 100644 index 0000000000..9959caf1b1 --- /dev/null +++ b/.changeset/long-humans-sink.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Avatar components in x-small and small sizes now display only one initial instead of two, improving readability at smaller dimensions. diff --git a/.changeset/loud-carpets-throw.md b/.changeset/loud-carpets-throw.md new file mode 100644 index 0000000000..169703d815 --- /dev/null +++ b/.changeset/loud-carpets-throw.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Added a template for the `yarn new` command to create an catalog entity provider. To add this template to an explicit list in the root `package.json`, use `@backstage/cli/templates/catalog-provider-module`. diff --git a/.changeset/lovely-cats-take.md b/.changeset/lovely-cats-take.md deleted file mode 100644 index ab1ee1c249..0000000000 --- a/.changeset/lovely-cats-take.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch ---- - -Support Bitbucket Cloud's `repo:updated` events at `BitbucketCloudEntityProvider`. - -To make use of the new event type, you have to configure your webhook or add a new ones -that delivers this event type to Backstage similar to `repo:push` before. - -Only `repo:updated` events that modify a repository's URL (e.g., due to a name change) -will cause changes (removing the "old", adding the "new" repository). diff --git a/.changeset/mean-parents-build.md b/.changeset/mean-parents-build.md deleted file mode 100644 index d3bba29019..0000000000 --- a/.changeset/mean-parents-build.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -Pin version of @base-ui-components/react. diff --git a/.changeset/mighty-carrots-decide.md b/.changeset/mighty-carrots-decide.md deleted file mode 100644 index 68f210da48..0000000000 --- a/.changeset/mighty-carrots-decide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-react': minor ---- - -Allow search filters to provide labels and values separately, and not only values diff --git a/.changeset/moody-plums-add.md b/.changeset/moody-plums-add.md new file mode 100644 index 0000000000..a88e11b347 --- /dev/null +++ b/.changeset/moody-plums-add.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-gateway-backend': minor +--- + +Update usage of the `instanceMetadata` service. diff --git a/.changeset/moody-women-itch.md b/.changeset/moody-women-itch.md deleted file mode 100644 index f68fddb848..0000000000 --- a/.changeset/moody-women-itch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-notifications-backend-module-email': patch ---- - -Enable the ability to configure the endpoint for the SES connection used in the notifications email module. This enables the configuration of alternate endpoints as required, for example for local testing or alternative stacks. diff --git a/.changeset/neat-glasses-occur.md b/.changeset/neat-glasses-occur.md deleted file mode 100644 index 5fea5b1886..0000000000 --- a/.changeset/neat-glasses-occur.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-import': patch ---- - -Add i18n support for `catalog-import` plugin. diff --git a/.changeset/neat-glasses-occured.md b/.changeset/neat-glasses-occured.md deleted file mode 100644 index 289e03e243..0000000000 --- a/.changeset/neat-glasses-occured.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-import': minor ---- - -**BREAKING**: `generateStepper` and `defaultGenerateStepper` now require a translation argument to be passed through for supporting translations. diff --git a/.changeset/new-hands-scream.md b/.changeset/new-hands-scream.md deleted file mode 100644 index 03291648db..0000000000 --- a/.changeset/new-hands-scream.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-auth-backend': minor ---- - -**BREAKING**: Removed support for the old backend system, and removed all deprecated exports. - -If you were using one of the deprecated imports from this package, you will have to follow the instructions in their respective deprecation notices before upgrading. Most of the general utilities are available from `@backstage/plugin-auth-node`, and the specific auth providers are available from dedicated packages such as for example `@backstage/plugin-auth-backend-module-github-provider`. See [the auth docs](https://backstage.io/docs/auth/) for specific instructions. diff --git a/.changeset/nice-vans-vanish.md b/.changeset/nice-vans-vanish.md deleted file mode 100644 index c52fc42488..0000000000 --- a/.changeset/nice-vans-vanish.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': minor ---- - -**Breaking Change** Icons on Button and IconButton now need to be imported and placed like this: } /> +- Content +- + ++ ++ ++ Content ++ +``` + +CSS classes: `.bui-CollapsibleRoot` → `.bui-Accordion`, `.bui-CollapsibleTrigger` → `.bui-AccordionTrigger` (now on heading element), `.bui-CollapsiblePanel` → `.bui-AccordionPanel` + +## Migration Path 2: React Aria Disclosure (Full Customization) + +For custom styling without preset styles: + +```tsx +import { Disclosure, Button, DisclosurePanel } from 'react-aria-components'; + + + + Content +; +``` diff --git a/.changeset/warm-llamas-return.md b/.changeset/warm-llamas-return.md deleted file mode 100644 index 743ad0a5bb..0000000000 --- a/.changeset/warm-llamas-return.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-events-backend-module-google-pubsub': minor ---- - -Added a module that is able to transfer messages from Google Pub/Sub subscriptions into the Backstage events system. diff --git a/.changeset/warm-moments-repeat.md b/.changeset/warm-moments-repeat.md new file mode 100644 index 0000000000..a72387d720 --- /dev/null +++ b/.changeset/warm-moments-repeat.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Fix #31348 issue where BitbucketUrlReader ignored provided token and instead always used integration credentials diff --git a/.changeset/warm-shrimps-clap.md b/.changeset/warm-shrimps-clap.md new file mode 100644 index 0000000000..0386df05de --- /dev/null +++ b/.changeset/warm-shrimps-clap.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch +--- + +Correctly handle entity removal computation when DB count query returns string diff --git a/.changeset/wicked-clubs-dream.md b/.changeset/wicked-clubs-dream.md deleted file mode 100644 index c866ac6312..0000000000 --- a/.changeset/wicked-clubs-dream.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-search-react': patch -'@backstage/plugin-search': patch ---- - -search plugin support i18n diff --git a/.changeset/wicked-dingos-stand.md b/.changeset/wicked-dingos-stand.md deleted file mode 100644 index 92d84825d1..0000000000 --- a/.changeset/wicked-dingos-stand.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-plugin-api': patch ---- - -The `TranslationApi` now supports interpolation of JSX elements by passing them directly as values to the translation function. If any of the provided interpolation values are JSX elements, the translation function will return a JSX element instead of a string. diff --git a/.changeset/wide-papers-run.md b/.changeset/wide-papers-run.md new file mode 100644 index 0000000000..e0e16d71af --- /dev/null +++ b/.changeset/wide-papers-run.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Set the color-scheme property depending on theme diff --git a/.changeset/wild-donkeys-sneeze.md b/.changeset/wild-donkeys-sneeze.md new file mode 100644 index 0000000000..5e2c4474c5 --- /dev/null +++ b/.changeset/wild-donkeys-sneeze.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Added new VisuallyHidden component for hiding content visually while keeping it accessible to screen readers. diff --git a/.changeset/wild-owls-divide.md b/.changeset/wild-owls-divide.md new file mode 100644 index 0000000000..d903b76bd0 --- /dev/null +++ b/.changeset/wild-owls-divide.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fix default font wight and font family in Backstage UI. diff --git a/.changeset/wise-cobras-sink.md b/.changeset/wise-cobras-sink.md deleted file mode 100644 index 7a6a73c726..0000000000 --- a/.changeset/wise-cobras-sink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -Use the Field component from Base UI within the TextField. diff --git a/.changeset/wise-pillows-smile.md b/.changeset/wise-pillows-smile.md deleted file mode 100644 index febdeab2c4..0000000000 --- a/.changeset/wise-pillows-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'yarn-plugin-backstage': patch ---- - -Add both `npm:` and `backstage:` ranges to the lockfile to ensure compatibility with tools that parse the lockfile and ensure dependencies stay locked when building dist workspaces. diff --git a/.changeset/yellow-beans-eat.md b/.changeset/yellow-beans-eat.md deleted file mode 100644 index 2380b19a6f..0000000000 --- a/.changeset/yellow-beans-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Fix for missing `routeRef` when using `core-plugin-api` in a dialog context diff --git a/.changeset/yellow-cows-tickle.md b/.changeset/yellow-cows-tickle.md deleted file mode 100644 index 026c7444f0..0000000000 --- a/.changeset/yellow-cows-tickle.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/catalog-client': minor -'@backstage/plugin-catalog-react': minor -'@backstage/plugin-catalog-node': minor ---- - -Add `getLocations` method to `CatalogApi` and `CatalogClient`. This method calls the [`GET /locations`](https://backstage.io/docs/features/software-catalog/software-catalog-api/#get-locations) endpoint from the catalog backend. diff --git a/.changeset/young-dancers-shave.md b/.changeset/young-dancers-shave.md deleted file mode 100644 index f7cdc3f3c2..0000000000 --- a/.changeset/young-dancers-shave.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-scaffolder-node': patch ---- - -Generating new tokens on each Scaffolder Task Retry diff --git a/.changeset/yummy-socks-brake.md b/.changeset/yummy-socks-brake.md new file mode 100644 index 0000000000..4f3dcfb598 --- /dev/null +++ b/.changeset/yummy-socks-brake.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Allow configuring dynamic client registration token expiration with config `auth.experimentalDynamicClientRegistration.tokenExpiration`. + +Maximum expiration for the DCR token is 24 hours. Default expiration is 1 hour. diff --git a/.eslintignore b/.eslintignore index ea8f6760c7..5cfe8188d3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,7 +7,7 @@ **/.git/** **/public/** **/microsite/** -**/canon-docs/** +**/docs-ui/** **/templates/** **/sample-templates/** playwright.config.ts diff --git a/.eslintrc.js b/.eslintrc.js index 409b820783..54f9e69576 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -18,8 +18,26 @@ var path = require('path'); module.exports = { root: true, - plugins: ['@spotify', 'notice', 'react', 'testing-library'], + plugins: ['@spotify', 'notice', 'react', 'testing-library', '@backstage'], rules: { + '@backstage/no-mixed-plugin-imports': [ + 'error', + { + // TODO: Fix these either by right role or by moving things to new packages + excludedTargetPackages: [ + '@backstage/plugin-catalog', + '@backstage/plugin-techdocs', + '@backstage/plugin-app', + '@backstage/plugin-catalog-backend', + '@backstage/test-utils', + '@backstage/plugin-auth-backend', + '@backstage/plugin-permission-backend', + '@backstage/plugin-kubernetes-backend', + '@backstage/config-loader', + '@backstage/plugin-app-backend' + ], + } + ], 'react/react-in-jsx-scope': 'off', 'notice/notice': [ 'error', diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2685926549..8491b1a260 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -10,6 +10,7 @@ yarn.lock @backstage/maintainers @backst /.changeset @backstage/operations-maintainers /.changeset/*.md /.github @backstage/operations-maintainers +/.github/vale @backstage/documentation-maintainers /beps/0001-notifications-system @backstage/maintainers @backstage/notifications-maintainers /docs @backstage/maintainers @backstage/documentation-maintainers /docs/assets/search @backstage/search-maintainers @@ -28,7 +29,6 @@ yarn.lock @backstage/maintainers @backst /microsite/static @backstage/maintainers @backstage/documentation-maintainers /packages @backstage/framework-maintainers /packages/backend-openapi-utils @backstage/maintainers @backstage/reviewers @backstage/openapi-tooling-maintainers -/packages/canon @backstage/design-system-maintainers /packages/catalog-client @backstage/catalog-maintainers /packages/catalog-model @backstage/catalog-maintainers /packages/cli @backstage/tooling-maintainers @@ -40,6 +40,7 @@ yarn.lock @backstage/maintainers @backst /packages/repo-tools @backstage/tooling-maintainers /packages/techdocs-cli @backstage/techdocs-maintainers /packages/techdocs-cli-embedded-app @backstage/techdocs-maintainers +/packages/ui @backstage/design-system-maintainers /packages/yarn-plugin @backstage/tooling-maintainers /plugins/app @backstage/framework-maintainers /plugins/app-* @backstage/framework-maintainers diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000000..98073c5128 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,31 @@ +This is a TypeScript project structured as a monorepo using Yarn workspaces. + +## Code Standards + +The following files contain guidelines for the project: + +- `/STYLE.md`: guidelines for code style. +- `/REVIEWING.md`: guidelines for pull requests. +- `/SECURITY.md`: guidelines for security. +- `/docs/architecture-decisions/`: contains the architecture decisions for the project. + +## Development Flow + +Before any of these commands can be run, you need to run `yarn install` in the project root. + +- Build: There is no need to build the project during development, and it is verified automatically in the CI pipeline. +- Test: Use `yarn test --no-watch ` in the project root to run tests. The path can be either a single file or a directory. Always provide a path, avoid running all tests. +- Type checking: Use `yarn tsc` in the project root to run the type checker. +- Code formatting: Use `yarn prettier --write ` to format code. +- Lint: Use `yarn lint --fix` in the project root to run the linter. +- API reports: Before submitting a pull request with changes to any package in the workspace, run `yarn build:api-reports` in the project root to generate API reports for all packages. + +You MUST NOT create a release by running `yarn changesets version` or `yarn release` as part of any changes. Releases are created by separate workflows. + +All changes that affect the published version of packages in the `/packages` and `/plugins` directories must be accompanied by a changeset. See the guidelines in `/REVIEWING.md` for information on how to write good changesets. Changesets are stored in the `/.changeset` directory. Breaking changes must be accompanied by a `minor` version bump for packages that below version `1.0.0`, or a `major` version bump for packages that are at version `1.0.0` or higher. + +Never update ESLint, Prettier, or TypeScript configuration files unless specifically requested. + +## Repository Structure + +See `/docs/contribute/project-structure.md` for a detailed description of the repository structure. diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 77faa9354f..da3cf3e8fb 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -31,9 +31,9 @@ matchSourceUrls: ['https://github.com/microsoft/rushstack{/,}**'], }, { - groupName: 'SVGR monorepo packages', + groupName: 'Module-federation monorepo packages', rangeStrategy: 'replace', - matchSourceUrls: ['https://github.com/gregberge/svgr{/,}**'], + matchSourceUrls: ['https://github.com/module-federation/core{/,}**'], }, // We update yarn packages manually as it's gzip'd and we don't want to pollute the repository too much. { diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index 36f9335b1f..80d55d498a 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -10,6 +10,7 @@ Airbrakes ajv Alaria Alef +allowedHosts allowlisted Anddddd Apdex @@ -20,9 +21,9 @@ asciidoc async Atlassian autofix +autologout automations autoscaling -Autoscaling autoselect Avro backend's @@ -37,15 +38,19 @@ Bitrise Blackbox bool boolean +breakpoint Brex broadcasted bugfixes builtins bundler bundlers +bursty callout +camelCase CDNs Chai +Chainguard changeset changesets Changesets @@ -75,6 +80,7 @@ Config configmaps configs configurability +configurer conformant const cookiecutter @@ -102,6 +108,9 @@ deliverables denormalized dependabot deps +dequeue +dequeueing +dereferencing deserialization destructured destructuring @@ -111,8 +120,6 @@ devcontainer devcontainers devops devs -dequeue -dequeueing dialogs disambiguator discoverability @@ -143,6 +150,7 @@ Expedia facto failover Fargate +faqs featureful Figma firehydrant @@ -150,8 +158,8 @@ FireHydrant Firekube Firestore Fiverr -Flightcontrol flightcontrol +Flightcontrol Francesco Frontside Gaurav @@ -172,11 +180,12 @@ graphql GraphQL graphviz Hackathons +hackathon haproxy hardcoded hardcoding -Harness harness +Harness Helidon Henneke Heroku @@ -197,11 +206,13 @@ impactful incentivised Indal indexable +infinispan ingestors inlined -inlining inlinehilite +inlining integrator's +intellij interop interoperate iterable @@ -213,11 +224,13 @@ jq js json jsonnet +JSONSchema jsx JWTs Kaewkasi Kaswell keepalive +Keycloak Keyv Knex knip @@ -242,6 +255,8 @@ lockdown lockfile lockfiles lookbehind +lookup +lookups lowercased lunr Luxon @@ -273,6 +288,7 @@ modularization monorepo Monorepo monorepos +monospace morgan msgraph msw @@ -285,6 +301,7 @@ namespaced namespaces Namespaces namespacing +navbar neuro newrelic nginx @@ -312,14 +329,16 @@ OpenSearch OpenShift openssl orgs -Overridable overridable +Overridable padding paddings pagerduty pageview Pandey parallelization +param +params parseable Patrik pattison @@ -364,6 +383,7 @@ readonly rebase rebasing Recharts +redactions Redash redis reimplement @@ -373,6 +393,7 @@ replicasets repo Repo repos +requestors rerender rerenders resourcequotas @@ -382,8 +403,11 @@ Reusability roadmaps rollbar rollout +rollouts Roboto +rollbar Rollbar +rollout Rollup routable Routable @@ -399,9 +423,11 @@ sanitization scaffolded scaffolder Scaffolder -scrollbar +scalprum SCM SCMs +scrollable +scrollbar sdks seb semlas @@ -409,14 +435,15 @@ semver sendmail serializable Serverless +severities shoutout SIG signoff SIGs siloed Sinon -snackbars snackbar +snackbars Snyk Sonarqube sourcemaps @@ -433,6 +460,7 @@ statefulsets stdout storable storages +Streamable stringified stringify subcommand @@ -444,7 +472,10 @@ subfolders subheader subheaders subkey +subpage subpath +subpaths +subroute subroutes substring subtree @@ -453,6 +484,7 @@ Superfences superset supertype SVGs +swappable talkdesk Talkdesk Tanzu @@ -468,6 +500,7 @@ templaters Templaters TFRecord theia +Themer threenager thumbsup todo @@ -486,6 +519,7 @@ transpiled transpiler transpilers truthy +tsconfig TSDoc typeahead ui @@ -536,7 +570,5 @@ zod Zolotusky zoomable zsh -scrollable -severities -intellij -tsconfig +resizable +enums diff --git a/.github/workflows/api-breaking-changes-comment.yml b/.github/workflows/api-breaking-changes-comment.yml index af625f67ab..29b8545766 100644 --- a/.github/workflows/api-breaking-changes-comment.yml +++ b/.github/workflows/api-breaking-changes-comment.yml @@ -23,7 +23,7 @@ jobs: comment-cache-key: ${{ steps.hash.outputs.COMMENT_FILE_HASH }} steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: disable-sudo: true egress-policy: block @@ -74,7 +74,7 @@ jobs: - name: Cache Comment if: ${{ steps.event.outputs.ACTION != 'closed' }} - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 with: path: comment.md key: ${{ steps.hash.outputs.COMMENT_FILE_HASH }} @@ -99,11 +99,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 - name: Fetch cached Manifests File id: cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: comment.md key: ${{ needs.setup.outputs.comment-cache-key }} diff --git a/.github/workflows/api-breaking-changes.yml b/.github/workflows/api-breaking-changes.yml index 74473f30d5..5ee0e35af9 100644 --- a/.github/workflows/api-breaking-changes.yml +++ b/.github/workflows/api-breaking-changes.yml @@ -14,7 +14,7 @@ jobs: if: ${{ github.event_name != 'pull_request' || github.event.action != 'closed' }} steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/automate_area-labels.yml b/.github/workflows/automate_area-labels.yml index ec6dd0c85c..0620c877eb 100644 --- a/.github/workflows/automate_area-labels.yml +++ b/.github/workflows/automate_area-labels.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/automate_changeset_feedback.yml b/.github/workflows/automate_changeset_feedback.yml index c1245c59b9..5c91ff0038 100644 --- a/.github/workflows/automate_changeset_feedback.yml +++ b/.github/workflows/automate_changeset_feedback.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/automate_merge_message.yml b/.github/workflows/automate_merge_message.yml index ebe2ef739d..2476ab71f4 100644 --- a/.github/workflows/automate_merge_message.yml +++ b/.github/workflows/automate_merge_message.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/automate_stale.yml b/.github/workflows/automate_stale.yml index 6be74ae99f..56bf1e26ec 100644 --- a/.github/workflows/automate_stale.yml +++ b/.github/workflows/automate_stale.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -27,7 +27,7 @@ jobs: recent activity. It will be closed if no further activity occurs. Thank you for your contributions. days-before-issue-stale: 60 - days-before-issue-close: 7 + days-before-issue-close: 14 exempt-issue-labels: after vacations,no stale stale-issue-label: stale stale-pr-message: > @@ -35,8 +35,8 @@ jobs: recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution! - days-before-pr-stale: 14 - days-before-pr-close: 7 + days-before-pr-stale: 30 + days-before-pr-close: 14 exempt-pr-labels: after vacations,no stale stale-pr-label: stale operations-per-run: 100 diff --git a/.github/workflows/ci-noop.yml b/.github/workflows/ci-noop.yml index 472a7a4e72..b1415652e5 100644 --- a/.github/workflows/ci-noop.yml +++ b/.github/workflows/ci-noop.yml @@ -24,7 +24,7 @@ jobs: name: Verify ${{ matrix.node-version }} steps: # - name: Harden Runner - # uses: step-security/harden-runner@8ca2b8b2ece13480cda6dacd3511b49857a23c09 # v2.5.1 + # uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.5.1 # with: # egress-policy: audit @@ -40,7 +40,7 @@ jobs: name: Test ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 059596265e..9eafd2c2a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: name: Install ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -64,7 +64,7 @@ jobs: name: Verify ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -102,9 +102,6 @@ jobs: - name: type checking and declarations run: yarn tsc:full - - name: prettier - run: yarn prettier:check - # We need to generate the API references as well, so that we can verify the doc links - name: check api reports and generate API reference run: yarn build:api-reports:only --ci --docs @@ -127,9 +124,9 @@ jobs: - name: build all packages run: yarn backstage-cli repo build --all - # For now canon has a custom build script and needs to be built separately - - name: build canon - run: yarn --cwd packages/canon build + # For now BUI has a custom build script and needs to be built separately + - name: build BUI + run: yarn --cwd packages/ui build - name: verify type dependencies run: yarn lint:type-deps @@ -161,8 +158,8 @@ jobs: name: Test ${{ matrix.node-version }} services: - postgres17: - image: postgres:17 + postgres18: + image: postgres:18 env: POSTGRES_PASSWORD: postgres options: >- @@ -172,8 +169,8 @@ jobs: --health-retries 5 ports: - 5432/tcp - postgres13: - image: postgres:13 + postgres14: + image: postgres:14 env: POSTGRES_PASSWORD: postgres options: >- @@ -239,13 +236,16 @@ jobs: # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds - name: restore backstage-cli cache - uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4 + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .cache/backstage-cli key: ${{ runner.os }}-v${{ matrix.node-version }}-backstage-cli-${{ github.run_id }} restore-keys: | ${{ runner.os }}-v${{ matrix.node-version }}-backstage-cli- + - name: prettier + run: yarn prettier:check --cache --cache-location .cache/backstage-cli/.prettier-cache + - name: lint changed packages run: yarn backstage-cli repo lint --since origin/master --successCache --successCacheDir .cache/backstage-cli @@ -253,14 +253,14 @@ jobs: run: yarn backstage-cli repo test --maxWorkers=3 --workerIdleMemoryLimit=1300M --since origin/master --successCache --successCacheDir .cache/backstage-cli env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 - BACKSTAGE_TEST_DATABASE_POSTGRES17_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres17.ports[5432] }} - BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres13.ports[5432] }} + BACKSTAGE_TEST_DATABASE_POSTGRES18_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres18.ports[5432] }} + BACKSTAGE_TEST_DATABASE_POSTGRES14_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres14.ports[5432] }} BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING: mysql://root:root@localhost:${{ job.services.mysql8.ports[3306] }}/ignored BACKSTAGE_TEST_CACHE_REDIS7_CONNECTION_STRING: redis://localhost:${{ job.services.redis.ports[6379] }} # Always save success cache even if there were failures, that way it can be used in re-triggered builds - name: save backstage-cli cache - uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4 + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 if: always() with: path: .cache/backstage-cli diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index b48bd2683d..156d676cd2 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -10,7 +10,7 @@ jobs: timeout-minutes: 10 steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/deploy_docker-image.yml b/.github/workflows/deploy_docker-image.yml index e1547801ef..18987aa3e0 100644 --- a/.github/workflows/deploy_docker-image.yml +++ b/.github/workflows/deploy_docker-image.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -52,17 +52,17 @@ jobs: working-directory: ./example-app - name: Login to GitHub Container Registry - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Build and push - uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: './example-app' file: ./example-app/packages/backend/Dockerfile diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index 5045e0c96f..a07ac06d99 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -23,12 +23,12 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit - name: find latest release - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 id: find-release with: script: | @@ -80,6 +80,34 @@ jobs: if-no-files-found: error retention-days: 1 + # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds + - name: restore package-docs cache + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .cache/package-docs + key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-stable-${{ github.run_id }} + restore-keys: | + ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-stable- + + - name: build API reference (beta) + run: yarn backstage-repo-tools package-docs + + - name: upload API reference (beta) + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: stable-reference-beta + path: type-docs/ + if-no-files-found: error + retention-days: 1 + + # Always save success cache even if there were failures, that way it can be used in re-triggered builds + - name: save package-docs cache + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + if: always() + with: + path: .cache/package-docs + key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-stable-${{ github.run_id }} + - name: microsite yarn install run: yarn install --immutable working-directory: microsite @@ -107,7 +135,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -136,20 +164,42 @@ jobs: if-no-files-found: error retention-days: 1 - # Also build and upload storybook - - name: storybook yarn install - run: yarn install --immutable - working-directory: storybook + # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds + - name: restore package-docs cache + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .cache/package-docs + key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-${{ github.run_id }} + restore-keys: | + ${{ runner.os }}-v${{ matrix.node-version }}-package-docs- - - name: storybook build + - name: build API reference (beta) + run: yarn backstage-repo-tools package-docs + + - name: upload API reference (beta) + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: next-reference-beta + path: type-docs/ + if-no-files-found: error + retention-days: 1 + + # Always save success cache even if there were failures, that way it can be used in re-triggered builds + - name: save package-docs cache + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + if: always() + with: + path: .cache/package-docs + key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-${{ github.run_id }} + + - name: Build Storybook run: yarn build-storybook - working-directory: storybook - - name: storybook upload + - name: Upload Storybook uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: storybook - path: storybook/dist/ + path: dist-storybook if-no-files-found: error retention-days: 1 @@ -190,7 +240,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -265,8 +315,18 @@ jobs: name: storybook path: microsite/build/storybook + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: stable-reference-beta + path: microsite/build/api/stable/ + + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: next-reference-beta + path: microsite/build/api/next/ + - name: Check the build output - run: ls microsite/build && ls microsite/build/storybook + run: ls microsite/build && ls microsite/build/storybook && ls microsite/build/api/stable && ls microsite/build/api/next - name: Deploy both microsite and storybook to gh-pages uses: JamesIves/github-pages-deploy-action@6c2d9db40f9296374acc17b90404b6e8864128c8 # v4.7.3 diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index b1d79713a4..b968c51782 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -16,8 +16,8 @@ jobs: node-version: [20.x, 22.x] services: - postgres17: - image: postgres:17 + postgres18: + image: postgres:18 env: POSTGRES_PASSWORD: postgres options: >- @@ -27,8 +27,8 @@ jobs: --health-retries 5 ports: - 5432/tcp - postgres13: - image: postgres:13 + postgres14: + image: postgres:14 env: POSTGRES_PASSWORD: postgres options: >- @@ -94,7 +94,7 @@ jobs: run: yarn backstage-cli config:check --lax - name: backstage-cli cache - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4 + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .cache/backstage-cli key: ${{ runner.os }}-v${{ matrix.node-version }}-backstage-cli-${{ github.run_id }} @@ -110,9 +110,9 @@ jobs: - name: build run: yarn backstage-cli repo build --all - # For now canon has a custom build script and needs to be built separately - - name: build canon - run: yarn --cwd packages/canon build + # For now BUI has a custom build script and needs to be built separately + - name: build BUI + run: yarn --cwd packages/ui build - name: verify type dependencies run: yarn lint:type-deps @@ -122,14 +122,14 @@ jobs: yarn backstage-cli repo test --maxWorkers=3 --workerIdleMemoryLimit=1300M --coverage --successCache --successCacheDir .cache/backstage-cli env: BACKSTAGE_TEST_DISABLE_DOCKER: 1 - BACKSTAGE_TEST_DATABASE_POSTGRES17_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres17.ports[5432] }} - BACKSTAGE_TEST_DATABASE_POSTGRES13_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres13.ports[5432] }} + BACKSTAGE_TEST_DATABASE_postgres18_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres18.ports[5432] }} + BACKSTAGE_TEST_DATABASE_postgres14_CONNECTION_STRING: postgresql://postgres:postgres@localhost:${{ job.services.postgres14.ports[5432] }} BACKSTAGE_TEST_DATABASE_MYSQL8_CONNECTION_STRING: mysql://root:root@localhost:${{ job.services.mysql8.ports[3306] }}/ignored BACKSTAGE_TEST_CACHE_REDIS7_CONNECTION_STRING: redis://localhost:${{ job.services.redis.ports[6379] }} - name: Discord notification if: ${{ failure() }} - uses: Ilshidur/action-discord@0c4b27844ba47cb1c7bee539c8eead5284ce9fa9 # 0.3.2 + uses: Ilshidur/action-discord@d2594079a10f1d6739ee50a2471f0ca57418b554 # 0.4.0 env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} with: @@ -151,13 +151,13 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit # Notify maintainers that a new release is ready to be published - name: Discord notification - uses: Ilshidur/action-discord@0c4b27844ba47cb1c7bee539c8eead5284ce9fa9 # 0.3.2 + uses: Ilshidur/action-discord@d2594079a10f1d6739ee50a2471f0ca57418b554 # 0.4.0 env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_MAINTAINERS_WEBHOOK }} with: diff --git a/.github/workflows/issue.yaml b/.github/workflows/issue.yaml index 50d0e4ceb0..8c1b0d028b 100644 --- a/.github/workflows/issue.yaml +++ b/.github/workflows/issue.yaml @@ -16,13 +16,13 @@ jobs: if: github.repository == 'backstage/backstage' steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit # We need to checkout the `.github/ISSUE_TEMPLATE` for the advanced labeler action to be able to read the templates # While at it we might as well checkout all of `.github` so that the labeling actions don't need to fetch their configs - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4 with: sparse-checkout: .github diff --git a/.github/workflows/mui-migration-tracker.yml b/.github/workflows/mui-migration-tracker.yml new file mode 100644 index 0000000000..4754ec51b0 --- /dev/null +++ b/.github/workflows/mui-migration-tracker.yml @@ -0,0 +1,70 @@ +name: MUI to BUI Migration Tracker + +on: + schedule: + # Run daily at midnight UTC + - cron: '0 0 * * *' + workflow_dispatch: + # Allow manual triggering + +permissions: + issues: write + contents: read + +jobs: + update-migration-progress: + runs-on: ubuntu-latest + name: Update Migration Progress Issue + + steps: + - name: Harden Runner + uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 20.x + registry-url: https://registry.npmjs.org/ # Needed for auth + + - name: yarn install + uses: backstage/actions/yarn-install@b3c1841fd69e1658ac631afafd0fb140a2309024 # v0.6.17 + with: + cache-prefix: ${{ runner.os }}-v20.x + + - name: Run migration analysis + id: analysis + run: | + # Run the migration script and save markdown output + yarn mui-to-bui --markdown > migration-report.md + + # Read the report into an environment variable (escape for GitHub Actions) + echo "REPORT<> $GITHUB_ENV + cat migration-report.md >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + + - name: Update GitHub Issue + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const issueNumber = 31467; + const reportBody = process.env.REPORT; + + try { + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + body: reportBody + }); + + console.log(`✅ Successfully updated issue #${issueNumber}`); + } catch (error) { + console.error(`❌ Error updating issue: ${error.message}`); + throw error; + } diff --git a/.github/workflows/pr-review-comment-trigger.yaml b/.github/workflows/pr-review-comment-trigger.yaml index e2bdb4c1cb..dc90da1384 100644 --- a/.github/workflows/pr-review-comment-trigger.yaml +++ b/.github/workflows/pr-review-comment-trigger.yaml @@ -20,7 +20,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/pr-review-comment.yaml b/.github/workflows/pr-review-comment.yaml index e108f3a4d7..30e7f5bad4 100644 --- a/.github/workflows/pr-review-comment.yaml +++ b/.github/workflows/pr-review-comment.yaml @@ -17,7 +17,7 @@ jobs: steps: # Inspired by https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index ab2630c2d9..b1a67bec15 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -18,7 +18,7 @@ jobs: if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request ) steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 45eb5de5c8..5bb4c13b25 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -39,7 +39,7 @@ jobs: persist-credentials: false - name: 'Run analysis' - uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 + uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 with: results_file: results.sarif results_format: sarif @@ -67,6 +67,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + uses: github/codeql-action/upload-sarif@a4e1a019f5e24960714ff6296aee04b736cbc3cf # v3.29.6 with: sarif_file: results.sarif diff --git a/.github/workflows/sync_canon.yml b/.github/workflows/sync_canon.yml index 2177177df0..4868fdaca9 100644 --- a/.github/workflows/sync_canon.yml +++ b/.github/workflows/sync_canon.yml @@ -1,14 +1,14 @@ -name: Sync Canon Docs +name: Sync BUI Docs on: push: branches: [master] jobs: - sync-canon-docs: + sync-docs-ui: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -26,36 +26,36 @@ jobs: with: cache-prefix: ${{ runner.os }}-v20.x - - name: Checkout backstage/canon-docs + - name: Checkout backstage/docs-ui uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - repository: backstage/canon-docs - path: canon-external-docs + repository: backstage/docs-ui + path: bui-external-docs token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} - name: Configure Git run: | git config --global user.email noreply@backstage.io - git config --global user.name 'Github Canon Docs workflow' + git config --global user.name 'Github BUI Docs workflow' - name: Install dependencies - working-directory: canon-docs + working-directory: docs-ui run: yarn install - - name: Build Canon Docs - working-directory: canon-docs + - name: Build Docs UI + working-directory: docs-ui run: | yarn build - - name: Replace contents of canon-external-docs repo with docs build output - working-directory: canon-external-docs + - name: Replace contents of bui-external-docs repo with docs build output + working-directory: bui-external-docs run: | git rm -rf . - cp -R ../canon-docs/dist/. . + cp -R ../docs-ui/dist/. . - - name: Commit to canon-storybook repo - working-directory: canon-external-docs + - name: Commit to bui-storybook repo + working-directory: bui-external-docs run: | git add . - git commit -am "Canon Docs build for backstage/backstage@${{ github.sha }}" + git commit -am "BUI Docs build for backstage/backstage@${{ github.sha }}" git push diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml index ee97f3fef3..458fa9ed99 100644 --- a/.github/workflows/sync_code-formatting.yml +++ b/.github/workflows/sync_code-formatting.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -30,7 +30,7 @@ jobs: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: Run Prettier on ADOPTERS.md - uses: creyD/prettier_action@31355f8eef017f8aeba2e0bc09d8502b13dbbad1 # v4.3 + uses: creyD/prettier_action@8c18391fdc98ed0d884c6345f03975edac71b8f0 # v4.6 with: # Modifies commit only if prettier autofixed the ADOPTERS.md prettier_options: --config docs/prettier.config.js --write ADOPTERS.md diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index 42efaa1142..26c0387cce 100644 --- a/.github/workflows/sync_dependabot-changesets.yml +++ b/.github/workflows/sync_dependabot-changesets.yml @@ -11,7 +11,7 @@ jobs: if: github.actor == 'dependabot[bot]' && github.repository == 'backstage/backstage' steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index 1c9d37aef0..7cf7e018bd 100644 --- a/.github/workflows/sync_release-manifest.yml +++ b/.github/workflows/sync_release-manifest.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/sync_renovate-changesets.yml b/.github/workflows/sync_renovate-changesets.yml index 2eb8f13dbc..caf697714a 100644 --- a/.github/workflows/sync_renovate-changesets.yml +++ b/.github/workflows/sync_renovate-changesets.yml @@ -11,7 +11,7 @@ jobs: if: github.actor == 'renovate[bot]' && github.repository == 'backstage/backstage' steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index b7cc0b33c7..697f63c991 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -29,7 +29,7 @@ jobs: cache-prefix: ${{ runner.os }}-v20.x - name: Create Snyk report - uses: snyk/actions/node@cdb760004ba9ea4d525f2e043745dfe85bb9077e # master + uses: snyk/actions/node@9adf32b1121593767fc3c057af55b55db032dc04 # master continue-on-error: true # Snyk CLI exits with error when vulnerabilities are found with: args: > diff --git a/.github/workflows/sync_snyk-monitor.yml b/.github/workflows/sync_snyk-monitor.yml index 741471d558..3f12815379 100644 --- a/.github/workflows/sync_snyk-monitor.yml +++ b/.github/workflows/sync_snyk-monitor.yml @@ -25,13 +25,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Monitor and Synchronize Snyk Policies - uses: snyk/actions/node@cdb760004ba9ea4d525f2e043745dfe85bb9077e # master + uses: snyk/actions/node@9adf32b1121593767fc3c057af55b55db032dc04 # master with: command: monitor args: > @@ -46,7 +46,7 @@ jobs: # Above we run the `monitor` command, this runs the `test` command which is # the one that generates the SARIF report that we can upload to GitHub. - name: Create Snyk report - uses: snyk/actions/node@cdb760004ba9ea4d525f2e043745dfe85bb9077e # master + uses: snyk/actions/node@9adf32b1121593767fc3c057af55b55db032dc04 # master continue-on-error: true # To make sure that SARIF upload gets called with: args: > @@ -58,6 +58,6 @@ jobs: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} NODE_OPTIONS: --max-old-space-size=7168 - name: Upload Snyk report - uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + uses: github/codeql-action/upload-sarif@a4e1a019f5e24960714ff6296aee04b736cbc3cf # v3.29.6 with: sarif_file: snyk.sarif diff --git a/.github/workflows/sync_version-packages.yml b/.github/workflows/sync_version-packages.yml index 42dadb5a57..3071990fbd 100644 --- a/.github/workflows/sync_version-packages.yml +++ b/.github/workflows/sync_version-packages.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -37,7 +37,7 @@ jobs: - name: Discord notification if: ${{ failure() }} - uses: Ilshidur/action-discord@0c4b27844ba47cb1c7bee539c8eead5284ce9fa9 # 0.3.2 + uses: Ilshidur/action-discord@d2594079a10f1d6739ee50a2471f0ca57418b554 # 0.4.0 env: DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} with: diff --git a/.github/workflows/verify_accessibility-noop.yml b/.github/workflows/verify_accessibility-noop.yml index c33acfd86d..837e8153be 100644 --- a/.github/workflows/verify_accessibility-noop.yml +++ b/.github/workflows/verify_accessibility-noop.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_accessibility.yml b/.github/workflows/verify_accessibility.yml index 02a303f9ea..c64a4d2ed1 100644 --- a/.github/workflows/verify_accessibility.yml +++ b/.github/workflows/verify_accessibility.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_chromatic-noop.yml b/.github/workflows/verify_chromatic-noop.yml new file mode 100644 index 0000000000..cd6248e004 --- /dev/null +++ b/.github/workflows/verify_chromatic-noop.yml @@ -0,0 +1,27 @@ +# NO-OP placeholder that always passes for other paths +# This is here so that we're able to set the status check as required + +name: Chromatic Void +on: + pull_request: + paths-ignore: + - '.github/workflows/verify_chromatic.yml' + - '.storybook/**' + - 'packages/ui/src/**' + - '**/*.stories.tsx' + +permissions: + contents: read + +jobs: + noop: + runs-on: ubuntu-latest + + name: Chromatic + steps: + - name: Harden Runner + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 + with: + egress-policy: audit + + - run: echo NOOP diff --git a/.github/workflows/verify_chromatic.yml b/.github/workflows/verify_chromatic.yml new file mode 100644 index 0000000000..705d769c83 --- /dev/null +++ b/.github/workflows/verify_chromatic.yml @@ -0,0 +1,92 @@ +name: Chromatic +on: + # NOTE: If you change these you must update verify_storybook-noop.yml as well + workflow_dispatch: + push: + branches: + - master + pull_request: + paths: + - '.github/workflows/verify_chromatic.yml' + - '.storybook/**' + - 'packages/ui/**' + - '**/*.stories.tsx' + +jobs: + chromatic: + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: [ubuntu-latest] + node-version: [20.x] + + name: Chromatic + steps: + - name: Harden Runner + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 + with: + egress-policy: audit + + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 10000 # Required to retrieve git history + + - name: Use node.js ${{ matrix.node-version }} + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: ${{ matrix.node-version }} + registry-url: https://registry.npmjs.org/ # Needed for auth + + - name: Install dependencies + uses: backstage/actions/yarn-install@b3c1841fd69e1658ac631afafd0fb140a2309024 # v0.6.17 + with: + cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} + + - name: Build Storybook + run: yarn build-storybook:chromatic + + - name: Run Chromatic + id: chromatic + uses: chromaui/action@latest + with: + token: ${{ secrets.GITHUB_TOKEN }} + # projectToken intentionally shared to allow collaborators to run Chromatic on forks + # https://www.chromatic.com/docs/custom-ci-provider#run-chromatic-on-external-forks-of-open-source-projects + projectToken: chpt_dab72dc0f97d55b + storybookBuildDir: dist-storybook + onlyChanged: true + externals: | + packages/ui/**/*.css + packages/ui/css/** + packages/ui/src/**/*.css + + - name: Prepare Chromatic Message + if: github.event_name == 'pull_request' && steps.chromatic.outputs.url + id: prepareMessage + run: | + if [ "${{ steps.chromatic.outputs.changeCount }}" = "0" ] || [ -z "${{ steps.chromatic.outputs.changeCount }}" ]; then + echo "changesText=No visual changes detected - [**View build in Chromatic**](${{ steps.chromatic.outputs.buildUrl }})" >> $GITHUB_OUTPUT + else + echo "changesText=**${{ steps.chromatic.outputs.changeCount }}** visual changes are waiting for review - [**Review changes in Chromatic**](${{ steps.chromatic.outputs.buildUrl }})" >> $GITHUB_OUTPUT + fi + + - name: Post Chromatic Results to Job Summary + if: github.event_name == 'pull_request' && steps.chromatic.outputs.url + run: | + echo "## 🎨 Visual Testing with Chromatic" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- ${{ steps.prepareMessage.outputs.changesText }}" >> $GITHUB_STEP_SUMMARY + echo "- **${{ steps.chromatic.outputs.specCount}}** stories for **${{ steps.chromatic.outputs.componentCount}}** Components - [**Preview changes in Storybook**](${{ steps.chromatic.outputs.storybookUrl }})" >> $GITHUB_STEP_SUMMARY + + - name: Post Chromatic Link in PR Comment + if: github.event_name == 'pull_request' && steps.chromatic.outputs.url && github.event.pull_request.head.repo.full_name == github.repository + uses: mshick/add-pr-comment@v2 + with: + message: | + ## 🎨 Visual Testing with Chromatic + + - ${{ steps.prepareMessage.outputs.changesText }} + - **${{ steps.chromatic.outputs.specCount}}** stories for **${{ steps.chromatic.outputs.componentCount}}** Components - [**Preview changes in Storybook**](${{ steps.chromatic.outputs.storybookUrl }}) + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/verify_codeql.yml b/.github/workflows/verify_codeql.yml index c4b21a9e1f..57da6f7f21 100644 --- a/.github/workflows/verify_codeql.yml +++ b/.github/workflows/verify_codeql.yml @@ -42,7 +42,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -55,7 +55,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + uses: github/codeql-action/init@a4e1a019f5e24960714ff6296aee04b736cbc3cf # v3.29.6 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -66,7 +66,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + uses: github/codeql-action/autobuild@a4e1a019f5e24960714ff6296aee04b736cbc3cf # v3.29.6 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -80,4 +80,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17 + uses: github/codeql-action/analyze@a4e1a019f5e24960714ff6296aee04b736cbc3cf # v3.29.6 diff --git a/.github/workflows/verify_docs-quality.yml b/.github/workflows/verify_docs-quality.yml index a3b80f498a..a0ec5a2eee 100644 --- a/.github/workflows/verify_docs-quality.yml +++ b/.github/workflows/verify_docs-quality.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-linux-noop.yml b/.github/workflows/verify_e2e-linux-noop.yml index 65fc6eccc9..f9e3d26e89 100644 --- a/.github/workflows/verify_e2e-linux-noop.yml +++ b/.github/workflows/verify_e2e-linux-noop.yml @@ -29,7 +29,7 @@ jobs: name: E2E Linux ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index 0995a85216..898de3d57c 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -21,7 +21,7 @@ jobs: services: postgres: - image: postgres:13 + image: postgres:14 env: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres @@ -43,7 +43,7 @@ jobs: name: E2E Linux ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-techdocs.yml b/.github/workflows/verify_e2e-techdocs.yml index fc30b377bc..abfdf17ee6 100644 --- a/.github/workflows/verify_e2e-techdocs.yml +++ b/.github/workflows/verify_e2e-techdocs.yml @@ -32,7 +32,7 @@ jobs: name: Techdocs steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -41,11 +41,14 @@ jobs: with: python-version: '3.9' - - name: install dependencies - run: yarn install --immutable - - - name: generate types - run: yarn tsc + - name: use node.js ${{ matrix.node-version }} + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: ${{ matrix.node-version }} + - name: yarn install + uses: backstage/actions/yarn-install@b3c1841fd69e1658ac631afafd0fb140a2309024 # v0.6.17 + with: + cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: build techdocs-cli working-directory: packages/techdocs-cli diff --git a/.github/workflows/verify_e2e-windows-noop.yml b/.github/workflows/verify_e2e-windows-noop.yml index e713f33ed6..fc4af922a5 100644 --- a/.github/workflows/verify_e2e-windows-noop.yml +++ b/.github/workflows/verify_e2e-windows-noop.yml @@ -25,7 +25,7 @@ jobs: name: E2E Windows ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index 0dc0bdaade..e859468462 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -33,7 +33,7 @@ jobs: name: E2E Windows ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_fossa.yml b/.github/workflows/verify_fossa.yml index 7bc612bf64..8f09531a94 100644 --- a/.github/workflows/verify_fossa.yml +++ b/.github/workflows/verify_fossa.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_microsite-noop.yml b/.github/workflows/verify_microsite-noop.yml index da4bc6ba25..169e447bbb 100644 --- a/.github/workflows/verify_microsite-noop.yml +++ b/.github/workflows/verify_microsite-noop.yml @@ -21,7 +21,7 @@ jobs: name: Microsite steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_microsite.yml b/.github/workflows/verify_microsite.yml index c22648bb8c..60fa039ec4 100644 --- a/.github/workflows/verify_microsite.yml +++ b/.github/workflows/verify_microsite.yml @@ -28,12 +28,12 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit - name: find latest release - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 id: find-release with: script: | @@ -85,6 +85,32 @@ jobs: if-no-files-found: error retention-days: 1 + # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds + - name: restore package-docs cache + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .cache/package-docs + key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-stable-${{ github.run_id }} + restore-keys: | + ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-stable- + + - name: build API reference (beta) + run: yarn backstage-repo-tools package-docs + + - name: upload API reference (beta) + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: stable-reference-beta + path: type-docs/ + + # Always save success cache even if there were failures, that way it can be used in re-triggered builds + - name: save package-docs cache + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + if: always() + with: + path: .cache/package-docs + key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-stable-${{ github.run_id }} + - name: microsite yarn install run: yarn install --immutable working-directory: microsite @@ -111,7 +137,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -140,20 +166,40 @@ jobs: if-no-files-found: error retention-days: 1 - # Also build and upload storybook - - name: storybook yarn install - run: yarn install --immutable - working-directory: storybook + # Use the lower-level cache actions for the success cache, so that we can store the cache even on failed builds + - name: restore package-docs cache + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .cache/package-docs + key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-next-${{ github.run_id }} + restore-keys: | + ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-next- - - name: storybook build + - name: build API reference (beta) + run: yarn backstage-repo-tools package-docs + + - name: upload API reference (beta) + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: next-reference-beta + path: type-docs/ + + # Always save success cache even if there were failures, that way it can be used in re-triggered builds + - name: save package-docs cache + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + if: always() + with: + path: .cache/package-docs + key: ${{ runner.os }}-v${{ matrix.node-version }}-package-docs-next-${{ github.run_id }} + + - name: Build Storybook run: yarn build-storybook - working-directory: storybook - - name: storybook upload + - name: Upload Storybook uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: storybook - path: storybook/dist/ + path: dist-storybook if-no-files-found: error retention-days: 1 @@ -188,7 +234,7 @@ jobs: name: Microsite steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit @@ -271,3 +317,15 @@ jobs: - name: build microsite run: yarn build working-directory: microsite + + - name: download stable reference (beta) + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: stable-reference-beta + path: api/stable/ + + - name: download next reference (beta) + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: next-reference-beta + path: api/next/ diff --git a/.github/workflows/verify_microsite_accessibility-noop.yml b/.github/workflows/verify_microsite_accessibility-noop.yml index d6f9d24b5e..26d4748772 100644 --- a/.github/workflows/verify_microsite_accessibility-noop.yml +++ b/.github/workflows/verify_microsite_accessibility-noop.yml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_microsite_accessibility.yml b/.github/workflows/verify_microsite_accessibility.yml index ee841f6fa8..01cf592a73 100644 --- a/.github/workflows/verify_microsite_accessibility.yml +++ b/.github/workflows/verify_microsite_accessibility.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/verify_storybook-noop.yml b/.github/workflows/verify_storybook-noop.yml deleted file mode 100644 index 392a218a83..0000000000 --- a/.github/workflows/verify_storybook-noop.yml +++ /dev/null @@ -1,35 +0,0 @@ -# NO-OP placeholder that always passes for other paths -# This is here so that we're able to set the status check as required - -name: Storybook Void -on: - pull_request: - paths-ignore: - - '.github/workflows/verify_storybook.yml' - - 'storybook/**' - - 'packages/config/src/**' - - 'packages/theme/src/**' - - 'packages/types/src/**' - - 'packages/errors/src/**' - - 'packages/version-bridge/src/**' - - 'packages/test-utils/src/**' - - 'packages/core-app-api/src/**' - - 'packages/core-plugin-api/src/**' - - 'packages/core-components/src/**' - - '**/*.stories.tsx' - -permissions: - contents: read - -jobs: - noop: - runs-on: ubuntu-latest - - name: Storybook - steps: - - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 - with: - egress-policy: audit - - - run: echo NOOP diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml deleted file mode 100644 index 3cc846a706..0000000000 --- a/.github/workflows/verify_storybook.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Storybook -on: - # NOTE: If you change these you must update verify_storybook-noop.yml as well - pull_request: - paths: - - '.github/workflows/verify_storybook.yml' - - 'storybook/**' - - 'packages/config/src/**' - - 'packages/theme/src/**' - - 'packages/types/src/**' - - 'packages/errors/src/**' - - 'packages/version-bridge/src/**' - - 'packages/test-utils/src/**' - - 'packages/core-app-api/src/**' - - 'packages/core-plugin-api/src/**' - - 'packages/core-components/src/**' - - '**/*.stories.tsx' - -jobs: - chromatic: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [ubuntu-latest] - node-version: [20.x] - - name: Storybook - steps: - - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 - with: - egress-policy: audit - - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - with: - fetch-depth: 0 # Required to retrieve git history - - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ # Needed for auth - - name: yarn install - uses: backstage/actions/yarn-install@b3c1841fd69e1658ac631afafd0fb140a2309024 # v0.6.17 - with: - cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - - name: storybook yarn install - run: yarn install --immutable - working-directory: storybook - - # Only for verification, the canon one is what we upload to Chromatic - - run: yarn build-storybook - - - run: yarn --cwd packages/canon build-storybook - - - uses: chromaui/action@e8cc4c31775280b175a3c440076c00d19a9014d7 # v11 - with: - token: ${{ secrets.GITHUB_TOKEN }} - # projectToken intentionally shared to allow collaborators to run Chromatic on forks - # https://www.chromatic.com/docs/custom-ci-provider#run-chromatic-on-external-forks-of-open-source-projects - projectToken: chpt_dab72dc0f97d55b - workingDir: packages/canon - storybookBuildDir: storybook-static diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index d7b172256d..187c3647d8 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4 + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.0 with: egress-policy: audit diff --git a/.github/workflows/welcome.yml b/.github/workflows/welcome.yml new file mode 100644 index 0000000000..5d47ba77da --- /dev/null +++ b/.github/workflows/welcome.yml @@ -0,0 +1,42 @@ +name: Add a welcome comment + +on: + pull_request_target: + types: [opened] + +permissions: + issues: write + pull-requests: write + contents: read + +jobs: + welcome: + runs-on: ubuntu-latest + if: github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' + steps: + - name: Add a welcome comment + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const pr = context.payload.pull_request + const login = pr.user.login + + const message = ` + Hi @${login}, thanks for opening your first pull request in Backstage! 👋 + + A couple of useful links to help you get started: + + * [Contributing Guide](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) + * [DCO Sign-off Instructions](https://github.com/backstage/backstage/blob/master/DCO) + * [Style Guide](https://github.com/backstage/backstage/blob/master/STYLE.md) + + We really appreciate your contribution and look forward to reviewing your work. Welcome aboard! + ` + + await github.rest.issues.createComment({ + issue_number: pr.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: message + }) diff --git a/.gitignore b/.gitignore index fa4184ecf2..aaf05b51cd 100644 --- a/.gitignore +++ b/.gitignore @@ -184,3 +184,6 @@ knip.json type-docs docs.json tsconfig.typedoc.tmp.json + +# Storybook +dist-storybook/ \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 04ca7d780d..7269620fe6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,13 +1,16 @@ +.cache +.lighthouseci .yarn dist microsite -canon-docs/.next -canon-docs/public -canon-docs/out -packages/canon/css +docs-ui/.next +docs-ui/public +docs-ui/out +packages/ui/css coverage *.hbs templates +type-docs # old reports api-report.md api-report-*.md diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 0000000000..788df83ba9 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,127 @@ +import type { StorybookConfig } from '@storybook/react-vite'; + +import { join, dirname, posix } from 'path'; + +const isChromatic = process.env.STORYBOOK_STORY_SET === 'chromatic'; + +// All stories for full development +const allStories = isChromatic + ? ['packages/ui'] + : [ + 'packages/ui', + 'packages/core-components', + 'packages/app', + 'plugins/org', + 'plugins/search', + 'plugins/search-react', + 'plugins/home', + 'plugins/catalog-react', + ]; + +const rootPath = '../'; +const storiesSrcMdx = 'src/**/*.mdx'; +const storiesSrcGlob = 'src/**/*.stories.@(js|jsx|mjs|ts|tsx)'; + +const getStoriesPath = (element: string, pattern: string) => + posix.join(rootPath, element, pattern); + +const stories = allStories.flatMap(element => [ + getStoriesPath(element, storiesSrcMdx), + getStoriesPath(element, storiesSrcGlob), +]); + +// Resolve absolute path of a package. Needed in monorepos. +function getAbsolutePath(value: string): any { + return dirname(require.resolve(join(value, 'package.json'))); +} + +const config: StorybookConfig = { + stories, + addons: [ + getAbsolutePath('@storybook/addon-links'), + getAbsolutePath('@storybook/addon-themes'), + getAbsolutePath('@storybook/addon-docs'), + getAbsolutePath('@storybook/addon-a11y'), + ], + framework: { + name: getAbsolutePath('@storybook/react-vite'), + options: {}, + }, + viteFinal: async (config, { configType }) => { + // Add Node.js polyfills for browser compatibility + // + // When upgrading from Storybook 8 to 9 with the react-vite framework, + // Node.js polyfills are no longer automatically included by Vite. + // This causes "ReferenceError: process is not defined" errors in the browser + // when code tries to access Node.js globals like `process` and `util`. + // + // The @vitest/mocker (included with Storybook 9) expects MSW v2 APIs, + // but we want to keep MSW v1 for the rest of the monorepo to avoid + // breaking changes. This configuration provides the necessary polyfills + // and handles the MSW compatibility issue specifically for Storybook. + // + // These polyfills provide browser-compatible versions of Node.js globals: + // - process: Node.js process object with env + // - global -> globalThis: Maps Node.js global to browser's globalThis + // + // Without these, Backstage components that rely on Node.js APIs will fail + // to load in Storybook's browser environment. + // Different configurations for development vs production + if (configType === 'DEVELOPMENT') { + // Development: Include process polyfill to prevent runtime errors + config.define = { + ...config.define, + global: 'globalThis', + 'process.env': {}, + process: '({ env: {}, browser: true })', + }; + } else if (configType === 'PRODUCTION') { + // Production: Minimal define to avoid esbuild errors + config.define = { + ...config.define, + global: 'globalThis', + 'process.env': {}, + // No process polyfill in production build + }; + } + + config.resolve = { + ...config.resolve, + alias: { + ...config.resolve?.alias, + // Provide Node.js polyfills for browser + process: 'process/browser', + util: 'util', + buffer: 'buffer', + stream: 'stream-browserify', + // Fix MSW v2 imports for @vitest/mocker compatibility + // @vitest/mocker expects MSW v2 APIs but we want to keep MSW v1 for the rest of the monorepo + 'msw/browser': join(__dirname, 'msw-browser-shim.js'), + 'msw/core/http': join(__dirname, 'msw-http-shim.js'), + }, + }; + + // Optimize dependencies for better performance + config.optimizeDeps = { + ...config.optimizeDeps, + include: [ + ...(config.optimizeDeps?.include || []), + 'process/browser', + 'util', + 'buffer', + 'stream-browserify', + ], + // Exclude MSW to prevent optimization conflicts with our shims + exclude: [ + ...(config.optimizeDeps?.exclude || []), + 'msw', + 'msw/browser', + 'msw/core/http', + ], + }; + + return config; + }, +}; + +export default config; diff --git a/.storybook/modes.ts b/.storybook/modes.ts new file mode 100644 index 0000000000..7087fa35eb --- /dev/null +++ b/.storybook/modes.ts @@ -0,0 +1,18 @@ +export const allModes = { + 'light backstage': { + themeMode: 'light', + themeName: 'backstage', + }, + 'dark backstage': { + themeMode: 'dark', + themeName: 'backstage', + }, + 'light spotify': { + themeMode: 'light', + themeName: 'spotify', + }, + 'dark spotify': { + themeMode: 'dark', + themeName: 'spotify', + }, +} as const; diff --git a/.storybook/msw-browser-shim.js b/.storybook/msw-browser-shim.js new file mode 100644 index 0000000000..e0c71e3d3e --- /dev/null +++ b/.storybook/msw-browser-shim.js @@ -0,0 +1,47 @@ +// MSW v2 browser compatibility shim for @vitest/mocker +// This provides MSW v2 exports using MSW v1 APIs to maintain compatibility +// while keeping the rest of the monorepo on MSW v1 + +try { + // Try to import from MSW v1 + const { setupWorker, rest } = require('msw'); + + // Export in MSW v2 format expected by @vitest/mocker + module.exports = { + setupWorker, + // MSW v2 uses 'http' instead of 'rest', but we provide both for compatibility + http: rest, + rest, // Keep rest for any MSW v1 code + }; +} catch (error) { + // Fallback if MSW is not available - provide minimal mock + console.warn( + 'MSW not available, providing minimal mock for @vitest/mocker compatibility', + ); + module.exports = { + setupWorker: () => ({ + start: () => Promise.resolve(), + stop: () => {}, + use: () => {}, + resetHandlers: () => {}, + }), + http: { + get: () => {}, + post: () => {}, + put: () => {}, + delete: () => {}, + patch: () => {}, + head: () => {}, + options: () => {}, + }, + rest: { + get: () => {}, + post: () => {}, + put: () => {}, + delete: () => {}, + patch: () => {}, + head: () => {}, + options: () => {}, + }, + }; +} diff --git a/.storybook/msw-http-shim.js b/.storybook/msw-http-shim.js new file mode 100644 index 0000000000..8653256960 --- /dev/null +++ b/.storybook/msw-http-shim.js @@ -0,0 +1,47 @@ +// MSW v2 http compatibility shim for @vitest/mocker +// This provides MSW v2 http exports using MSW v1 APIs + +try { + // Try to import from MSW v1 + const { rest } = require('msw'); + + // Export MSW v1 'rest' as MSW v2 'http' for @vitest/mocker compatibility + module.exports = { + http: rest, + // Provide individual methods that @vitest/mocker might expect + get: rest.get, + post: rest.post, + put: rest.put, + delete: rest.delete, + patch: rest.patch, + head: rest.head, + options: rest.options, + all: rest.all, + }; +} catch (error) { + // Fallback if MSW is not available + console.warn( + 'MSW not available, providing minimal http mock for @vitest/mocker compatibility', + ); + const noop = () => {}; + module.exports = { + http: { + get: noop, + post: noop, + put: noop, + delete: noop, + patch: noop, + head: noop, + options: noop, + all: noop, + }, + get: noop, + post: noop, + put: noop, + delete: noop, + patch: noop, + head: noop, + options: noop, + all: noop, + }; +} diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 0000000000..8f987ebab1 --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,145 @@ +import React, { useEffect } from 'react'; +import { TestApiProvider } from '@backstage/test-utils'; +import { Content, AlertDisplay } from '@backstage/core-components'; +import { apis } from './support/apis'; +import type { Decorator, Preview } from '@storybook/react-vite'; +import { useGlobals } from 'storybook/preview-api'; +import { UnifiedThemeProvider, themes } from '@backstage/theme'; +import { allModes } from './modes'; + +// Default Backstage theme CSS (from packages/ui) +import '../packages/ui/src/css/styles.css'; + +// Custom Storybook chrome/styles +import './storybook.css'; + +// Custom themes +import './themes/spotify.css'; + +const preview: Preview = { + globalTypes: { + themeMode: { + name: 'Theme Mode', + description: 'Global theme mode for components', + defaultValue: 'light', + toolbar: { + icon: 'circlehollow', + items: [ + { value: 'light', icon: 'circlehollow', title: 'Light' }, + { value: 'dark', icon: 'circle', title: 'Dark' }, + ], + showName: true, + dynamicTitle: true, + }, + }, + themeName: { + name: 'Theme Name', + description: 'Global theme name for components', + defaultValue: 'backstage', + toolbar: { + icon: 'paintbrush', + items: [ + { value: 'backstage', title: 'Backstage' }, + { value: 'spotify', title: 'Spotify' }, + ], + showName: true, + dynamicTitle: true, + }, + }, + }, + initialGlobals: { + themeMode: 'light', + themeName: 'backstage', + }, + parameters: { + layout: 'fullscreen', + + backgrounds: { + disable: true, + }, + + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + + options: { + storySort: { + order: ['Backstage UI', 'Plugins', 'Layout', 'Navigation'], + }, + }, + + viewport: { + viewports: { + initial: { + name: 'Initial', + styles: { width: '320px', height: '100%' }, + }, + xs: { name: 'Extra Small', styles: { width: '640px', height: '100%' } }, + sm: { name: 'Small', styles: { width: '768px', height: '100%' } }, + md: { name: 'Medium', styles: { width: '1024px', height: '100%' } }, + lg: { name: 'Large', styles: { width: '1280px', height: '100%' } }, + xl: { + name: 'Extra Large', + styles: { width: '1536px', height: '100%' }, + }, + }, + }, + + docs: { + codePanel: true, + }, + + chromatic: { + modes: { + 'light backstage': allModes['light backstage'], + // TODO: Enable these modes when we have more Chromatic snapshots. + // 'dark backstage': allModes['dark backstage'], + // 'light spotify': allModes['light spotify'], + // 'dark spotify': allModes['dark spotify'], + }, + }, + }, + decorators: [ + Story => { + const [globals] = useGlobals(); + const selectedTheme = + globals.themeMode === 'light' ? themes.light : themes.dark; + const selectedThemeMode = globals.themeMode || 'light'; + const selectedThemeName = globals.themeName || 'backstage'; + + useEffect(() => { + document.body.removeAttribute('data-theme-mode'); + document.body.removeAttribute('data-theme-name'); + document.body.setAttribute('data-theme-mode', selectedThemeMode); + document.body.setAttribute('data-theme-name', selectedThemeName); + return () => { + document.body.removeAttribute('data-theme-mode'); + document.body.removeAttribute('data-theme-name'); + }; + }, [selectedTheme, selectedThemeName]); + + document.body.style.backgroundColor = 'var(--bui-bg)'; + const docsStoryElements = document.getElementsByClassName('docs-story'); + Array.from(docsStoryElements).forEach(element => { + (element as HTMLElement).style.backgroundColor = 'var(--bui-bg)'; + }); + + return ( + + {/* @ts-ignore */} + + + + + + + + ); + }, + ], +}; + +export default preview; diff --git a/.storybook/storybook.css b/.storybook/storybook.css new file mode 100644 index 0000000000..e69c4a8eb1 --- /dev/null +++ b/.storybook/storybook.css @@ -0,0 +1,38 @@ +:root { + --sb-panel-radius: 0; + --sb-panel-top: 0; + --sb-panel-bottom: 0; + --sb-panel-left: 0; + --sb-panel-right: 0; + --sb-sidebar-border: none; + --sb-sidebar-border-right: 1px solid var(--bui-border); + --sb-sidebar-bg: #000; + --sb-options-border: none; + --sb-options-border-left: 1px solid var(--bui-border); + --sb-content-padding-inline: 250px; +} + +[data-theme-mode='dark'] { + --sb-sidebar-bg: var(--bui-bg-surface-1); +} + +[data-theme-name='spotify'] { + --sb-panel-radius: var(--bui-radius-3); + --sb-panel-top: 8px; + --sb-panel-bottom: 8px; + --sb-panel-left: 8px; + --sb-panel-right: 8px; + --sb-sidebar-border: none; + --sb-sidebar-border-right: none; + --sb-sidebar-bg: var(--bui-bg-surface-1); + --sb-options-border: none; + --sb-options-border-left: none; + --sb-content-padding-inline: 258px; +} + +[data-theme-name='spotify'][data-theme-mode='light'] { + --sb-sidebar-border: 1px solid var(--bui-border); + --sb-sidebar-border-right: 1px solid var(--bui-border); + --sb-options-border: 1px solid var(--bui-border); + --sb-options-border-left: 1px solid var(--bui-border); +} diff --git a/storybook/.storybook/apis.js b/.storybook/support/apis.js similarity index 100% rename from storybook/.storybook/apis.js rename to .storybook/support/apis.js diff --git a/.storybook/themes/spotify.css b/.storybook/themes/spotify.css new file mode 100644 index 0000000000..bcb1ded9ff --- /dev/null +++ b/.storybook/themes/spotify.css @@ -0,0 +1,288 @@ +@font-face { + font-family: CircularSpTitle; + font-weight: 900; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSpTitle-Black-4588c99025b967475c31695b0743dd1a.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSpTitle-Black-506746f387a26f25aa3d023b3e501d34.woff') + format('woff'); +} +@font-face { + font-family: CircularSpTitle; + font-weight: 700; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSpTitle-Bold-b2586b06a2e1522e9d879d84c2792a58.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSpTitle-Bold-1624fb2df28c20d7203d7fb86ce8b481.woff') + format('woff'); +} +@font-face { + font-family: CircularSp; + font-weight: 700; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSp-Bold-602e7aefc706aa36c6ec1324b9bbc461.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSp-Bold-856afe2da4ba4e61239b129e2c16d633.woff') + format('woff'); +} +@font-face { + font-family: CircularSp; + font-weight: 400; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSp-Book-a00e99ef9996a3a157fb6b746856d04f.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSp-Book-3f73da7d35bd81c706bce7bbb84964de.woff') + format('woff'); +} + +@font-face { + font-family: CircularSp; + font-weight: 700; + font-display: swap; + unicode-range: U+0000, U+000D, U+0020-007E, U+00A0-017E, U+018F, U+0192, + U+01A0-01A1, U+01AF-01B0, U+01B5-01B6, U+01C4-01C6, U+01F1-01F3, U+01FA-01FF, + U+0218-021B, U+0237, U+0259, U+02BB-02BC, U+02C6-02C7, U+02C9, U+02D8-02DD, + U+0300-0301, U+0303, U+0309, U+0323, U+0394, U+03A9, U+03BC, U+03C0, + U+1E80-1E85, U+1E8A-1E8B, U+1EA0-1EF9, U+1FD6, U+2007-2008, U+200B, + U+2010-2011, U+2013-2014, U+2018-201A, U+201C-201E, U+2020-2022, U+2026, + U+2030, U+2032-2033, U+2039-203A, U+2042, U+2044, U+2051, U+2070, + U+2074-2079, U+2080-2089, U+20AB-20AC, U+2113, U+2117, U+2122, U+2126, + U+2160-2169, U+216C-216F, U+2190-2193, U+2196-2199, U+21A9, U+21B0-21B5, + U+21C6, U+2202, U+2206, U+220F, U+2211-2212, U+2215, U+2219-221A, U+221E, + U+222B, U+2248, U+2260, U+2264-2265, U+22C5, U+24C5, U+25A0-25A1, U+25AF, + U+25B2-25B3, U+25CA-25CB, U+25CF, U+262E, U+2713, U+2715, U+2780-2788, + U+E000, U+E002, U+F6C3, U+FB00-FB04, U+FEFF, U+FF0C, U+FF0E, U+FF1A-FF1B, + U+FFFF; + src: url('https://encore.scdn.co/fonts/CircularSp-Bold-602e7aefc706aa36c6ec1324b9bbc461.woff2') + format('woff2'), + url('https://encore.scdn.co/fonts/CircularSp-Bold-856afe2da4ba4e61239b129e2c16d633.woff') + format('woff'); +} + +[data-theme-name='spotify'] { + --bui-font-text: CircularSp, CircularSp-Arab, CircularSp-Hebr, CircularSp-Cyrl, + CircularSp-Grek, CircularSp-Deva; + --bui-font-title: CircularSpTitle, CircularSp-Arab, CircularSp-Hebr, + CircularSp-Cyrl, CircularSp-Grek, CircularSp-Deva; + --bui-font-regular: CircularSp, CircularSp-Arab, CircularSp-Hebr, + CircularSp-Cyrl, CircularSp-Grek, CircularSp-Deva; + + .bui-Button { + border-radius: var(--bui-radius-3); + padding-inline: var(--bui-space-3); + } + + .bui-ButtonIcon { + padding: 0; + } + + .bui-MenuPopup { + box-sizing: border-box; + max-width: 21.25rem; + } + + .bui-MenuSubmenuTrigger, + .bui-MenuItem { + height: auto; + min-height: 2rem; + } + + .bui-Text { + font-family: var(--bui-font-text); + } + + .bui-Heading { + font-family: var(--bui-font-title); + } + + .bui-TableRow { + border: none; + border-radius: var(--bui-radius-4); + } + + .bui-TableRow:hover td:first-child { + border-top-left-radius: var(--bui-radius-2); + border-bottom-left-radius: var(--bui-radius-2); + } + + .bui-TableRow:hover td:last-child { + border-top-right-radius: var(--bui-radius-2); + border-bottom-right-radius: var(--bui-radius-2); + } + + .bui-TableBody:before, + .bui-TableBody:after { + line-height: var(--bui-space-1); + content: '\200C'; + display: block; + } + + .bui-TableHeader .bui-TableRow { + border-bottom: 1px solid var(--bui-border); + } + + .bui-TableHead { + font-size: var(--bui-font-size-2); + color: var(--bui-fg-secondary); + font-weight: var(--bui-font-weight-regular); + } + + .bui-HeaderToolbar { + padding-top: var(--bui-space-2); + padding-inline: var(--bui-space-2); + } + + .bui-HeaderToolbarWrapper { + border-radius: var(--bui-radius-3); + padding-inline: var(--bui-space-3); + border: none; + } + + .bui-HeaderToolbarControls { + right: calc(var(--bui-space-3) - 1px); + } + + .bui-HeaderTabsWrapper { + margin-top: var(--bui-space-2); + margin-inline: var(--bui-space-2); + border-radius: var(--bui-radius-3); + padding-inline: var(--bui-space-1); + border: none; + } + + .bui-Input { + border-radius: var(--bui-radius-3); + } + + .bui-Tag { + border-radius: var(--bui-radius-full); + } +} + +[data-theme-mode='light'][data-theme-name='spotify'] { + --bui-bg: var(--bui-gray-1); + --bui-bg-surface-1: var(--bui-white); + --bui-bg-surface-2: var(--bui-gray-2); + --bui-bg-solid: #1ed760; + --bui-bg-solid-hover: #3be477; + --bui-bg-solid-pressed: #1abc54; + --bui-bg-solid-disabled: var(--bui-gray-2); + + --bui-fg-primary: var(--bui-black); + --bui-fg-secondary: var(--bui-gray-7); + --bui-fg-solid: var(--bui-black); + + --bui-border: var(--bui-gray-3); + --bui-border-hover: rgba(0, 0, 0, 0.3); + --bui-border-pressed: rgba(0, 0, 0, 0.5); + --bui-border-disabled: rgba(0, 0, 0, 0.1); + --bui-border-danger: #f87a7a; + --bui-border-warning: #e36d05; + --bui-border-success: #53db83; + + --bui-ring: rgba(0, 0, 0, 0.2); + + .bui-HeaderToolbarWrapper { + border: 1px solid var(--bui-border); + } + + .bui-HeaderTabsWrapper { + border: 1px solid var(--bui-border); + } +} + +[data-theme-mode='dark'][data-theme-name='spotify'] { + --bui-bg: var(--bui-black); + --bui-bg-surface-1: var(--bui-gray-1); + --bui-bg-surface-2: var(--bui-gray-2); + --bui-bg-solid: #1ed760; + --bui-bg-solid-hover: #3be477; + --bui-bg-solid-pressed: #1abc54; + --bui-bg-solid-disabled: #0f6c30; + --bui-bg-tint: #242424; + --bui-bg-tint-hover: #202020; + --bui-bg-tint-pressed: #292929; + --bui-bg-tint-disabled: rgba(255, 255, 255, 0.8); + --bui-bg-danger: #3b1219; + --bui-bg-warning: #302008; + --bui-bg-success: #132d21; + + --bui-fg-primary: var(--bui-white); + --bui-fg-secondary: var(--bui-gray-7); + --bui-fg-link: var(--bui-white); + --bui-fg-link-hover: var(--bui-white); + --bui-fg-disabled: var(--bui-gray-5); + --bui-fg-solid: var(--bui-black); + --bui-fg-solid-disabled: #083618; + --bui-fg-tint: var(--bui-white); + --bui-fg-tint-disabled: var(--bui-gray-5); + --bui-fg-danger: #e22b2b; + --bui-fg-warning: #e36d05; + --bui-fg-success: #1db954; + + --bui-border: var(--bui-gray-3); + --bui-border-hover: rgba(255, 255, 255, 0.4); + --bui-border-pressed: rgba(255, 255, 255, 0.5); + --bui-border-disabled: rgba(255, 255, 255, 0.2); + --bui-border-danger: #f87a7a; + --bui-border-warning: #e36d05; + --bui-border-success: #53db83; + + --bui-ring: rgba(255, 255, 255, 0.2); +} diff --git a/.yarn/patches/ast-types-npm-0.16.1-43c4ac4b0d.patch b/.yarn/patches/ast-types-npm-0.16.1-43c4ac4b0d.patch new file mode 100644 index 0000000000..996a23c205 --- /dev/null +++ b/.yarn/patches/ast-types-npm-0.16.1-43c4ac4b0d.patch @@ -0,0 +1,15 @@ +diff --git a/lib/main.d.ts b/lib/main.d.ts +index 9b54fef0086ea0c99368d8a95f2476e5dcd6d9c1..5c3853901e522c445cdb23b07538aad8a15bafb0 100644 +--- a/lib/main.d.ts ++++ b/lib/main.d.ts +@@ -1,7 +1,7 @@ +-import { ASTNode, Type, AnyType, Field } from "./types"; +-import { NodePath } from "./node-path"; ++import { ASTNode, type Type, AnyType, Field } from "./types"; ++import { type NodePath } from "./node-path"; + import { namedTypes } from "./gen/namedTypes"; +-import { builders } from "./gen/builders"; ++import { type builders } from "./gen/builders"; + import { Visitor } from "./gen/visitor"; + declare const astNodesAreEquivalent: { + (a: any, b: any, problemPath?: any): boolean; diff --git a/ADOPTERS.md b/ADOPTERS.md index e97c213adf..208cd370ba 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -284,3 +284,6 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Scalepoint](https://scalepoint.com) | [Yuriy Ostapenko](https://github.com/yuriyostapenko), [Dmytro Pasko](https://github.com/dimapasko), [Yuri Sedykh ](https://github.com/yuiri-sedykh), [Bartosz Wisniewski](https://github.com/Epgor) | Internal Developer Portal: Software Catalog with infrastructure resources and dependencies, Software Templates, TechDocs, Tech Radar, Kubernetes and Observability, as well as custom CI/CD components | | [VR](https://www.vr.com.br) | [Felipe Gomes](https://www.linkedin.com/in/felipe-gomes-da-silva), [Tiago Garcia](https://www.linkedin.com/in/tiago-garcia-6301a925) | Internal portal for development squads, service catalog, documentation hub, and application mapping for the entire company ecosystem, simplifying cloud infrastructure construction through templates. | | [Plata](https://platacard.mx/en) | [Shamil Ganiev](https://github.com/ganievs) | Internal Developer Portal for the whole engineering team | +| [Syngenta Digital](https://www.syngentadigital.com) | [Bitan Mallick](https://www.linkedin.com/in/bitanmallick) | Internal developer portal, designed to empower developers and streamline workflows. We use software catalog, tech-radar, software templates, tech-docs and various custom plugins to ensure an efficient and collaborative development experience. | +| [Sophotech](https://sopho.tech) | [@archy-rock3t-cloud](https://github.com/archy-rock3t-cloud), [Artem Muterko](mailto:artem@sopho.tech) | Custom Developer Platform based on Backstage, providing a service catalog, infrastructure templates, and integrated tooling to give developers a self-service experience. | +| [Swiss Mobiliar Insurance Company Ltd.](https://www.mobiliar.ch/) | [Patrick Wyler](mailto:patrick.wyler@mobiliar.ch) and [Beat Winistörfer](mailto:beat.winistoerfer@mobiliar.ch) | The portal provides a unified interface for accessing all relevant DevOps information previously scattered across various locations, enhancing accessibility and clarity for all IT employees. It relies on an internal graph database that enhances the Backstage software catalog with many additional elements. Significant effort has been invested in the visual representation of information through graphs and diagrams, facilitating analysis and improving the understanding of dependencies. | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9413206197..ba40be86c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -102,6 +102,16 @@ Visit and you should see the bleeding edge of Backstage If you want to get a better understanding of the layout of the repo now that you have a local copy running feel free to review the [Backstage Project Structure](https://backstage.io/docs/getting-started/#general-folder-structure) documentation. +#### Using Docker for the Example App + +You can run the Example App using Docker with Postgres, OpenSearch and Redis services. This setup very closely resembles how Backstage is run in production in many occasions. + +To start the Example App with Docker, make sure you have Docker and Docker Compose installed on your machine, then run the following command from the root of the repository: + +```bash +yarn start:docker +``` + ## Coding Guidelines All code is formatted with `prettier` using the configuration in the repo. If possible, we recommend configuring your editor to format automatically, but you can also use the `yarn prettier --write ` command to format files. diff --git a/LABELS.md b/LABELS.md index 7f8804f75a..f1af06d4fa 100644 --- a/LABELS.md +++ b/LABELS.md @@ -26,6 +26,7 @@ These labels indicate what is needed to move an issue forward before it can be a - `needs:bep` - The issue is an advanced addition that needs a [Backstage Enhancement Proposal](./beps/README.md). - `needs:direction` - The issue needs direction from the owners of the area. +- `needs:discussion` - The way forward for this issue is unclear and it needs further discussion with the author and other participants. - `needs:more-info` - The issue needs more information from the author. - `needs:motivation` - It is not clear why this change is needed. The author should provide motivation for the change, for instance by giving examples of concrete use cases or scenarios. - `needs:repro` - The issue cannot be reproduced by the owners of the area. The author should provide more information to help them reproduce the issue, if possible with a minimal reproduction repository. @@ -39,7 +40,7 @@ These labels indicate which part of Backstage an issue or pull request relates t - `area:auditor` - Auditor service and it's use in plugins. - `area:auth` - Authentication and 3rd party authorization. - `area:catalog` - The Catalog plugin and the Software Catalog model and integrations. -- `area:design-system` - The Canon design system and library. +- `area:design-system` - The Backstage UI design system and library. - `area:documentation` - Documentation for adopters, users, and developers. - `area:events` - The Events system and integrations for other plugins. - `area:framework` - The core Backstage framework. @@ -81,11 +82,17 @@ These labels indicate that an issue is related to specific domains of expertise. - `domain:tooling` - Tooling and automation in Node.js and GitHub Actions. - `domain:web` - Frontend development using TypeScript and React. +## Workflow Labels + +These labels indicate a workflow status for the owners. + +- `workflow:do-not-merge` - The Pull Request should not be merged. +- `workflow:before-release` - Should be handled before the next main-line release. +- `workflow:after-release` - Should be handled after the next main-line release. +- `workflow:after-vacations` - To be handled once the owners return from vacation. + ## General Labels -- `after vacations` - To be handled once the owners return from vacation. -- `do not merge` - The pull request should not be merged. -- `fix before release` - Should be handled before the next release. - `good first issue` - Good for new contributors. - `stale` - The issue or pull request has not seen any activity for a while and will be closed if no further activity is seen. - `no stale` - The issue or pull request should not be closed due to inactivity. diff --git a/OWNERS.md b/OWNERS.md index 85ffadae42..d4ee3c6400 100644 --- a/OWNERS.md +++ b/OWNERS.md @@ -56,6 +56,18 @@ Scope: The Backstage design system, component library, as well as surrounding to | Charles de Dreuille | Spotify | | [cdedreuille](https://github.com/cdedreuille) | `cdedreuille` | | Patrik Oldsberg | Spotify | Cubic Belugas | [Rugvip](https://github.com/Rugvip) | `Rugvip` | +### Documentation + +Team: @backstage/documentation-maintainers + +Scope: The Backstage Documentation and Microsite, excluding the plugins listing + +| Name | Organization | GitHub | Discord | +| --------------- | ------------- | ----------------------------------------------------- | ------------- | +| Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | +| Aramis Sennyey | DoorDash | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` | +| Peter Macdonald | VodafoneZiggo | [Parsifal-M](https://github.com/Parsifal-M) | `parsifal` | + ### Framework Team: @backstage/framework-maintainers @@ -77,11 +89,11 @@ Team: @backstage/helm-chart-maintainers Scope: The Backstage [Helm Chart(s)](https://github.com/backstage/charts). -| Name | Organization | Team | GitHub | Discord | -| -------------------- | ------------ | ---- | ---------------------------------------- | -------------- | -| Andrew Block | Red Hat | | [sabre1041](http://github.com/sabre1041) | sabre1041#2622 | -| Tom Coufal | Red Hat | | [tumido](http://github.com/tumido) | Tumi#4346 | -| Vincenzo Scamporlino | Spotify | | [vinzscam](http://github.com/vinzscam) | vinzscam#6944 | +| Name | Organization | Team | GitHub | Discord | +| -------------------- | ------------ | ---- | ---------------------------------------- | ---------------- | +| Andrew Block | Red Hat | | [sabre1041](http://github.com/sabre1041) | `sabre1041#2622` | +| Tom Coufal | Red Hat | | [tumido](http://github.com/tumido) | `Tumi#4346` | +| Vincenzo Scamporlino | Spotify | | [vinzscam](http://github.com/vinzscam) | `vinzscam#6944` | ### Home @@ -89,12 +101,14 @@ Team: @backstage/home-maintainers Scope: The Backstage home page and information architecture -| Name | Organization | Team | GitHub | Discord | -| ------------------------ | ------------ | -------------- | ---------------------------------------- | ----------------- | -| Avantika Iyer | Spotify | Infinite Buck$ | [tikabom](http://github.com/tikabom) | - | -| Emma Indal | Spotify | Infinite Buck$ | [emmaindal](http://github.com/emmaindal) | emmaindal#7503 | -| Djamaile Rahamat | Spotify | Infinite Buck$ | [djamaile](http://github.com/djamaile) | dyoqi | -| Raghunandan Balachandran | Spotify | Infinite Buck$ | [soapraj](http://github.com/soapraj) | raghunandanb#1114 | +| Name | Organization | Team | GitHub | Discord | +| ------------------ | ------------ | --------------- | ----------------------------------------- | ------- | +| Ainhoa Larumbe | Spotify | Imaginary Goats | [ainhoaL](http://github.com/ainhoaL) | - | +| Avantika Iyer | Spotify | Imaginary Goats | [tikabom](http://github.com/tikabom) | - | +| Daniel Jelčić | Spotify | Imaginary Goats | [djelcic](http://github.com/danieljelcic) | - | +| Eric Peterson | Spotify | Imaginary Goats | [iamEAP](http://github.com/iamEAP) | - | +| Musaab Elfaqih | Spotify | Imaginary Goats | [TheSabby](http://github.com/TheSabby) | - | +| Landry Zinda-Snead | Spotify | Imaginary Goats | [landryzs](http://github.com/landryzs) | - | ### Kubernetes @@ -206,18 +220,6 @@ Scope: Tooling and Community Repo Maintainers for the Backstage [Community Plugi | Vincenzo Scamporlino | Spotify | [vinzscam](https://github.com/vinzscam) | `vinzscam` | | Peter Macdonald | VodafoneZiggo | [Parsifal-M](https://github.com/Parsifal-M) | `parsifal` | -### Documentation - -Team: @backstage/documentation-maintainers - -Scope: The Backstage Documentation and Microsite, excluding the plugins listing - -| Name | Organization | GitHub | Discord | -| --------------- | ------------- | ----------------------------------------------------- | ------------- | -| Andre Wanlin | Spotify | [awanlin](https://github.com/awanlin) | `ahhhndre` | -| Aramis Sennyey | DoorDash | [aramissennyeydd](https://github.com/aramissennyeydd) | `Aramis#7984` | -| Peter Macdonald | VodafoneZiggo | [Parsifal-M](https://github.com/Parsifal-M) | `parsifal` | - ### Events Team: @backstage/events-maintainers diff --git a/README.md b/README.md index e3e9bd77dd..ba44ca951d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +> [!NOTE] +> 🏖 From Monday October 27th through November 3rd, maintainers and Spotify employees will be on vacation due to Wellness Week. Expect the project to move a little slower than normal, and support to be limited. Normal service will resume after that! 🏝 + [![headline](docs/assets/headline.png)](https://backstage.io/) # [Backstage](https://backstage.io) diff --git a/app-config.docker.yaml b/app-config.docker.yaml new file mode 100644 index 0000000000..07f7c7ac8c --- /dev/null +++ b/app-config.docker.yaml @@ -0,0 +1,23 @@ +# To run local backstage instance with docker services, +# run: +# 1. `docker compose -f docker-compose.deps.yml up --wait` +# 2. `BACKSTAGE_ENV=docker yarn dev` +backend: + database: + client: pg + connection: + host: localhost + port: 5432 + user: postgres + password: postgres + cache: + store: redis + connection: redis://localhost:6379 + +search: + elasticsearch: + provider: opensearch + node: 'http://localhost:9200' + auth: + username: admin + password: admin diff --git a/app-config.yaml b/app-config.yaml index 89e417fad3..b45255d26c 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -1,8 +1,7 @@ app: title: Backstage Example App baseUrl: http://localhost:3000 - experimental: - packages: all # ✨ + packages: all # ✨ #datadogRum: # clientToken: '123456789' @@ -36,6 +35,12 @@ backend: # keys: # - secret: ${BACKEND_SECRET} + # Used for testing rate limiting locally + # rateLimit: + # windowMs: 1m + # incomingRequestLimit: 1 + # ipAllowList: [] + auth: # TODO: once plugins have been migrated we can remove this, but right now it # is require for the backend-next to work in this repo @@ -60,87 +65,17 @@ backend: - host: example.com - host: '*.mozilla.org' # workingDirectory: /tmp # Use this to configure a working directory for the scaffolder, defaults to the OS temp-dir - + actions: + pluginSources: + - catalog # See README.md in the proxy-backend plugin for information on the configuration format proxy: endpoints: - '/circleci/api': - target: https://circleci.com/api/v1.1 - headers: - Circle-Token: ${CIRCLECI_AUTH_TOKEN} - - '/jenkins/api': - target: http://localhost:8080 - headers: - Authorization: ${JENKINS_BASIC_AUTH_HEADER} - - '/travisci/api': - target: https://api.travis-ci.com - changeOrigin: true - headers: - Authorization: ${TRAVISCI_AUTH_TOKEN} - travis-api-version: '3' - - '/newrelic/apm/api': - target: https://api.newrelic.com/v2 - headers: - X-Api-Key: ${NEW_RELIC_REST_API_KEY} - allowedHeaders: - - link - - '/newrelic/api': - target: https://api.newrelic.com - headers: - X-Api-Key: ${NEW_RELIC_USER_KEY} - '/pagerduty': target: https://api.pagerduty.com headers: Authorization: Token token=${PAGERDUTY_TOKEN} - '/buildkite/api': - target: https://api.buildkite.com/v2/ - headers: - Authorization: ${BUILDKITE_TOKEN} - - '/sentry/api': - target: https://sentry.io/api/ - allowedMethods: ['GET'] - headers: - Authorization: ${SENTRY_TOKEN} - - '/ilert': - target: https://api.ilert.com - allowedMethods: ['GET', 'POST', 'PUT'] - allowedHeaders: ['Authorization'] - headers: - Authorization: ${ILERT_AUTH_HEADER} - - '/airflow': - target: https://your.airflow.instance.com/api/v1 - headers: - Authorization: ${AIRFLOW_BASIC_AUTH_HEADER} - - '/gocd': - target: https://your.gocd.instance.com/go/api - allowedMethods: ['GET'] - allowedHeaders: ['Authorization'] - headers: - Authorization: Basic ${GOCD_AUTH_CREDENTIALS} - - '/dynatrace': - target: https://your.dynatrace.instance.com/api/v2 - headers: - Authorization: 'Api-Token ${DYNATRACE_ACCESS_TOKEN}' - - '/stackstorm': - target: https://your.stackstorm.instance.com/api - headers: - St2-Api-Key: ${ST2_API_KEY} - - '/puppetdb': - target: https://your.puppetdb.instance.com - organization: name: My Company @@ -157,46 +92,6 @@ techdocs: publisher: type: 'local' # Alternatives - 'googleGcs' or 'awsS3' or 'azureBlobStorage' or 'openStackSwift'. Read documentation for using alternatives. -dynatrace: - baseUrl: https://your.dynatrace.instance.com - -nomad: - addr: 0.0.0.0 - -# Score-cards sample configuration. -scorecards: - jsonDataUrl: https://raw.githubusercontent.com/Oriflame/backstage-plugins/main/plugins/score-card/sample-data/ - wikiLinkTemplate: https://link-to-wiki/{id} - -sentry: - organization: my-company - -rollbar: - organization: my-company - # NOTE: The rollbar-backend & accountToken key may be deprecated in the future (replaced by a proxy config) - accountToken: my-rollbar-account-token - -lighthouse: - baseUrl: http://localhost:3003 - -kubernetes: - serviceLocatorMethod: - type: 'multiTenant' - clusterLocatorMethods: - - type: 'config' - clusters: [] - -kafka: - clientId: backstage - clusters: - - name: cluster - dashboardUrl: https://akhq.io/ - brokers: - - localhost:9092 - -allure: - baseUrl: http://localhost:5050/allure-docker-service - integrations: github: - host: github.com @@ -244,7 +139,6 @@ integrations: secretAccessKey: ${AWS_SECRET_ACCESS_KEY} catalog: - useUrlReadersSearch: true import: entityFilename: catalog-info.yaml pullRequestBranchName: backstage-integration @@ -269,26 +163,6 @@ catalog: plugins: - catalog - search - - processors: - ldapOrg: - ### Example for how to add your enterprise LDAP server - # providers: - # - target: ldaps://ds.example.net - # bind: - # dn: uid=ldap-reader-user,ou=people,ou=example,dc=example,dc=net - # secret: ${LDAP_SECRET} - # users: - # dn: ou=people,ou=example,dc=example,dc=net - # options: - # filter: (uid=*) - # map: - # description: l - # groups: - # dn: ou=access,ou=groups,ou=example,dc=example,dc=net - # options: - # filter: (&(objectClass=some-group-class)(!(groupType=email))) - locations: # Add a location here to ingest it, for example from a URL: # @@ -325,15 +199,23 @@ catalog: target: ../../plugins/scaffolder-backend/sample-templates/all-templates.yaml rules: - allow: [Template] + scaffolder: + auditor: + taskParameterMaxLength: 256 # Use to customize default commit author info used when new components are created - # defaultAuthor: - # name: Scaffolder - # email: scaffolder@backstage.io + defaultAuthor: + name: Scaffolder + email: scaffolder@backstage.io # Use to customize the default commit message when new components are created - # defaultCommitMessage: 'Initial commit' + defaultCommitMessage: 'Initial commit' auth: + experimentalDynamicClientRegistration: + enabled: true + allowedRedirectUriPatterns: + - cursor://* + ### Add auth.keyStore.provider to more granularly control how to store JWK data when running # the auth-backend. # @@ -422,80 +304,5 @@ auth: myproxy: {} guest: {} -costInsights: - engineerCost: 200000 - engineerThreshold: 0.5 - products: - computeEngine: - name: Compute Engine - icon: compute - cloudDataflow: - name: Cloud Dataflow - icon: data - cloudStorage: - name: Cloud Storage - icon: storage - bigQuery: - name: BigQuery - icon: search - events: - name: Events - icon: data - metrics: - DAU: - name: Daily Active Users - default: true - MSC: - name: Monthly Subscribers - currencies: - engineers: - label: 'Engineers 🛠' - unit: 'engineer' - usd: - label: 'US Dollars 💵' - kind: 'USD' - unit: 'dollar' - prefix: '$' - rate: 1 - carbonOffsetTons: - label: 'Carbon Offset Tons ♻️⚖️s' - kind: 'CARBON_OFFSET_TONS' - unit: 'carbon offset ton' - rate: 3.5 - beers: - label: 'Beers 🍺' - kind: 'BEERS' - unit: 'beer' - rate: 4.5 - pintsIceCream: - label: 'Pints of Ice Cream 🍦' - kind: 'PINTS_OF_ICE_CREAM' - unit: 'ice cream pint' - rate: 5.5 - -pagerDuty: - eventsBaseUrl: 'https://events.pagerduty.com/v2' - -jenkins: - instances: - - name: default - baseUrl: https://jenkins.example.com - username: backstage-bot - apiKey: 123456789abcdef0123456789abcedf012 - -azureDevOps: - host: dev.azure.com - token: my-token - organization: my-company - -apacheAirflow: - baseUrl: https://your.airflow.instance.com - -gocd: - baseUrl: https://your.gocd.instance.com - -stackstorm: - webUrl: https://your.stackstorm.webui.instance.com - permission: enabled: true diff --git a/beps/0001-notifications-system/README.md b/beps/0001-notifications-system/README.md index 91c1a81fe1..bfea3115f9 100644 --- a/beps/0001-notifications-system/README.md +++ b/beps/0001-notifications-system/README.md @@ -1,6 +1,6 @@ --- title: Backstage Notifications System -status: implementable +status: implemented authors: - '@Rugvip' - '@drodil' @@ -105,7 +105,6 @@ The notification backend stores notification using the [database service](https: - Description (optional) - Origin - Link (optional) - - Additional links (optional) - Severity (optional, default normal) - Topic (optional) - Scope (optional) @@ -193,8 +192,6 @@ The following backend service interfaces are added as part of this proposal. #### `NotificationService` ```ts -// TODO - We may want to add an additional wrapping here with interfaces for Notification and NotificationParameters - export type NotificationRecipients = | { type: 'entity'; @@ -210,15 +207,11 @@ export type NotificationPayload = { title: string; description?: string; link?: string; - additionalLinks?: string[]; severity?: NotificationSeverity; topic?: string; scope?: string; icon?: string; - metadata?: Array<{ - type: string; - value: JsonValue; - }>; + metadata?: { [KMetadataKey in string]?: JsonValue }; }; export type Notification = { @@ -233,20 +226,20 @@ export type Notification = { payload: NotificationPayload; }; -interface SendNotificationRequest { +interface NotificationSendOptions { recipients: NotificationRecipients; payload: NotificationPayload; } interface NotificationService { - sendNotification(request: SendNotificationRequest): Promise; + send(request: NotificationSendOptions): Promise; } ``` Each notification contains a human-readable `title`, `origin` and optionally `link` for additional details. The `created`, `id`, `read` and `saved` properties are handled by the backend based and cannot be passed during the notification creation. Any optional additional details could be stored in `metadata`. We advise to provide the name to the type which contains the information about the context and the version, for example: 'core.icon.v1'. -Calling `sendNotification` should never throw an error so that it doesn't block the current processing. Notifications should be considered as second-level citizens that are not critical if not delivered. +Calling `send` should never throw an error so that it doesn't block the current processing. Notifications should be considered as second-level citizens that are not critical if not delivered. Each notification is always routed to individual users unless its type is `broadcast`. @@ -300,8 +293,6 @@ Example signal payload for a new notification: - OpenAPI tooling is taken into use for the notification router and client - Allow using dynamic values in notification payload, for example entity references `{{ user:default/john.doe }}` should be rendered by the frontend with `EntityRefLink` component. Defining the dynamic data values should be done before implementation. -- Add configurable automatic clean-up of old notifications to save storage space -- Support for saving user notification settings ### Frontend API @@ -309,7 +300,7 @@ Notification frontend shows users their own notifications in its own page and th Notifications are set to `read` when the `Mark as read` action is triggered by the user (bulk or single). -Notifications can be saved for better visibility in the future. +Notifications can be saved for better visibility. Notifications can be filtered by `read`, `saved`, `content` (text search in title or description), `created` (since multiple predefined options) and `severity`. @@ -322,42 +313,64 @@ The following frontend API is added as part of this proposal. ```ts export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low'; -export type GetNotificationsOptions = { - offset?: number; - limit?: number; +export type GetNotificationsCommonOptions = { search?: string; - createdSince?: Date; - severity?: NotificationSeverity; + read?: boolean; + saved?: boolean; + createdAfter?: Date; + minimumSeverity?: NotificationSeverity; }; -export type NotificationUpdateOptions = { +export type GetNotificationsOptions = GetNotificationsCommonOptions & { + offset?: number; + limit?: number; + sort?: 'created' | 'topic' | 'origin'; + sortOrder?: 'asc' | 'desc'; + topic?: string; +}; + +export type GetTopicsOptions = GetNotificationsCommonOptions; + +export type UpdateNotificationsOptions = { ids: string[]; read?: boolean; saved?: boolean; }; -export type NotificationStatus = { - unread: number; - read: number; +export type GetNotificationsResponse = { + notifications: Notification[]; + totalCount: number; }; -interface NotificationsApi { - getNotifications(options?: GetNotificationsOptions): Promise; +export type GetTopicsResponse = { + topics: string[]; +}; + +export interface NotificationsApi { + getNotifications( + options?: GetNotificationsOptions, + ): Promise; + + getNotification(id: string): Promise; getStatus(): Promise; updateNotifications( options: UpdateNotificationsOptions, ): Promise; + + getNotificationSettings(): Promise; + + updateNotificationSettings( + settings: NotificationSettings, + ): Promise; + + getTopics(options?: GetTopicsOptions): Promise; } ``` #### `SignalApi` -> TODO - we likely need a slightly different approach here, since APIs are lazy loaded. - -> TODO - signal typing in https://github.com/backstage/backstage/pull/22656 - ```ts export type NotificationSignal = { action: string; @@ -427,14 +440,14 @@ The notification and signal plugins are released as two new plugins in the Backs For the notification plugin to reach a stable release we much reach the following: -- [ ] A stable notifications payload format. -- [ ] A stable notifications recipient filter format. +- [x] A stable notifications payload format. +- [x] A stable notifications recipient filter format. - [x] The events service must have at least one implementation that supports scaled deployments. Done in #24916. For the signal plugin to reach a stable release we much reach the following: -- [ ] A stable signal recipient filter format. -- [ ] A stable signal channel API in the frontend. +- [x] A stable signal recipient filter format. +- [x] A stable signal channel API in the frontend. If any changes are required to the frontend framework to facilitate the implementation of notifications or signals, these will be released as experimental alpha features. They will stay in alpha until they are deemed stable enough, which must happen before a stable release of the notifications system. diff --git a/beps/0012-metrics-service/README.md b/beps/0012-metrics-service/README.md new file mode 100644 index 0000000000..59096d11d8 --- /dev/null +++ b/beps/0012-metrics-service/README.md @@ -0,0 +1,250 @@ +--- +title: Backstage Metrics Service +status: implementable +authors: + - '@kurtaking' +owners: + - '@kurtaking' +project-areas: + - core-framework +creation-date: 2025-06-23 +--- + +## Table of Contents + +- [Summary](#summary) +- [Motivation](#motivation) + - [Goals](#goals) + - [Non-Goals](#non-goals) +- [Proposal](#proposal) +- [Naming Conventions](#naming-conventions) +- [Design Details](#design-details) + - [References](#references) + - [Integration with OpenTelemetry Auto-Instrumentation](#integration-with-opentelemetry-auto-instrumentation) + - [Configuration](#configuration) + - [Interface](#interface) + - [Root Metrics Service](#root-metrics-service) + - [Plugin Metrics Service](#plugin-metrics-service) + - [Example](#example) +- [Release Plan](#release-plan) +- [Dependencies](#dependencies) +- [Alternatives](#alternatives) + +## Summary + +Add a core `MetricsService` to Backstage's framework to provide a unified interface for metrics instrumentation. The service offers industry standards (OTEL) while focusing the `MetricsService` on distinct Backstage concerns, following the same pattern as other core services (DatabaseService builds on Knex, LoggerService builds on Winston, HttpRouterService builds on Express, etc.). + +## Motivation + +While individual plugins may implement their own metrics, there's no standardized approach leading to inconsistent metrics patterns across the ecosystem. For example, both `catalog_entities_count` and `catalog.processed.entities.count` are examples of existing metric patterns. Ideally, these would be standardized to `backstage.plugin.catalog.entities.count` and `backstage.plugin.catalog.entities.processed.total` respectively. + +By providing a core metrics service: + +- **Plugin Authors** and the **Community** gain a straightforward way to address metrics instrumentation and can focus on business logic instead of needing to reimplement metrics plumbing. +- **Backstage Admins** receive a reliable stream of metrics from the core system for monitoring, alerting, and troubleshooting. + +### Goals + +- Plugin-scoped metric namespacing +- Consistent metrics patterns across all plugins +- Aligned with OpenTelemetry industry standards +- Provide a familiar interface as other core services + +The catalog and scaffolder plugins will be updated to use the new metrics service in the initial alpha release. + +### Non-Goals + +- Providing a way to configure the OpenTelemetry SDK. This is out of scope for this BEP. +- Adding metrics to plugins missing existing metrics (outside of catalog and scaffolder) +- Tracing and other telemetry concerns are out of scope for this BEP. +- Refactoring the existing `LoggerService`. Future work to unify observability related concerns would be ideal, but not a goal. + +## Proposal + +Following similar patterns to other core services, create a new `RootMetricsService` responsible for root-level concerns and the creation of plugin-specific `MetricsService` instances. + +## Naming Conventions + +All Backstage metrics follow this hierarchical pattern: + +`backstage.{scope}.{scope_name}.{metric_name}` + +**Where:** + +- `backstage` is the root namespace for all Backstage metrics +- `{scope}` is the system scope (either **plugin** or **core**) +- `{scope_name}` is the name of the plugin or core service (e.g., `catalog`, `scaffolder`, `database`, `scheduler`) +- `{metric_name}` is the hierarchical metric name as provided by the plugin author (e.g., `entity.count`, `tasks.completed.total`) + +### Scope + +The `scope` represents where it belongs in the Backstage ecosystem. + +- `plugin` - A plugin-specific metric (e.g. `backstage.plugin.catalog.entity.count`) +- `core` - A metric provided by the core system (e.g. `backstage.core.database.connections.active`) + +### Plugin-Scoped Metrics + +Pattern: `backstage.plugin.{pluginId}.{metric_name}` + +```yaml +# Examples +backstage.plugin.catalog.entities.processed.total +backstage.plugin.scaffolder.tasks.completed.total +backstage.plugin.techdocs.builds.active +backstage.plugin.auth.sessions.active.total # todo: technically a core service and a backend plugin +``` + +### Core-Scoped Metrics + +Pattern: `backstage.core.{service}.{metric_name}` + +```yaml +# Examples +backstage.core.database.connections.active +backstage.core.scheduler.tasks.queued.total +backstage.core.httpRouter.requests.total +``` + +## Design Details + +### References + +- [General naming considerations](https://opentelemetry.io/docs/specs/semconv/general/naming/#general-naming-considerations) +- [Acquiring a meter](https://opentelemetry.io/docs/languages/js/instrumentation/#acquiring-a-meter) + +### Integration with OpenTelemetry Auto-Instrumentation + +The `MetricsService` **complements** rather than duplicates auto-instrumentation by focusing on **application-level metrics** that only Backstage can provide. For example, the catalog plugin may want to track the number of entities processed by the `refresh` operation and the kind of entity being processed. + +```ts +// Auto-instrumentation provides (automatically): +// - http.server.requests.total{method="GET", route="/catalog/entities", status_code="200"} +// - http.server.request.duration{method="GET", route="/catalog/entities"} + +// MetricsService provides (manually): +const entityMetrics = metricsService.createCounter('entities.processed.total'); +entityMetrics.add(entities.length, { operation: 'refresh', kind: 'Component' }); + +// Metric is now available as `backstage.plugin.catalog.entities.processed.total` +``` + +### Configuration + +A challenging factor of only introducing a `MetricsService` is the need to collect other OTEL-related configuration such as resources, tracing providers, views, and more prior to starting the SDK. This means that in order to introduce a `MetricsService`, we must support all OTEL Node SDK configuration along with it. Along with this, the official recommendation from the OTEL team is to not initialize and start the SDK on behalf of the user. + +With this, **we will not include any configuration** as part of this BEP. Users will be responsible for initializing the SDK based on the current guidance + +### Interface + +Provide a wrapper around OpenTelemetry's API while leveraging the types from the `@opentelemetry/api` package. This introduces concepts already familiar to both the Backstage community and those familiar with OpenTelemetry. + +```ts +interface MetricsService { + // Synchronous instrumentation + createCounter(name: string, options?: MetricOptions): Counter; + createUpDownCounter(name: string, options?: MetricOptions): UpDownCounter; + createHistogram(name: string, options?: MetricOptions): Histogram; + createGauge(name: string, options?: MetricOptions): Gauge; + + // Asynchronous instrumentation + createObservableCounter( + name: string, + options?: MetricOptions, + ): ObservableCounter; + createObservableUpDownCounter( + name: string, + options?: MetricOptions, + ): ObservableUpDownCounter; + createObservableGauge(name: string, options?: MetricOptions): ObservableGauge; + + // Future - add additional convenience methods as we learn more about the needs of the framework +} +``` + +#### Root Metrics Service + +The `RootMetricsService` is responsible for providing metrics to other root services and creating both plugin-scoped and core-scoped `MetricsService` instances. + +```ts +interface RootMetricsService { + // note: no config is provided to the root service. + static forRoot(): RootMetricsService; + forPlugin(pluginId: string): MetricsService; + + // final implementation will be similar to + forService(serviceName: string, scope: 'plugin' | 'core'): MetricsService; +} + +export const rootMetricsServiceFactory = createServiceFactory({ + // depends on as little as possible so that it can be initialized as early as possible. + service: rootMetricsServiceRef, + deps: {}, + factory: () => { + return DefaultRootMetricsService.forRoot(); + }, +}); +``` + +#### Plugin Metrics Service + +Each plugin receives a metrics service that automatically namespaces all metrics to match the naming conventions. + +```ts +const metricsServiceFactory = createServiceFactory({ + service: metricsServiceRef, + deps: { + rootMetrics: coreServices.rootMetrics, + pluginMetadata: coreServices.pluginMetadata, + }, + factory: ({ rootMetrics, pluginMetadata }) => { + return rootMetrics.forPlugin(pluginMetadata.getId()); + }, +}); +``` + +#### Example + +```ts +const entitiesProcessed = metricsService.createCounter( + 'entities.processed.total', + { + description: 'Total entities processed during refresh', + unit: '{entity}', + }, +); + +entitiesProcessed.add(100); + +// ... +// metric is now available as `backstage.plugin.catalog.entities.processed.total` +``` + +## Release Plan + +1. Create the new metrics-related services. +1. Create alpha-related documentation to add to existing core service [docs](https://backstage.io/docs/backend-system/core-services/index). +1. Release the metrics service under `@alpha`. +1. Mark all existing metrics implementations as deprecated. +1. Refactor catalog and scaffolder plugins to use the new (alpha) `MetricsService`. +1. Offer a migration path for existing adopters to migrate to the new metrics service. +1. Release the metrics service under `@public` +1. Update remaining documentation to reference the new metrics service. +1. Create follow-up action items to integrate the new metrics service into the core system. +1. Fully deprecate all existing metrics implementations like the existing Prometheus one-off implementations. + +## Deprecation Plan + +1. Deprecation warning are added to all existing metrics +2. New metrics will run in parallel with the deprecated ones for a period of time +3. All existing metrics are removed from the codebase in the next major version + +## Dependencies + +1. The `otel` SDK MUST BE initialized as EARLY as possible to prevent dependents from receiving no-op meters - we will not change the current guidance on this +1. There are one-off implementations of metrics in the wild that may conflict with the proposed service. However, this is unlikely to be a problem as the SDK should continue to pick things up. + +## Alternatives + +- Plugin authors continue to implement their own metrics as they see fit. +- A combined TelemetryService that provides both metrics and tracing. diff --git a/canon-docs/next.config.mjs b/canon-docs/next.config.mjs deleted file mode 100644 index ca221d9a8c..0000000000 --- a/canon-docs/next.config.mjs +++ /dev/null @@ -1,15 +0,0 @@ -import createMDX from '@next/mdx'; - -const nextConfig = { - pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'], - output: 'export', - assetPrefix: '/', - distDir: 'dist', - images: { - unoptimized: true, - }, -}; - -const withMDX = createMDX({}); - -export default withMDX(nextConfig); diff --git a/canon-docs/package.json b/canon-docs/package.json deleted file mode 100644 index 5a4affc45b..0000000000 --- a/canon-docs/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "canon-docs", - "version": "0.1.0", - "private": true, - "scripts": { - "build": "npm run build:css && next build", - "build:css": "node scripts/build-css.js", - "lint": "next lint", - "start": "npm run build:css && next dev" - }, - "dependencies": { - "@codemirror/lang-sass": "^6.0.2", - "@lezer/highlight": "^1.2.1", - "@mdx-js/loader": "^3.1.0", - "@mdx-js/react": "^3.1.0", - "@next/mdx": "^15.1.4", - "@storybook/react": "^8.6.8", - "@uiw/codemirror-themes": "^4.23.7", - "@uiw/react-codemirror": "^4.23.7", - "motion": "^12.4.1", - "next": "14.2.26", - "react": "^18.0.2", - "react-dom": "^18.0.2", - "react-frame-component": "^5.2.7", - "shiki": "^1.26.1", - "storybook": "^8.6.8" - }, - "devDependencies": { - "@types/mdx": "^2.0.13", - "@types/node": "^20", - "@types/react": "^18.0.0", - "@types/react-dom": "^18.0.0", - "eslint": "^8", - "eslint-config-next": "14.2.23", - "lightningcss": "^1.28.2", - "typescript": "^5" - } -} diff --git a/canon-docs/public/CNAME b/canon-docs/public/CNAME deleted file mode 100644 index 01f6d196cc..0000000000 --- a/canon-docs/public/CNAME +++ /dev/null @@ -1 +0,0 @@ -canon.backstage.io \ No newline at end of file diff --git a/canon-docs/public/css-classname-structure.png b/canon-docs/public/css-classname-structure.png deleted file mode 100644 index df9894ff2b..0000000000 Binary files a/canon-docs/public/css-classname-structure.png and /dev/null differ diff --git a/canon-docs/scripts/build-css.js b/canon-docs/scripts/build-css.js deleted file mode 100644 index dd9775150f..0000000000 --- a/canon-docs/scripts/build-css.js +++ /dev/null @@ -1,39 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const { bundle } = require('lightningcss'); - -const source = '../../packages/canon/src/css'; -const destination = '../public'; - -const source1 = path.join(__dirname, `${source}/core.css`); -const destination1 = path.join(__dirname, `${destination}/core.css`); -const source2 = path.join(__dirname, `${source}/components.css`); -const destination2 = path.join(__dirname, `${destination}/components.css`); - -// Function to bundle and copy the CSS file -const bundleAndCopyFile = async (source, destination) => { - try { - const result = await bundle({ - filename: source, - minify: true, - }); - - fs.writeFileSync(destination, result.code); - console.log('File bundled and copied successfully!'); - } catch (err) { - console.error('Error bundling file:', err); - } -}; - -// Initial bundle and copy -Promise.all([ - bundleAndCopyFile(source1, destination1), - bundleAndCopyFile(source2, destination2), -]) - .then(() => { - // Add an empty line after all operations are complete - It looks better in the terminal :) - console.log(''); - }) - .catch(err => { - console.error('Error in processing files:', err); - }); diff --git a/canon-docs/src/app/(docs)/about/page.mdx b/canon-docs/src/app/(docs)/about/page.mdx deleted file mode 100644 index a4c16ee79e..0000000000 --- a/canon-docs/src/app/(docs)/about/page.mdx +++ /dev/null @@ -1,32 +0,0 @@ -# About Canon - -Canon is a design system created specifically for Backstage, built with React, TypeScript, and vanilla CSS. -This open-source library is hosted in the Backstage monorepo. While it can be used in other projects, Canon -is designed to deliver a consistent, accessible, and extensible experience tailored to Backstage users. - -## Philosophy - -Backstage empowers product teams to build software faster and with greater quality. Its extensibility, -however, required us to rethink how to deliver a consistent and accessible user experience. Our goal is -to enable plugin creators to design plugins that seamlessly integrate with Backstage's look and feel while -still allowing customization to match individual brands. - -Instead of reinventing the wheel, we chose to focus on layout and styling while leveraging existing headless -component libraries for functionality. This approach allows us to dedicate our efforts to creating a cohesive -and flexible theming system. - -## Team - -Canon is designed and maintained primarily by Spotify's Backstage team, leveraging Spotify's expertise in -crafting high-quality design and technology. Drawing from our experience in building reliable and intuitive -user experiences for the music industry, we've created a design system that looks great and works seamlessly. - -## Community - -Canon is an open-source project and we welcome contributions from the community. If you are interested in -contributing to Canon, please read our [contributing guide](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) -and our [code of conduct](https://github.com/backstage/backstage/blob/master/CODE_OF_CONDUCT.md). - -## License - -Canon is licensed under the Apache 2.0 license. See the [LICENSE](https://github.com/backstage/backstage/blob/master/LICENSE) file for more details. diff --git a/canon-docs/src/app/(docs)/components/avatar/page.mdx b/canon-docs/src/app/(docs)/components/avatar/page.mdx deleted file mode 100644 index b46caf8d62..0000000000 --- a/canon-docs/src/app/(docs)/components/avatar/page.mdx +++ /dev/null @@ -1,75 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { AvatarSnippet } from '@/snippets/stories-snippets'; -import { avatarPropDefs } from './props'; - -# Avatar - -An avatar component with a fallback for initials. - -} - code={``} -/> - - - - Usage - Theming - - - `} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - - `canon-AvatarRoot` - - `canon-AvatarRoot[data-size='small']` - - `canon-AvatarRoot[data-size='medium']` - - `canon-AvatarRoot[data-size='large']` - - `canon-AvatarImage` - - `canon-AvatarFallback` - - - -## API reference - - - -## Examples - -### Sizes - -Avatar sizes can be set using the `size` prop. - -} - code={` - - - - `} -/> - -### Fallback - -If the image is not available, the avatar will show the initials of the name. - -} - code={``} -/> diff --git a/canon-docs/src/app/(docs)/components/avatar/props.ts b/canon-docs/src/app/(docs)/components/avatar/props.ts deleted file mode 100644 index e86c67a41e..0000000000 --- a/canon-docs/src/app/(docs)/components/avatar/props.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs'; -import type { PropDef } from '@/utils/propDefs'; - -export const avatarPropDefs: Record = { - src: { - type: 'string', - }, - name: { - type: 'string', - }, - size: { - type: 'enum', - values: ['small', 'medium', 'large'], - default: 'medium', - responsive: true, - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/box/props.ts b/canon-docs/src/app/(docs)/components/box/props.ts deleted file mode 100644 index f3e38984dd..0000000000 --- a/canon-docs/src/app/(docs)/components/box/props.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { - classNamePropDefs, - displayPropDefs, - heightPropDefs, - positionPropDefs, - stylePropDefs, - widthPropDefs, -} from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const boxPropDefs: Record = { - as: { - type: 'enum', - values: ['div', 'span'], - default: 'div', - responsive: true, - }, - ...widthPropDefs, - ...heightPropDefs, - ...positionPropDefs, - ...displayPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/button/page.mdx b/canon-docs/src/app/(docs)/components/button/page.mdx deleted file mode 100644 index e1ecee8920..0000000000 --- a/canon-docs/src/app/(docs)/components/button/page.mdx +++ /dev/null @@ -1,136 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { ButtonSnippet } from '@/snippets/stories-snippets'; -import { buttonVariants } from '@/snippets/code-snippets'; -import { buttonPropDefs } from './props'; - -# Button - -A button component that can be used to trigger actions. - -} - code={` - - - -`} -/> - - - - Usage - Theming - - - -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - `} - /> - - - - -## API reference - - - -## Examples - -### Variants - -Here's a view when buttons have different variants. - -} - code={buttonVariants} -/> - -### Sizes - -Here's a view when buttons have different sizes. - -} - code={` - - -`} -/> - -### With Icons - -Here's a view when buttons have icons. - -} - code={` - - - -`} -/> - -### Full width - -Here's a view when buttons are full width. - -} - code={` - -`} -/> - -### Disabled - -Here's a view when buttons are disabled. - -} - code={``} -/> - -### Responsive - -Here's a view when buttons are responsive. - - - Responsive Button - `} -/> diff --git a/canon-docs/src/app/(docs)/components/button/props.ts b/canon-docs/src/app/(docs)/components/button/props.ts deleted file mode 100644 index 813dcaa6f0..0000000000 --- a/canon-docs/src/app/(docs)/components/button/props.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const buttonPropDefs: Record = { - variant: { - type: 'enum', - values: ['primary', 'secondary'], - default: 'primary', - responsive: true, - }, - size: { - type: 'enum', - values: ['small', 'medium'], - default: 'medium', - responsive: true, - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/checkbox/page.mdx b/canon-docs/src/app/(docs)/components/checkbox/page.mdx deleted file mode 100644 index 413636dc9a..0000000000 --- a/canon-docs/src/app/(docs)/components/checkbox/page.mdx +++ /dev/null @@ -1,66 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { CheckboxSnippet } from '@/snippets/stories-snippets'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { BaseUI } from '@/components/HeadlessBanners/BaseUI'; -import { checkboxPropDefs } from './props'; - -# Checkbox - -A checkbox component that can be used to trigger actions. - -} - code={``} -/> - - - - Usage - Theming - - - -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - `} - /> - - - - -## API reference - - - - - -## Examples - -### All variants - -Here's a view when checkboxes have different variants. - -} - code={` - - - - - `} -/> diff --git a/canon-docs/src/app/(docs)/components/checkbox/props.ts b/canon-docs/src/app/(docs)/components/checkbox/props.ts deleted file mode 100644 index 8abbac1ec9..0000000000 --- a/canon-docs/src/app/(docs)/components/checkbox/props.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const checkboxPropDefs: Record = { - label: { - type: 'string', - responsive: false, - }, - defaultChecked: { - type: 'enum', - values: ['boolean', "'indeterminate'"], - responsive: false, - }, - checked: { - type: 'enum', - values: ['boolean', "'indeterminate'"], - responsive: false, - }, - onChange: { - type: 'enum', - values: ["(checked: boolean | 'indeterminate') => void"], - responsive: false, - }, - disabled: { - type: 'enum', - values: ['boolean'], - responsive: false, - }, - required: { - type: 'enum', - values: ['boolean'], - responsive: false, - }, - name: { - type: 'string', - responsive: false, - }, - value: { - type: 'string', - responsive: false, - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/collapsible/page.mdx b/canon-docs/src/app/(docs)/components/collapsible/page.mdx deleted file mode 100644 index e013dff89c..0000000000 --- a/canon-docs/src/app/(docs)/components/collapsible/page.mdx +++ /dev/null @@ -1,113 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { CollapsibleSnippet } from '@/snippets/stories-snippets'; -import { - collapsibleRootPropDefs, - collapsibleTriggerPropDefs, - collapsiblePanelPropDefs, -} from './props'; - -# Collapsible - -An avatar component with a fallback for initials. - -} - code={` - ( - - )} /> - - - It's the edge of the world and all of Western civilization - The sun may rise in the East, at least it settled in a final location - It's understood that Hollywood sells Californication - - -`} -/> - - - - Usage - Theming - - - - ( - - )} /> - Your content -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - - `canon-CollapsibleRoot` - - `canon-CollapsibleTrigger` - - `canon-CollapsiblePanel` - - - -## API reference - -### Collapsible.Root - -Groups all parts of the collapsible. Renders a `
` element. - - - -### Collapsible.Trigger - -The trigger by default render a simple unstyled button. Because menus can be rendered in different ways, we recommend -using the `render` prop to render a custom trigger. - - - )} /> - - - It's the edge of the world and all of Western civilization - The sun may rise in the East, at least it settled in a final location - It's understood that Hollywood sells Californication - - -`} -/> diff --git a/canon-docs/src/app/(docs)/components/collapsible/props.ts b/canon-docs/src/app/(docs)/components/collapsible/props.ts deleted file mode 100644 index 02c62dc89e..0000000000 --- a/canon-docs/src/app/(docs)/components/collapsible/props.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - classNamePropDefs, - stylePropDefs, - renderPropDefs, -} from '@/utils/propDefs'; -import type { PropDef } from '@/utils/propDefs'; - -export const collapsibleRootPropDefs: Record = { - defaultOpen: { - type: 'boolean', - default: 'false', - }, - open: { - type: 'boolean', - }, - onOpenChange: { - type: 'enum', - values: ['(open) => void'], - }, - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const collapsibleTriggerPropDefs: Record = { - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const collapsiblePanelPropDefs: Record = { - hiddenUntilFound: { - type: 'boolean', - default: 'false', - }, - keepMounted: { - type: 'boolean', - default: 'false', - }, - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/container/page.mdx b/canon-docs/src/app/(docs)/components/container/page.mdx deleted file mode 100644 index 40f0321624..0000000000 --- a/canon-docs/src/app/(docs)/components/container/page.mdx +++ /dev/null @@ -1,62 +0,0 @@ -import { CodeBlock } from '@/components/CodeBlock'; -import { PropsTable } from '@/components/PropsTable'; -import { Tabs } from '@/components/Tabs'; -import { Snippet } from '@/components/Snippet'; -import { ContainerSnippet } from '@/snippets/stories-snippets'; -import { containerPropDefs } from './props'; - -# Container - -The container component let you use our default max-width and center the -content on the page. - -} - code={` - -`} -/> - - - - Usage - - - Hello World! -`} /> - - - -## API reference - - - -## Examples - -### Simple - -A simple example of how to use the Container component. - - - Hello World - Hello World - Hello World -`} -/> - -### Responsive padding & margin - -The Container component also supports responsive values, making it easy to -create responsive designs. - - - Hello World - Hello World - Hello World -`} -/> diff --git a/canon-docs/src/app/(docs)/components/container/props.ts b/canon-docs/src/app/(docs)/components/container/props.ts deleted file mode 100644 index 4a3410ec12..0000000000 --- a/canon-docs/src/app/(docs)/components/container/props.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { - classNamePropDefs, - stylePropDefs, - gapPropDefs, -} from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const containerPropDefs: Record = { - ...gapPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/flex/page.mdx b/canon-docs/src/app/(docs)/components/flex/page.mdx deleted file mode 100644 index 8150f3e3c5..0000000000 --- a/canon-docs/src/app/(docs)/components/flex/page.mdx +++ /dev/null @@ -1,83 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { - flexFAQ1, - flexSimple, - flexResponsive, - flexAlign, -} from '@/snippets/code-snippets'; -import { Snippet } from '@/components/Snippet'; -import { FlexSnippet } from '@/snippets/stories-snippets'; -import { flexPropDefs } from './props'; -import { spacingPropDefs } from '../../../../utils/propDefs'; - -# Flex - -This is the flex container component. It will help to define the number of -columns that will be used in the grid. You can also define the gap between the -columns. All values are responsive. - -} - code={` - - - -`} -/> - - - - Usage - - - -`} - /> - - - -## API reference - - - -The grid component also accepts all the spacing props from the Box component. - - - -## Common questions - -### Can I stack horizontally? - -The Flex component only allows for stacking elements vertically. If you want -to create a column layout, please use the Grid component. - - - -## Examples - -### Simple - -A simple example of how to use the Flex component. - - - -### Responsive - -The Flex component also supports responsive values, making it easy to create -responsive designs. - - - -### Align - -The Flex component also supports responsive alignment, making it easy to -create responsive designs. - - diff --git a/canon-docs/src/app/(docs)/components/flex/props.ts b/canon-docs/src/app/(docs)/components/flex/props.ts deleted file mode 100644 index 2268a6909d..0000000000 --- a/canon-docs/src/app/(docs)/components/flex/props.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { - PropDef, - childrenPropDefs, - classNamePropDefs, - stylePropDefs, -} from '../../../../utils/propDefs'; - -export const flexPropDefs: Record = { - align: { - type: 'enum', - values: ['start', 'center', 'end', 'baseline', 'stretch'], - responsive: true, - }, - direction: { - type: 'enum', - values: ['row', 'column', 'row-reverse', 'column-reverse'], - responsive: true, - }, - justify: { - type: 'enum', - values: ['start', 'center', 'end', 'between'], - responsive: true, - }, - ...childrenPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/grid/props.ts b/canon-docs/src/app/(docs)/components/grid/props.ts deleted file mode 100644 index a9e8717fa1..0000000000 --- a/canon-docs/src/app/(docs)/components/grid/props.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { - PropDef, - childrenPropDefs, - classNamePropDefs, - stylePropDefs, -} from '../../../../utils/propDefs'; - -const columnsValues = [ - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '10', - '11', - '12', -]; - -export const gridPropDefs: Record = { - columns: { - type: 'enum | string', - values: [...columnsValues, 'auto'], - responsive: true, - default: 'auto', - }, - ...childrenPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const gridItemPropDefs: Record = { - colSpan: { - type: 'enum | string', - values: [...columnsValues, 'full'], - responsive: true, - }, - rowSpan: { - type: 'enum | string', - values: [...columnsValues, 'full'], - responsive: true, - }, - start: { - type: 'enum | string', - values: [...columnsValues, 'auto'], - responsive: true, - }, - end: { - type: 'enum | string', - values: [...columnsValues, 'auto'], - responsive: true, - }, - ...childrenPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/heading/page.mdx b/canon-docs/src/app/(docs)/components/heading/page.mdx deleted file mode 100644 index 10fd60bef1..0000000000 --- a/canon-docs/src/app/(docs)/components/heading/page.mdx +++ /dev/null @@ -1,74 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { HeadingSnippet } from '@/snippets/stories-snippets'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { headingPropDefs } from './props'; - -# Heading - -Headings are used to structure the content of your page. - -} - code={`Hello World!`} -/> - - - - Usage - Theming - - - -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - `} - /> - - - - -## API reference - - - -## Examples - -### All variants - -The `Heading` component has a `variant` prop that can be used to change the -appearance of the heading. - -} - code={` - Display - Title 1 - Title 2 - Title 3 - Title 4 -`} -/> - -### Responsive - -You can also use the `variant` prop to change the appearance of the text based -on the screen size. - - - Responsive heading - `} -/> diff --git a/canon-docs/src/app/(docs)/components/heading/props.ts b/canon-docs/src/app/(docs)/components/heading/props.ts deleted file mode 100644 index a3dd3288ff..0000000000 --- a/canon-docs/src/app/(docs)/components/heading/props.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const headingPropDefs: Record = { - variant: { - type: 'enum', - values: ['display', 'title1', 'title2', 'title3', 'title4', 'title5'], - responsive: true, - }, - children: { - type: 'enum', - values: ['ReactNode'], - responsive: false, - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/icon-button/page.mdx b/canon-docs/src/app/(docs)/components/icon-button/page.mdx deleted file mode 100644 index 60530ec9ea..0000000000 --- a/canon-docs/src/app/(docs)/components/icon-button/page.mdx +++ /dev/null @@ -1,97 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { IconButtonSnippet } from '@/snippets/stories-snippets'; -import { iconButtonVariants } from '@/snippets/code-snippets'; -import { iconButtonPropDefs } from './props'; - -# Icon Button - -A button component with a single icon that can be used to trigger actions. - -} - code={` - - - `} -/> - - - - Usage - Theming - - - -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - `} - /> - - - - -## API reference - - - -## Examples - -### Variants - -Here's a view when buttons have different variants. - -} - code={iconButtonVariants} -/> - -### Sizes - -Here's a view when buttons have different sizes. - -} - code={` - - -`} -/> - -### Disabled - -Here's a view when buttons are disabled. - -} - code={``} -/> - -### Responsive - -Here's a view when buttons are responsive. - -`} -/> diff --git a/canon-docs/src/app/(docs)/components/icon-button/props.ts b/canon-docs/src/app/(docs)/components/icon-button/props.ts deleted file mode 100644 index bcb1580247..0000000000 --- a/canon-docs/src/app/(docs)/components/icon-button/props.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const iconButtonPropDefs: Record = { - variant: { - type: 'enum', - values: ['primary', 'secondary'], - default: 'primary', - responsive: true, - }, - size: { - type: 'enum', - values: ['small', 'medium'], - default: 'medium', - responsive: true, - }, - icon: { type: 'enum', values: 'icon', responsive: false }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/icon/page.mdx b/canon-docs/src/app/(docs)/components/icon/page.mdx deleted file mode 100644 index 66be460d13..0000000000 --- a/canon-docs/src/app/(docs)/components/icon/page.mdx +++ /dev/null @@ -1,44 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { IconSnippet } from '@/snippets/stories-snippets'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { iconPropDefs } from './props'; - -# Icon - -Icons are used to represent an action or a state. - -} - code={``} -/> - - - - Usage - Theming - - - -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - `} - /> - - - - -## API reference - - diff --git a/canon-docs/src/app/(docs)/components/icon/props.ts b/canon-docs/src/app/(docs)/components/icon/props.ts deleted file mode 100644 index 2ddbafd94e..0000000000 --- a/canon-docs/src/app/(docs)/components/icon/props.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const iconPropDefs: Record = { - name: { - type: 'enum', - values: 'icon', - responsive: false, - }, - size: { - type: 'number', - responsive: false, - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/link/page.mdx b/canon-docs/src/app/(docs)/components/link/page.mdx deleted file mode 100644 index 64a3261590..0000000000 --- a/canon-docs/src/app/(docs)/components/link/page.mdx +++ /dev/null @@ -1,84 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { - MenuSnippet, - ButtonSnippet, - LinkSnippet, -} from '@/snippets/stories-snippets'; -import { linkPropDefs } from './props'; - -# Link - -A link component that renders a `` element. - -} - code={`Sign up for Backstage`} -/> - - - - Usage - Theming - - - Sign up for Backstage`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - - `canon-Link` - - `canon-Link[data-variant='body']` - - `canon-Link[data-variant='subtitle']` - - `canon-Link[data-variant='caption']` - - `canon-Link[data-variant='label']` - - `canon-Link[data-weight='regular']` - - `canon-Link[data-weight='bold']` - - - -## API reference - - - -## Examples - -### Variants - -Here's a view when links have different variants. - -} - code={` - - - - - `} -/> - -### Weights - -Here's a view when links have different weights. - -} - code={` - - - `} -/> diff --git a/canon-docs/src/app/(docs)/components/link/props.ts b/canon-docs/src/app/(docs)/components/link/props.ts deleted file mode 100644 index 83507c5594..0000000000 --- a/canon-docs/src/app/(docs)/components/link/props.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs'; -import type { PropDef } from '@/utils/propDefs'; - -export const linkPropDefs: Record = { - to: { - type: 'string', - }, - variant: { - type: 'enum', - values: ['subtitle', 'body', 'caption', 'label'], - default: 'body', - responsive: true, - }, - weight: { - type: 'enum', - values: ['regular', 'bold'], - default: 'regular', - responsive: true, - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/menu/page.mdx b/canon-docs/src/app/(docs)/components/menu/page.mdx deleted file mode 100644 index 98c4949438..0000000000 --- a/canon-docs/src/app/(docs)/components/menu/page.mdx +++ /dev/null @@ -1,157 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { MenuSnippet } from '@/snippets/stories-snippets'; -import { BaseUI } from '@/components/HeadlessBanners/BaseUI'; -import { - menuRootPropDefs, - menuTriggerPropDefs, - menuPositionerPropDefs, - menuItemPropDefs, -} from './props'; - -# Menu - -A list of actions in a dropdown, enhanced with keyboard navigation. - -} - code={` - ( - - )} - /> - - - - Settings - Invite new members - Download app - Log out - - - - `} -/> - - - - Usage - Theming - - - - - - - - - - - - `} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - - `canon-MenuTrigger` - - `canon-MenuBackdrop` - - `canon-MenuPositioner` - - `canon-MenuPopup` - - `canon-MenuArrow` - - `canon-MenuItem` - - `canon-MenuGroup` - - `canon-MenuGroupLabel` - - `canon-MenuRadioGroup` - - `canon-MenuRadioItem` - - `canon-MenuRadioItemIndicator` - - `canon-MenuCheckboxItem` - - `canon-MenuCheckboxItemIndicator` - - `canon-MenuSubmenuTrigger` - - `canon-MenuSeparator` - - - -## API reference - - - -### Menu.Root - -Groups all parts of the menu. Doesn't render its own HTML element. - - - -### Menu.Trigger - -The trigger by default render a simple unstyled button. Because menus can be rendered in different ways, we recommend -using the `render` prop to render a custom trigger. - - - )} - /> - - - - Settings - Invite new members - Download app - Log out - - - - `} -/> diff --git a/canon-docs/src/app/(docs)/components/menu/props.ts b/canon-docs/src/app/(docs)/components/menu/props.ts deleted file mode 100644 index 5cf41fa5f9..0000000000 --- a/canon-docs/src/app/(docs)/components/menu/props.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { - classNamePropDefs, - stylePropDefs, - renderPropDefs, -} from '@/utils/propDefs'; -import type { PropDef } from '@/utils/propDefs'; - -export const menuRootPropDefs: Record = { - defaultOpen: { - type: 'boolean', - default: 'false', - }, - open: { - type: 'boolean', - }, - onOpenChange: { - type: 'enum', - values: ['(open, event) => void'], - }, - closeParentOnEsc: { - type: 'boolean', - default: 'true', - }, - modal: { - type: 'boolean', - default: 'true', - }, - onOpenChangeComplete: { - type: 'enum', - values: ['(open) => void'], - }, - disabled: { - type: 'boolean', - default: 'false', - }, - openOnHover: { - type: 'boolean', - }, - delay: { - type: 'number', - default: '100', - }, - loop: { - type: 'boolean', - default: 'true', - }, - orientation: { - type: 'enum', - values: ['horizontal', 'vertical'], - default: 'vertical', - }, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const menuTriggerPropDefs: Record = { - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const menuPositionerPropDefs: Record = { - align: { - type: 'enum', - values: ['start', 'center', 'end'], - default: 'center', - }, - alignOffset: { - type: 'enum', - values: ['number', '(data) => number'], - default: '0', - }, - side: { - type: 'enum', - values: ['bottom', 'inline-end', 'inline-start', 'left', 'right', 'top'], - default: 'bottom', - }, - sideOffset: { - type: 'enum', - values: ['number', '(data) => number'], - default: '0', - }, - arrowPadding: { - type: 'number', - default: '5', - }, - anchor: { - type: 'enum', - values: [ - 'React.Ref', - 'Element', - 'VirtualElement', - '(() => Element | VirtualElement | null)', - 'null', - ], - }, - collisionBoundary: { - type: 'enum', - values: ['clipping-ancestors', 'Element', 'Element[]', 'Rect'], - default: 'clipping-ancestors', - }, - collisionPadding: { - type: 'enum', - values: ['number', 'Rect'], - default: '5', - }, - sticky: { - type: 'boolean', - default: 'false', - }, - positionMethod: { - type: 'enum', - values: ['absolute', 'fixed'], - default: 'absolute', - }, - trackAnchor: { - type: 'boolean', - default: 'true', - }, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const menuItemPropDefs: Record = { - label: { - type: 'string', - }, - onClick: { - type: 'enum', - values: ['(event) => void'], - }, - closeOnClick: { - type: 'boolean', - default: 'true', - }, - disabled: { - type: 'boolean', - default: 'false', - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/select/page.mdx b/canon-docs/src/app/(docs)/components/select/page.mdx deleted file mode 100644 index 4399f62235..0000000000 --- a/canon-docs/src/app/(docs)/components/select/page.mdx +++ /dev/null @@ -1,128 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { SelectSnippet } from '@/snippets/stories-snippets'; -import { selectPropDefs } from './props'; - -# Select - -A common form component for choosing a predefined value in a dropdown menu. - -} - code={``} -/> - -### Sizes - -Here's a view when the selects have different sizes. - -} - code={` - - `} -/> - -### Disabled - -Here's a view when the select is disabled. - -} - code={` + + + + {themes.map(({ name, value }) => ( + + {name} + + ))} + + + + + Version {version} + + + + + + + + + + +
+ + ); +}; diff --git a/docs-ui/src/components/Toolbar/index.ts b/docs-ui/src/components/Toolbar/index.ts new file mode 100644 index 0000000000..f362defa5e --- /dev/null +++ b/docs-ui/src/components/Toolbar/index.ts @@ -0,0 +1 @@ +export { Toolbar } from './Toolbar'; diff --git a/docs-ui/src/content/accordion.mdx b/docs-ui/src/content/accordion.mdx new file mode 100644 index 0000000000..2694f8d144 --- /dev/null +++ b/docs-ui/src/content/accordion.mdx @@ -0,0 +1,128 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { AccordionSnippet } from '@/snippets/stories-snippets'; +import { + accordionPropDefs, + accordionTriggerPropDefs, + accordionPanelPropDefs, + accordionGroupPropDefs, + accordionUsageSnippet, + accordionWithSubtitleSnippet, + accordionCustomTriggerSnippet, + accordionDefaultExpandedSnippet, + accordionGroupSingleOpenSnippet, + accordionGroupMultipleOpenSnippet, +} from './accordion.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={accordionUsageSnippet} +/> + +## Usage + + + +## API reference + +### Accordion + +Root container for the accordion. Renders a `
` element. + + + +### AccordionTrigger + +Trigger component with built-in animated chevron icon. Renders a heading element (defaults to `

`, configurable via `level` prop) wrapping a ` + +`; + +export const buttonSizesSnippet = ` + + +`; + +export const buttonIconsSnippet = ` + + + +`; + +export const buttonDisabledSnippet = ` + + +`; + +export const buttonResponsiveSnippet = ``; + +export const buttonAsLinkSnippet = `import { ButtonLink } from '@backstage/ui'; + + + Button +`; diff --git a/docs-ui/src/content/card.mdx b/docs-ui/src/content/card.mdx new file mode 100644 index 0000000000..06c3a5bc2e --- /dev/null +++ b/docs-ui/src/content/card.mdx @@ -0,0 +1,89 @@ +import { PropsTable } from '@/components/PropsTable'; +import { CardSnippet } from '@/snippets/stories-snippets'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { + cardPropDefs, + cardUsageSnippet, + cardDefaultSnippet, + cardHeaderPropDefs, + cardBodyPropDefs, + cardFooterPropDefs, + cardLongBodySnippet, + cardListRowSnippet, +} from './card.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={cardDefaultSnippet} +/> + +## Usage + + + +## API reference + +### Card + +A card component that can be used to display content in a box. + + + +### CardHeader + +To display a header in a card, use the `CardHeader` component. This will be fixed at the top of the card. + + + +### CardBody + +To display content in a card, use the `CardBody` component. This will automatically fill the card. + + + +### CardFooter + +To display a footer in a card, use the `CardFooter` component. This will be fixed at the bottom of the card. + + + +## Examples + +### With long body + +Here's a view when card has a long body. + +} + code={cardLongBodySnippet} + open +/> + +### With list + +Here's a view when card has a list. + +} + code={cardListRowSnippet} + open +/> + + + + diff --git a/docs-ui/src/content/card.props.ts b/docs-ui/src/content/card.props.ts new file mode 100644 index 0000000000..70c71bdf56 --- /dev/null +++ b/docs-ui/src/content/card.props.ts @@ -0,0 +1,83 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const cardPropDefs: Record = { + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const cardHeaderPropDefs: Record = { + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const cardBodyPropDefs: Record = { + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const cardFooterPropDefs: Record = { + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const cardUsageSnippet = `import { card } from '@backstage/ui'; + + + Header + Body + Footer +`; + +export const cardDefaultSnippet = ` + Header + Body + Footer +`; + +export const cardLongBodySnippet = ` + + Header + + + + This is the first paragraph of a long body text that demonstrates how + the Card component handles extensive content. The card should adjust + accordingly to display all the text properly while maintaining its + structure. + + + Here's a second paragraph that adds more content to our card body. + Having multiple paragraphs helps to visualize how spacing works within + the card component. + + + This third paragraph continues to add more text to ensure we have a + proper demonstration of a card with significant content. This makes it + easier to test scrolling behavior and overall layout when content + exceeds the initial view. + + + + Footer + +`; + +export const cardListRowSnippet = ` + + Header + + + Hello world + Hello world + Hello world + Hello world + ... + + + Footer + +`; diff --git a/docs-ui/src/content/checkbox.mdx b/docs-ui/src/content/checkbox.mdx new file mode 100644 index 0000000000..5770396ebb --- /dev/null +++ b/docs-ui/src/content/checkbox.mdx @@ -0,0 +1,51 @@ +import { PropsTable } from '@/components/PropsTable'; +import { CheckboxSnippet } from '@/snippets/stories-snippets'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { + checkboxPropDefs, + checkboxUsageSnippet, + checkboxDefaultSnippet, + checkboxVariantsSnippet, +} from './checkbox.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={checkboxDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### All variants + +Here's a view when checkboxes have different variants. + +} + code={checkboxVariantsSnippet} +/> + + + + diff --git a/docs-ui/src/content/checkbox.props.ts b/docs-ui/src/content/checkbox.props.ts new file mode 100644 index 0000000000..ce0f1033ff --- /dev/null +++ b/docs-ui/src/content/checkbox.props.ts @@ -0,0 +1,61 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const checkboxPropDefs: Record = { + children: { + type: 'enum', + values: ['React.ReactNode'], + responsive: false, + }, + isSelected: { + type: 'enum', + values: ['boolean'], + responsive: false, + }, + defaultSelected: { + type: 'enum', + values: ['boolean'], + responsive: false, + }, + onChange: { + type: 'enum', + values: ['(isSelected: boolean) => void'], + responsive: false, + }, + isDisabled: { + type: 'enum', + values: ['boolean'], + responsive: false, + }, + isRequired: { + type: 'enum', + values: ['boolean'], + responsive: false, + }, + name: { + type: 'string', + responsive: false, + }, + value: { + type: 'string', + responsive: false, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const checkboxUsageSnippet = `import { Checkbox } from '@backstage/ui'; + +Accept terms`; + +export const checkboxDefaultSnippet = `Accept terms and conditions`; + +export const checkboxVariantsSnippet = ` + Unchecked + Checked + Disabled + Checked & Disabled +`; diff --git a/docs-ui/src/content/container.mdx b/docs-ui/src/content/container.mdx new file mode 100644 index 0000000000..05615cb1c2 --- /dev/null +++ b/docs-ui/src/content/container.mdx @@ -0,0 +1,53 @@ +import { CodeBlock } from '@/components/CodeBlock'; +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { ContainerSnippet } from '@/snippets/stories-snippets'; +import { + containerPropDefs, + containerUsageSnippet, + containerDefaultSnippet, + containerSimpleSnippet, + containerResponsiveSnippet, +} from './container.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={containerDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### Simple + +A simple example of how to use the Container component. + + + +### Responsive padding & margin + +The Container component also supports responsive values, making it easy to +create responsive designs. + + + + + + diff --git a/docs-ui/src/content/container.props.ts b/docs-ui/src/content/container.props.ts new file mode 100644 index 0000000000..a4d23a8495 --- /dev/null +++ b/docs-ui/src/content/container.props.ts @@ -0,0 +1,32 @@ +import { + classNamePropDefs, + stylePropDefs, + gapPropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const containerPropDefs: Record = { + ...gapPropDefs, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const containerUsageSnippet = `import { Container } from "@backstage/ui"; + +Hello World!`; + +export const containerDefaultSnippet = ` + +`; + +export const containerSimpleSnippet = ` + Hello World + Hello World + Hello World +`; + +export const containerResponsiveSnippet = ` + Hello World + Hello World + Hello World +`; diff --git a/docs-ui/src/content/dialog.mdx b/docs-ui/src/content/dialog.mdx new file mode 100644 index 0000000000..4aa43c69de --- /dev/null +++ b/docs-ui/src/content/dialog.mdx @@ -0,0 +1,107 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { DialogSnippet } from '@/snippets/stories-snippets'; +import { + dialogPropDefs, + dialogTriggerPropDefs, + dialogHeaderPropDefs, + dialogBodyPropDefs, + dialogFooterPropDefs, + dialogClosePropDefs, + dialogUsageSnippet, + dialogDefaultSnippet, + dialogFixedWidthAndHeightSnippet, + dialogWithFormSnippet, + dialogWithNoTriggerSnippet, + dialogCloseSnippet, +} from './dialog.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={dialogDefaultSnippet} +/> + +## Usage + + + +## API reference + +### DialogTrigger + +Wraps a trigger element and the dialog content to handle open/close state. + + + +### Dialog + +The main dialog container that renders as a modal overlay. + + + +### DialogHeader + +Displays the dialog title with a built-in close button. + + + +### DialogBody + +The main content area of the dialog with optional scrolling. + + + +### DialogFooter + +Contains action buttons or other footer content. + + + +If you want to close the dialog while pressing a button, you can use the `slot="close"` prop on the button. + + + +## Examples + +### Fixed Width and Height + +Dialog with a fixed height body that scrolls when content overflows. + +} + code={dialogFixedWidthAndHeightSnippet} +/> + +### Dialog with Form + +Dialog containing form elements for user input. + +} + code={dialogWithFormSnippet} +/> + +### Dialog with no trigger and controlled by props + +You can also control the dialog using your own states. + + + + + + diff --git a/docs-ui/src/content/dialog.props.ts b/docs-ui/src/content/dialog.props.ts new file mode 100644 index 0000000000..162ec307dc --- /dev/null +++ b/docs-ui/src/content/dialog.props.ts @@ -0,0 +1,172 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const dialogTriggerPropDefs: Record = { + children: { type: 'enum', values: ['ReactNode'], responsive: false }, + isOpen: { + type: 'boolean', + description: 'Whether the overlay is open by default (controlled).', + }, + defaultOpen: { + type: 'boolean', + description: 'Whether the overlay is open by default (uncontrolled).', + }, + onOpenChange: { + type: 'enum', + values: ['(isOpen: boolean) => void'], + description: + "Handler that is called when the overlay's open state changes.", + }, +}; + +export const dialogPropDefs: Record = { + children: { type: 'enum', values: ['ReactNode'], responsive: false }, + isOpen: { + type: 'boolean', + description: 'Whether the overlay is open by default (controlled).', + }, + defaultOpen: { + type: 'boolean', + description: 'Whether the overlay is open by default (uncontrolled).', + }, + onOpenChange: { + type: 'enum', + values: ['(isOpen: boolean) => void'], + description: + "Handler that is called when the overlay's open state changes.", + }, + width: { + type: 'enum', + values: ['number', 'string'], + responsive: false, + }, + height: { + type: 'enum', + values: ['number', 'string'], + responsive: false, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const dialogHeaderPropDefs: Record = { + children: { type: 'enum', values: ['ReactNode'], responsive: false }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const dialogBodyPropDefs: Record = { + children: { type: 'enum', values: ['ReactNode'], responsive: false }, + height: { + type: 'enum', + values: ['number', 'string'], + responsive: false, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const dialogFooterPropDefs: Record = { + children: { type: 'enum', values: ['ReactNode'], responsive: false }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const dialogClosePropDefs: Record = { + variant: { + type: 'enum', + values: ['primary', 'secondary', 'tertiary'], + default: 'secondary', + responsive: false, + }, + children: { type: 'enum', values: ['ReactNode'], responsive: false }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const dialogUsageSnippet = `import { + Dialog, + DialogTrigger, + DialogHeader, + DialogBody, + DialogFooter, +} from '@backstage/ui'; + + + + + Title + Content + + + + +`; + +export const dialogDefaultSnippet = ` + + + Example Dialog + + This is a basic dialog example. + + + + + + +`; + +export const dialogFixedWidthAndHeightSnippet = ` + + + Long Content Dialog + + ... + + + + + + +`; + +export const dialogWithFormSnippet = ` + + + Create New User + + + + + + + + + + + + +`; + +export const dialogWithNoTriggerSnippet = `const [isOpen, setIsOpen] = useState(false); + + + Create New User + + Your content + + + + + +`; + +export const dialogCloseSnippet = ``; diff --git a/docs-ui/src/content/flex.mdx b/docs-ui/src/content/flex.mdx new file mode 100644 index 0000000000..89cd2e380a --- /dev/null +++ b/docs-ui/src/content/flex.mdx @@ -0,0 +1,68 @@ +import { PropsTable } from '@/components/PropsTable'; +import { CodeBlock } from '@/components/CodeBlock'; +import { Snippet } from '@/components/Snippet'; +import { FlexSnippet } from '@/snippets/stories-snippets'; +import { + flexPropDefs, + flexUsageSnippet, + flexDefaultSnippet, + flexFAQ1Snippet, + flexSimpleSnippet, + flexResponsiveSnippet, + flexAlignSnippet, +} from './flex.props'; +import { spacingPropDefs } from '@/utils/propDefs'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={flexDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +The grid component also accepts all the spacing props from the Box component. + + + +## Examples + +### Simple + +A simple example of how to use the Flex component. + + + +### Responsive + +The Flex component also supports responsive values, making it easy to create +responsive designs. + + + +### Align + +The Flex component also supports responsive alignment, making it easy to +create responsive designs. + + + + + + diff --git a/docs-ui/src/content/flex.props.ts b/docs-ui/src/content/flex.props.ts new file mode 100644 index 0000000000..cc4c2d5a75 --- /dev/null +++ b/docs-ui/src/content/flex.props.ts @@ -0,0 +1,55 @@ +import { + childrenPropDefs, + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const flexPropDefs: Record = { + align: { + type: 'enum', + values: ['start', 'center', 'end', 'baseline', 'stretch'], + responsive: true, + }, + direction: { + type: 'enum', + values: ['row', 'column', 'row-reverse', 'column-reverse'], + responsive: true, + }, + justify: { + type: 'enum', + values: ['start', 'center', 'end', 'between'], + responsive: true, + }, + ...childrenPropDefs, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const flexUsageSnippet = `import { Flex } from '@backstage/ui'; + +`; + +export const flexDefaultSnippet = ` + + + +`; + +export const flexSimpleSnippet = ` + Hello World + Hello World + Hello World +`; + +export const flexResponsiveSnippet = ` + Hello World + Hello World + Hello World +`; + +export const flexAlignSnippet = ` + Hello World + Hello World + Hello World +`; diff --git a/canon-docs/src/app/(docs)/components/grid/page.mdx b/docs-ui/src/content/grid.mdx similarity index 50% rename from canon-docs/src/app/(docs)/components/grid/page.mdx rename to docs-ui/src/content/grid.mdx index c8604076eb..0ffdba6a66 100644 --- a/canon-docs/src/app/(docs)/components/grid/page.mdx +++ b/docs-ui/src/content/grid.mdx @@ -1,39 +1,42 @@ import { CodeBlock } from '@/components/CodeBlock'; import { PropsTable } from '@/components/PropsTable'; -import { Tabs } from '@/components/Tabs'; -import { grid } from '@/snippets/code-snippets'; import { Snippet } from '@/components/Snippet'; import { GridSnippet } from '@/snippets/stories-snippets'; -import { spacingPropDefs } from '../../../../utils/propDefs'; -import { gridPropDefs, gridItemPropDefs } from './props'; +import { spacingPropDefs } from '@/utils/propDefs'; +import { + gridPropDefs, + gridItemPropDefs, + gridUsageSnippet, + gridDefaultSnippet, + gridSimpleSnippet, + gridComplexSnippet, + gridMixingRowsSnippet, + gridResponsiveSnippet, + gridStartEndSnippet, +} from './grid.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; -# Grid - -A layout component that helps to create simple column-based layouts as well as -more complex ones. + } - code={` - - - -`} + code={gridDefaultSnippet} /> - - - Usage - - - - - +## Usage + + ## API reference -### Grid +### Grid.Root This is the grid container component. It will help to define the number of columns that will be used in the grid. You can also define the gap between the @@ -60,31 +63,14 @@ elements directly if you prefer. A simple grid with 3 columns and a gap of md. - - Hello World - Hello World - Hello World - -`} -/> + ### Complex grid You can also use the grid item to create more complex layouts. In this example the first column will span 1 column and the second column will span 2 columns. - - - Hello World - - - Hello World - - -`} -/> + ### Mixing rows and columns @@ -92,47 +78,21 @@ The grid item component also supports the `rowSpan` prop, which allows you to span multiple rows within the grid layout. In this example, the first item will span 2 rows to achieve a dynamic and flexible grid structure. - - - Hello World - - - Hello World - - - Hello World - - -`} -/> + ### Responsive grid The grid component also supports responsive values, making it easy to create responsive designs. - - - Hello World - - - Hello World - - -`} -/> + ### Start and End The start and end props can be used to position the item in the grid. - - - Hello World - - -`} -/> + + + + + diff --git a/docs-ui/src/content/grid.props.ts b/docs-ui/src/content/grid.props.ts new file mode 100644 index 0000000000..6f037cd64f --- /dev/null +++ b/docs-ui/src/content/grid.props.ts @@ -0,0 +1,111 @@ +import { + childrenPropDefs, + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +const columnsValues = [ + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '11', + '12', +]; + +export const gridPropDefs: Record = { + columns: { + type: 'enum | string', + values: [...columnsValues, 'auto'], + responsive: true, + default: 'auto', + }, + ...childrenPropDefs, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const gridItemPropDefs: Record = { + colSpan: { + type: 'enum | string', + values: [...columnsValues, 'full'], + responsive: true, + }, + rowSpan: { + type: 'enum | string', + values: [...columnsValues, 'full'], + responsive: true, + }, + colStart: { + type: 'enum | string', + values: [...columnsValues, 'auto'], + responsive: true, + }, + colEnd: { + type: 'enum | string', + values: [...columnsValues, 'auto'], + responsive: true, + }, + ...childrenPropDefs, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const gridUsageSnippet = `import { Grid } from '@backstage/ui'; + +`; + +export const gridDefaultSnippet = ` + + + +`; + +export const gridSimpleSnippet = ` + Hello World + Hello World + Hello World +`; + +export const gridComplexSnippet = ` + + Hello World + + + Hello World + +`; + +export const gridMixingRowsSnippet = ` + + Hello World + + + Hello World + + + Hello World + +`; + +export const gridResponsiveSnippet = ` + + + + Hello World + +`; + +export const gridStartEndSnippet = ` + + Hello World + +`; diff --git a/docs-ui/src/content/header-page.mdx b/docs-ui/src/content/header-page.mdx new file mode 100644 index 0000000000..d3f93058ee --- /dev/null +++ b/docs-ui/src/content/header-page.mdx @@ -0,0 +1,87 @@ +import { PropsTable } from '@/components/PropsTable'; +import { CodeBlock } from '@/components/CodeBlock'; +import { Snippet } from '@/components/Snippet'; +import { HeaderPageSnippet } from '@/snippets/stories-snippets'; +import { + propDefs, + usage, + simple, + defaultSnippet, + withTabs, + withBreadcrumbs, + withCustomActions, + withMenuItems, +} from './header-page.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={defaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### With Breadcrumbs + +You can add breadcrumbs to the header page to help users navigate to the previous page. The `breadcrumbs` +prop is an array of objects with a `label` and `href` property. By default we truncate the breadcrumb label to 240px. + +} + code={withBreadcrumbs} +/> + +### With Tabs + +You can add tabs to the header page to help users navigate to the different sections of the page. The `tabs` +prop is an array of objects with a `label` and `href` property. + +} + code={withTabs} +/> + +### With Custom Actions + +You can add custom actions to the header page to help users navigate to the different sections of the page. The `customActions` +prop is a React node. + +} + code={withCustomActions} +/> + +### With Menu Items + +You can add menu items to the header page to help users navigate to the different sections of the page. The `menuItems` +prop is an array of objects with a `label`, `value` and `onClick` property. + +} + code={withMenuItems} +/> + + + + diff --git a/docs-ui/src/content/header-page.props.ts b/docs-ui/src/content/header-page.props.ts new file mode 100644 index 0000000000..fca9497b58 --- /dev/null +++ b/docs-ui/src/content/header-page.props.ts @@ -0,0 +1,141 @@ +import { + childrenPropDefs, + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const propDefs: Record = { + title: { + type: 'string', + default: 'Your plugin', + }, + customActions: { + type: 'enum', + values: ['ReactNode'], + }, + menuItems: { + type: 'complex', + complexType: { + name: 'MenuItem[]', + properties: { + label: { + type: 'string', + required: true, + description: 'Display text for the menu item', + }, + value: { + type: 'string', + required: true, + description: 'Unique value for the menu item', + }, + onClick: { + type: '() => void', + required: false, + description: 'Callback function when menu item is clicked', + }, + }, + }, + }, + tabs: { + type: 'complex', + complexType: { + name: 'HeaderTab[]', + properties: { + id: { + type: 'string', + required: true, + description: 'Unique identifier for the tab', + }, + label: { + type: 'string', + required: true, + description: 'Display text for the tab', + }, + href: { + type: 'string', + required: false, + description: 'URL to navigate to when tab is clicked', + }, + matchStrategy: { + type: "'exact' | 'prefix'", + required: false, + description: 'How to match the current route to highlight the tab', + }, + }, + }, + }, + breadcrumbs: { + type: 'complex', + complexType: { + name: 'Breadcrumb[]', + properties: { + label: { + type: 'string', + required: true, + description: 'Display text for the breadcrumb', + }, + href: { + type: 'string', + required: true, + description: 'URL for the breadcrumb link', + }, + }, + }, + }, + ...childrenPropDefs, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const usage = `import { HeaderPage } from '@backstage/ui'; + +`; + +export const defaultSnippet = `Custom action} +/>`; + +export const withBreadcrumbs = ``; + +export const withTabs = ``; + +export const withCustomActions = `Custom action} +/>`; + +export const withMenuItems = ` {} }, + { label: 'Invite new members', value: 'invite-new-members', onClick: () => {} }, + ]} +/>`; diff --git a/docs-ui/src/content/header.mdx b/docs-ui/src/content/header.mdx new file mode 100644 index 0000000000..af4e8010c5 --- /dev/null +++ b/docs-ui/src/content/header.mdx @@ -0,0 +1,85 @@ +import { PropsTable } from '@/components/PropsTable'; +import { CodeBlock } from '@/components/CodeBlock'; +import { Snippet } from '@/components/Snippet'; +import { HeaderSnippet } from '@/snippets/stories-snippets'; +import { + propDefs, + usage, + simple, + defaultSnippet, + withTabs, + withBreadcrumbs, + withHeaderPage, +} from './header.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={defaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### Simple header + +A simple example of how to use the Header component. + +} + code={simple} + open +/> + +### Header with tabs + +A simple example of how to use the Header component with tabs. All links are using React Router +under the hood and will be active when you are on the corresponding page. + +} +code={withTabs} +open +/> + +### Header with breadcrumbs + +Breacrumbs should appear when you scroll down (and not directly visible as it is in the demo below). + +} + code={withBreadcrumbs} + open +/> + +### Header with HeaderPage + +You can use the `Header` component inside the [HeaderPage](/components/header-page) component to compose your multi-level navigation. + +} + code={withHeaderPage} + open +/> + + + + diff --git a/docs-ui/src/content/header.props.ts b/docs-ui/src/content/header.props.ts new file mode 100644 index 0000000000..af9a745fc5 --- /dev/null +++ b/docs-ui/src/content/header.props.ts @@ -0,0 +1,200 @@ +import { + childrenPropDefs, + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const propDefs: Record = { + icon: { + type: 'enum', + values: ['ReactNode'], + }, + title: { + type: 'string', + default: 'Your plugin', + }, + titleLink: { + type: 'string', + default: '/', + }, + customActions: { + type: 'enum', + values: ['ReactNode'], + }, + menuItems: { + type: 'complex', + complexType: { + name: 'MenuItem[]', + properties: { + label: { + type: 'string', + required: true, + description: 'Display text for the menu item', + }, + value: { + type: 'string', + required: true, + description: 'Unique value for the menu item', + }, + onClick: { + type: '() => void', + required: false, + description: 'Callback function when menu item is clicked', + }, + }, + }, + }, + tabs: { + type: 'complex', + complexType: { + name: 'HeaderTab[]', + properties: { + id: { + type: 'string', + required: true, + description: 'Unique identifier for the tab', + }, + label: { + type: 'string', + required: true, + description: 'Display text for the tab', + }, + href: { + type: 'string', + required: false, + description: 'URL to navigate to when tab is clicked', + }, + matchStrategy: { + type: "'exact' | 'prefix'", + required: false, + description: 'How to match the current route to highlight the tab', + }, + }, + }, + }, + onTabSelectionChange: { + type: 'enum', + values: ['(key: string) => void'], + }, + ...childrenPropDefs, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const usage = `import { Header } from '@backstage/ui'; + +
`; + +export const defaultSnippet = `
+ } /> + } /> + } /> + + } +/>`; + +export const simple = `
+ } /> + } /> + } /> + + } +/>`; + +export const withTabs = ` +
+ } /> + } /> + } /> + + } + tabs={[ + { id: 'overview', label: 'Overview' }, + { id: 'checks', label: 'Checks' }, + { id: 'tracks', label: 'Tracks' }, + { id: 'campaigns', label: 'Campaigns' }, + { id: 'integrations', label: 'Integrations' }, + ]} +/> +`; + +export const withBreadcrumbs = `
`; + +export const withHeaderPage = `
+Custom action} +/>`; diff --git a/docs-ui/src/content/link.mdx b/docs-ui/src/content/link.mdx new file mode 100644 index 0000000000..e0c1be353f --- /dev/null +++ b/docs-ui/src/content/link.mdx @@ -0,0 +1,102 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { + MenuSnippet, + ButtonSnippet, + LinkSnippet, +} from '@/snippets/stories-snippets'; +import { + linkPropDefs, + linkUsageSnippet, + linkDefaultSnippet, + linkVariantsSnippet, + linkWeightsSnippet, + linkColorsSnippet, + linkRouterSnippet, + linkTruncateSnippet, +} from './link.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={linkDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Router Integration + +The `Link` component handles both internal and external navigation. It automatically detects whether the provided URL is internal (relative path) or external (absolute URL with protocol) and renders the appropriate element: + +- **Internal routes**: Uses `react-router-dom`'s `Link` component for client-side navigation +- **External URLs**: Renders a standard `` element for traditional navigation + + + +## Examples + +### Variants + +Here's a view when links have different variants. + +} + code={linkVariantsSnippet} +/> + +### Weights + +Here's a view when links have different weights. + +} + code={linkWeightsSnippet} +/> + +### Colors + +Here's a view when links have different colors. + +} + code={linkColorsSnippet} +/> + +### Truncate + +The `Link` component has a `truncate` prop that can be used to truncate the text. + +} + code={linkTruncateSnippet} +/> + + + + diff --git a/docs-ui/src/content/link.props.ts b/docs-ui/src/content/link.props.ts new file mode 100644 index 0000000000..748e64cc15 --- /dev/null +++ b/docs-ui/src/content/link.props.ts @@ -0,0 +1,81 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const linkPropDefs: Record = { + href: { + type: 'string', + }, + variant: { + type: 'enum', + values: [ + 'title-large', + 'title-medium', + 'title-small', + 'title-x-small', + 'body-large', + 'body-medium', + 'body-small', + 'body-x-small', + ], + default: 'body-medium', + responsive: true, + }, + weight: { + type: 'enum', + values: ['regular', 'bold'], + default: 'regular', + responsive: true, + }, + color: { + type: 'enum', + values: ['primary', 'secondary', 'danger', 'warning', 'success'], + default: 'primary', + responsive: true, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const linkUsageSnippet = `import { Link } from '@backstage/ui'; + +Sign up for Backstage`; + +export const linkDefaultSnippet = `Sign up for Backstage`; + +export const linkVariantsSnippet = ` + ... + ... + ... + ... + ... + ... + ... + ... +`; + +export const linkWeightsSnippet = ` + + +`; + +export const linkColorsSnippet = ` + I am primary + I am secondary + I am danger + I am warning + I am success +`; + +export const linkRouterSnippet = `import { Link } from '@backstage/ui'; + +// Internal route +Home + +// External URL +Backstage +`; + +export const linkTruncateSnippet = `...`; diff --git a/docs-ui/src/content/menu.mdx b/docs-ui/src/content/menu.mdx new file mode 100644 index 0000000000..743d884809 --- /dev/null +++ b/docs-ui/src/content/menu.mdx @@ -0,0 +1,236 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { MenuSnippet } from '@/snippets/stories-snippets'; +import { + usage, + preview, + submenu, + icons, + sections, + separators, + links, + autocomplete, + autocompleteListbox, + autocompleteListboxMultiple, + menuTriggerPropDefs, + submenuTriggerPropDefs, + menuPropDefs, + menuListBoxPropDefs, + menuAutocompletePropDefs, + menuAutocompleteListboxPropDefs, + menuItemPropDefs, + menuListBoxItemPropDefs, + menuSectionPropDefs, + menuSeparatorPropDefs, +} from './menu.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={preview} +/> + +## Usage + + + +### Triggers + +- `MenuTrigger` is a wrapper component that combines a button or other trigger element with a menu displayed in a popover. +- `SubmenuTrigger` is a wrapper component that combines a `MenuItem` with a menu displayed in a popover. + +### Containers + +- `Menu` is a container component that contains a list of menu items or sections. +- `MenuListBox` is a container component that contains a list of menu items or sections. +- `MenuAutocomplete` is a container component that contains a list of menu items or sections. +- `MenuAutocompleteListbox` is a container component that contains a list of menu items or sections. + +### Items + +- `MenuItem` is an individual interactive item in the menu. +- `MenuListBoxItem` is an individual interactive item in the menu list box. + +### Separators + +- `MenuSeparator` is a component that renders a horizontal line to separate menu items. +- `MenuSection` is a component that renders a section in the menu. + +## API reference + +### MenuTrigger + +`MenuTrigger` accepts exactly two children: the first child should be the trigger element, and second child should be +one of the menu containers containing the menu. + + + +### SubmenuTrigger + +The `SubmenuTrigger` accepts exactly two children: the first child should be the `MenuItem` which triggers opening +of the submenu, and second child should be one of the menu containers containing the submenu. + + + +### Menu + +`Menu` is a container component that contains a list of menu items or sections. + + + +### MenuListBox + +`MenuListBox` is a container component that contains a list of menu items or sections. + + + +### MenuAutocomplete + +`MenuAutocomplete` is a container component that contains a list of menu items or sections. + + + +### MenuAutocompleteListbox + +`MenuAutocompleteListbox` is a container component that contains a list of menu items or sections. + + + +### MenuItem + +`MenuItem` is an individual interactive item in the menu. + + + +### MenuListBoxItem + +`MenuListBoxItem` is an individual interactive item in the menu list box. + + + +### MenuSection + +`MenuSection` is a component that renders a section in the menu. + + + +### MenuSeparator + +`MenuSeparator` is a component that renders a horizontal line to separate menu items. + + + +## Examples + +### Nested navigation + +You can nest menus to create a more complex navigation structure. It is important to use the `placement` prop to ensure +the submenu is displayed in the correct position. The best practice is to use the `right top` placement for the submenu. + +} + code={submenu} +/> + +### With icons + +You can use the `iconStart` prop to add an icon to the menu item. + +} + code={icons} +/> + +### With links + +You can use the `href` prop to add a link to the menu item. This is using our router provider under the hood +to work for both internal and external links. + +} + code={links} +/> + +### With sections + +You can use the `MenuSection` component to add a section to the menu. + +} + code={sections} +/> + +### With separators + +You can use the `MenuSeparator` component to add a separator to the menu. + +} + code={separators} +/> + +### With autocomplete + +You can use the `MenuAutocomplete` component to add a autocomplete to the menu. + +} + code={autocomplete} +/> + +### With list box + +You can use the `MenuListBox` component to add a list box to the menu. + +} + code={autocompleteListbox} +/> + +### With list box with multiple selection + +You can use the `MenuListBox` component to add a list box to the menu. You can also use the `selectionMode` prop to +allow multiple selection. + +} + code={autocompleteListboxMultiple} +/> + + + + diff --git a/docs-ui/src/content/menu.props.ts b/docs-ui/src/content/menu.props.ts new file mode 100644 index 0000000000..2c7d76dd5d --- /dev/null +++ b/docs-ui/src/content/menu.props.ts @@ -0,0 +1,372 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +const placementValues = [ + 'bottom', + 'bottom left', + 'bottom right', + 'bottom start', + 'bottom end', + 'top', + 'top left', + 'top right', + 'top start', + 'top end', + 'left', + 'left top', + 'left bottom', + 'start', + 'start top', + 'start bottom', + 'right', + 'right top', + 'right bottom', + 'end', + 'end top', + 'end bottom', +]; + +export const menuTriggerPropDefs: Record = { + isOpen: { + type: 'boolean', + }, + defaultOpen: { + type: 'boolean', + }, + onOpenChange: { + type: 'enum', + values: ['(isOpen: boolean) => void'], + }, +}; + +export const submenuTriggerPropDefs: Record = { + delay: { + type: 'number', + default: '200', + }, +}; + +export const menuPropDefs: Record = { + disabledKeys: { + type: 'enum', + values: ['Iterable'], + }, + selectionMode: { + type: 'enum', + values: ['none', 'single', 'multiple'], + }, + selectedKeys: { + type: 'enum', + values: ['all', 'Iterable'], + }, + defaultSelectedKeys: { + type: 'enum', + values: ['all', 'Iterable'], + }, + placement: { + type: 'enum', + values: placementValues, + }, + virtualized: { + type: 'boolean', + default: 'false', + }, + maxWidth: { + type: 'number', + }, + maxHeight: { + type: 'number', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const menuListBoxPropDefs: Record = { + disabledKeys: { + type: 'enum', + values: ['Iterable'], + }, + selectionMode: { + type: 'enum', + values: ['none', 'single', 'multiple'], + }, + selectedKeys: { + type: 'enum', + values: ['all', 'Iterable'], + }, + defaultSelectedKeys: { + type: 'enum', + values: ['all', 'Iterable'], + }, + placement: { + type: 'enum', + values: placementValues, + }, + virtualized: { + type: 'boolean', + default: 'false', + }, + maxWidth: { + type: 'number', + }, + maxHeight: { + type: 'number', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const menuAutocompletePropDefs: Record = { + placement: { + type: 'enum', + values: placementValues, + }, + virtualized: { + type: 'boolean', + default: 'false', + }, + maxWidth: { + type: 'number', + }, + maxHeight: { + type: 'number', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const menuAutocompleteListboxPropDefs: Record = { + placement: { + type: 'enum', + values: placementValues, + }, + virtualized: { + type: 'boolean', + default: 'false', + }, + maxWidth: { + type: 'number', + }, + maxHeight: { + type: 'number', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const menuItemPropDefs: Record = { + id: { + type: 'enum', + values: ['Key'], + }, + value: { + type: 'string', + }, + textValue: { + type: 'string', + }, + isDisabled: { + type: 'boolean', + }, + href: { + type: 'string', + }, + onAction: { + type: 'enum', + values: ['(event) => void'], + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const menuListBoxItemPropDefs: Record = { + id: { + type: 'enum', + values: ['Key'], + }, + value: { + type: 'string', + }, + textValue: { + type: 'string', + }, + isDisabled: { + type: 'boolean', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const menuSectionPropDefs: Record = { + title: { + type: 'string', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const menuSeparatorPropDefs: Record = { + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const usage = `import { MenuTrigger, Menu, MenuItem } from '@backstage/ui'; + + + + + Apple + Banana + Blueberry + + + Vegetables + + Carrot + Tomato + Potato + + + +`; + +export const preview = ` + + + {options.map(option => ( + {option.label} + ))} + +`; + +export const submenu = ` + + + Edit + Duplicate + + Submenu + + Edit + Duplicate + Rename + + Share + Move + + }>Feedback + + + +`; + +export const icons = ` + + + }>Copy + }>Rename + }>Send feedback + +`; + +export const sections = ` + + + + }>Profile + }>Settings + + + }>Help Center + }> + Contact Support + + }>Feedback + + +`; + +export const separators = ` + + + Edit + Duplicate + Rename + + Share + Move + + }>Feedback + +`; + +export const links = ` + + + Internal link + + External link + + Email link + +`; + +export const autocomplete = ` + + + Create new file... + Create new folder... + Assign to... + Assign to me + Change status... + Change priority... + Add label... + Remove label... + +`; + +export const autocompleteListbox = `const [selected, setSelected] = useState( + new Set(['blueberry']), +); + + + Selected: {Array.from(selected).join(', ')} + + + + {options.map(option => ( + + {option.label} + + ))} + + +`; + +export const autocompleteListboxMultiple = `const [selected, setSelected] = useState( + new Set(['blueberry', 'cherry']), +); + + + Selected: {Array.from(selected).join(', ')} + + + + {options.map(option => ( + + {option.label} + + ))} + + +`; diff --git a/docs-ui/src/content/password-field.mdx b/docs-ui/src/content/password-field.mdx new file mode 100644 index 0000000000..14fbc9e34d --- /dev/null +++ b/docs-ui/src/content/password-field.mdx @@ -0,0 +1,64 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { PasswordFieldSnippet } from '@/snippets/stories-snippets'; +import { + inputPropDefs, + passwordFieldUsageSnippet, + passwordFieldDefaultSnippet, + passwordFieldSizesSnippet, + passwordFieldDescriptionSnippet, +} from './password-field.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { CodeBlock } from '@/components/CodeBlock'; + + + +} + code={passwordFieldDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### Sizes + +We support two different sizes: `small`, `medium`. + +} + code={passwordFieldSizesSnippet} +/> + +### With description + +Here's a simple PasswordField with a description. + +} + code={passwordFieldDescriptionSnippet} +/> + + + + diff --git a/docs-ui/src/content/password-field.props.ts b/docs-ui/src/content/password-field.props.ts new file mode 100644 index 0000000000..493405b5fd --- /dev/null +++ b/docs-ui/src/content/password-field.props.ts @@ -0,0 +1,43 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const inputPropDefs: Record = { + size: { + type: 'enum', + values: ['small', 'medium'], + default: 'small', + responsive: true, + }, + label: { + type: 'string', + }, + icon: { + type: 'enum', + values: ['ReactNode'], + }, + description: { + type: 'string', + }, + name: { + type: 'string', + required: true, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const passwordFieldUsageSnippet = `import { PasswordField } from '@backstage/ui'; + +`; + +export const passwordFieldDefaultSnippet = ``; + +export const passwordFieldSizesSnippet = ` + } /> + } /> +`; + +export const passwordFieldDescriptionSnippet = ``; diff --git a/docs-ui/src/content/radio-group.mdx b/docs-ui/src/content/radio-group.mdx new file mode 100644 index 0000000000..ab3d28ad81 --- /dev/null +++ b/docs-ui/src/content/radio-group.mdx @@ -0,0 +1,104 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { RadioGroupSnippet } from '@/snippets/stories-snippets'; +import { + radioGroupPropDefs, + radioGroupUsageSnippet, + radioGroupDefaultSnippet, + radioGroupDescriptionSnippet, + radioGroupHorizontalSnippet, + radioGroupDisabledSnippet, + radioGroupDisabledSingleSnippet, + radioGroupValidationSnippet, + radioGroupReadOnlySnippet, +} from './radio-group.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { CodeBlock } from '@/components/CodeBlock'; + + + +} + code={radioGroupDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### Horizontal + +Here's a simple TextField with a description. + +} + code={radioGroupHorizontalSnippet} +/> + +### Disabled + +You can disable the entire radio group by adding the `isDisabled` prop to the `RadioGroup` component. + +} + code={radioGroupDisabledSnippet} +/> + +### Disabled Single radio + +You can disable a single radio by adding the `isDisabled` prop to the `Radio` component. + +} + code={radioGroupDisabledSingleSnippet} +/> + +### Validation + +Here's an example of a radio group with errors. + +} + code={radioGroupValidationSnippet} +/> + +### Read only + +You can make the radio group read only by adding the `isReadOnly` prop to the `RadioGroup` component. + +} + code={radioGroupReadOnlySnippet} +/> + + + + diff --git a/docs-ui/src/content/radio-group.props.ts b/docs-ui/src/content/radio-group.props.ts new file mode 100644 index 0000000000..3ed08f1053 --- /dev/null +++ b/docs-ui/src/content/radio-group.props.ts @@ -0,0 +1,64 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const radioGroupPropDefs: Record = { + size: { + type: 'enum', + values: ['small', 'medium'], + default: 'small', + responsive: true, + }, + label: { + type: 'string', + }, + icon: { + type: 'enum', + values: ['ReactNode'], + }, + description: { + type: 'string', + }, + name: { + type: 'string', + required: true, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const radioGroupUsageSnippet = `import { RadioGroup } from '@backstage/ui'; + +`; + +export const radioGroupDefaultSnippet = ``; + +export const radioGroupDescriptionSnippet = ``; + +export const radioGroupHorizontalSnippet = ``; + +export const radioGroupDisabledSnippet = ` + Bulbasaur + Charmander + Squirtle +`; + +export const radioGroupDisabledSingleSnippet = ` + Bulbasaur + Charmander + Squirtle +`; + +export const radioGroupValidationSnippet = ` (value === \'charmander\' ? \'Nice try!\' : null)> + Bulbasaur + Charmander + Squirtle +`; + +export const radioGroupReadOnlySnippet = ` + Bulbasaur + Charmander + Squirtle +`; diff --git a/docs-ui/src/content/search-field.mdx b/docs-ui/src/content/search-field.mdx new file mode 100644 index 0000000000..2a2d93f262 --- /dev/null +++ b/docs-ui/src/content/search-field.mdx @@ -0,0 +1,77 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { SearchFieldSnippet } from '@/snippets/stories-snippets'; +import { + searchFieldPropDefs, + searchFieldUsageSnippet, + searchFieldDefaultSnippet, + searchFieldSizesSnippet, + searchFieldDescriptionSnippet, + searchFieldCollapsibleSnippet, +} from './search-field.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { CodeBlock } from '@/components/CodeBlock'; + + + +} + code={searchFieldDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### Sizes + +We support two different sizes: `small`, `medium`. + +} + code={searchFieldSizesSnippet} +/> + +### With description + +Here's a simple SearchField with a description. + +} + code={searchFieldDescriptionSnippet} +/> + +### Collapsible + +You can make the SearchField collapsible by setting the `startCollapsed` prop to `true`. + +} + code={searchFieldCollapsibleSnippet} +/> + + + + diff --git a/docs-ui/src/content/search-field.props.ts b/docs-ui/src/content/search-field.props.ts new file mode 100644 index 0000000000..b11ae3931c --- /dev/null +++ b/docs-ui/src/content/search-field.props.ts @@ -0,0 +1,49 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const searchFieldPropDefs: Record = { + size: { + type: 'enum', + values: ['small', 'medium'], + default: 'small', + responsive: true, + }, + label: { + type: 'string', + }, + icon: { + type: 'enum', + values: ['ReactNode'], + }, + description: { + type: 'string', + }, + name: { + type: 'string', + required: true, + }, + startCollapsed: { + type: 'boolean', + default: 'false', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const searchFieldUsageSnippet = `import { SearchField } from '@backstage/ui'; + +`; + +export const searchFieldDefaultSnippet = ``; + +export const searchFieldSizesSnippet = ` + } /> + } /> +`; + +export const searchFieldDescriptionSnippet = ``; + +export const searchFieldCollapsibleSnippet = ``; diff --git a/docs-ui/src/content/select.mdx b/docs-ui/src/content/select.mdx new file mode 100644 index 0000000000..09a852e871 --- /dev/null +++ b/docs-ui/src/content/select.mdx @@ -0,0 +1,98 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { SelectSnippet } from '@/snippets/stories-snippets'; +import { + selectPropDefs, + selectUsageSnippet, + selectDefaultSnippet, + selectDescriptionSnippet, + selectSizesSnippet, + selectDisabledSnippet, + selectResponsiveSnippet, + selectIconSnippet, +} from './select.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={selectDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### With Label and description + +Select component with label and description. + +} + code={selectDescriptionSnippet} +/> + +### Sizes + +Here's a view when the selects have different sizes. + +} + code={selectSizesSnippet} +/> + +### With Icon + +Here's a view when the select has an icon. + +} +code={selectIconSnippet} +/> + +### Disabled + +Here's a view when the select is disabled. + +} + code={selectDisabledSnippet} +/> + +### Responsive + +Here's a view when the select is responsive. + + + + + + diff --git a/docs-ui/src/content/select.props.ts b/docs-ui/src/content/select.props.ts new file mode 100644 index 0000000000..a93f448bd8 --- /dev/null +++ b/docs-ui/src/content/select.props.ts @@ -0,0 +1,153 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const selectPropDefs: Record = { + label: { + type: 'string', + responsive: false, + }, + description: { + type: 'string', + responsive: false, + }, + name: { + type: 'string', + responsive: false, + required: true, + }, + options: { + type: 'enum', + values: ['Array<{ value: string, label: string }>'], + required: true, + }, + placeholder: { + type: 'string', + default: 'Select an item', + responsive: false, + }, + icon: { + type: 'enum', + values: ['ReactNode'], + responsive: false, + }, + value: { + type: 'string', + responsive: false, + }, + defaultValue: { + type: 'string', + responsive: false, + }, + size: { + type: 'enum', + values: ['small', 'medium'], + default: 'medium', + responsive: true, + }, + isOpen: { + type: 'boolean', + responsive: false, + }, + defaultOpen: { + type: 'boolean', + responsive: false, + }, + disabledKeys: { + type: 'enum', + values: ['string[]'], + responsive: false, + }, + isDisabled: { + type: 'boolean', + responsive: false, + }, + isRequired: { + type: 'boolean', + responsive: false, + }, + isInvalid: { + type: 'boolean', + responsive: false, + }, + selectedKey: { + type: 'string', + responsive: false, + }, + defaultSelectedKey: { + type: 'string', + responsive: false, + }, + onOpenChange: { + type: 'enum', + values: ['(isOpen: boolean) => void'], + responsive: false, + }, + onSelectionChange: { + type: 'enum', + values: ['(key: Key | null) => void'], + responsive: false, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const selectUsageSnippet = `import { Select } from '@backstage/ui'; + +`; + +export const selectDescriptionSnippet = `} + options={[ ... ]} +/>`; + +export const selectSizesSnippet = ` + +`; + +export const selectDisabledSnippet = ``; diff --git a/docs-ui/src/content/skeleton.mdx b/docs-ui/src/content/skeleton.mdx new file mode 100644 index 0000000000..f0d3fbc39a --- /dev/null +++ b/docs-ui/src/content/skeleton.mdx @@ -0,0 +1,64 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { SkeletonSnippet } from '@/snippets/stories-snippets'; +import { + skeletonPropDefs, + skeletonUsageSnippet, + skeletonDefaultSnippet, + skeletonDemo1Snippet, + skeletonDemo2Snippet, +} from './skeleton.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={skeletonDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### Demo 1 + +You can use a mix of different sizes to create a more complex skeleton. + +} + code={skeletonDemo1Snippet} + open +/> + +### Demo 2 + +You can use a mix of different sizes to create a more complex skeleton. + +} + code={skeletonDemo2Snippet} + open +/> + + + + diff --git a/docs-ui/src/content/skeleton.props.ts b/docs-ui/src/content/skeleton.props.ts new file mode 100644 index 0000000000..ab79268d15 --- /dev/null +++ b/docs-ui/src/content/skeleton.props.ts @@ -0,0 +1,58 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const skeletonPropDefs: Record = { + width: { + type: 'number', + default: '80', + responsive: false, + }, + height: { + type: 'number', + default: '24', + responsive: false, + }, + rounded: { + type: 'boolean', + default: 'false', + responsive: false, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const skeletonUsageSnippet = `import { Flex, Skeleton } from '@backstage/ui'; + + + + + +`; + +export const skeletonDefaultSnippet = ` + + + +`; + +export const skeletonDemo1Snippet = ` + + + + + + + + + + +`; + +export const skeletonDemo2Snippet = ` + + + +`; diff --git a/docs-ui/src/content/switch.mdx b/docs-ui/src/content/switch.mdx new file mode 100644 index 0000000000..acf588e37d --- /dev/null +++ b/docs-ui/src/content/switch.mdx @@ -0,0 +1,46 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { SwitchSnippet } from '@/snippets/stories-snippets'; +import { switchPropDefs, snippetUsage } from './switch.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={``} +/> + +## Usage + + + +## API reference + + + +## Examples + +### Disabled + +A switch can be disabled using the `isDisabled` prop. + +} + code={``} +/> + + + + diff --git a/docs-ui/src/content/switch.props.ts b/docs-ui/src/content/switch.props.ts new file mode 100644 index 0000000000..5576436102 --- /dev/null +++ b/docs-ui/src/content/switch.props.ts @@ -0,0 +1,71 @@ +import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs'; +import type { PropDef } from '@/utils/propDefs'; + +export const switchPropDefs: Record = { + autoFocus: { + type: 'boolean', + }, + defaultSelected: { + type: 'boolean', + }, + ...classNamePropDefs, + isDisabled: { + type: 'boolean', + }, + isReadOnly: { + type: 'boolean', + }, + isSelected: { + type: 'boolean', + }, + label: { + type: 'string', + }, + name: { + type: 'string', + }, + onChange: { + type: 'enum', + values: ['(isSelected: boolean) => void'], + }, + onFocus: { + type: 'enum', + values: ['(e: FocusEvent) => void'], + }, + onBlur: { + type: 'enum', + values: ['(e: FocusEvent) => void'], + }, + onFocusChange: { + type: 'enum', + values: ['(isFocused: boolean) => void'], + }, + onKeyDown: { + type: 'enum', + values: ['(e: KeyboardEvent) => void'], + }, + onKeyUp: { + type: 'enum', + values: ['(e: KeyboardEvent) => void'], + }, + onHoverStart: { + type: 'enum', + values: ['(e: HoverEvent) => void'], + }, + onHoverEnd: { + type: 'enum', + values: ['(e: HoverEvent) => void'], + }, + onHoverChange: { + type: 'enum', + values: ['(isHovered: boolean) => void'], + }, + ...stylePropDefs, + value: { + type: 'string', + }, +}; + +export const snippetUsage = `import { Switch } from '@backstage/ui'; + +`; diff --git a/docs-ui/src/content/table.mdx b/docs-ui/src/content/table.mdx new file mode 100644 index 0000000000..4ea5fd1677 --- /dev/null +++ b/docs-ui/src/content/table.mdx @@ -0,0 +1,133 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { TableSnippet } from '@/snippets/stories-snippets'; +import { + tablePropDefs, + tableHeaderPropDefs, + tableBodyPropDefs, + tablePaginationPropDefs, + tableUsageSnippet, + tableBasicSnippet, + tableRowClickSnippet, + tableHybridSnippet, + tableCellInteractionsSnippet, + tablePaginationSnippet, + tableSelectionSnippet, + tableSortingSnippet, + columnPropDefs, + rowPropDefs, + cellPropDefs, +} from './table.props'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; + + + +} + code={tableBasicSnippet} +/> + +## Usage + + + +## API reference + +### Table + +The main table component that renders data in a structured grid format. + + + +### TableHeader + +The header section of the table that contains the column definitions. + + + +### Column + +A column definition that describes how a column should be rendered. + + + +### TableBody + +The body section of the table that contains the rows. + + + +### Row + +A row definition that describes how a row should be rendered. + + + +### Cell + +A cell definition that describes how a cell should be rendered. + + + +### TablePagination + +A pagination component designed to work with the Table component. + + + +## Examples + +### Basic Table + +Coming soon. + +### Row selection + +Coming soon. + +### Row Clicks + +Coming soon. + +### Pagination + +Coming soon. + +### Sorting + +Coming soon. + +### Asynchronous loading + +Coming soon. + +### Empty state + +Coming soon. + +### Column resizing + +This feature is not available yet — let us know if you'd like us to explore it! + +### Column reordering + +This feature is not available yet — let us know if you'd like us to explore it! + +### Column pinning + +This feature is not available yet — let us know if you'd like us to explore it! + +### Column visibility + +This feature is not available yet — let us know if you'd like us to explore it! + + + + diff --git a/docs-ui/src/content/table.props.ts b/docs-ui/src/content/table.props.ts new file mode 100644 index 0000000000..443526182e --- /dev/null +++ b/docs-ui/src/content/table.props.ts @@ -0,0 +1,328 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const tablePropDefs: Record = { + selectionBehavior: { + type: 'enum', + values: ['toggle', 'replace'], + default: 'toggle', + description: 'How multiple selection should behave in the collection.', + }, + disabledBehavior: { + type: 'enum', + values: ['selection', 'all'], + default: 'selection', + description: + 'Whether disabledKeys applies to all interactions, or only selection.', + }, + disabledKeys: { + type: 'enum', + values: ['Iterable'], + description: 'A list of row keys to disable.', + }, + selectionMode: { + type: 'enum', + values: ['single', 'multiple'], + description: 'The type of selection that is allowed in the collection.', + }, + selectedKeys: { + type: 'enum', + values: ['all', 'Iterable'], + description: 'The currently selected keys in the collection (controlled).', + }, + defaultSelectedKeys: { + type: 'enum', + values: ['all', 'Iterable'], + description: 'The initial selected keys in the collection (uncontrolled).', + }, + onRowAction: { + type: 'enum', + values: ['(key: Key) => void'], + description: + 'Handler that is called when a user performs an action on the row.', + }, + onSelectionChange: { + type: 'enum', + values: ['(keys: Selection) => void'], + description: 'Handler that is called when the selection changes.', + }, + onSortChange: { + type: 'enum', + values: ['(descriptor: SortDescriptor) => any'], + description: + 'Handler that is called when the sorted column or direction changes.', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const tableHeaderPropDefs: Record = { + onHoverStart: { + type: 'enum', + values: ['(e: HoverEvent) => void'], + description: 'Handler that is called when a hover interaction starts.', + }, + onHoverEnd: { + type: 'enum', + values: ['(e: HoverEvent) => void'], + description: 'Handler that is called when a hover interaction ends.', + }, + onHoverChange: { + type: 'enum', + values: ['(isHovering: boolean) => void'], + description: 'Handler that is called when the hover state changes.', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const columnPropDefs: Record = { + id: { + type: 'enum', + values: ['Key'], + description: 'The unique id of the column.', + }, + allowsSorting: { + type: 'boolean', + description: 'Whether the column allows sorting.', + }, + isRowHeader: { + type: 'boolean', + description: + 'Whether a column is a row header and should be announced by assistive technology during row navigation.', + }, + textValue: { + type: 'string', + description: + "A string representation of the column's contents, used for accessibility announcements.", + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const tableBodyPropDefs: Record = { + renderEmptyState: { + type: 'enum', + values: ['(props) => ReactNode'], + description: + 'Provides content to display when there are no rows in the table.', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const rowPropDefs: Record = { + textValue: { + type: 'string', + description: + "A string representation of the row's contents, used for accessibility announcements.", + }, + isDisabled: { + type: 'boolean', + description: 'Whether the row is disabled.', + }, + id: { + type: 'enum', + values: ['Key'], + description: 'The unique id of the row.', + }, + href: { + type: 'string', + description: 'The URL to navigate to when the row is clicked.', + }, + hrefLang: { + type: 'string', + description: + 'The language of the URL to navigate to when the row is clicked.', + }, + target: { + type: 'string', + description: + 'The target of the URL to navigate to when the row is clicked.', + }, + rel: { + type: 'string', + description: + 'The relationship of the URL to navigate to when the row is clicked.', + }, + onAction: { + type: 'enum', + values: ['() => void'], + description: + "Handler that is called when a user performs an action on the row. The exact user event depends on the collection's selectionBehavior prop and the interaction modality.", + }, + onHoverStart: { + type: 'enum', + values: ['(e: HoverEvent) => void'], + description: 'Handler that is called when a hover interaction starts.', + }, + onHoverEnd: { + type: 'enum', + values: ['(e: HoverEvent) => void'], + description: 'Handler that is called when a hover interaction ends.', + }, + onHoverChange: { + type: 'enum', + values: ['(isHovering: boolean) => void'], + description: 'Handler that is called when the hover state changes.', + }, + onPress: { + type: 'enum', + values: ['(e: PressEvent) => void'], + description: + 'Handler that is called when the press is released over the target.', + }, + onPressStart: { + type: 'enum', + values: ['(e: PressEvent) => void'], + description: 'Handler that is called when a press interaction starts.', + }, + onPressEnd: { + type: 'enum', + values: ['(e: PressEvent) => void'], + description: + 'Handler that is called when a press interaction ends, either over the target or when the pointer leaves the target.', + }, + onPressChange: { + type: 'enum', + values: ['(isPressed: boolean) => void'], + description: 'Handler that is called when the press state changes.', + }, + onPressUp: { + type: 'enum', + values: ['(e: PressEvent) => void'], + description: + 'Handler that is called when a press is released over the target, regardless of whether it started on the target or not.', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const cellPropDefs: Record = { + id: { + type: 'enum', + values: ['Key'], + description: 'The unique id of the cell.', + }, + textValue: { + type: 'string', + description: + "A string representation of the cell's contents, used for features like typeahead.", + }, + leadingIcon: { + type: 'enum', + values: ['ReactNode'], + description: 'Optional icon to display before the cell content.', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const tablePaginationPropDefs: Record = { + offset: { + type: 'number', + description: 'The current offset (starting index) for pagination.', + }, + pageSize: { + type: 'number', + description: 'The number of items per page.', + }, + setOffset: { + type: 'enum', + values: ['(offset: number) => void'], + description: 'Handler that is called when the offset changes.', + }, + setPageSize: { + type: 'enum', + values: ['(pageSize: number) => void'], + description: 'Handler that is called when the page size changes.', + }, + rowCount: { + type: 'number', + description: 'The total number of rows in the table.', + }, + onNextPage: { + type: 'enum', + values: ['() => void'], + description: 'Handler that is called when the next page is requested.', + }, + onPreviousPage: { + type: 'enum', + values: ['() => void'], + description: 'Handler that is called when the previous page is requested.', + }, + onPageSizeChange: { + type: 'enum', + values: ['(pageSize: number) => void'], + description: 'Handler that is called when the page size changes.', + }, + showPageSizeOptions: { + type: 'boolean', + description: 'Whether to show the page size options.', + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const tableUsageSnippet = `import { Cell, ..., TableHeader, TablePagination } from '@backstage/ui'; + + + + + + + + + + + +
+`; + +export const tableBasicSnippet = `import { Table, TableHeader, Column, TableBody, Row, Cell, CellProfile, TablePagination, useTable } from '@backstage/ui'; + +const data = [ + { + name: 'The Beatles', + image: 'https://upload.wikimedia.org/wikipedia/en/thumb/4/42/Beatles_-...jpg', + genre: 'Rock, Pop, Psychedelic Rock', + yearFormed: 1960, + albums: 13 + }, + // ... more data +]; + +// Uncontrolled pagination (easiest) +const { data: paginatedData, paginationProps } = useTable({ + data, + pagination: { + defaultPageSize: 5, + }, +}); + + + + Band name + Genre + Year formed + Albums + + + {paginatedData?.map(item => ( + + + + + + + ))} + +
+`; diff --git a/docs-ui/src/content/tabs.mdx b/docs-ui/src/content/tabs.mdx new file mode 100644 index 0000000000..26905d4733 --- /dev/null +++ b/docs-ui/src/content/tabs.mdx @@ -0,0 +1,84 @@ +import { PropsTable } from '@/components/PropsTable'; +import { TabsSnippet } from '@/snippets/stories-snippets'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { + tabsPropDefs, + tabPropDefs, + tabsUsageSnippet, + tabsDefaultSnippet, + tabsWithTabPanelsSnippet, + tabsWithLinksSnippet, + tabsWithDeeplyNestedRoutesSnippet, +} from './tabs.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={tabsDefaultSnippet} +/> + +## Usage + + + +## API reference + +### Tabs + +Groups the tabs and the corresponding panels. Renders a `
` element. + + + +### Tab + +An individual interactive tab button that toggles the corresponding panel. Renders a ` + I am a tooltip +`; + +export const tooltipDefaultSnippet = ` + + I am a tooltip +`; diff --git a/docs-ui/src/content/visually-hidden.mdx b/docs-ui/src/content/visually-hidden.mdx new file mode 100644 index 0000000000..26a609b245 --- /dev/null +++ b/docs-ui/src/content/visually-hidden.mdx @@ -0,0 +1,51 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { VisuallyHiddenSnippet } from '@/snippets/stories-snippets'; +import { + visuallyHiddenPropDefs, + visuallyHiddenUsageSnippet, + visuallyHiddenDefaultSnippet, + visuallyHiddenExampleUsageSnippet, +} from './visually-hidden.props'; +import { PageTitle } from '@/components/PageTitle'; +import { Theming } from '@/components/Theming'; +import { ChangelogComponent } from '@/components/ChangelogComponent'; + + + +} + code={visuallyHiddenDefaultSnippet} +/> + +## Usage + + + +## API reference + + + +## Examples + +### Example Usage + +Here's an example of providing screen reader context for a list of links in a footer. + +} + code={visuallyHiddenExampleUsageSnippet} + open +/> + + + + diff --git a/docs-ui/src/content/visually-hidden.props.ts b/docs-ui/src/content/visually-hidden.props.ts new file mode 100644 index 0000000000..18a1c503d1 --- /dev/null +++ b/docs-ui/src/content/visually-hidden.props.ts @@ -0,0 +1,47 @@ +import { + classNamePropDefs, + stylePropDefs, + type PropDef, +} from '@/utils/propDefs'; + +export const visuallyHiddenPropDefs: Record = { + children: { + type: 'enum', + values: ['ReactNode'], + responsive: false, + }, + ...classNamePropDefs, + ...stylePropDefs, +}; + +export const visuallyHiddenUsageSnippet = `import { VisuallyHidden } from '@backstage/ui'; + + + This content is visually hidden but accessible to screen readers +`; + +export const visuallyHiddenDefaultSnippet = ` + + This text is followed by a paragraph that is visually hidden but + accessible to screen readers. Try using a screen reader to hear it, or + inspect the DOM to see it's there. + + + This content is visually hidden but accessible to screen readers + +`; + +export const visuallyHiddenExampleUsageSnippet = ` + + Footer links + + + About us + + + Jobs + + + Terms and Conditions + +`; diff --git a/canon-docs/src/css/globals.css b/docs-ui/src/css/globals.css similarity index 58% rename from canon-docs/src/css/globals.css rename to docs-ui/src/css/globals.css index 21f55587d1..dcc348a9ee 100644 --- a/canon-docs/src/css/globals.css +++ b/docs-ui/src/css/globals.css @@ -1,8 +1,9 @@ :root { - --bg: #f8f8f8; - --panel: #fff; + --bg: #ffffff; + --bg-hover: #fafafa; --primary: #000; - --secondary: #757575; + --secondary: #929292; + --action: #f3f3f3; --link: #4f5ce0; --font-regular: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', @@ -11,25 +12,31 @@ 'Courier New', monospace; --font-weight-regular: 400; --font-weight-bold: 600; - --border: rgba(0, 0, 0, 0.1); + --border: #e5e5e5; + --border2: #cdcdcd; + --surface-1: #f4f4f4; + --code-bg: #3e444f; + --code-title: #505865; } -[data-theme='dark'] { - --bg: #000; - --panel: #222222; +[data-theme-mode='dark'] { + --bg: #000000; + --bg-hover: #202020; + --code-bg: #202020; + --code-title: #292929; --primary: #fff; - --secondary: #9e9e9e; + --secondary: #818181; + --action: #202020; --link: #4856e8; - --border: rgba(255, 255, 255, 0.1); + --border: #2a2a2a; + --border2: #2a2a2a; + --surface-1: #282828; } body { - display: flex; - flex-direction: row; background-color: var(--bg); color: var(--primary); font-family: var(--font-regular); - transition: background-color 0.2s ease-in-out; } iframe { @@ -43,14 +50,15 @@ iframe { .shiki, .shiki span { - background-color: transparent !important; + background-color: transparent; font-family: var(--font-mono); font-size: 0.875rem; line-height: 1.7; + padding-block: 0.2rem; } -[data-theme='dark'] .shiki, -[data-theme='dark'] .shiki span { +[data-theme-mode='dark'] .shiki, +[data-theme-mode='dark'] .shiki span { color: var(--shiki-dark) !important; /* Optional, if you also want font styles */ font-style: var(--shiki-dark-font-style) !important; @@ -58,6 +66,36 @@ iframe { text-decoration: var(--shiki-dark-text-decoration) !important; } +/* Add styles for diff notation */ +pre.shiki.has-diff .line.diff { + position: relative; + padding-left: 1.5rem; + border-radius: 0.25rem; +} + +pre.shiki.has-diff .line.diff::before { + position: absolute; + left: 0.5rem; +} + +pre.shiki.has-diff .line.diff.add { + background-color: rgba(46, 160, 67, 0.15); +} + +pre.shiki.has-diff .line.diff.add::before { + content: '+'; + color: #2ea043; +} + +pre.shiki.has-diff .line.diff.remove { + background-color: rgba(248, 81, 73, 0.15); +} + +pre.shiki.has-diff .line.diff.remove::before { + content: '-'; + color: #f85149; +} + .cm-editor { transition: background-color 0.2s ease-in-out; } diff --git a/canon-docs/src/css/mdx.module.css b/docs-ui/src/css/mdx.module.css similarity index 52% rename from canon-docs/src/css/mdx.module.css rename to docs-ui/src/css/mdx.module.css index 4900455504..7cc2422ecd 100644 --- a/canon-docs/src/css/mdx.module.css +++ b/docs-ui/src/css/mdx.module.css @@ -1,8 +1,9 @@ .h1 { - font-size: 2.5rem; - margin-top: 4rem; - margin-bottom: 1.5rem; + font-size: 3rem; + margin-top: 0; + margin-bottom: 1.25rem; color: var(--primary); + font-weight: 400; } .h2 { @@ -10,6 +11,7 @@ margin-top: 3rem; margin-bottom: 1.5rem; color: var(--primary); + font-weight: 400; } .h3 { @@ -17,6 +19,7 @@ margin-top: 2rem; margin-bottom: 0.5rem; color: var(--primary); + font-weight: 400; } .p { @@ -35,6 +38,7 @@ .li { color: var(--secondary); margin-bottom: 0.5rem; + line-height: 1.5; } .a { @@ -45,3 +49,27 @@ .a:hover { text-decoration: underline; } + +.headingWithAnchor { + position: relative; + scroll-margin-top: 80px; +} + +.anchorLink { + color: inherit; + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 0.5rem; +} + +.anchorHash { + opacity: 0; + transition: opacity 0.2s; + font-size: 0.8em; + color: var(--text-secondary); +} + +.anchorLink:hover .anchorHash { + opacity: 1; +} diff --git a/docs-ui/src/hooks/useCurrentPage.ts b/docs-ui/src/hooks/useCurrentPage.ts new file mode 100644 index 0000000000..1f5f978846 --- /dev/null +++ b/docs-ui/src/hooks/useCurrentPage.ts @@ -0,0 +1,31 @@ +'use client'; + +import { usePathname } from 'next/navigation'; +import { getPageName } from '@/utils/getPageName'; + +export function useCurrentPage(): string | null { + const pathname = usePathname(); + + // Handle root path + if (pathname === '/') { + return 'Getting Started'; + } + + // Extract slug from various path patterns + const patterns = [ + /^\/components\/(.+)$/, // /components/button + /^\/theme\/(.+)$/, // /theme/typography + /^\/about$/, // /about + /^\/changelog$/, // /changelog + ]; + + for (const pattern of patterns) { + const match = pathname.match(pattern); + if (match) { + const slug = match[1] || pathname.slice(1); // Use full path for exact matches + return getPageName(slug); + } + } + + return null; +} diff --git a/docs-ui/src/mdx-components.tsx b/docs-ui/src/mdx-components.tsx new file mode 100644 index 0000000000..bae798bf7c --- /dev/null +++ b/docs-ui/src/mdx-components.tsx @@ -0,0 +1,107 @@ +import { isValidElement, ReactNode } from 'react'; +import type { MDXComponents } from 'mdx/types'; +import Image, { ImageProps } from 'next/image'; +import { CodeBlock } from '@/components/CodeBlock'; +import styles from './css/mdx.module.css'; + +// Utility function to generate slug from heading text +function slugify(text: string): string { + return text + .toString() + .toLocaleLowerCase('en-US') + .trim() + .replace(/\s+/g, '-') + .replace(/[^\w\-]+/g, '') + .replace(/\-\-+/g, '-') + .replace(/^-+/, '') + .replace(/-+$/, ''); +} + +// Component for heading with anchor link +function HeadingWithAnchor({ + level, + children, + className, +}: { + level: number; + children: ReactNode; + className: string; +}) { + const text = + typeof children === 'string' + ? children + : Array.isArray(children) + ? children.join('') + : ''; + const id = slugify(text); + + const Tag = `h${level}` as keyof JSX.IntrinsicElements; + + return ( + + + {children} + # + + + ); +} + +export const formattedMDXComponents: MDXComponents = { + h1: ({ children }) =>

{children as ReactNode}

, + h2: ({ children }) => ( + + {children as ReactNode} + + ), + h3: ({ children }) => ( + + {children as ReactNode} + + ), + p: ({ children }) =>

{children as ReactNode}

, + a: ({ children, href }) => ( + + {children as ReactNode} + + ), + ul: ({ children }) =>
    {children as ReactNode}
, + li: ({ children }) =>
  • {children as ReactNode}
  • , + pre: ({ children }) => { + const codeContent = isValidElement(children) + ? (children.props as { children: string }).children + : ''; + + return ; + }, + code: ({ children }) => ( + + {children} + + ), + img: ({ src, ...rest }) => ( + )} + /> + ), +}; + +export function useMDXComponents(components: MDXComponents): MDXComponents { + return { + ...formattedMDXComponents, + ...components, + }; +} diff --git a/docs-ui/src/snippets/code-snippets.ts b/docs-ui/src/snippets/code-snippets.ts new file mode 100644 index 0000000000..1a22a24340 --- /dev/null +++ b/docs-ui/src/snippets/code-snippets.ts @@ -0,0 +1,32 @@ +// Sometimes codes are not formatted correctly in the docs, so we need to use snippets + +export const customTheme = `:root { + --bui-font-regular: system-ui; + --bui-font-weight-regular: 400; + --bui-font-weight-bold: 600; + --bui-bg: #f8f8f8; + --bui-bg-surface-1: #fff; + /* ... other CSS variables */ + + /* Add your custom components styles here */ + .bui-Button { + background-color: #000; + color: #fff; + } +} + +[data-theme-mode='dark'] { + --bui-font-regular: system-ui; + --bui-font-weight-regular: 400; + --bui-font-weight-bold: 600; + --bui-bg: #f8f8f8; + --bui-bg-surface-1: #fff; + /* ... other CSS variables */ + + /* Add your custom components styles here */ + .bui-Button { + background-color: #000; + color: #fff; + } +} +`; diff --git a/docs-ui/src/snippets/stories-snippets.tsx b/docs-ui/src/snippets/stories-snippets.tsx new file mode 100644 index 0000000000..0cb6119ce6 --- /dev/null +++ b/docs-ui/src/snippets/stories-snippets.tsx @@ -0,0 +1,80 @@ +'use client'; + +import { composeStories } from '@storybook/react'; +import * as BoxStories from '../../../packages/ui/src/components/Box/Box.stories'; +import * as ButtonStories from '../../../packages/ui/src/components/Button/Button.stories'; +import * as ButtonIconStories from '../../../packages/ui/src/components/ButtonIcon/ButtonIcon.stories'; +import * as ButtonLinkStories from '../../../packages/ui/src/components/ButtonLink/ButtonLink.stories'; +import * as CheckboxStories from '../../../packages/ui/src/components/Checkbox/Checkbox.stories'; +import * as ContainerStories from '../../../packages/ui/src/components/Container/Container.stories'; +import * as GridStories from '../../../packages/ui/src/components/Grid/Grid.stories'; +import * as TextFieldStories from '../../../packages/ui/src/components/TextField/TextField.stories'; +import * as TextStories from '../../../packages/ui/src/components/Text/Text.stories'; +import * as FlexStories from '../../../packages/ui/src/components/Flex/Flex.stories'; +import * as SelectStories from '../../../packages/ui/src/components/Select/Select.stories'; +import * as MenuStories from '../../../packages/ui/src/components/Menu/Menu.stories'; +import * as LinkStories from '../../../packages/ui/src/components/Link/Link.stories'; +import * as AvatarStories from '../../../packages/ui/src/components/Avatar/Avatar.stories'; +import * as AccordionStories from '../../../packages/ui/src/components/Accordion/Accordion.stories'; +import * as DialogStories from '../../../packages/ui/src/components/Dialog/Dialog.stories'; +import * as RadioGroupStories from '../../../packages/ui/src/components/RadioGroup/RadioGroup.stories'; +import * as TabsStories from '../../../packages/ui/src/components/Tabs/Tabs.stories'; +import * as SwitchStories from '../../../packages/ui/src/components/Switch/Switch.stories'; +import * as SearchFieldStories from '../../../packages/ui/src/components/SearchField/SearchField.stories'; +import * as TooltipStories from '../../../packages/ui/src/components/Tooltip/Tooltip.stories'; +import * as SkeletonStories from '../../../packages/ui/src/components/Skeleton/Skeleton.stories'; +import * as CardStories from '../../../packages/ui/src/components/Card/Card.stories'; +import * as HeaderStories from '../../../packages/ui/src/components/Header/Header.stories'; +import * as HeaderPageStories from '../../../packages/ui/src/components/HeaderPage/HeaderPage.stories'; +import * as TableStories from '../../../packages/ui/src/components/Table/Table.stories'; +import * as TagGroupStories from '../../../packages/ui/src/components/TagGroup/TagGroup.stories'; +import * as PasswordFieldStories from '../../../packages/ui/src/components/PasswordField/PasswordField.stories'; +import * as VisuallyHiddenStories from '../../../packages/ui/src/components/VisuallyHidden/VisuallyHidden.stories'; + +// Helper function to create snippet components +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const createSnippetComponent = (stories: any) => { + return function SnippetComponent({ story }: { story: string }) { + const composedStories = composeStories(stories); + const StoryComponent = composedStories[ + story as keyof typeof composedStories + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ] as any; + + return StoryComponent ? : null; + }; +}; + +// Create snippet components using the helper function +export const BoxSnippet = createSnippetComponent(BoxStories); +export const ButtonSnippet = createSnippetComponent(ButtonStories); +export const ButtonIconSnippet = createSnippetComponent(ButtonIconStories); +export const ButtonLinkSnippet = createSnippetComponent(ButtonLinkStories); +export const CheckboxSnippet = createSnippetComponent(CheckboxStories); +export const ContainerSnippet = createSnippetComponent(ContainerStories); +export const GridSnippet = createSnippetComponent(GridStories); +export const TextFieldSnippet = createSnippetComponent(TextFieldStories); +export const PasswordFieldSnippet = + createSnippetComponent(PasswordFieldStories); +export const TextSnippet = createSnippetComponent(TextStories); +export const FlexSnippet = createSnippetComponent(FlexStories); +export const SelectSnippet = createSnippetComponent(SelectStories); +export const MenuSnippet = createSnippetComponent(MenuStories); +export const LinkSnippet = createSnippetComponent(LinkStories); +export const AvatarSnippet = createSnippetComponent(AvatarStories); +export const AccordionSnippet = createSnippetComponent(AccordionStories); +export const DialogSnippet = createSnippetComponent(DialogStories); +export const RadioGroupSnippet = createSnippetComponent(RadioGroupStories); +export const TabsSnippet = createSnippetComponent(TabsStories); +export const SwitchSnippet = createSnippetComponent(SwitchStories); +export const SearchFieldSnippet = createSnippetComponent(SearchFieldStories); +export const TooltipSnippet = createSnippetComponent(TooltipStories); +export const SkeletonSnippet = createSnippetComponent(SkeletonStories); +export const CardSnippet = createSnippetComponent(CardStories); +export const HeaderSnippet = createSnippetComponent(HeaderStories); +export const HeaderPageSnippet = createSnippetComponent(HeaderPageStories); +export const TableSnippet = createSnippetComponent(TableStories); +export const TagGroupSnippet = createSnippetComponent(TagGroupStories); +export const VisuallyHiddenSnippet = createSnippetComponent( + VisuallyHiddenStories, +); diff --git a/docs-ui/src/utils/changelog.ts b/docs-ui/src/utils/changelog.ts new file mode 100644 index 0000000000..05a06fdb9f --- /dev/null +++ b/docs-ui/src/utils/changelog.ts @@ -0,0 +1,538 @@ +export type Component = + | 'avatar' + | 'box' + | 'button' + | 'button-link' + | 'heading' + | 'text' + | 'button-icon' + | 'icon' + | 'tabs' + | 'menu' + | 'textfield' + | 'datatable' + | 'select' + | 'collapsible' + | 'accordion' + | 'checkbox' + | 'container' + | 'link' + | 'tooltip' + | 'scrollarea' + | 'flex' + | 'switch' + | 'grid' + | 'searchfield' + | 'radio-group' + | 'card' + | 'skeleton' + | 'header' + | 'passwordfield'; + +export type Version = `${number}.${number}.${number}`; + +export interface ChangelogProps { + components: Component[]; + description: string; + version: Version; + prs: string[]; + type?: 'breaking' | 'new' | 'fix'; +} + +export const changelog: ChangelogProps[] = [ + { + components: ['tooltip'], + version: '0.6.0', + description: 'New `Tooltip` component.', + prs: ['30461'], + type: 'new', + }, + { + components: ['card'], + version: '0.6.0', + description: 'New `Card` component.', + prs: ['30467'], + type: 'new', + }, + { + components: ['header'], + version: '0.6.0', + description: 'New `Header` component.', + prs: ['30410', '30459', '30493'], + type: 'new', + }, + { + components: ['button', 'button-link', 'button-icon'], + version: '0.6.0', + description: 'Improve `Button`, `ButtonIcon` and `ButtonLink` styling.', + prs: ['30448'], + type: 'fix', + }, + { + components: ['text', 'heading'], + version: '0.6.0', + description: + 'Update return types for `Heading` & `Text` components for React 19.', + prs: ['30440'], + type: 'fix', + }, + { + components: ['button', 'button-link', 'button-icon'], + version: '0.6.0', + description: + 'New `tertiary` variant to `Button`, `ButtonIcon` and `ButtonLink`.', + prs: ['30453'], + type: 'new', + }, + { + components: ['skeleton'], + version: '0.6.0', + description: 'New `Skeleton` component.', + prs: ['30466'], + type: 'new', + }, + { + components: ['button-icon'], + version: '0.6.0', + description: 'Rename `IconButton` to `ButtonIcon`.', + prs: ['30297'], + type: 'breaking', + }, + { + components: ['button-link'], + version: '0.6.0', + description: + 'New `ButtonLink`, which replaces the previous render prop pattern on `Button` and `IconButton`.', + prs: ['30297'], + type: 'new', + }, + { + components: ['button', 'button-link', 'button-icon'], + version: '0.6.0', + description: 'Remove the `render` prop from all button-related components.', + prs: ['30297'], + type: 'breaking', + }, + { + components: [], + version: '0.6.0', + description: 'We are consolidating all css files into a single styles.css.', + prs: ['30325'], + type: 'fix', + }, + { + components: ['searchfield'], + version: '0.6.0', + description: 'New `SearchField` component.', + prs: ['30357'], + type: 'new', + }, + { + components: ['radio-group'], + version: '0.6.0', + description: 'New `RadioGroup` + `Radio` component.', + prs: ['30327'], + type: 'new', + }, + { + components: ['textfield'], + version: '0.6.0', + description: 'Added placeholder prop back to `TextField` component.', + prs: ['30286'], + type: 'fix', + }, + { + components: ['textfield'], + version: '0.5.0', + description: '`TextField` now has multiple label sizes.', + prs: ['30249'], + type: 'breaking', + }, + { + components: ['textfield'], + version: '0.5.0', + description: + '`TextField` can now hide label and description while keeping them available for screen readers.', + prs: ['30249'], + type: 'breaking', + }, + { + components: ['textfield'], + version: '0.5.0', + description: + 'We are removing the `render` prop in favour of the `as` prop on `Heading` and `Text`.', + prs: ['30291'], + type: 'breaking', + }, + { + components: ['textfield'], + version: '0.5.0', + description: 'Move `TextField` component to use react Aria under the hood.', + prs: ['30286'], + type: 'breaking', + }, + { + components: ['button', 'button-link'], + version: '0.5.0', + description: + 'Added a render prop to the `Button` component to use it as a link.', + prs: ['30165'], + type: 'new', + }, + { + components: ['heading'], + version: '0.5.0', + description: 'Fix styling for the title4 prop on the Heading component.', + prs: ['30167'], + type: 'fix', + }, + { + components: ['flex'], + version: '0.5.0', + description: + 'Add `min-width: 0;` by default on Flex components to support truncated text.', + prs: ['30168'], + type: 'fix', + }, + { + components: ['button', 'button-link', 'button-icon'], + version: '0.5.0', + description: + '`Button`, `ButtonLink`, `ButtonIcon` now default to size `small` instead of `medium`', + prs: ['30085', '30097'], + type: 'breaking', + }, + { + components: ['grid'], + version: '0.5.0', + description: 'Rename Grid component to ``', + prs: ['30013'], + type: 'breaking', + }, + { + components: ['flex', 'container', 'grid', 'box'], + version: '0.5.0', + description: 'Fixes spacing props on layout components', + prs: ['30013'], + type: 'fix', + }, + { + components: ['switch'], + version: '0.5.0', + description: 'New `Switch` component', + prs: ['30251'], + type: 'new', + }, + { + components: ['tabs'], + version: '0.4.0', + description: 'New `Tabs` component', + prs: ['29996'], + type: 'new', + }, + { + components: ['text', 'heading'], + version: '0.4.0', + description: 'Add `truncate` prop to `Text` and `Heading`', + prs: ['29988'], + type: 'new', + }, + { + components: ['menu'], + version: '0.4.0', + description: 'Add combobox option to `Menu`', + prs: ['29986'], + type: 'new', + }, + { + components: ['textfield'], + version: '0.4.0', + description: 'Add icon prop on `TextField`', + prs: ['29820'], + type: 'new', + }, + { + components: ['button', 'button-icon'], + version: '0.4.0', + description: 'Improve icon props on `Button` and `IconButton`', + prs: ['29667'], + }, + { + components: ['text', 'heading'], + version: '0.4.0', + description: + 'Improve the way we treat custom render on `Text` and `Heading`', + prs: ['29989'], + }, + { + components: ['menu'], + version: '0.4.0', + description: 'Improve `Menu` styles', + prs: ['29986'], + }, + { + components: ['textfield'], + version: '0.4.0', + description: 'Improve `TextField` styles', + prs: ['29974'], + }, + { + components: ['textfield'], + version: '0.4.0', + description: 'Improve clear button on `TextField`', + prs: ['29878'], + }, + { + components: ['flex'], + version: '0.4.0', + description: 'Fix spacing props on all layout components', + prs: ['30013'], + }, + { + components: [], + version: '0.4.0', + description: 'Fix - Pin Base UI version', + prs: ['29782'], + }, + { + components: ['select'], + version: '0.4.0', + description: 'Fix - Clicking `Select` label moves focus to trigger', + prs: ['29755'], + }, + { + components: ['datatable'], + version: '0.4.0', + description: 'Fix `DataTable.Pagination` count issue', + prs: ['29688'], + }, + { + components: ['datatable'], + version: '0.3.0', + description: 'Add `DataTable` component', + prs: ['29484', '29603'], + type: 'new', + }, + { + components: ['select'], + version: '0.3.0', + description: 'Add `Select` component', + prs: ['29440'], + type: 'new', + }, + { + components: ['avatar'], + version: '0.3.0', + description: 'Add `Avatar` component', + prs: ['29594'], + type: 'new', + }, + { + components: ['collapsible'], + version: '0.3.0', + description: 'Add `Collapsible` component', + prs: ['29617'], + type: 'new', + }, + { + components: ['textfield'], + version: '0.3.0', + description: 'Add `TextField` component instead of `Field` + `Input`', + prs: ['29364'], + type: 'new', + }, + { + components: ['datatable'], + version: '0.3.0', + description: 'Add `TableCellProfile`', + prs: ['29600'], + type: 'new', + }, + { + components: [], + version: '0.3.0', + description: 'Add breakpoint hooks - `up()` and `down()`', + prs: ['29564'], + type: 'new', + }, + { + components: [], + version: '0.3.0', + description: 'Add gray scale css tokens', + prs: ['29543'], + type: 'new', + }, + { + components: [], + version: '0.3.0', + description: + 'Update CSS styling API using `[data-___]` instead of class names for props', + prs: ['29560'], + }, + { + components: ['checkbox'], + version: '0.3.0', + description: 'Update `Checkbox` dark mode', + prs: ['29544'], + }, + { + components: ['container'], + version: '0.3.0', + description: 'Update `Container` styles', + prs: ['29475'], + }, + { + components: ['menu'], + version: '0.3.0', + description: 'Update `Menu` styles', + prs: ['29351'], + }, + { + components: ['select'], + version: '0.3.0', + description: 'Fix `Select` styles on small sizes + with long option names', + prs: ['29545'], + }, + { + components: ['link'], + version: '0.3.0', + description: 'Fix render prop on `Link`', + prs: ['29247'], + }, + { + components: ['textfield', 'select'], + version: '0.3.0', + description: 'Remove `Field` from `TextField` + `Select`', + prs: ['29482'], + }, + { + components: ['text', 'heading'], + version: '0.3.0', + description: 'Update `textDecoration` to `none` on `Text` / `Heading`', + prs: ['29357'], + }, + { + components: ['text', 'heading'], + version: '0.3.0', + description: 'Update `textDecoration` to `none` on `Text` / `Heading`', + prs: ['29357'], + }, + { + components: [], + version: '0.3.0', + description: 'Docs - Use stories from Storybook for all examples in Nextjs', + prs: ['29306'], + }, + { + components: [], + version: '0.3.0', + description: 'Docs - Add release page (this one 🤗)', + prs: ['29461'], + }, + { + components: [], + version: '0.3.0', + description: 'Docs - Add docs for Menu, Link', + prs: ['29576'], + }, + { + components: [], + version: '0.3.0', + description: 'Fix CSS watch mode', + prs: ['29352'], + }, + { + components: ['menu'], + version: '0.2.0', + description: 'New `Menu` component', + prs: ['29151'], + type: 'new', + }, + { + components: ['button-icon'], + version: '0.2.0', + description: 'New `IconButton` component', + prs: ['29239'], + type: 'new', + }, + { + components: ['scrollarea'], + version: '0.2.0', + description: 'New `ScrollArea` component', + prs: ['29240'], + type: 'new', + }, + { + components: ['button', 'checkbox'], + version: '0.2.0', + description: 'Improve `Button` & `Checkbox` styles', + prs: ['29127', '28789'], + }, + { + components: ['text'], + version: '0.2.0', + description: 'Improve `Text` styles', + prs: ['29200'], + }, + { + components: ['icon'], + version: '0.2.0', + description: 'Renamed `CanonProvider` to `IconProvider`', + prs: ['29002'], + }, + { + components: ['icon'], + version: '0.2.0', + description: 'Added about 40+ new icons', + prs: ['29264'], + }, + { + components: [], + version: '0.2.0', + description: 'Simplified styling into a unique styles.css file', + prs: ['29199'], + }, + { + components: [], + version: '0.2.0', + description: 'Added global styles to Backstage', + prs: ['29137'], + type: 'new', + }, + { + components: [], + version: '0.2.0', + description: 'Update global CSS tokens', + prs: ['28804'], + }, + { + components: ['flex'], + version: '0.2.0', + description: 'Merge Stack + Inline into Flex', + prs: ['28634'], + }, + { + components: ['button'], + version: '0.2.0', + description: 'Improve `Button` types', + prs: ['29205'], + }, + { + components: [], + version: '0.2.0', + description: 'Move font weight and family back to each components', + prs: ['28972'], + }, + { + components: [], + version: '0.2.0', + description: 'Fix custom values in spacing props', + prs: ['28770'], + }, + { + components: [], + version: '0.2.0', + description: 'Multiple updates on the docs site', + prs: ['28760'], + }, +]; diff --git a/docs-ui/src/utils/data.ts b/docs-ui/src/utils/data.ts new file mode 100644 index 0000000000..de369043d1 --- /dev/null +++ b/docs-ui/src/utils/data.ts @@ -0,0 +1,127 @@ +interface Page { + title: string; + slug: string; + status?: 'alpha' | 'beta' | 'stable' | 'deprecated' | 'inProgress' | 'new'; +} + +export const layoutComponents: Page[] = [ + { + title: 'Box', + slug: 'box', + }, + { + title: 'Container', + slug: 'container', + }, + { + title: 'Grid', + slug: 'grid', + }, + { + title: 'Flex', + slug: 'flex', + }, +]; + +export const components: Page[] = [ + { + title: 'Accordion', + slug: 'accordion', + }, + { + title: 'Avatar', + slug: 'avatar', + }, + { + title: 'Button', + slug: 'button', + }, + { + title: 'ButtonIcon', + slug: 'button-icon', + }, + { + title: 'ButtonLink', + slug: 'button-link', + }, + { + title: 'Card', + slug: 'card', + }, + { + title: 'Checkbox', + slug: 'checkbox', + }, + { + title: 'Dialog', + slug: 'dialog', + }, + { + title: 'Header', + slug: 'header', + }, + { + title: 'HeaderPage', + slug: 'header-page', + }, + { + title: 'Link', + slug: 'link', + }, + { + title: 'Menu', + slug: 'menu', + }, + { + title: 'PasswordField', + slug: 'password-field', + }, + { + title: 'RadioGroup', + slug: 'radio-group', + }, + { + title: 'SearchField', + slug: 'search-field', + }, + { + title: 'Select', + slug: 'select', + }, + { + title: 'Skeleton', + slug: 'skeleton', + }, + { + title: 'Switch', + slug: 'switch', + }, + { + title: 'Table', + slug: 'table', + }, + { + title: 'Tabs', + slug: 'tabs', + }, + { + title: 'TagGroup', + slug: 'tag-group', + }, + { + title: 'Text', + slug: 'text', + }, + { + title: 'TextField', + slug: 'text-field', + }, + { + title: 'Tooltip', + slug: 'tooltip', + }, + { + title: 'VisuallyHidden', + slug: 'visually-hidden', + }, +]; diff --git a/docs-ui/src/utils/getPageName.ts b/docs-ui/src/utils/getPageName.ts new file mode 100644 index 0000000000..7a1ccbf2a1 --- /dev/null +++ b/docs-ui/src/utils/getPageName.ts @@ -0,0 +1,17 @@ +import { components, layoutComponents } from './data'; + +export function getPageName(slug: string): string | null { + // Search in components array + const component = components.find(c => c.slug === slug); + if (component) { + return component.title; + } + + // Search in layoutComponents array + const layoutComponent = layoutComponents.find(c => c.slug === slug); + if (layoutComponent) { + return layoutComponent.title; + } + + return null; +} diff --git a/canon-docs/src/utils/playground-context.tsx b/docs-ui/src/utils/playground-context.tsx similarity index 57% rename from canon-docs/src/utils/playground-context.tsx rename to docs-ui/src/utils/playground-context.tsx index 9d4e23217f..a1cee6ecba 100644 --- a/canon-docs/src/utils/playground-context.tsx +++ b/docs-ui/src/utils/playground-context.tsx @@ -8,7 +8,7 @@ import { import { components } from './data'; type Theme = 'light' | 'dark'; -type ThemeName = 'legacy' | 'default' | 'custom'; +type ThemeName = 'backstage' | 'spotify' | 'custom'; // Create a context with an empty array as the default value const PlaygroundContext = createContext<{ @@ -16,8 +16,8 @@ const PlaygroundContext = createContext<{ setSelectedScreenSizes: (screenSizes: string[]) => void; selectedComponents: string[]; setSelectedComponents: (components: string[]) => void; - selectedTheme: Theme; - setSelectedTheme: (theme: Theme) => void; + selectedTheme: Set; + setSelectedTheme: (keys: Set) => void; selectedThemeName: ThemeName; setSelectedThemeName: (themeName: ThemeName) => void; }>({ @@ -25,9 +25,9 @@ const PlaygroundContext = createContext<{ setSelectedScreenSizes: () => {}, selectedComponents: [], setSelectedComponents: () => {}, - selectedTheme: 'light', + selectedTheme: new Set(['light']), setSelectedTheme: () => {}, - selectedThemeName: 'default', + selectedThemeName: 'backstage', setSelectedThemeName: () => {}, }); @@ -40,24 +40,45 @@ export const PlaygroundProvider = ({ children }: { children: ReactNode }) => { const [selectedComponents, setSelectedComponents] = useState( components.map(component => component.slug), ); - const [selectedTheme, setSelectedTheme] = useState(() => { - return isBrowser - ? (localStorage.getItem('theme') as Theme) || 'light' - : 'light'; - }); - const [selectedThemeName, setSelectedThemeName] = useState(() => { - return isBrowser - ? (localStorage.getItem('theme-name') as ThemeName) || 'default' - : 'default'; - }); + const [selectedTheme, setSelectedTheme] = useState>( + new Set(['light']), + ); + const [selectedThemeName, setSelectedThemeName] = + useState('backstage'); + + // Load saved theme from localStorage after hydration + useEffect(() => { + if (isBrowser) { + const savedThemeString = localStorage.getItem('theme-mode'); + if (savedThemeString) { + // Parse the comma-separated string back into a Set + const themeArray = savedThemeString + .split(',') + .filter(Boolean) as Theme[]; + setSelectedTheme(new Set(themeArray)); + } else { + setSelectedTheme(new Set(['light'])); + } + } + }, [isBrowser]); + + // Load saved theme name from localStorage after hydration + useEffect(() => { + if (isBrowser) { + const savedThemeName = localStorage.getItem('theme-name') as ThemeName; + if (savedThemeName) { + setSelectedThemeName(savedThemeName); + } + } + }, [isBrowser]); useEffect(() => { if (isBrowser) { document.documentElement.setAttribute( - 'data-theme', - selectedTheme || 'light', + 'data-theme-mode', + Array.from(selectedTheme).join(','), ); - localStorage.setItem('theme', selectedTheme || 'light'); + localStorage.setItem('theme-mode', Array.from(selectedTheme).join(',')); } }, [selectedTheme, isBrowser]); @@ -65,9 +86,9 @@ export const PlaygroundProvider = ({ children }: { children: ReactNode }) => { if (isBrowser) { document.documentElement.setAttribute( 'data-theme-name', - selectedThemeName || 'default', + selectedThemeName || 'backstage', ); - localStorage.setItem('theme-name', selectedThemeName || 'default'); + localStorage.setItem('theme-name', selectedThemeName || 'backstage'); } }, [selectedThemeName, isBrowser]); diff --git a/canon-docs/src/utils/propDefs.ts b/docs-ui/src/utils/propDefs.ts similarity index 90% rename from canon-docs/src/utils/propDefs.ts rename to docs-ui/src/utils/propDefs.ts index 3805665346..ed4a07e7ee 100644 --- a/canon-docs/src/utils/propDefs.ts +++ b/docs-ui/src/utils/propDefs.ts @@ -1,13 +1,34 @@ -import type { Breakpoint } from '@backstage/canon/src/types'; +import type { Breakpoint } from '@backstage/ui/src/types'; const breakpoints = ['initial', 'xs', 'sm', 'md', 'lg', 'xl'] as Breakpoint[]; +export type ComplexTypeDef = { + name: string; + properties: Record< + string, + { + type: string; + required?: boolean; + description?: string; + } + >; +}; + export type PropDef = { - type: 'string' | 'enum' | 'enum | string' | 'number' | 'boolean'; + type: + | 'string' + | 'enum' + | 'enum | string' + | 'number' + | 'boolean' + | 'spacing' + | 'complex'; values?: string | string[]; + complexType?: ComplexTypeDef; default?: string; required?: boolean; responsive?: boolean; + description?: string; }; export { breakpoints }; diff --git a/docs-ui/src/utils/theme-switcher.ts b/docs-ui/src/utils/theme-switcher.ts new file mode 100644 index 0000000000..d2e82de958 --- /dev/null +++ b/docs-ui/src/utils/theme-switcher.ts @@ -0,0 +1,32 @@ +// Auto-generated theme switcher utility + +export const availableThemes = { + default: '/styles.css', + spotify: '/spotify-theme.css', +} as const; + +export type ThemeName = keyof typeof availableThemes; + +export function switchTheme(themeName: ThemeName) { + // Remove existing theme links + const existingLinks = document.querySelectorAll('link[data-theme-mode]'); + existingLinks.forEach(link => link.remove()); + + // Add new theme link + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = availableThemes[themeName]; + link.setAttribute('data-theme-mode', themeName); + document.head.appendChild(link); +} + +export function getCurrentTheme(): ThemeName { + const existingLink = document.querySelector('link[data-theme-mode]'); + if (existingLink) { + const href = existingLink.getAttribute('href'); + for (const [name, path] of Object.entries(availableThemes)) { + if (path === href) return name as ThemeName; + } + } + return 'default'; +} diff --git a/canon-docs/tsconfig.json b/docs-ui/tsconfig.json similarity index 81% rename from canon-docs/tsconfig.json rename to docs-ui/tsconfig.json index 2baa7cde8f..e1b3951aa8 100644 --- a/canon-docs/tsconfig.json +++ b/docs-ui/tsconfig.json @@ -3,7 +3,7 @@ "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, - "strict": true, + "strict": false, "noEmit": true, "esModuleInterop": true, "module": "esnext", @@ -12,6 +12,7 @@ "isolatedModules": true, "jsx": "preserve", "incremental": true, + "noImplicitAny": false, "plugins": [ { "name": "next" @@ -19,14 +20,16 @@ ], "paths": { "@/*": ["./src/*"] - } + }, + "target": "ES2017" }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", - "dist/types/**/*.ts" + "dist/types/**/*.ts", + "src/types/**/*.d.ts" ], "exclude": ["node_modules"] } diff --git a/canon-docs/yarn.lock b/docs-ui/yarn.lock similarity index 63% rename from canon-docs/yarn.lock rename to docs-ui/yarn.lock index decb4e7efe..faba322cfc 100644 --- a/canon-docs/yarn.lock +++ b/docs-ui/yarn.lock @@ -5,36 +5,52 @@ __metadata: version: 8 cacheKey: 10 -"@babel/runtime@npm:^7.18.6": - version: 7.26.10 - resolution: "@babel/runtime@npm:7.26.10" +"@babel/code-frame@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" dependencies: - regenerator-runtime: "npm:^0.14.0" - checksum: 10/9d7ff8e96abe3791047c1138789c742411e3ef19c4d7ca18ce916f83cec92c06ec5dc64401759f6dd1e377cf8a01bbd2c62e033eb7550f435cf6579768d0d4a5 + "@babel/helper-validator-identifier": "npm:^7.27.1" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10/721b8a6e360a1fa0f1c9fe7351ae6c874828e119183688b533c477aa378f1010f37cc9afbfc4722c686d1f5cdd00da02eab4ba7278a0c504fa0d7a321dcd4fdf + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-identifier@npm:7.27.1" + checksum: 10/75041904d21bdc0cd3b07a8ac90b11d64cd3c881e89cb936fa80edd734bf23c35e6bd1312611e8574c4eab1f3af0f63e8a5894f4699e9cfdf70c06fcf4252320 + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.18.6": + version: 7.28.3 + resolution: "@babel/runtime@npm:7.28.3" + checksum: 10/f2415e4dbface7496f6fc561d640b44be203071fb0dfb63fbe338c7d2d2047419cb054ef13d1ebb8fc11e35d2b55aa3045def4b985e8b82aea5d7e58e1133e52 languageName: node linkType: hard "@codemirror/autocomplete@npm:^6.0.0": - version: 6.18.4 - resolution: "@codemirror/autocomplete@npm:6.18.4" + version: 6.18.6 + resolution: "@codemirror/autocomplete@npm:6.18.6" dependencies: "@codemirror/language": "npm:^6.0.0" "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.17.0" "@lezer/common": "npm:^1.0.0" - checksum: 10/7cd62db2ee87d6cb3936ced4f211bdcd9ce75515f64922119370c303a8bdbf5640e640a8d802c30d01cb55fb6c9b5299426ff799f04cff0bef8d0c3450fe2528 + checksum: 10/0574d96fd04ccf2d3b7ae3c4efe0a72f423fa81658876ec50865ce3371cea038aeddf026976ec0d0ccbee72ac66bdf7deec9106dee251ad49019ae7e1a871663 languageName: node linkType: hard "@codemirror/commands@npm:^6.0.0, @codemirror/commands@npm:^6.1.0": - version: 6.8.0 - resolution: "@codemirror/commands@npm:6.8.0" + version: 6.8.1 + resolution: "@codemirror/commands@npm:6.8.1" dependencies: "@codemirror/language": "npm:^6.0.0" "@codemirror/state": "npm:^6.4.0" "@codemirror/view": "npm:^6.27.0" "@lezer/common": "npm:^1.1.0" - checksum: 10/0c7991736bc84d0a7f8e49c311c78a78def84fca36ff61c2f9887067e2c06b1b232711cb99282cd410527ddbe0671d2b9aff93e0848fa731a2014c3691c737ea + checksum: 10/72b6343777d4fe4af1bcc91331eb64705b33e871c9f8e2a0cd177269478a6f3282bf25aeaecdbb55fd5e031b67aabfede068e919fe69e473d07e5090dd76b381 languageName: node linkType: hard @@ -65,8 +81,8 @@ __metadata: linkType: hard "@codemirror/language@npm:^6.0.0": - version: 6.10.8 - resolution: "@codemirror/language@npm:6.10.8" + version: 6.11.3 + resolution: "@codemirror/language@npm:6.11.3" dependencies: "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.23.0" @@ -74,247 +90,283 @@ __metadata: "@lezer/highlight": "npm:^1.0.0" "@lezer/lr": "npm:^1.0.0" style-mod: "npm:^4.0.0" - checksum: 10/63b83b41d9f8475f757144cc204df08834bb14411c484aa265ffa3e93b7d8f696a21110df72101159a8675eda29018c6d08f864965bd4651b607a39f10ad32ed + checksum: 10/8538a2835c1de6ca2d520ff66449185f2ea3a93e7d69382d9db3b4db6460f4c46b44f19724458c50230abfa87cf2c225834d39c3fe3119c48370db6b3de0b772 languageName: node linkType: hard "@codemirror/lint@npm:^6.0.0": - version: 6.8.4 - resolution: "@codemirror/lint@npm:6.8.4" + version: 6.8.5 + resolution: "@codemirror/lint@npm:6.8.5" dependencies: "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.35.0" crelt: "npm:^1.0.5" - checksum: 10/401ead0591d88d31d1bf6527d4caba26e0deb7b49382dfbb8c712037d858047b0699fa2c15831a07db928194549eea9b942004fee42f334b34ff5973c7dbec58 + checksum: 10/9eddfea1dd0615431d57687c2a0d4de510d725aac6f6bbc2eba4bc934963371304dfa4c49398b3043372ef34cead3ebc0ec3f652632a87f5d8a458fa911a309a languageName: node linkType: hard "@codemirror/search@npm:^6.0.0": - version: 6.5.8 - resolution: "@codemirror/search@npm:6.5.8" + version: 6.5.11 + resolution: "@codemirror/search@npm:6.5.11" dependencies: "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.0.0" crelt: "npm:^1.0.5" - checksum: 10/1389fa4e05da72b621ae10ff00d4ef0d23b08a3a7ac48f6e0b867429da7b80036bd7a6feef1a54f5b4c4af9fc4277f754a313a858fbfc12ccdfa48e9bf300cef + checksum: 10/d057f37cb369460b25625d7eb72f40636bf78ecd140608da53010cf3660f982a9e613826e38d85d87c9c2ff11e45c9482429987bfd4f29cbbd192f1ee3fd2695 languageName: node linkType: hard "@codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.1.1, @codemirror/state@npm:^6.4.0, @codemirror/state@npm:^6.5.0": - version: 6.5.1 - resolution: "@codemirror/state@npm:6.5.1" + version: 6.5.2 + resolution: "@codemirror/state@npm:6.5.2" dependencies: "@marijn/find-cluster-break": "npm:^1.0.0" - checksum: 10/117f21ba2ff5bc9f9b946ca9943279a29bb9461ec77fc2313cfd8908ed6eb7df2950d7c5b0ba0a0a23c3e0633c6bba56f8c105f97875665e0376a9e110d10a48 + checksum: 10/5ccd3acb0c0a5b88e83fb91be39099fceb9f44a5047cc41a75d53f160e736851f65c8de40950b90c6519e6d2828e12f468db0af658dde30e938896f1c39eec91 languageName: node linkType: hard "@codemirror/theme-one-dark@npm:^6.0.0": - version: 6.1.2 - resolution: "@codemirror/theme-one-dark@npm:6.1.2" + version: 6.1.3 + resolution: "@codemirror/theme-one-dark@npm:6.1.3" dependencies: "@codemirror/language": "npm:^6.0.0" "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.0.0" "@lezer/highlight": "npm:^1.0.0" - checksum: 10/ea4517975b4004bd7d3ef7731a861b59c36d2ddc603d9c4ceca2c5b7637d62a8290f3f9e15004cd0f0e2ea1cc0f6c882a5ad2dd79862a6971b6654325914ccbc + checksum: 10/f62c2393aad715626a1fe3a766c87f3f835bfdae7c56f738601cdee56f02417d56b203cfbbaffbd601887865ce0b1a662c1473296a107616adb311d63fc81146 languageName: node linkType: hard -"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0, @codemirror/view@npm:^6.35.0": - version: 6.36.2 - resolution: "@codemirror/view@npm:6.36.2" +"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0, @codemirror/view@npm:^6.34.4, @codemirror/view@npm:^6.35.0": + version: 6.38.6 + resolution: "@codemirror/view@npm:6.38.6" dependencies: "@codemirror/state": "npm:^6.5.0" + crelt: "npm:^1.0.6" style-mod: "npm:^4.1.0" w3c-keyname: "npm:^2.2.4" - checksum: 10/9ef7fcf4f9d9b6e66645ae65da1bf0c90e08f6ba786de0373b9f3644632066b91b8ea20faf67bb81eb9adf310ae76888cc7fd0901e2bb4821193f5427455c137 + checksum: 10/5a047337a98de111817ce8c8d39e6429c90ca0b0a4d2678d6e161e9e5961b1d476a891f447ab7a05cac395d4a93530e7c68bedd93191285265f0742a308ad00b languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/aix-ppc64@npm:0.25.0" +"@emnapi/core@npm:^1.4.3": + version: 1.4.5 + resolution: "@emnapi/core@npm:1.4.5" + dependencies: + "@emnapi/wasi-threads": "npm:1.0.4" + tslib: "npm:^2.4.0" + checksum: 10/412322102dc861e8aa78123ae20560ac980362a220c736fe59ddea3228d490757780ea4cdc3bd54903a5ca2a92085f119e42f2c07f60e2aec2c0b8a69ea094c0 + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.4.3, @emnapi/runtime@npm:^1.4.4": + version: 1.4.5 + resolution: "@emnapi/runtime@npm:1.4.5" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/1d6f406ff116d2363e60aef3ed49eb8d577387f4941abea508ba376900d8831609d5cce92a58076b1a9613f8e83c75c2e3fea71e4fbcdbe06019876144c2559b + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.0.4": + version: 1.0.4 + resolution: "@emnapi/wasi-threads@npm:1.0.4" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/86688f416095b59d8d3e5ea2d8b5574a7c180257fe0c067c7a492f3de2cf5ebc2c8b00af17d6341c7555c614266d3987f332015d7ce6e88b234a9a314e66f396 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/aix-ppc64@npm:0.25.9" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/android-arm64@npm:0.25.0" +"@esbuild/android-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm64@npm:0.25.9" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/android-arm@npm:0.25.0" +"@esbuild/android-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-arm@npm:0.25.9" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/android-x64@npm:0.25.0" +"@esbuild/android-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/android-x64@npm:0.25.9" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/darwin-arm64@npm:0.25.0" +"@esbuild/darwin-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-arm64@npm:0.25.9" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/darwin-x64@npm:0.25.0" +"@esbuild/darwin-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/darwin-x64@npm:0.25.9" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/freebsd-arm64@npm:0.25.0" +"@esbuild/freebsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-arm64@npm:0.25.9" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/freebsd-x64@npm:0.25.0" +"@esbuild/freebsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/freebsd-x64@npm:0.25.9" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-arm64@npm:0.25.0" +"@esbuild/linux-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm64@npm:0.25.9" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-arm@npm:0.25.0" +"@esbuild/linux-arm@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-arm@npm:0.25.9" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-ia32@npm:0.25.0" +"@esbuild/linux-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ia32@npm:0.25.9" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-loong64@npm:0.25.0" +"@esbuild/linux-loong64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-loong64@npm:0.25.9" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-mips64el@npm:0.25.0" +"@esbuild/linux-mips64el@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-mips64el@npm:0.25.9" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-ppc64@npm:0.25.0" +"@esbuild/linux-ppc64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-ppc64@npm:0.25.9" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-riscv64@npm:0.25.0" +"@esbuild/linux-riscv64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-riscv64@npm:0.25.9" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-s390x@npm:0.25.0" +"@esbuild/linux-s390x@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-s390x@npm:0.25.9" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-x64@npm:0.25.0" +"@esbuild/linux-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/linux-x64@npm:0.25.9" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/netbsd-arm64@npm:0.25.0" +"@esbuild/netbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-arm64@npm:0.25.9" conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/netbsd-x64@npm:0.25.0" +"@esbuild/netbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/netbsd-x64@npm:0.25.9" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/openbsd-arm64@npm:0.25.0" +"@esbuild/openbsd-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-arm64@npm:0.25.9" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/openbsd-x64@npm:0.25.0" +"@esbuild/openbsd-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openbsd-x64@npm:0.25.9" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/sunos-x64@npm:0.25.0" +"@esbuild/openharmony-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/openharmony-arm64@npm:0.25.9" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/sunos-x64@npm:0.25.9" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/win32-arm64@npm:0.25.0" +"@esbuild/win32-arm64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-arm64@npm:0.25.9" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/win32-ia32@npm:0.25.0" +"@esbuild/win32-ia32@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-ia32@npm:0.25.9" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/win32-x64@npm:0.25.0" +"@esbuild/win32-x64@npm:0.25.9": + version: 0.25.9 + resolution: "@esbuild/win32-x64@npm:0.25.9" 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.1 - resolution: "@eslint-community/eslint-utils@npm:4.4.1" +"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.7.0": + version: 4.7.0 + resolution: "@eslint-community/eslint-utils@npm:4.7.0" dependencies: eslint-visitor-keys: "npm:^3.4.3" peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10/ae92a11412674329b4bd38422518601ec9ceae28e251104d1cad83715da9d38e321f68c817c39b64e66d0af7d98df6f9a10ad2dc638911254b47fb8932df00ef + checksum: 10/43ed5d391526d9f5bbe452aef336389a473026fca92057cf97c576db11401ce9bcf8ef0bf72625bbaf6207ed8ba6bf0dcf4d7e809c24f08faa68a28533c491a7 languageName: node linkType: hard @@ -374,6 +426,207 @@ __metadata: languageName: node linkType: hard +"@img/sharp-darwin-arm64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-darwin-arm64@npm:0.34.3" + dependencies: + "@img/sharp-libvips-darwin-arm64": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-darwin-arm64": + optional: true + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-darwin-x64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-darwin-x64@npm:0.34.3" + dependencies: + "@img/sharp-libvips-darwin-x64": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-darwin-x64": + optional: true + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@img/sharp-libvips-darwin-arm64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-darwin-arm64@npm:1.2.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-libvips-darwin-x64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-darwin-x64@npm:1.2.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-arm64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-arm64@npm:1.2.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-arm@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-arm@npm:1.2.0" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-ppc64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-ppc64@npm:1.2.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-s390x@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-s390x@npm:1.2.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-x64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linux-x64@npm:1.2.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linuxmusl-arm64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.2.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-libvips-linuxmusl-x64@npm:1.2.0": + version: 1.2.0 + resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.2.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-linux-arm64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-arm64@npm:0.34.3" + dependencies: + "@img/sharp-libvips-linux-arm64": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-linux-arm64": + optional: true + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-arm@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-arm@npm:0.34.3" + dependencies: + "@img/sharp-libvips-linux-arm": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-linux-arm": + optional: true + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-ppc64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-ppc64@npm:0.34.3" + dependencies: + "@img/sharp-libvips-linux-ppc64": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-linux-ppc64": + optional: true + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-s390x@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-s390x@npm:0.34.3" + dependencies: + "@img/sharp-libvips-linux-s390x": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-linux-s390x": + optional: true + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-x64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linux-x64@npm:0.34.3" + dependencies: + "@img/sharp-libvips-linux-x64": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-linux-x64": + optional: true + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linuxmusl-arm64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linuxmusl-arm64@npm:0.34.3" + dependencies: + "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-linuxmusl-arm64": + optional: true + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-linuxmusl-x64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-linuxmusl-x64@npm:0.34.3" + dependencies: + "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.0" + dependenciesMeta: + "@img/sharp-libvips-linuxmusl-x64": + optional: true + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-wasm32@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-wasm32@npm:0.34.3" + dependencies: + "@emnapi/runtime": "npm:^1.4.4" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@img/sharp-win32-arm64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-win32-arm64@npm:0.34.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-win32-ia32@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-win32-ia32@npm:0.34.3" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@img/sharp-win32-x64@npm:0.34.3": + version: 0.34.3 + resolution: "@img/sharp-win32-x64@npm:0.34.3" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -388,34 +641,43 @@ __metadata: languageName: node linkType: hard -"@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.0.2, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.2.0": - version: 1.2.3 - resolution: "@lezer/common@npm:1.2.3" - checksum: 10/dad24e353e4e67d88b203191361ca1dff26c01c2b7b4ae829b668a1d115929334d077217367683e39180c0556510ed2066ea8ddba2b079be7c08a7152208cc87 +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: "npm:^7.0.4" + checksum: 10/4412e9e6713c89c1e66d80bb0bb5a2a93192f10477623a27d08f228ba0316bb880affabc5bfe7f838f58a34d26c2c190da726e576cdfc18c49a72e89adabdcf5 + languageName: node + linkType: hard + +"@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.0.2, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.2.0, @lezer/common@npm:^1.3.0": + version: 1.3.0 + resolution: "@lezer/common@npm:1.3.0" + checksum: 10/8e195a8e426bc18d4339b3f2a1a7ad39c3b2cfa740c7108657a241985f63bdee5255a5f5cf8d863b878881744288bcb679d16170f0e5bcebb141188b53cfd8c0 languageName: node linkType: hard "@lezer/css@npm:^1.1.7": - version: 1.1.9 - resolution: "@lezer/css@npm:1.1.9" + version: 1.3.0 + resolution: "@lezer/css@npm:1.3.0" dependencies: "@lezer/common": "npm:^1.2.0" "@lezer/highlight": "npm:^1.0.0" - "@lezer/lr": "npm:^1.0.0" - checksum: 10/bcc277bb6b806961ebfd03e98faf8e5870dd7da2eb565c43922ac378d926b49f479309b28cc824fd4e17baac2c8952966807d06fbe2a45d53e9a3f1518134729 + "@lezer/lr": "npm:^1.3.0" + checksum: 10/142609b690b9fef139ea947faf43253df596834805c0805c69bc8866c4366790eb1b392d65a25dae5f840ff3de676768cc3b808013435c82db20d6a0f3917e97 languageName: node linkType: hard "@lezer/highlight@npm:^1.0.0, @lezer/highlight@npm:^1.2.1": - version: 1.2.1 - resolution: "@lezer/highlight@npm:1.2.1" + version: 1.2.3 + resolution: "@lezer/highlight@npm:1.2.3" dependencies: - "@lezer/common": "npm:^1.0.0" - checksum: 10/fec3082419ee87fb265039b680fbac6796f862d8e3042dcb860e8c5a34291503a74927302b568ff1a626f0d2b5cf8dae02a51cfd200084eb329e5fd1236c3163 + "@lezer/common": "npm:^1.3.0" + checksum: 10/8f787d464f8a036f117a0b23e73ac034d224a57d72501c6559089098a28f127c9e495b90ac7d132acc86199e0b64d4c038f75f9293a37c7c61add52fa1acdb4e languageName: node linkType: hard -"@lezer/lr@npm:^1.0.0": +"@lezer/lr@npm:^1.0.0, @lezer/lr@npm:^1.3.0": version: 1.4.2 resolution: "@lezer/lr@npm:1.4.2" dependencies: @@ -425,13 +687,13 @@ __metadata: linkType: hard "@lezer/sass@npm:^1.0.0": - version: 1.0.7 - resolution: "@lezer/sass@npm:1.0.7" + version: 1.1.0 + resolution: "@lezer/sass@npm:1.1.0" dependencies: "@lezer/common": "npm:^1.2.0" "@lezer/highlight": "npm:^1.0.0" "@lezer/lr": "npm:^1.0.0" - checksum: 10/a7531cbf0766d3875480c24ae8929dd56053d71f9eaef8815e6f468e2252e66e38236a3f89395463e4cee43230dc35351386bedc6138cf1a19a44a64ce58a372 + checksum: 10/2f42dfaf5a328d4626a0a8ff8cd5973b7f52e8112541281cf1cbb1970acdc52c7c9f55c71f635bcff75a6151a55f7653d277306a15494b23b652e87d16df9ce3 languageName: node linkType: hard @@ -457,14 +719,15 @@ __metadata: languageName: node linkType: hard -"@mdx-js/mdx@npm:^3.0.0": - version: 3.1.0 - resolution: "@mdx-js/mdx@npm:3.1.0" +"@mdx-js/mdx@npm:^3.0.0, @mdx-js/mdx@npm:^3.1.1": + version: 3.1.1 + resolution: "@mdx-js/mdx@npm:3.1.1" dependencies: "@types/estree": "npm:^1.0.0" "@types/estree-jsx": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" "@types/mdx": "npm:^2.0.0" + acorn: "npm:^8.0.0" collapse-white-space: "npm:^2.0.0" devlop: "npm:^1.0.0" estree-util-is-identifier-name: "npm:^3.0.0" @@ -485,41 +748,52 @@ __metadata: unist-util-stringify-position: "npm:^4.0.0" unist-util-visit: "npm:^5.0.0" vfile: "npm:^6.0.0" - checksum: 10/4bd4e1160e2b2bc9ea2b5b93246ce0e34a11ac5fd420ec025e82fb1120a72b80025d9cb205cce6394bb5f0013f209b9ea453cbda4c0ca4f97a2169df60084742 + checksum: 10/b871da2497f6e0f11da1574fe772a50b09b7c177de8df0f821f708bf162febe76c01a572a5c68e860960189209fd66f768c2e747fdb3a1f497c5c32e11890c11 languageName: node linkType: hard -"@mdx-js/react@npm:^3.1.0": - version: 3.1.0 - resolution: "@mdx-js/react@npm:3.1.0" +"@mdx-js/react@npm:^3.1.0, @mdx-js/react@npm:^3.1.1": + version: 3.1.1 + resolution: "@mdx-js/react@npm:3.1.1" dependencies: "@types/mdx": "npm:^2.0.0" peerDependencies: "@types/react": ">=16" react: ">=16" - checksum: 10/cf89d6392c76091622fb647f205e1ab5cbdf5edd4401dde7092138cefc9fbb6d61428aa63557de0bccca3695d5a8854dd4a93b34a27cb8e27369da7eaeaa3e73 + checksum: 10/52a740e2f37761694fa94d4704b7825084b4055616a95c8b8f4c1676190d399ddc5cdbb399ffc45b550beecd30497a7224c2e5b05bf43ecb668c7473641037d1 languageName: node linkType: hard -"@next/env@npm:14.2.26": - version: 14.2.26 - resolution: "@next/env@npm:14.2.26" - checksum: 10/0caa679cdf9367501daf1bff0e762b720613a3ee1689e5585bfb7c792fdd07c251bc1f7488919a296047eb1f2b82ceb13955b673143468cad338a87b7d98c196 - languageName: node - linkType: hard - -"@next/eslint-plugin-next@npm:14.2.23": - version: 14.2.23 - resolution: "@next/eslint-plugin-next@npm:14.2.23" +"@napi-rs/wasm-runtime@npm:^0.2.11": + version: 0.2.12 + resolution: "@napi-rs/wasm-runtime@npm:0.2.12" dependencies: - glob: "npm:10.3.10" - checksum: 10/e46513a7601bf682f1e60cc668188cf2c9f0471be73ffbbac69da240e9f91c6b9c3aad3e83a8da54c0ba8bce37cc6368bbafb04b74b385d5df0c36dde09a3217 + "@emnapi/core": "npm:^1.4.3" + "@emnapi/runtime": "npm:^1.4.3" + "@tybys/wasm-util": "npm:^0.10.0" + checksum: 10/5fd518182427980c28bc724adf06c5f32f9a8915763ef560b5f7d73607d30cd15ac86d0cbd2eb80d4cfab23fc80d0876d89ca36a9daadcb864bc00917c94187c languageName: node linkType: hard -"@next/mdx@npm:^15.1.4": - version: 15.1.6 - resolution: "@next/mdx@npm:15.1.6" +"@next/env@npm:15.4.7": + version: 15.4.7 + resolution: "@next/env@npm:15.4.7" + checksum: 10/8341fa6f1b5aebb6f99d8abad2f3ee2685281aaa51785f8ceff3c9a7f03186645f372003ee833715c0ce05e4e7d960defa4252018977f19564001b872b24714e + languageName: node + linkType: hard + +"@next/eslint-plugin-next@npm:15.3.4": + version: 15.3.4 + resolution: "@next/eslint-plugin-next@npm:15.3.4" + dependencies: + fast-glob: "npm:3.3.1" + checksum: 10/8a473bd32a06f62c16f60f9c40b7b8149cf91170ce4c1546cda57e9c85ac8481c7ad3aa4a77e8c3c7000e80d3de809d2db7df6cb79e13fd258fff382729abf60 + languageName: node + linkType: hard + +"@next/mdx@npm:15.3.4": + version: 15.3.4 + resolution: "@next/mdx@npm:15.3.4" dependencies: source-map: "npm:^0.7.0" peerDependencies: @@ -530,69 +804,62 @@ __metadata: optional: true "@mdx-js/react": optional: true - checksum: 10/3b46e99934543df94bcb335dddab794db4fcaff09223343e9e00597d3df1e094f16dd619c433fb2fa7fff38c3da57b3118cbc010cdeb9790d0cf01e6c37016e8 + checksum: 10/07904beda049317e43857f9dfe659adb6e57c4417475de1d21a7605f8ace5d9aa992a06465d1a94fe4b62331901765b15659555e8aadedbd410f86df1bebd1bd languageName: node linkType: hard -"@next/swc-darwin-arm64@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-darwin-arm64@npm:14.2.26" +"@next/swc-darwin-arm64@npm:15.4.7": + version: 15.4.7 + resolution: "@next/swc-darwin-arm64@npm:15.4.7" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@next/swc-darwin-x64@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-darwin-x64@npm:14.2.26" +"@next/swc-darwin-x64@npm:15.4.7": + version: 15.4.7 + resolution: "@next/swc-darwin-x64@npm:15.4.7" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@next/swc-linux-arm64-gnu@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-linux-arm64-gnu@npm:14.2.26" +"@next/swc-linux-arm64-gnu@npm:15.4.7": + version: 15.4.7 + resolution: "@next/swc-linux-arm64-gnu@npm:15.4.7" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-arm64-musl@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-linux-arm64-musl@npm:14.2.26" +"@next/swc-linux-arm64-musl@npm:15.4.7": + version: 15.4.7 + resolution: "@next/swc-linux-arm64-musl@npm:15.4.7" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@next/swc-linux-x64-gnu@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-linux-x64-gnu@npm:14.2.26" +"@next/swc-linux-x64-gnu@npm:15.4.7": + version: 15.4.7 + resolution: "@next/swc-linux-x64-gnu@npm:15.4.7" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-x64-musl@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-linux-x64-musl@npm:14.2.26" +"@next/swc-linux-x64-musl@npm:15.4.7": + version: 15.4.7 + resolution: "@next/swc-linux-x64-musl@npm:15.4.7" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@next/swc-win32-arm64-msvc@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-win32-arm64-msvc@npm:14.2.26" +"@next/swc-win32-arm64-msvc@npm:15.4.7": + version: 15.4.7 + resolution: "@next/swc-win32-arm64-msvc@npm:15.4.7" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@next/swc-win32-ia32-msvc@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-win32-ia32-msvc@npm:14.2.26" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@next/swc-win32-x64-msvc@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-win32-x64-msvc@npm:14.2.26" +"@next/swc-win32-x64-msvc@npm:15.4.7": + version: 15.4.7 + resolution: "@next/swc-win32-x64-msvc@npm:15.4.7" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -631,6 +898,28 @@ __metadata: languageName: node linkType: hard +"@npmcli/agent@npm:^3.0.0": + version: 3.0.0 + resolution: "@npmcli/agent@npm:3.0.0" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 10/775c9a7eb1f88c195dfb3bce70c31d0fe2a12b28b754e25c08a3edb4bc4816bfedb7ac64ef1e730579d078ca19dacf11630e99f8f3c3e0fd7b23caa5fd6d30a6 + languageName: node + linkType: hard + +"@npmcli/fs@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/fs@npm:4.0.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10/405c4490e1ff11cf299775449a3c254a366a4b1ffc79d87159b0ee7d5558ac9f6a2f8c0735fd6ff3873cef014cb1a44a5f9127cb6a1b2dbc408718cca9365b5a + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -638,6 +927,15 @@ __metadata: languageName: node linkType: hard +"@remixicon/react@npm:^4.6.0": + version: 4.6.0 + resolution: "@remixicon/react@npm:4.6.0" + peerDependencies: + react: ">=18.2.0" + checksum: 10/d92c8131734062fca8d82d55dd8f3f4e28cb72c5eefda528c8aba5f3298f0c847342eecdbd7787d6da5af21b699d735f6cf27f151f0c982c1c9f06a78b235c94 + languageName: node + linkType: hard + "@rtsao/scc@npm:^1.1.0": version: 1.1.0 resolution: "@rtsao/scc@npm:1.1.0" @@ -645,97 +943,105 @@ __metadata: languageName: node linkType: hard -"@rushstack/eslint-patch@npm:^1.3.3": - version: 1.10.5 - resolution: "@rushstack/eslint-patch@npm:1.10.5" - checksum: 10/769d130dfb088c21e7ce72b552ea58c0d6d790cfe9fcadc4cd66e1282a0213a2c6b570d679723e0d3792a6b6ebfcbdeb5e785261d196017840853b8a5c57dfea +"@rushstack/eslint-patch@npm:^1.10.3": + version: 1.12.0 + resolution: "@rushstack/eslint-patch@npm:1.12.0" + checksum: 10/d03e67425e6bd6dd6521dd2e1c04a676ae439ea1ddb528775f8f9d8d87d52d535120650d06d6b3782e209e3b799ff901fa36abb4fe636f90a5c631d240b1237d languageName: node linkType: hard -"@shikijs/core@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/core@npm:1.26.1" +"@shikijs/core@npm:3.13.0": + version: 3.13.0 + resolution: "@shikijs/core@npm:3.13.0" dependencies: - "@shikijs/engine-javascript": "npm:1.26.1" - "@shikijs/engine-oniguruma": "npm:1.26.1" - "@shikijs/types": "npm:1.26.1" - "@shikijs/vscode-textmate": "npm:^10.0.1" + "@shikijs/types": "npm:3.13.0" + "@shikijs/vscode-textmate": "npm:^10.0.2" "@types/hast": "npm:^3.0.4" - hast-util-to-html: "npm:^9.0.4" - checksum: 10/d70dd7e267da624bdc098f9f0295699d30d6bb0873a0c7f239f0664f253532af395208efe10cb0ad6f96b8c63fee439ce7ddbf5bd60b41149e2911fc3c55fc8f + hast-util-to-html: "npm:^9.0.5" + checksum: 10/c9b301a170cd76fa2ce446adee26b539b19204107a2e60207f3f5e7d96773df322367f6035e2d689d43f97a3e9f741793e976c366015d8e3a9709dcac1399af2 languageName: node linkType: hard -"@shikijs/engine-javascript@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/engine-javascript@npm:1.26.1" +"@shikijs/engine-javascript@npm:3.13.0": + version: 3.13.0 + resolution: "@shikijs/engine-javascript@npm:3.13.0" dependencies: - "@shikijs/types": "npm:1.26.1" - "@shikijs/vscode-textmate": "npm:^10.0.1" - oniguruma-to-es: "npm:0.10.0" - checksum: 10/fd7dac25fe4310bcd055af5163044fa598a65ec54376938f2ee70b8ab864a4d2f4bba2e76353d739ffcf071ffbc57b16147f47e5c9f950bf82f826cf88d3dd85 + "@shikijs/types": "npm:3.13.0" + "@shikijs/vscode-textmate": "npm:^10.0.2" + oniguruma-to-es: "npm:^4.3.3" + checksum: 10/acd4e78fdc732738c6a3a9f254011b7d8995a2149f2f72f7396d5e4514f3b0c3fdc767d52bf8852d65066e613dd8d1157bc4900442ab42684db7ef7396a44871 languageName: node linkType: hard -"@shikijs/engine-oniguruma@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/engine-oniguruma@npm:1.26.1" +"@shikijs/engine-oniguruma@npm:3.13.0": + version: 3.13.0 + resolution: "@shikijs/engine-oniguruma@npm:3.13.0" dependencies: - "@shikijs/types": "npm:1.26.1" - "@shikijs/vscode-textmate": "npm:^10.0.1" - checksum: 10/17b3355fc226f58ef67d419c9e64a4dc99a63481c66f7ec55fdfb5035363605359414211e40ac8260db9c10c507e587dfac1061c0f57f111050e921e38cd58ef + "@shikijs/types": "npm:3.13.0" + "@shikijs/vscode-textmate": "npm:^10.0.2" + checksum: 10/bc7f1c69640ccece9a3ac3f3adc9cebde9c24bcd722747cc464c338a32725af2b9087a42646cd0f56fbea98d99414918c558f2ca0beadc13db0a740183e7707f languageName: node linkType: hard -"@shikijs/langs@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/langs@npm:1.26.1" +"@shikijs/langs@npm:3.13.0": + version: 3.13.0 + resolution: "@shikijs/langs@npm:3.13.0" dependencies: - "@shikijs/types": "npm:1.26.1" - checksum: 10/b3909ffa30a89aa81e21da3c0af9388dfadab4f5ce9ce6f5a1cc3f7728e46702c02720123bad49dcd3f02e823c0ce9d533534164b0feb57856d2f8ee9504bce2 + "@shikijs/types": "npm:3.13.0" + checksum: 10/2a0478246ce61745d9012cf5051c9790ef5afad6c89fe5716be4a81d04d7dfd9ffc90af0bad0be0061111bfc001a3bc0c55ffd4fc0b82bc1c09a4c33d7b593ca languageName: node linkType: hard -"@shikijs/themes@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/themes@npm:1.26.1" +"@shikijs/themes@npm:3.13.0": + version: 3.13.0 + resolution: "@shikijs/themes@npm:3.13.0" dependencies: - "@shikijs/types": "npm:1.26.1" - checksum: 10/5e2f5fe828f1b74dcc4027239768b3fe91567a5e07c3d014747627a7bd8a5ecf22460c59c20924172a96d99f4deed3e81e6f377e5f81239d6c6666d09e12fbd6 + "@shikijs/types": "npm:3.13.0" + checksum: 10/4ab0ecf1ddb35e387cef22e267cdf3ed7548a84f24ad58885d19401f75cc01a5a10152ee0196222e01cead8202f20012615aa0076f798599f7dfc2bb7beaa617 languageName: node linkType: hard -"@shikijs/types@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/types@npm:1.26.1" +"@shikijs/transformers@npm:^3.13.0": + version: 3.13.0 + resolution: "@shikijs/transformers@npm:3.13.0" dependencies: - "@shikijs/vscode-textmate": "npm:^10.0.1" + "@shikijs/core": "npm:3.13.0" + "@shikijs/types": "npm:3.13.0" + checksum: 10/30f3e66334b60320dc976b9f645f823ba13b312aead4c891ae6db23d076f1570dad488443f603fb5eecd5937973ba7c2907da6678ccae2363a66e0c5b173bb02 + languageName: node + linkType: hard + +"@shikijs/types@npm:3.13.0": + version: 3.13.0 + resolution: "@shikijs/types@npm:3.13.0" + dependencies: + "@shikijs/vscode-textmate": "npm:^10.0.2" "@types/hast": "npm:^3.0.4" - checksum: 10/68ad9307424012cb833c02b7e0db4f0792d6ff9b633591318c76edb5a4ffb84da0de56dbe33b9b62ae810a878fdfd4f9ff6655a067997c664d9b0436266bcb16 + checksum: 10/a57cc95847edd84134166de1f11a044e356581834b2dfd75dcd67f2221aef6f20f505839c090a76b7c8e0a79d7d5cee829de50d261f363a633ae9afca29546c4 languageName: node linkType: hard -"@shikijs/vscode-textmate@npm:^10.0.1": - version: 10.0.1 - resolution: "@shikijs/vscode-textmate@npm:10.0.1" - checksum: 10/8bb005efbf472a9cac19bb5fb0bb1a2b612e128122e5a9d7b2bb2af674c29912db0e59c547ec458e5333f8f7ac7a8f054a24cb653f11dc20951e299933b416e4 +"@shikijs/vscode-textmate@npm:^10.0.2": + version: 10.0.2 + resolution: "@shikijs/vscode-textmate@npm:10.0.2" + checksum: 10/d924cba8a01cd9ca12f56ba097d628fdb81455abb85884c8d8a5ae85b628a37dd5907e7691019b97107bd6608c866adf91ba04a1c3bba391281c88e386c044ea languageName: node linkType: hard -"@storybook/components@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/components@npm:8.6.12" +"@storybook/components@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/components@npm:8.6.14" peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/ccc6af275bdfbc66de8afb272f59b2b4b6b76bb2961903335cb62e7defae4a2368bd8f5a2008f8598dd8417e5368d824bce836ca96c3c6ff659dbf2f081ec0dd + checksum: 10/d3647505510313aa3c32fd1f8f202eda723ad99bd353b20aa929c5ecab4edc3c86ad06d0eac02f3c6d948e88f13f65ca5fa35ef27c079ef1b92abe8692f23699 languageName: node linkType: hard -"@storybook/core@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/core@npm:8.6.12" +"@storybook/core@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/core@npm:8.6.14" dependencies: - "@storybook/theming": "npm:8.6.12" + "@storybook/theming": "npm:8.6.14" better-opn: "npm:^3.0.2" browser-assert: "npm:^1.2.1" esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0" @@ -751,7 +1057,7 @@ __metadata: peerDependenciesMeta: prettier: optional: true - checksum: 10/78776f51b9eae00f9387421b33b646b1dc67ef833fd6272de03399daa7f0ffa248c65b5f24d5d2a9af923a029d06d84d5425e3455302ece542bf47c7a9ec0df6 + checksum: 10/8f8c811edd4ea8dcedcc63a79b3168dc83aa0401e3760990cb5995ea6beaac4026c6ccc1046182f41eed7c09333005f3348d8b42f89fc5dd5b2ce011a9d2a48f languageName: node linkType: hard @@ -762,92 +1068,84 @@ __metadata: languageName: node linkType: hard -"@storybook/manager-api@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/manager-api@npm:8.6.12" +"@storybook/manager-api@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/manager-api@npm:8.6.14" peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/d1c44c6649a024c4007461c12a15337f5d13532dbaccc4c02f71bd99599fb973e2574eb8f1bc2d93e05da24e4ae43fa47ec637a7c4cccf5ffc67045cafbf087c + checksum: 10/4544b317050b81574f1cd6f911dcb99ee2adbd7190555209171a7dd2233cd331165fa11c16a5977ebe58eeaf26c86bbfcb23f701cfd79a10f0d034dae65197bd languageName: node linkType: hard -"@storybook/preview-api@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/preview-api@npm:8.6.12" +"@storybook/preview-api@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/preview-api@npm:8.6.14" peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/d24f11e4e54e9e51297b0f87e1d462b3f14a974b4681f31d93b62b0706ce5b5ed4ffaaac521ec049dcb0e08e7aa7590f2e039aee4bbe9f85033d69474d982f23 + checksum: 10/9b77288f2f627a7c70cfd3e88bdc4348c1425fab6b333ed77efb913e45881bcdf2ca67f1174e47fe978a7993c2a653fb8accf518ba51441cfb9450145101e9d8 languageName: node linkType: hard -"@storybook/react-dom-shim@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/react-dom-shim@npm:8.6.12" +"@storybook/react-dom-shim@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/react-dom-shim@npm:8.6.14" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.6.12 - checksum: 10/7677b4fae978209af239471f9eb609db4318815bd4249a0f48b9875482d9ae910b93fbe4db5d7f794ecc2a1249edf40da26af9de673c941c48fccc4007819c96 + storybook: ^8.6.14 + checksum: 10/d14d970b98dc8266d4df80225538fb537449c15877f0f54465dfe52242f0c3f041c975824cc2894f72a3a8023fdffa0a281d90325b95297858e3684913b3cc15 languageName: node linkType: hard -"@storybook/react@npm:^8.6.8": - version: 8.6.12 - resolution: "@storybook/react@npm:8.6.12" +"@storybook/react@npm:^8.6.12": + version: 8.6.14 + resolution: "@storybook/react@npm:8.6.14" dependencies: - "@storybook/components": "npm:8.6.12" + "@storybook/components": "npm:8.6.14" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:8.6.12" - "@storybook/preview-api": "npm:8.6.12" - "@storybook/react-dom-shim": "npm:8.6.12" - "@storybook/theming": "npm:8.6.12" + "@storybook/manager-api": "npm:8.6.14" + "@storybook/preview-api": "npm:8.6.14" + "@storybook/react-dom-shim": "npm:8.6.14" + "@storybook/theming": "npm:8.6.14" peerDependencies: - "@storybook/test": 8.6.12 + "@storybook/test": 8.6.14 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.6.12 + storybook: ^8.6.14 typescript: ">= 4.2.x" peerDependenciesMeta: "@storybook/test": optional: true typescript: optional: true - checksum: 10/d8258c82743906f48a872a781f3e5a63e9ce3fda2ba3b911e959cf62ebda43989b23746257d97905addb7142ac7e53d0089dc178bcbeea48ed4d37d025dd047b + checksum: 10/a8710dcb80da9df4a78cfb3560a8c0c31c6f6c04902aa95446d4e40f6a9179770ead6f9a0a06fa44d00677cd1cd92eb60fdc57f433035ec722275847139671a4 languageName: node linkType: hard -"@storybook/theming@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/theming@npm:8.6.12" +"@storybook/theming@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/theming@npm:8.6.14" peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/c811d9dbb9eaaa680b922111fca126a2985f2238dfb01c1cd23184323eea12899dc9f079063ac42c5e63b0c83de326bd9cc17241e4060ff04e860c57a55fb8b9 + checksum: 10/6936ea3348968fe598ad47421c11a78c6ee2ce62336ea1ce9cb8257e9faa2553d3ac3e443f8a36d35a41b0d60eb169231516649c710582ec68fdead4f23ffc0e languageName: node linkType: hard -"@swc/counter@npm:^0.1.3": - version: 0.1.3 - resolution: "@swc/counter@npm:0.1.3" - checksum: 10/df8f9cfba9904d3d60f511664c70d23bb323b3a0803ec9890f60133954173047ba9bdeabce28cd70ba89ccd3fd6c71c7b0bd58be85f611e1ffbe5d5c18616598 - languageName: node - linkType: hard - -"@swc/helpers@npm:0.5.5": - version: 0.5.5 - resolution: "@swc/helpers@npm:0.5.5" +"@swc/helpers@npm:0.5.15": + version: 0.5.15 + resolution: "@swc/helpers@npm:0.5.15" + dependencies: + tslib: "npm:^2.8.0" + checksum: 10/e3f32c6deeecfb0fa3f22edff03a7b358e7ce16d27b0f1c8b5cdc3042c5c4ce4da6eac0b781ab7cc4f54696ece657467d56734fb26883439fb00017385364c4c + languageName: node + linkType: hard + +"@tybys/wasm-util@npm:^0.10.0": + version: 0.10.0 + resolution: "@tybys/wasm-util@npm:0.10.0" dependencies: - "@swc/counter": "npm:^0.1.3" tslib: "npm:^2.4.0" - checksum: 10/1c5ef04f642542212df28c669438f3e0f459dcde7b448a5b1fcafb2e9e4f13e76d8428535a270e91ed123dd2a21189dbed34086b88a8cf68baf84984d6d0e39b - languageName: node - linkType: hard - -"@types/acorn@npm:^4.0.0": - version: 4.0.6 - resolution: "@types/acorn@npm:4.0.6" - dependencies: - "@types/estree": "npm:*" - checksum: 10/e00671d5055d06b07feccb8c2841467a4bdd1ab95a29e191d51cacc08c496e1ba1f54edeefab274bb2ba51cb45b0aaaa662a63897650e9d02e9997ad82124ae4 + checksum: 10/779d047a77e8a619b6e26b6fe556f413316d846e9a35438668a15510a4d6e7294388c998f65911f6f1a13838745575d7793cb1d27182752f6f95991725b15d45 languageName: node linkType: hard @@ -870,9 +1168,9 @@ __metadata: linkType: hard "@types/estree@npm:*, @types/estree@npm:^1.0.0": - version: 1.0.6 - resolution: "@types/estree@npm:1.0.6" - checksum: 10/9d35d475095199c23e05b431bcdd1f6fec7380612aed068b14b2a08aa70494de8a9026765a5a91b1073f636fb0368f6d8973f518a31391d519e20c59388ed88d + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10/25a4c16a6752538ffde2826c2cc0c6491d90e69cd6187bef4a006dd2c3c45469f049e643d7e516c515f21484dc3d48fd5c870be158a5beb72f5baf3dc43e4099 languageName: node linkType: hard @@ -892,7 +1190,7 @@ __metadata: languageName: node linkType: hard -"@types/mdast@npm:^4.0.0": +"@types/mdast@npm:^4.0.0, @types/mdast@npm:^4.0.4": version: 4.0.4 resolution: "@types/mdast@npm:4.0.4" dependencies: @@ -909,44 +1207,36 @@ __metadata: linkType: hard "@types/ms@npm:*": - version: 0.7.34 - resolution: "@types/ms@npm:0.7.34" - checksum: 10/f38d36e7b6edecd9badc9cf50474159e9da5fa6965a75186cceaf883278611b9df6669dc3a3cc122b7938d317b68a9e3d573d316fcb35d1be47ec9e468c6bd8a + version: 2.1.0 + resolution: "@types/ms@npm:2.1.0" + checksum: 10/532d2ebb91937ccc4a89389715e5b47d4c66e708d15942fe6cc25add6dc37b2be058230a327dd50f43f89b8b6d5d52b74685a9e8f70516edfc9bdd6be910eff4 languageName: node linkType: hard "@types/node@npm:^20": - version: 20.17.30 - resolution: "@types/node@npm:20.17.30" + version: 20.19.11 + resolution: "@types/node@npm:20.19.11" dependencies: - undici-types: "npm:~6.19.2" - checksum: 10/69fd3b177417be77b459e8f1dd4e78c85c686167086920fbf35a9fda301709bbeee6a87ad2591fb1ddd96c65e725ec6bb527a06496626a1c94367d1361048f8d + undici-types: "npm:~6.21.0" + checksum: 10/7179ed464a781cad20117362df58c12839b40922b53356e1a74f86c99d9d1ef9a27edce360901608f896c247c9c4131ba9c7222331e92cde17b723c75d5c8f2e languageName: node linkType: hard -"@types/prop-types@npm:*": - version: 15.7.14 - resolution: "@types/prop-types@npm:15.7.14" - checksum: 10/d0c5407b9ccc3dd5fae0ccf9b1007e7622ba5e6f1c18399b4f24dff33619d469da4b9fa918a374f19dc0d9fe6a013362aab0b844b606cfc10676efba3f5f736d - languageName: node - linkType: hard - -"@types/react-dom@npm:^18.0.0": - version: 18.3.7 - resolution: "@types/react-dom@npm:18.3.7" +"@types/react-dom@npm:19.1.7": + version: 19.1.7 + resolution: "@types/react-dom@npm:19.1.7" peerDependencies: - "@types/react": ^18.0.0 - checksum: 10/317569219366d487a3103ba1e5e47154e95a002915fdcf73a44162c48fe49c3a57fcf7f57fc6979e70d447112681e6b13c6c3c1df289db8b544df4aab2d318f3 + "@types/react": ^19.0.0 + checksum: 10/a99465e5a17d40725dedb3708357f8998c57caab768cee0992b4bb7822ce7ed2ec697a5f426cb98d3397b020756a6e4b0986dc5f6f4254e13b3536afb38538e6 languageName: node linkType: hard -"@types/react@npm:^18.0.0": - version: 18.3.21 - resolution: "@types/react@npm:18.3.21" +"@types/react@npm:19.1.9": + version: 19.1.9 + resolution: "@types/react@npm:19.1.9" dependencies: - "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/89adc2fe391fd63b620db0aaa10b2be89fad338039415fd748e60c962e47bf2b0f1897cb5226f181eda963f37a1c8ac1bf0b3b29a0e35313bacd0355e5d6c736 + checksum: 10/b1032eae52e3b4f2a8b9ea6aac936385a78b7eff55cad4ff4f0d7e726c6ea87c1f287a1ba0e57a76a8e4456d3fb918b4f97a01e71686fdc11a65b26b8d296be4 languageName: node linkType: hard @@ -965,120 +1255,145 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0": - version: 8.19.1 - resolution: "@typescript-eslint/eslint-plugin@npm:8.19.1" + version: 8.39.1 + resolution: "@typescript-eslint/eslint-plugin@npm:8.39.1" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.19.1" - "@typescript-eslint/type-utils": "npm:8.19.1" - "@typescript-eslint/utils": "npm:8.19.1" - "@typescript-eslint/visitor-keys": "npm:8.19.1" + "@typescript-eslint/scope-manager": "npm:8.39.1" + "@typescript-eslint/type-utils": "npm:8.39.1" + "@typescript-eslint/utils": "npm:8.39.1" + "@typescript-eslint/visitor-keys": "npm:8.39.1" graphemer: "npm:^1.4.0" - ignore: "npm:^5.3.1" + ignore: "npm:^7.0.0" natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^2.0.0" + ts-api-utils: "npm:^2.1.0" peerDependencies: - "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + "@typescript-eslint/parser": ^8.39.1 eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10/c9a6d3181ec01068075b85ad3ac454910b4452281d60c775cc7229827f6d6a076b7336f5f07a7ad89bf08b3224f6a49aa20342b9438702393bee0aa7315d23b2 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/446050aa43d54c0107c7c927ae1f68a4384c2bba514d5c22edabbe355426cb37bd5bb5a3faf240a6be8ef06f68de6099c2a53d9cbb1849ed35a152fb156171e2 languageName: node linkType: hard "@typescript-eslint/parser@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0": - version: 8.19.1 - resolution: "@typescript-eslint/parser@npm:8.19.1" + version: 8.39.1 + resolution: "@typescript-eslint/parser@npm:8.39.1" dependencies: - "@typescript-eslint/scope-manager": "npm:8.19.1" - "@typescript-eslint/types": "npm:8.19.1" - "@typescript-eslint/typescript-estree": "npm:8.19.1" - "@typescript-eslint/visitor-keys": "npm:8.19.1" + "@typescript-eslint/scope-manager": "npm:8.39.1" + "@typescript-eslint/types": "npm:8.39.1" + "@typescript-eslint/typescript-estree": "npm:8.39.1" + "@typescript-eslint/visitor-keys": "npm:8.39.1" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10/da3db63ff655cf0fb91745ba8e52d853386f601cf6106d36f4541efcb9e2c6c3b82c6743b15680eff9eafeccaf31c9b26191a955e66ae19de9172f67335463ab + typescript: ">=4.8.4 <6.0.0" + checksum: 10/ff45ce76353ed564e0f9db47b02b4b20895c96182b3693c610ef3dbceda373c476037a99f90d9f28633c192f301e5d554c89e1ba72da216763f960648ddf1f34 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/scope-manager@npm:8.19.1" +"@typescript-eslint/project-service@npm:8.39.1": + version: 8.39.1 + resolution: "@typescript-eslint/project-service@npm:8.39.1" dependencies: - "@typescript-eslint/types": "npm:8.19.1" - "@typescript-eslint/visitor-keys": "npm:8.19.1" - checksum: 10/6ffc78b15367f211eb6650459ca2bb6bfe4c1fa95a3474adc08ee9a20c250b2e0e02fd99be36bd3dad74967ecd9349e792b5d818d85735cba40f1b5c236074d1 - languageName: node - linkType: hard - -"@typescript-eslint/type-utils@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/type-utils@npm:8.19.1" - dependencies: - "@typescript-eslint/typescript-estree": "npm:8.19.1" - "@typescript-eslint/utils": "npm:8.19.1" + "@typescript-eslint/tsconfig-utils": "npm:^8.39.1" + "@typescript-eslint/types": "npm:^8.39.1" debug: "npm:^4.3.4" - ts-api-utils: "npm:^2.0.0" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10/1970633d1a338190f0125e186beaa39b3ef912f287e4815934faf64b72f140e87fdf7d861962683635a450d270dd76faf0c865d72bfd57b471a36739f943676b + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:8.39.1": + version: 8.39.1 + resolution: "@typescript-eslint/scope-manager@npm:8.39.1" + dependencies: + "@typescript-eslint/types": "npm:8.39.1" + "@typescript-eslint/visitor-keys": "npm:8.39.1" + checksum: 10/8874f7479043b3fc878f2c04b2c565051deceb7e425a8e4e79a7f40f1ee696bb979bd91fff619e016fe6793f537b30609c0ee8a5c40911c4829fa264863f7a70 + languageName: node + linkType: hard + +"@typescript-eslint/tsconfig-utils@npm:8.39.1, @typescript-eslint/tsconfig-utils@npm:^8.39.1": + version: 8.39.1 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.39.1" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10/38c1e1982504e606e525ad0ce47fdb4c7acc686a28a94c2b30fe988c439977e991ce69cb88a1724a41a8096fc2d18d7ced7fe8725e42879d841515ff36a37ecf + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:8.39.1": + version: 8.39.1 + resolution: "@typescript-eslint/type-utils@npm:8.39.1" + dependencies: + "@typescript-eslint/types": "npm:8.39.1" + "@typescript-eslint/typescript-estree": "npm:8.39.1" + "@typescript-eslint/utils": "npm:8.39.1" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^2.1.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10/123ecda88b057d6a4b68226701f435661440a420fda88cba60b49d7fb3e4f49483164ff174f259e28c0beabb0ed04500462a20faefd78331ba202bf54b01e3ef + typescript: ">=4.8.4 <6.0.0" + checksum: 10/1195d65970f79f820558810f7e1edf0ea360bbeee55841fdbb71b5b40c09f1a65741b67a70b85c2834ae1f9a027b82da4234d01f42ab4e85dceef3eea84bfdaa languageName: node linkType: hard -"@typescript-eslint/types@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/types@npm:8.19.1" - checksum: 10/5833a5f8fdac4a490dd3906a0243a0713fbf138fabb451870c70b0b089c539a9624b467b0913ddc0a225a8284342e7fd31cd506dec53c1a6d8f3c8c8902b9cae +"@typescript-eslint/types@npm:8.39.1, @typescript-eslint/types@npm:^8.39.1": + version: 8.39.1 + resolution: "@typescript-eslint/types@npm:8.39.1" + checksum: 10/8013f4f48a98da0de270d5fef1ff28b35407de82fce5acf3efa212fce60bc92a81bbb15b4b358d9facf4f161e49feec856fbf1a6d96f5027d013b542f2fe1bcc languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.19.1" +"@typescript-eslint/typescript-estree@npm:8.39.1": + version: 8.39.1 + resolution: "@typescript-eslint/typescript-estree@npm:8.39.1" dependencies: - "@typescript-eslint/types": "npm:8.19.1" - "@typescript-eslint/visitor-keys": "npm:8.19.1" + "@typescript-eslint/project-service": "npm:8.39.1" + "@typescript-eslint/tsconfig-utils": "npm:8.39.1" + "@typescript-eslint/types": "npm:8.39.1" + "@typescript-eslint/visitor-keys": "npm:8.39.1" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" minimatch: "npm:^9.0.4" semver: "npm:^7.6.0" - ts-api-utils: "npm:^2.0.0" + ts-api-utils: "npm:^2.1.0" peerDependencies: - typescript: ">=4.8.4 <5.8.0" - checksum: 10/5de467452d5ef1a380d441b06cd0134652a0c98cdb4ce31b93eb589f7dc75ef60364d03fd80ca0a48d0c8b268f7258d4f6528b16fe1b89442d60a4bc960fe5f5 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/07ed9d7ab4d146ee3ce6cf82ffebf947e045a9289b01522e11b3985b64f590c00cac0ca10366df828ca213bf08216a67c7b2b76e7c8be650df2511a7e6385425 languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/utils@npm:8.19.1" +"@typescript-eslint/utils@npm:8.39.1": + version: 8.39.1 + resolution: "@typescript-eslint/utils@npm:8.39.1" dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.19.1" - "@typescript-eslint/types": "npm:8.19.1" - "@typescript-eslint/typescript-estree": "npm:8.19.1" + "@eslint-community/eslint-utils": "npm:^4.7.0" + "@typescript-eslint/scope-manager": "npm:8.39.1" + "@typescript-eslint/types": "npm:8.39.1" + "@typescript-eslint/typescript-estree": "npm:8.39.1" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10/bb92116a53fe143ee87e830941afb21d4222a64ca3f2b6dac5c2d9984f981408e60e52b04c32d95208896075ac222fb4ee631c5b0c4826b87d4bd8091c421ab1 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/39bb105f26aa1ba234ad7d284c277cbd66df9d51e245094892db140aac80d3656d0480f133b2db54e87af3ef9c371a12973120c9cfbff71e8e85865f9e1d0077 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.19.1" +"@typescript-eslint/visitor-keys@npm:8.39.1": + version: 8.39.1 + resolution: "@typescript-eslint/visitor-keys@npm:8.39.1" dependencies: - "@typescript-eslint/types": "npm:8.19.1" - eslint-visitor-keys: "npm:^4.2.0" - checksum: 10/510eb196e7b7d59d3981d672a75454615159e931fe78e2a64b09607c3cfa45110709b0eb5ac3dd271d757a0d98cf4868ad2f45bf9193f96e9efec3efa92a19c1 + "@typescript-eslint/types": "npm:8.39.1" + eslint-visitor-keys: "npm:^4.2.1" + checksum: 10/6d4e4d0b19ebb3f21b692bbb0dcf9961876ca28cdf502296888a78eb4cd802a2ec8d3d5721d19970411edfd1c06f3e272e4057014c859ee1f0546804d07945e3 languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.23.7": - version: 4.23.7 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.23.7" +"@uiw/codemirror-extensions-basic-setup@npm:4.25.1": + version: 4.25.1 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.25.1" dependencies: "@codemirror/autocomplete": "npm:^6.0.0" "@codemirror/commands": "npm:^6.0.0" @@ -1095,13 +1410,13 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: 10/7b8cbb9ccc931bc1a6909d009e653f78797e4b851aa9fb8e11f90ae1cea233e643a1951ad4ad9e10123ef166808acee1acff24732ea9fc15cd77164f6b179b91 + checksum: 10/61d128a7896e086c3cc0558e0b5f85715f5387ee983cc9f1e341db4b383ade1973f389a63cdf9312a5421a0f5a6044755a573d6dd7bb805dc256d9f9ce4f0d15 languageName: node linkType: hard "@uiw/codemirror-themes@npm:^4.23.7": - version: 4.23.12 - resolution: "@uiw/codemirror-themes@npm:4.23.12" + version: 4.25.1 + resolution: "@uiw/codemirror-themes@npm:4.25.1" dependencies: "@codemirror/language": "npm:^6.0.0" "@codemirror/state": "npm:^6.0.0" @@ -1110,19 +1425,19 @@ __metadata: "@codemirror/language": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: 10/472121efadf2b9eb110030f06d657cb9693861e1ca360c81c7b0d7aa4533e6e6791737dfd14bcbe496bcb818d33f4cf6a18caf504ec628807e273441f969ef83 + checksum: 10/337316f7c15a57bca4824498769448e38861197ab3d73b3bc58b2193028751c525a175af06f1f3984fd25b001f990e1d30ce442ddc756642698d9f8adff7f95a languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.23.7": - version: 4.23.7 - resolution: "@uiw/react-codemirror@npm:4.23.7" + version: 4.25.1 + resolution: "@uiw/react-codemirror@npm:4.25.1" dependencies: "@babel/runtime": "npm:^7.18.6" "@codemirror/commands": "npm:^6.1.0" "@codemirror/state": "npm:^6.1.1" "@codemirror/theme-one-dark": "npm:^6.0.0" - "@uiw/codemirror-extensions-basic-setup": "npm:4.23.7" + "@uiw/codemirror-extensions-basic-setup": "npm:4.25.1" codemirror: "npm:^6.0.0" peerDependencies: "@babel/runtime": ">=7.11.0" @@ -1130,16 +1445,158 @@ __metadata: "@codemirror/theme-one-dark": ">=6.0.0" "@codemirror/view": ">=6.0.0" codemirror: ">=6.0.0" - react: ">=16.8.0" - react-dom: ">=16.8.0" - checksum: 10/dc6f1fd2f1863120e29ea331b2e279054bf508f00656d3fed97779f17818ae00b6cf9d74d3b0996800174d444b59702da74ca88c303db563daad85c0824fc952 + react: ">=17.0.0" + react-dom: ">=17.0.0" + checksum: 10/32311a3b2037bf57533bd4d7c50117385c6e3cfce8dcd45f2c2ff8d9170f8ae53bc868b4ac91a58f5502ed065fce11bfffb8af5e829e8a5609290053dcdb0b2e languageName: node linkType: hard "@ungap/structured-clone@npm:^1.0.0, @ungap/structured-clone@npm:^1.2.0": - version: 1.2.1 - resolution: "@ungap/structured-clone@npm:1.2.1" - checksum: 10/6770f71e8183311b2871601ddb02d62a26373be7cf2950cb546a345a2305c75b502e36ce80166120aa2f5f1ea1562141684651ebbfcc711c58acd32035d3e545 + version: 1.3.0 + resolution: "@ungap/structured-clone@npm:1.3.0" + checksum: 10/80d6910946f2b1552a2406650051c91bbd1f24a6bf854354203d84fe2714b3e8ce4618f49cc3410494173a1c1e8e9777372fe68dce74bd45faf0a7a1a6ccf448 + languageName: node + linkType: hard + +"@unrs/resolver-binding-android-arm-eabi@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.11.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-android-arm64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-android-arm64@npm:1.11.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-arm64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.11.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-x64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-darwin-x64@npm:1.11.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-freebsd-x64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.11.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-musl@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.11.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-wasm32-wasi@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.11.1" + dependencies: + "@napi-rs/wasm-runtime": "npm:^0.2.11" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"abbrev@npm:^3.0.0": + version: 3.0.1 + resolution: "abbrev@npm:3.0.1" + checksum: 10/ebd2c149dda6f543b66ce3779ea612151bb3aa9d0824f169773ee9876f1ca5a4e0adbcccc7eed048c04da7998e1825e2aa76fcca92d9e67dea50ac2b0a58dc2e languageName: node linkType: hard @@ -1153,11 +1610,18 @@ __metadata: linkType: hard "acorn@npm:^8.0.0, acorn@npm:^8.9.0": - version: 8.14.0 - resolution: "acorn@npm:8.14.0" + version: 8.15.0 + resolution: "acorn@npm:8.15.0" bin: acorn: bin/acorn - checksum: 10/6df29c35556782ca9e632db461a7f97947772c6c1d5438a81f0c873a3da3a792487e83e404d1c6c25f70513e91aa18745f6eafb1fcc3a43ecd1920b21dd173d2 + checksum: 10/77f2de5051a631cf1729c090e5759148459cdb76b5f5c70f890503d629cf5052357b0ce783c0f976dd8a93c5150f59f6d18df1def3f502396a20f81282482fa4 + languageName: node + linkType: hard + +"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": + version: 7.1.4 + resolution: "agent-base@npm:7.1.4" + checksum: 10/79bef167247789f955aaba113bae74bf64aa1e1acca4b1d6bb444bdf91d82c3e07e9451ef6a6e2e35e8f71a6f97ce33e3d855a5328eb9fad1bc3cc4cfd031ed8 languageName: node linkType: hard @@ -1203,6 +1667,16 @@ __metadata: languageName: node linkType: hard +"anymatch@npm:~3.1.2": + version: 3.1.3 + resolution: "anymatch@npm:3.1.3" + dependencies: + normalize-path: "npm:^3.0.0" + picomatch: "npm:^2.0.4" + checksum: 10/3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2 + languageName: node + linkType: hard + "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -1227,17 +1701,19 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8": - version: 3.1.8 - resolution: "array-includes@npm:3.1.8" +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8, array-includes@npm:^3.1.9": + version: 3.1.9 + resolution: "array-includes@npm:3.1.9" dependencies: - call-bind: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.4" - is-string: "npm:^1.0.7" - checksum: 10/290b206c9451f181fb2b1f79a3bf1c0b66bb259791290ffbada760c79b284eef6f5ae2aeb4bcff450ebc9690edd25732c4c73a3c2b340fcc0f4563aed83bf488 + es-abstract: "npm:^1.24.0" + es-object-atoms: "npm:^1.1.1" + get-intrinsic: "npm:^1.3.0" + is-string: "npm:^1.1.1" + math-intrinsics: "npm:^1.1.0" + checksum: 10/8bfe9a58df74f326b4a76b04ee05c13d871759e888b4ee8f013145297cf5eb3c02cfa216067ebdaac5d74eb9763ac5cad77cdf2773b8ab475833701e032173aa languageName: node linkType: hard @@ -1255,21 +1731,22 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlastindex@npm:^1.2.5": - version: 1.2.5 - resolution: "array.prototype.findlastindex@npm:1.2.5" +"array.prototype.findlastindex@npm:^1.2.6": + version: 1.2.6 + resolution: "array.prototype.findlastindex@npm:1.2.6" dependencies: - call-bind: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" + es-abstract: "npm:^1.23.9" es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-shim-unscopables: "npm:^1.0.2" - checksum: 10/7c5c821f357cd53ab6cc305de8086430dd8d7a2485db87b13f843e868055e9582b1fd338f02338f67fc3a1603ceaf9610dd2a470b0b506f9d18934780f95b246 + es-object-atoms: "npm:^1.1.1" + es-shim-unscopables: "npm:^1.1.0" + checksum: 10/5ddb6420e820bef6ddfdcc08ce780d0fd5e627e97457919c27e32359916de5a11ce12f7c55073555e503856618eaaa70845d6ca11dcba724766f38eb1c22f7a2 languageName: node linkType: hard -"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.3": version: 1.3.3 resolution: "array.prototype.flat@npm:1.3.3" dependencies: @@ -1346,6 +1823,13 @@ __metadata: languageName: node linkType: hard +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 10/1a09379937d846f0ce7614e75071c12826945d4e417db634156bf0e4673c495989302f52186dfa9767a1d9181794554717badd193ca2bbab046ef1da741d8efd + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" @@ -1356,9 +1840,9 @@ __metadata: linkType: hard "axe-core@npm:^4.10.0": - version: 4.10.2 - resolution: "axe-core@npm:4.10.2" - checksum: 10/a69423b2ff16c15922c4ea7cf9cc5112728a2817bbe0f2cc212248d648885ffd1ba554e3a341dfc289cd9e67fc0d06f333b5c6837c5c38ca6652507381216fc1 + version: 4.10.3 + resolution: "axe-core@npm:4.10.3" + checksum: 10/9ff51ad0fd0fdec5c0247ea74e8ace5990b54c7f01f8fa3e5cd8ba98b0db24d8ebd7bab4a9bd4d75c28c4edcd1eac455b44c8c6c258c6a98f3d2f88bc60af4cc languageName: node linkType: hard @@ -1392,26 +1876,33 @@ __metadata: languageName: node linkType: hard +"binary-extensions@npm:^2.0.0": + version: 2.3.0 + resolution: "binary-extensions@npm:2.3.0" + checksum: 10/bcad01494e8a9283abf18c1b967af65ee79b0c6a9e6fcfafebfe91dbe6e0fc7272bafb73389e198b310516ae04f7ad17d79aacf6cb4c0d5d5202a7e2e52c7d98 + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": - version: 1.1.11 - resolution: "brace-expansion@npm:1.1.11" + version: 1.1.12 + resolution: "brace-expansion@npm:1.1.12" dependencies: balanced-match: "npm:^1.0.0" concat-map: "npm:0.0.1" - checksum: 10/faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + checksum: 10/12cb6d6310629e3048cadb003e1aca4d8c9bb5c67c3c321bafdd7e7a50155de081f78ea3e0ed92ecc75a9015e784f301efc8132383132f4f7904ad1ac529c562 languageName: node linkType: hard "brace-expansion@npm:^2.0.1": - version: 2.0.1 - resolution: "brace-expansion@npm:2.0.1" + version: 2.0.2 + resolution: "brace-expansion@npm:2.0.2" dependencies: balanced-match: "npm:^1.0.0" - checksum: 10/a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + checksum: 10/01dff195e3646bc4b0d27b63d9bab84d2ebc06121ff5013ad6e5356daa5a9d6b60fa26cf73c74797f2dc3fbec112af13578d51f75228c1112b26c790a87b0488 languageName: node linkType: hard -"braces@npm:^3.0.3": +"braces@npm:^3.0.3, braces@npm:~3.0.2": version: 3.0.3 resolution: "braces@npm:3.0.3" dependencies: @@ -1427,12 +1918,23 @@ __metadata: languageName: node linkType: hard -"busboy@npm:1.6.0": - version: 1.6.0 - resolution: "busboy@npm:1.6.0" +"cacache@npm:^19.0.1": + version: 19.0.1 + resolution: "cacache@npm:19.0.1" dependencies: - streamsearch: "npm:^1.1.0" - checksum: 10/bee10fa10ea58e7e3e7489ffe4bda6eacd540a17de9f9cd21cc37e297b2dd9fe52b2715a5841afaec82900750d810d01d7edb4b2d456427f449b92b417579763 + "@npmcli/fs": "npm:^4.0.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^7.0.2" + ssri: "npm:^12.0.0" + tar: "npm:^7.4.3" + unique-filename: "npm:^4.0.0" + checksum: 10/ea026b27b13656330c2bbaa462a88181dcaa0435c1c2e705db89b31d9bdf7126049d6d0445ba746dca21454a0cfdf1d6f47fd39d34c8c8435296b30bc5738a13 languageName: node linkType: hard @@ -1476,42 +1978,12 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001579": - version: 1.0.30001690 - resolution: "caniuse-lite@npm:1.0.30001690" - checksum: 10/9fb4659eb09a298601b9593739072c481e2f5cc524bd0530e5e0f002e66246da5e866669854dfc0d53195ee36b201dab02f7933a7cdf60ccba7adb2d4a304caf + version: 1.0.30001735 + resolution: "caniuse-lite@npm:1.0.30001735" + checksum: 10/4b404ed363a5ccf3ec07144c2360106aa47dcec1f896ea6705a2773c6977e9ffb19a2b58be9492462733170e29b4823211533b0986d5a25f0f65f7ff702470ab languageName: node linkType: hard -"canon-docs@workspace:.": - version: 0.0.0-use.local - resolution: "canon-docs@workspace:." - dependencies: - "@codemirror/lang-sass": "npm:^6.0.2" - "@lezer/highlight": "npm:^1.2.1" - "@mdx-js/loader": "npm:^3.1.0" - "@mdx-js/react": "npm:^3.1.0" - "@next/mdx": "npm:^15.1.4" - "@storybook/react": "npm:^8.6.8" - "@types/mdx": "npm:^2.0.13" - "@types/node": "npm:^20" - "@types/react": "npm:^18.0.0" - "@types/react-dom": "npm:^18.0.0" - "@uiw/codemirror-themes": "npm:^4.23.7" - "@uiw/react-codemirror": "npm:^4.23.7" - eslint: "npm:^8" - eslint-config-next: "npm:14.2.23" - lightningcss: "npm:^1.28.2" - motion: "npm:^12.4.1" - next: "npm:14.2.26" - react: "npm:^18.0.2" - react-dom: "npm:^18.0.2" - react-frame-component: "npm:^5.2.7" - shiki: "npm:^1.26.1" - storybook: "npm:^8.6.8" - typescript: "npm:^5" - languageName: unknown - linkType: soft - "ccount@npm:^2.0.0": version: 2.0.1 resolution: "ccount@npm:2.0.1" @@ -1557,6 +2029,32 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^3.6.0": + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" + dependencies: + anymatch: "npm:~3.1.2" + braces: "npm:~3.0.2" + fsevents: "npm:~2.3.2" + glob-parent: "npm:~5.1.2" + is-binary-path: "npm:~2.1.0" + is-glob: "npm:~4.0.1" + normalize-path: "npm:~3.0.0" + readdirp: "npm:~3.6.0" + dependenciesMeta: + fsevents: + optional: true + checksum: 10/c327fb07704443f8d15f7b4a7ce93b2f0bc0e6cea07ec28a7570aa22cd51fcf0379df589403976ea956c369f25aa82d84561947e227cd925902e1751371658df + languageName: node + linkType: hard + +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: 10/b63cb1f73d171d140a2ed8154ee6566c8ab775d3196b0e03a2a94b5f6a0ce7777ee5685ca56849403c8d17bd457a6540672f9a60696a6137c7a409097495b82c + languageName: node + linkType: hard + "client-only@npm:0.0.1": version: 0.0.1 resolution: "client-only@npm:0.0.1" @@ -1564,9 +2062,16 @@ __metadata: languageName: node linkType: hard +"clsx@npm:^2.1.1": + version: 2.1.1 + resolution: "clsx@npm:2.1.1" + checksum: 10/cdfb57fa6c7649bbff98d9028c2f0de2f91c86f551179541cf784b1cfdc1562dcb951955f46d54d930a3879931a980e32a46b598acaea274728dbe068deca919 + languageName: node + linkType: hard + "codemirror@npm:^6.0.0": - version: 6.0.1 - resolution: "codemirror@npm:6.0.1" + version: 6.0.2 + resolution: "codemirror@npm:6.0.2" dependencies: "@codemirror/autocomplete": "npm:^6.0.0" "@codemirror/commands": "npm:^6.0.0" @@ -1575,7 +2080,7 @@ __metadata: "@codemirror/search": "npm:^6.0.0" "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.0.0" - checksum: 10/4f858cde1cf8ce4670de9df4a64f4990bb8abdb8e13d3e437f278c40c86d841ef505aa1e5dc798582109ceaac8577a3bb4a1f026c0e5ce730465c89652ee6036 + checksum: 10/bd73c9ebbd8cb709a697fa4e2484c188c44aafce4b4d2a342807a5648c6be5bd5876f0caac47db0c1181f1ec8d86e38bd2b6efe51b971bf240fd3382bef0b371 languageName: node linkType: hard @@ -1595,13 +2100,33 @@ __metadata: languageName: node linkType: hard -"color-name@npm:~1.1.4": +"color-name@npm:^1.0.0, color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" checksum: 10/b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 languageName: node linkType: hard +"color-string@npm:^1.9.0": + version: 1.9.1 + resolution: "color-string@npm:1.9.1" + dependencies: + color-name: "npm:^1.0.0" + simple-swizzle: "npm:^0.2.2" + checksum: 10/72aa0b81ee71b3f4fb1ac9cd839cdbd7a011a7d318ef58e6cb13b3708dca75c7e45029697260488709f1b1c7ac4e35489a87e528156c1e365917d1c4ccb9b9cd + languageName: node + linkType: hard + +"color@npm:^4.2.3": + version: 4.2.3 + resolution: "color@npm:4.2.3" + dependencies: + color-convert: "npm:^2.0.1" + color-string: "npm:^1.9.0" + checksum: 10/b23f5e500a79ea22428db43d1a70642d983405c0dd1f95ef59dbdb9ba66afbb4773b334fa0b75bb10b0552fd7534c6b28d4db0a8b528f91975976e70973c0152 + languageName: node + linkType: hard + "comma-separated-tokens@npm:^2.0.0": version: 2.0.3 resolution: "comma-separated-tokens@npm:2.0.3" @@ -1616,14 +2141,14 @@ __metadata: languageName: node linkType: hard -"crelt@npm:^1.0.5": +"crelt@npm:^1.0.5, crelt@npm:^1.0.6": version: 1.0.6 resolution: "crelt@npm:1.0.6" checksum: 10/5ed326ca6bd243b1dba6b943f665b21c2c04be03271824bc48f20dba324b0f8233e221f8c67312526d24af2b1243c023dc05a41bd8bd05d1a479fd2c72fb39c3 languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2": +"cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -1681,6 +2206,18 @@ __metadata: languageName: node linkType: hard +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0": + version: 4.4.1 + resolution: "debug@npm:4.4.1" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10/8e2709b2144f03c7950f8804d01ccb3786373df01e406a0f66928e47001cf2d336cbed9ee137261d4f90d68d8679468c755e3548ed83ddacdc82b194d2468afe + languageName: node + linkType: hard + "debug@npm:^3.2.7": version: 3.2.7 resolution: "debug@npm:3.2.7" @@ -1690,24 +2227,12 @@ __metadata: languageName: node linkType: hard -"debug@npm:^4.0.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.7": - version: 4.4.0 - resolution: "debug@npm:4.4.0" - dependencies: - ms: "npm:^2.1.3" - peerDependenciesMeta: - supports-color: - optional: true - checksum: 10/1847944c2e3c2c732514b93d11886575625686056cd765336212dc15de2d2b29612b6cd80e1afba767bb8e1803b778caf9973e98169ef1a24a7a7009e1820367 - languageName: node - linkType: hard - "decode-named-character-reference@npm:^1.0.0": - version: 1.0.2 - resolution: "decode-named-character-reference@npm:1.0.2" + version: 1.2.0 + resolution: "decode-named-character-reference@npm:1.2.0" dependencies: character-entities: "npm:^2.0.0" - checksum: 10/f4c71d3b93105f20076052f9cb1523a22a9c796b8296cd35eef1ca54239c78d182c136a848b83ff8da2071e3ae2b1d300bf29d00650a6d6e675438cc31b11d78 + checksum: 10/f26b23046c1a137c0b41fa51e3ce07ba8364640322c742a31570999784abc8572fc24cb108a76b14ff72ddb75d35aad3d14b10d7743639112145a2664b9d1864 languageName: node linkType: hard @@ -1754,10 +2279,10 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.3": - version: 2.0.3 - resolution: "detect-libc@npm:2.0.3" - checksum: 10/b4ea018d623e077bd395f168a9e81db77370dde36a5b01d067f2ad7989924a81d31cb547ff764acb2aa25d50bb7fdde0b0a93bec02212b0cb430621623246d39 +"detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4": + version: 2.0.4 + resolution: "detect-libc@npm:2.0.4" + checksum: 10/136e995f8c5ffbc515955b0175d441b967defd3d5f2268e89fa695e9c7170d8bed17993e31a34b04f0fad33d844a3a598e0fd519a8e9be3cad5f67662d96fee0 languageName: node linkType: hard @@ -1770,6 +2295,43 @@ __metadata: languageName: node linkType: hard +"docs-ui@workspace:.": + version: 0.0.0-use.local + resolution: "docs-ui@workspace:." + dependencies: + "@codemirror/lang-sass": "npm:^6.0.2" + "@codemirror/view": "npm:^6.34.4" + "@lezer/highlight": "npm:^1.2.1" + "@mdx-js/loader": "npm:^3.1.0" + "@mdx-js/react": "npm:^3.1.0" + "@next/mdx": "npm:15.3.4" + "@remixicon/react": "npm:^4.6.0" + "@shikijs/transformers": "npm:^3.13.0" + "@storybook/react": "npm:^8.6.12" + "@types/mdx": "npm:^2.0.13" + "@types/node": "npm:^20" + "@types/react": "npm:19.1.9" + "@types/react-dom": "npm:19.1.7" + "@uiw/codemirror-themes": "npm:^4.23.7" + "@uiw/react-codemirror": "npm:^4.23.7" + chokidar: "npm:^3.6.0" + clsx: "npm:^2.1.1" + eslint: "npm:^8" + eslint-config-next: "npm:15.3.4" + html-react-parser: "npm:^5.2.5" + lightningcss: "npm:^1.28.2" + motion: "npm:^12.4.1" + next: "npm:15.4.7" + next-mdx-remote-client: "npm:^2.1.2" + prop-types: "npm:^15.8.1" + react: "npm:19.1.1" + react-dom: "npm:19.1.1" + shiki: "npm:^3.13.0" + storybook: "npm:^8.6.12" + typescript: "npm:^5" + languageName: unknown + linkType: soft + "doctrine@npm:^2.1.0": version: 2.1.0 resolution: "doctrine@npm:2.1.0" @@ -1788,6 +2350,44 @@ __metadata: languageName: node linkType: hard +"dom-serializer@npm:^2.0.0": + version: 2.0.0 + resolution: "dom-serializer@npm:2.0.0" + dependencies: + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.2" + entities: "npm:^4.2.0" + checksum: 10/e3bf9027a64450bca0a72297ecdc1e3abb7a2912268a9f3f5d33a2e29c1e2c3502c6e9f860fc6625940bfe0cfb57a44953262b9e94df76872fdfb8151097eeb3 + languageName: node + linkType: hard + +"domelementtype@npm:^2.3.0": + version: 2.3.0 + resolution: "domelementtype@npm:2.3.0" + checksum: 10/ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6 + languageName: node + linkType: hard + +"domhandler@npm:5.0.3, domhandler@npm:^5.0.2, domhandler@npm:^5.0.3": + version: 5.0.3 + resolution: "domhandler@npm:5.0.3" + dependencies: + domelementtype: "npm:^2.3.0" + checksum: 10/809b805a50a9c6884a29f38aec0a4e1b4537f40e1c861950ed47d10b049febe6b79ab72adaeeebb3cc8fc1cd33f34e97048a72a9265103426d93efafa78d3e96 + languageName: node + linkType: hard + +"domutils@npm:^3.2.1": + version: 3.2.2 + resolution: "domutils@npm:3.2.2" + dependencies: + dom-serializer: "npm:^2.0.0" + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + checksum: 10/2e08842151aa406f50fe5e6d494f4ec73c2373199fa00d1f77b56ec604e566b7f226312ae35ab8160bb7f27a27c7285d574c8044779053e499282ca9198be210 + languageName: node + linkType: hard + "dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" @@ -1806,13 +2406,6 @@ __metadata: languageName: node linkType: hard -"emoji-regex-xs@npm:^1.0.0": - version: 1.0.0 - resolution: "emoji-regex-xs@npm:1.0.0" - checksum: 10/e216ec4270f765e1097cefc1b9518a7166b872b4424c60a85d79765f318d989cd458e036c76c13e9ce2ed1fe1bb5935a7fd5c1fab7600668bc8e92a789045b3c - languageName: node - linkType: hard - "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -1827,36 +2420,63 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.15.0": - version: 5.18.0 - resolution: "enhanced-resolve@npm:5.18.0" +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" dependencies: - graceful-fs: "npm:^4.2.4" - tapable: "npm:^2.2.0" - checksum: 10/e88463ef97b68d40d0da0cd0c572e23f43dba0be622d6d44eae5cafed05f0c5dac43e463a83a86c4f70186d029357f82b56d9e1e47e8fc91dce3d6602f8bd6ce + iconv-lite: "npm:^0.6.2" + checksum: 10/bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f languageName: node linkType: hard -"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9": - version: 1.23.9 - resolution: "es-abstract@npm:1.23.9" +"entities@npm:^4.2.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: 10/ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48 + languageName: node + linkType: hard + +"entities@npm:^6.0.0": + version: 6.0.1 + resolution: "entities@npm:6.0.1" + checksum: 10/62af1307202884349d2867f0aac5c60d8b57102ea0b0e768b16246099512c28e239254ad772d6834e7e14cb1b6f153fc3d0c031934e3183b086c86d3838d874a + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10/65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 10/1d20d825cdcce8d811bfbe86340f4755c02655a7feb2f13f8c880566d9d72a3f6c92c192a6867632e490d6da67b678271f46e01044996a6443e870331100dfdd + languageName: node + linkType: hard + +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0": + version: 1.24.0 + resolution: "es-abstract@npm:1.24.0" dependencies: array-buffer-byte-length: "npm:^1.0.2" arraybuffer.prototype.slice: "npm:^1.0.4" available-typed-arrays: "npm:^1.0.7" call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.3" + call-bound: "npm:^1.0.4" data-view-buffer: "npm:^1.0.2" data-view-byte-length: "npm:^1.0.2" data-view-byte-offset: "npm:^1.0.1" es-define-property: "npm:^1.0.1" es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" + es-object-atoms: "npm:^1.1.1" es-set-tostringtag: "npm:^2.1.0" es-to-primitive: "npm:^1.3.0" function.prototype.name: "npm:^1.1.8" - get-intrinsic: "npm:^1.2.7" - get-proto: "npm:^1.0.0" + get-intrinsic: "npm:^1.3.0" + get-proto: "npm:^1.0.1" get-symbol-description: "npm:^1.1.0" globalthis: "npm:^1.0.4" gopd: "npm:^1.2.0" @@ -1868,21 +2488,24 @@ __metadata: is-array-buffer: "npm:^3.0.5" is-callable: "npm:^1.2.7" is-data-view: "npm:^1.0.2" + is-negative-zero: "npm:^2.0.3" is-regex: "npm:^1.2.1" + is-set: "npm:^2.0.3" is-shared-array-buffer: "npm:^1.0.4" is-string: "npm:^1.1.1" is-typed-array: "npm:^1.1.15" - is-weakref: "npm:^1.1.0" + is-weakref: "npm:^1.1.1" math-intrinsics: "npm:^1.1.0" - object-inspect: "npm:^1.13.3" + object-inspect: "npm:^1.13.4" object-keys: "npm:^1.1.1" object.assign: "npm:^4.1.7" own-keys: "npm:^1.0.1" - regexp.prototype.flags: "npm:^1.5.3" + regexp.prototype.flags: "npm:^1.5.4" safe-array-concat: "npm:^1.1.3" safe-push-apply: "npm:^1.0.0" safe-regex-test: "npm:^1.1.0" set-proto: "npm:^1.0.0" + stop-iteration-iterator: "npm:^1.1.0" string.prototype.trim: "npm:^1.2.10" string.prototype.trimend: "npm:^1.0.9" string.prototype.trimstart: "npm:^1.0.8" @@ -1891,8 +2514,8 @@ __metadata: typed-array-byte-offset: "npm:^1.0.4" typed-array-length: "npm:^1.0.7" unbox-primitive: "npm:^1.1.0" - which-typed-array: "npm:^1.1.18" - checksum: 10/31a321966d760d88fc2ed984104841b42f4f24fc322b246002b9be0af162e03803ee41fcc3cf8be89e07a27ba3033168f877dd983703cb81422ffe5322a27582 + which-typed-array: "npm:^1.1.19" + checksum: 10/64e07a886f7439cf5ccfc100f9716e6173e10af6071a50a5031afbdde474a3dbc9619d5965da54e55f8908746a9134a46be02af8c732d574b7b81ed3124e2daf languageName: node linkType: hard @@ -1955,12 +2578,12 @@ __metadata: languageName: node linkType: hard -"es-shim-unscopables@npm:^1.0.2": - version: 1.0.2 - resolution: "es-shim-unscopables@npm:1.0.2" +"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0": + version: 1.1.0 + resolution: "es-shim-unscopables@npm:1.1.0" dependencies: - hasown: "npm:^2.0.0" - checksum: 10/6d3bf91f658a27cc7217cd32b407a0d714393a84d125ad576319b9e83a893bea165cf41270c29e9ceaa56d3cf41608945d7e2a2c31fd51c0009b0c31402b91c7 + hasown: "npm:^2.0.2" + checksum: 10/c351f586c30bbabc62355be49564b2435468b52c3532b8a1663672e3d10dc300197e69c247869dd173e56d86423ab95fc0c10b0939cdae597094e0fdca078cba languageName: node linkType: hard @@ -2011,34 +2634,35 @@ __metadata: linkType: hard "esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0": - version: 0.25.0 - resolution: "esbuild@npm:0.25.0" + version: 0.25.9 + resolution: "esbuild@npm:0.25.9" dependencies: - "@esbuild/aix-ppc64": "npm:0.25.0" - "@esbuild/android-arm": "npm:0.25.0" - "@esbuild/android-arm64": "npm:0.25.0" - "@esbuild/android-x64": "npm:0.25.0" - "@esbuild/darwin-arm64": "npm:0.25.0" - "@esbuild/darwin-x64": "npm:0.25.0" - "@esbuild/freebsd-arm64": "npm:0.25.0" - "@esbuild/freebsd-x64": "npm:0.25.0" - "@esbuild/linux-arm": "npm:0.25.0" - "@esbuild/linux-arm64": "npm:0.25.0" - "@esbuild/linux-ia32": "npm:0.25.0" - "@esbuild/linux-loong64": "npm:0.25.0" - "@esbuild/linux-mips64el": "npm:0.25.0" - "@esbuild/linux-ppc64": "npm:0.25.0" - "@esbuild/linux-riscv64": "npm:0.25.0" - "@esbuild/linux-s390x": "npm:0.25.0" - "@esbuild/linux-x64": "npm:0.25.0" - "@esbuild/netbsd-arm64": "npm:0.25.0" - "@esbuild/netbsd-x64": "npm:0.25.0" - "@esbuild/openbsd-arm64": "npm:0.25.0" - "@esbuild/openbsd-x64": "npm:0.25.0" - "@esbuild/sunos-x64": "npm:0.25.0" - "@esbuild/win32-arm64": "npm:0.25.0" - "@esbuild/win32-ia32": "npm:0.25.0" - "@esbuild/win32-x64": "npm:0.25.0" + "@esbuild/aix-ppc64": "npm:0.25.9" + "@esbuild/android-arm": "npm:0.25.9" + "@esbuild/android-arm64": "npm:0.25.9" + "@esbuild/android-x64": "npm:0.25.9" + "@esbuild/darwin-arm64": "npm:0.25.9" + "@esbuild/darwin-x64": "npm:0.25.9" + "@esbuild/freebsd-arm64": "npm:0.25.9" + "@esbuild/freebsd-x64": "npm:0.25.9" + "@esbuild/linux-arm": "npm:0.25.9" + "@esbuild/linux-arm64": "npm:0.25.9" + "@esbuild/linux-ia32": "npm:0.25.9" + "@esbuild/linux-loong64": "npm:0.25.9" + "@esbuild/linux-mips64el": "npm:0.25.9" + "@esbuild/linux-ppc64": "npm:0.25.9" + "@esbuild/linux-riscv64": "npm:0.25.9" + "@esbuild/linux-s390x": "npm:0.25.9" + "@esbuild/linux-x64": "npm:0.25.9" + "@esbuild/netbsd-arm64": "npm:0.25.9" + "@esbuild/netbsd-x64": "npm:0.25.9" + "@esbuild/openbsd-arm64": "npm:0.25.9" + "@esbuild/openbsd-x64": "npm:0.25.9" + "@esbuild/openharmony-arm64": "npm:0.25.9" + "@esbuild/sunos-x64": "npm:0.25.9" + "@esbuild/win32-arm64": "npm:0.25.9" + "@esbuild/win32-ia32": "npm:0.25.9" + "@esbuild/win32-x64": "npm:0.25.9" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -2082,6 +2706,8 @@ __metadata: optional: true "@esbuild/openbsd-x64": optional: true + "@esbuild/openharmony-arm64": + optional: true "@esbuild/sunos-x64": optional: true "@esbuild/win32-arm64": @@ -2092,7 +2718,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/451daf6a442df29ec5d528587caa4ce783d41ff4acb93252da5a852b8d36c22e9f84d17f6721d4fbef9a1ba9855bc9fe1f167dd732c11665fe53032f2b89f114 + checksum: 10/fc174ae7f646ad413adb641c7e46f16be575e462ed209866b55d5954d382e5da839e3f3f89a8e42e2b71d48895cc636ba43523011249fe5ff9c63d8d39d3a364 languageName: node linkType: hard @@ -2103,27 +2729,27 @@ __metadata: languageName: node linkType: hard -"eslint-config-next@npm:14.2.23": - version: 14.2.23 - resolution: "eslint-config-next@npm:14.2.23" +"eslint-config-next@npm:15.3.4": + version: 15.3.4 + resolution: "eslint-config-next@npm:15.3.4" dependencies: - "@next/eslint-plugin-next": "npm:14.2.23" - "@rushstack/eslint-patch": "npm:^1.3.3" + "@next/eslint-plugin-next": "npm:15.3.4" + "@rushstack/eslint-patch": "npm:^1.10.3" "@typescript-eslint/eslint-plugin": "npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0" "@typescript-eslint/parser": "npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0" eslint-import-resolver-node: "npm:^0.3.6" eslint-import-resolver-typescript: "npm:^3.5.2" - eslint-plugin-import: "npm:^2.28.1" - eslint-plugin-jsx-a11y: "npm:^6.7.1" - eslint-plugin-react: "npm:^7.33.2" - eslint-plugin-react-hooks: "npm:^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + eslint-plugin-import: "npm:^2.31.0" + eslint-plugin-jsx-a11y: "npm:^6.10.0" + eslint-plugin-react: "npm:^7.37.0" + eslint-plugin-react-hooks: "npm:^5.0.0" peerDependencies: - eslint: ^7.23.0 || ^8.0.0 + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 typescript: ">=3.3.1" peerDependenciesMeta: typescript: optional: true - checksum: 10/ee23822e91c155cb0531c786cf11573b8914bc7dfa3b506c45c1d13d4b0c1b515764bd2744daa9c36bddf3bb7cfff434fa6bd169540a2fb933a336df78e7d850 + checksum: 10/6c21254d3383b9158ff5f3b2881cc702bee3d2635b4326757965945691f6e65e25fdfef4f2964382fb4b2f52d9f03b929cb71d267709727df7365e7da80c8c3a languageName: node linkType: hard @@ -2139,17 +2765,16 @@ __metadata: linkType: hard "eslint-import-resolver-typescript@npm:^3.5.2": - version: 3.7.0 - resolution: "eslint-import-resolver-typescript@npm:3.7.0" + version: 3.10.1 + resolution: "eslint-import-resolver-typescript@npm:3.10.1" dependencies: "@nolyfill/is-core-module": "npm:1.0.39" - debug: "npm:^4.3.7" - enhanced-resolve: "npm:^5.15.0" - fast-glob: "npm:^3.3.2" - get-tsconfig: "npm:^4.7.5" - is-bun-module: "npm:^1.0.2" - is-glob: "npm:^4.0.3" - stable-hash: "npm:^0.0.4" + debug: "npm:^4.4.0" + get-tsconfig: "npm:^4.10.0" + is-bun-module: "npm:^2.0.0" + stable-hash: "npm:^0.0.5" + tinyglobby: "npm:^0.2.13" + unrs-resolver: "npm:^1.6.2" peerDependencies: eslint: "*" eslint-plugin-import: "*" @@ -2159,52 +2784,52 @@ __metadata: optional: true eslint-plugin-import-x: optional: true - checksum: 10/8158730c11e562c56ed9bf7236dc75bce35b6992dc32c39ac2f4177ab77fca97b95999850204a6458054243607b54aee88c028a61fed4184f24f425fa1afff01 + checksum: 10/b8d6a9b2045c70f043f722f78c9e65bc0283126f0ad92c8f07473f7647d77f7b1562f765a472f17e06b81897b407091c0ec9f2e4592b158c9fd92d0b0c33de89 languageName: node linkType: hard -"eslint-module-utils@npm:^2.12.0": - version: 2.12.0 - resolution: "eslint-module-utils@npm:2.12.0" +"eslint-module-utils@npm:^2.12.1": + version: 2.12.1 + resolution: "eslint-module-utils@npm:2.12.1" dependencies: debug: "npm:^3.2.7" peerDependenciesMeta: eslint: optional: true - checksum: 10/dd27791147eca17366afcb83f47d6825b6ce164abb256681e5de4ec1d7e87d8605641eb869298a0dbc70665e2446dbcc2f40d3e1631a9475dd64dd23d4ca5dee + checksum: 10/bd25d6610ec3abaa50e8f1beb0119541562bbb8dd02c035c7e887976fe1e0c5dd8175f4607ca8d86d1146df24d52a071bd3d1dd329f6902bd58df805a8ca16d3 languageName: node linkType: hard -"eslint-plugin-import@npm:^2.28.1": - version: 2.31.0 - resolution: "eslint-plugin-import@npm:2.31.0" +"eslint-plugin-import@npm:^2.31.0": + version: 2.32.0 + resolution: "eslint-plugin-import@npm:2.32.0" dependencies: "@rtsao/scc": "npm:^1.1.0" - array-includes: "npm:^3.1.8" - array.prototype.findlastindex: "npm:^1.2.5" - array.prototype.flat: "npm:^1.3.2" - array.prototype.flatmap: "npm:^1.3.2" + array-includes: "npm:^3.1.9" + array.prototype.findlastindex: "npm:^1.2.6" + array.prototype.flat: "npm:^1.3.3" + array.prototype.flatmap: "npm:^1.3.3" debug: "npm:^3.2.7" doctrine: "npm:^2.1.0" eslint-import-resolver-node: "npm:^0.3.9" - eslint-module-utils: "npm:^2.12.0" + eslint-module-utils: "npm:^2.12.1" hasown: "npm:^2.0.2" - is-core-module: "npm:^2.15.1" + is-core-module: "npm:^2.16.1" is-glob: "npm:^4.0.3" minimatch: "npm:^3.1.2" object.fromentries: "npm:^2.0.8" object.groupby: "npm:^1.0.3" - object.values: "npm:^1.2.0" + object.values: "npm:^1.2.1" semver: "npm:^6.3.1" - string.prototype.trimend: "npm:^1.0.8" + string.prototype.trimend: "npm:^1.0.9" tsconfig-paths: "npm:^3.15.0" peerDependencies: eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - checksum: 10/6b76bd009ac2db0615d9019699d18e2a51a86cb8c1d0855a35fb1b418be23b40239e6debdc6e8c92c59f1468ed0ea8d7b85c817117a113d5cc225be8a02ad31c + checksum: 10/1bacf4967e9ebf99e12176a795f0d6d3a87d1c9a030c2207f27b267e10d96a1220be2647504c7fc13ab543cdf13ffef4b8f5620e0447032dba4ff0d3922f7c9e languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:^6.7.1": +"eslint-plugin-jsx-a11y@npm:^6.10.0": version: 6.10.2 resolution: "eslint-plugin-jsx-a11y@npm:6.10.2" dependencies: @@ -2229,18 +2854,18 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": - version: 5.0.0-canary-7118f5dd7-20230705 - resolution: "eslint-plugin-react-hooks@npm:5.0.0-canary-7118f5dd7-20230705" +"eslint-plugin-react-hooks@npm:^5.0.0": + version: 5.2.0 + resolution: "eslint-plugin-react-hooks@npm:5.2.0" peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 10/0e0e80c21552998b7af2b92a74aec5e862b33f6f16c3e1303d42b5821d68b7ba11c2037bd73e3581fc7d97d9a2e64dd19e202d47d6885f53e33aac87c048d641 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + checksum: 10/ebb79e9cf69ae06e3a7876536653c5e556b5fd8cd9dc49577f10a6e728360e7b6f5ce91f4339b33e93b26e3bb23805418f8b5e75db80baddd617b1dffe73bed1 languageName: node linkType: hard -"eslint-plugin-react@npm:^7.33.2": - version: 7.37.3 - resolution: "eslint-plugin-react@npm:7.37.3" +"eslint-plugin-react@npm:^7.37.0": + version: 7.37.5 + resolution: "eslint-plugin-react@npm:7.37.5" dependencies: array-includes: "npm:^3.1.8" array.prototype.findlast: "npm:^1.2.5" @@ -2252,7 +2877,7 @@ __metadata: hasown: "npm:^2.0.2" jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.8" + object.entries: "npm:^1.1.9" object.fromentries: "npm:^2.0.8" object.values: "npm:^1.2.1" prop-types: "npm:^15.8.1" @@ -2262,7 +2887,7 @@ __metadata: string.prototype.repeat: "npm:^1.0.0" peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - checksum: 10/30042b95c440a962157192f67369d8c9171f7c73e992695e5674c9d28c3cfe4098488eca86dfa7c433d4c8a91243cbafdc80c7e42d2c1720a427ddb36e65457e + checksum: 10/ee1bd4e0ec64f29109d5a625bb703d179c82e0159c86c3f1b52fc1209d2994625a137dae303c333fb308a2e38315e44066d5204998177e31974382f9fda25d5c languageName: node linkType: hard @@ -2283,10 +2908,10 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^4.2.0": - version: 4.2.0 - resolution: "eslint-visitor-keys@npm:4.2.0" - checksum: 10/9651b3356b01760e586b4c631c5268c0e1a85236e3292bf754f0472f465bf9a856c0ddc261fceace155334118c0151778effafbab981413dbf9288349343fa25 +"eslint-visitor-keys@npm:^4.2.1": + version: 4.2.1 + resolution: "eslint-visitor-keys@npm:4.2.1" + checksum: 10/3ee00fc6a7002d4b0ffd9dc99e13a6a7882c557329e6c25ab254220d71e5c9c4f89dca4695352949ea678eb1f3ba912a18ef8aac0a7fe094196fd92f441bfce2 languageName: node linkType: hard @@ -2459,6 +3084,13 @@ __metadata: languageName: node linkType: hard +"exponential-backoff@npm:^3.1.1": + version: 3.1.2 + resolution: "exponential-backoff@npm:3.1.2" + checksum: 10/ca2f01f1aa4dafd3f3917bd531ab5be08c6f5f4b2389d2e974f903de3cbeb50b9633374353516b6afd70905775e33aba11afab1232d3acf0aa2963b98a611c51 + languageName: node + linkType: hard + "extend@npm:^3.0.0": version: 3.0.2 resolution: "extend@npm:3.0.2" @@ -2473,6 +3105,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:3.3.1": + version: 3.3.1 + resolution: "fast-glob@npm:3.3.1" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 10/51bcd15472879dfe51d4b01c5b70bbc7652724d39cdd082ba11276dbd7d84db0f6b33757e1938af8b2768a4bf485d9be0c89153beae24ee8331d6dcc7550379f + languageName: node + linkType: hard + "fast-glob@npm:^3.3.2": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" @@ -2501,11 +3146,23 @@ __metadata: linkType: hard "fastq@npm:^1.6.0": - version: 1.18.0 - resolution: "fastq@npm:1.18.0" + version: 1.19.1 + resolution: "fastq@npm:1.19.1" dependencies: reusify: "npm:^1.0.4" - checksum: 10/c5b501333dc8f5d188d828ea162aad03ff5a81aed185b6d4a5078aaeae0a42babc34296d7af13ebce86401cccd93c9b7b3cbf61280821c5f20af233378b42fbb + checksum: 10/75679dc226316341c4f2a6b618571f51eac96779906faecd8921b984e844d6ae42fabb2df69b1071327d398d5716693ea9c9c8941f64ac9e89ec2032ce59d730 + languageName: node + linkType: hard + +"fdir@npm:^6.4.4": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10/14ca1c9f0a0e8f4f2e9bf4e8551065a164a09545dae548c12a18d238b72e51e5a7b39bd8e5494b56463a0877672d0a6c1ef62c6fa0677db1b0c847773be939b1 languageName: node linkType: hard @@ -2549,9 +3206,9 @@ __metadata: linkType: hard "flatted@npm:^3.2.9": - version: 3.3.2 - resolution: "flatted@npm:3.3.2" - checksum: 10/ac3c159742e01d0e860a861164bcfd35bb567ccbebb8a0dd041e61cf3c64a435b917dd1e7ed1c380c2ebca85735fb16644485ec33665bc6aafc3b316aa1eed44 + version: 3.3.3 + resolution: "flatted@npm:3.3.3" + checksum: 10/8c96c02fbeadcf4e8ffd0fa24983241e27698b0781295622591fc13585e2f226609d95e422bcf2ef044146ffacb6b68b1f20871454eddf75ab3caa6ee5f4a1fe languageName: node linkType: hard @@ -2565,21 +3222,21 @@ __metadata: linkType: hard "foreground-child@npm:^3.1.0": - version: 3.3.0 - resolution: "foreground-child@npm:3.3.0" + version: 3.3.1 + resolution: "foreground-child@npm:3.3.1" dependencies: - cross-spawn: "npm:^7.0.0" + cross-spawn: "npm:^7.0.6" signal-exit: "npm:^4.0.1" - checksum: 10/e3a60480f3a09b12273ce2c5fcb9514d98dd0e528f58656a1b04680225f918d60a2f81f6a368f2f3b937fcee9cfc0cbf16f1ad9a0bc6a3a6e103a84c9a90087e + checksum: 10/427b33f997a98073c0424e5c07169264a62cda806d8d2ded159b5b903fdfc8f0a1457e06b5fc35506497acb3f1e353f025edee796300209ac6231e80edece835 languageName: node linkType: hard -"framer-motion@npm:^12.5.0": - version: 12.5.0 - resolution: "framer-motion@npm:12.5.0" +"framer-motion@npm:^12.23.24": + version: 12.23.24 + resolution: "framer-motion@npm:12.23.24" dependencies: - motion-dom: "npm:^12.5.0" - motion-utils: "npm:^12.5.0" + motion-dom: "npm:^12.23.23" + motion-utils: "npm:^12.23.6" tslib: "npm:^2.4.0" peerDependencies: "@emotion/is-prop-valid": "*" @@ -2592,7 +3249,16 @@ __metadata: optional: true react-dom: optional: true - checksum: 10/6659e0b704d3216dafdcb11175e3c5f55d536469ddd8ad62b37d00bc7e893d914989791c018cfdfa17b3142b655f0d85226adc94ed390c1524312c3653b8c75f + checksum: 10/c46015626d140557f3f225ffeaea14146988a42a99b33e46e3efbab88814343867a63014544169283b9518e1a3abed231ccefd890e601cf66b6c43425b0465e2 + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10/af143246cf6884fe26fa281621d45cfe111d34b30535a475bfa38dafe343dadb466c047a924ffc7d6b7b18265df4110224ce3803806dbb07173bf2087b648d7f languageName: node linkType: hard @@ -2603,6 +3269,25 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:~2.3.2": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 10/4c1ade961ded57cdbfbb5cac5106ec17bc8bccd62e16343c569a0ceeca83b9dfef87550b4dc5cbb89642da412b20c5071f304c8c464b80415446e8e155a038c0 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "function-bind@npm:^1.1.2": version: 1.1.2 resolution: "function-bind@npm:1.1.2" @@ -2670,16 +3355,16 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.7.5": - version: 4.8.1 - resolution: "get-tsconfig@npm:4.8.1" +"get-tsconfig@npm:^4.10.0": + version: 4.10.1 + resolution: "get-tsconfig@npm:4.10.1" dependencies: resolve-pkg-maps: "npm:^1.0.0" - checksum: 10/3fb5a8ad57b9633eaea085d81661e9e5c9f78b35d8f8689eaf8b8b45a2a3ebf3b3422266d4d7df765e308cc1e6231648d114803ab3d018332e29916f2c1de036 + checksum: 10/04d63f47fdecaefbd1f73ec02949be4ec4db7d6d9fbc8d4e81f9a4bb1c6f876e48943712f2f9236643d3e4d61d9a7b06da08564d08b034631ebe3f5605bef237 languageName: node linkType: hard -"glob-parent@npm:^5.1.2": +"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" dependencies: @@ -2697,18 +3382,19 @@ __metadata: languageName: node linkType: hard -"glob@npm:10.3.10": - version: 10.3.10 - resolution: "glob@npm:10.3.10" +"glob@npm:^10.2.2": + version: 10.4.5 + resolution: "glob@npm:10.4.5" dependencies: foreground-child: "npm:^3.1.0" - jackspeak: "npm:^2.3.5" - minimatch: "npm:^9.0.1" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry: "npm:^1.10.1" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" bin: glob: dist/esm/bin.mjs - checksum: 10/38bdb2c9ce75eb5ed168f309d4ed05b0798f640b637034800a6bf306f39d35409bf278b0eaaffaec07591085d3acb7184a201eae791468f0f617771c2486a6a8 + checksum: 10/698dfe11828b7efd0514cd11e573eaed26b2dff611f0400907281ce3eab0c1e56143ef9b35adc7c77ecc71fba74717b510c7c223d34ca8a98ec81777b293d4ac languageName: node linkType: hard @@ -2752,7 +3438,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4": +"graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10/bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 @@ -2814,7 +3500,7 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.0, hasown@npm:^2.0.2": +"hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -2824,8 +3510,8 @@ __metadata: linkType: hard "hast-util-to-estree@npm:^3.0.0": - version: 3.1.1 - resolution: "hast-util-to-estree@npm:3.1.1" + version: 3.1.3 + resolution: "hast-util-to-estree@npm:3.1.3" dependencies: "@types/estree": "npm:^1.0.0" "@types/estree-jsx": "npm:^1.0.0" @@ -2838,18 +3524,18 @@ __metadata: mdast-util-mdx-expression: "npm:^2.0.0" mdast-util-mdx-jsx: "npm:^3.0.0" mdast-util-mdxjs-esm: "npm:^2.0.0" - property-information: "npm:^6.0.0" + property-information: "npm:^7.0.0" space-separated-tokens: "npm:^2.0.0" - style-to-object: "npm:^1.0.0" + style-to-js: "npm:^1.0.0" unist-util-position: "npm:^5.0.0" zwitch: "npm:^2.0.0" - checksum: 10/f72b0d72d6f3e1d55a876e175716b78bf93b8246fac8dd6db6b46c03b0288d03f40644606f36c00e8f12829a6bef0e7a73b405825b651a94b41f0bc5b53b92b4 + checksum: 10/efe69c8af68f021d853e70916c6e940765be519aec8703765898c1c3814424b0470f70c0272cf4ac06dcaf6d6f3cc781ebf034701ed240a33ac691d1f5eaf65b languageName: node linkType: hard -"hast-util-to-html@npm:^9.0.4": - version: 9.0.4 - resolution: "hast-util-to-html@npm:9.0.4" +"hast-util-to-html@npm:^9.0.5": + version: 9.0.5 + resolution: "hast-util-to-html@npm:9.0.5" dependencies: "@types/hast": "npm:^3.0.0" "@types/unist": "npm:^3.0.0" @@ -2858,17 +3544,17 @@ __metadata: hast-util-whitespace: "npm:^3.0.0" html-void-elements: "npm:^3.0.0" mdast-util-to-hast: "npm:^13.0.0" - property-information: "npm:^6.0.0" + property-information: "npm:^7.0.0" space-separated-tokens: "npm:^2.0.0" stringify-entities: "npm:^4.0.0" zwitch: "npm:^2.0.4" - checksum: 10/a0b4ed9058e57fa2ca010d10c077fda78d2ab2af99f5bd09fe4b9948970025ac4a2a1a03ec7e2e0f3b0444066b1b35d602fa3e9fbd9b7fc9cdd35d0cafa909ca + checksum: 10/4278e5246f43adf7a30bf3b87db4a4e628b5362b8c149eb4360bf7e0f731f81fa31e4e844e8090d1dd5f739d0884678f8165b28f97c14139e4da4f945f9ff5f7 languageName: node linkType: hard "hast-util-to-jsx-runtime@npm:^2.0.0": - version: 2.3.2 - resolution: "hast-util-to-jsx-runtime@npm:2.3.2" + version: 2.3.6 + resolution: "hast-util-to-jsx-runtime@npm:2.3.6" dependencies: "@types/estree": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" @@ -2880,12 +3566,12 @@ __metadata: mdast-util-mdx-expression: "npm:^2.0.0" mdast-util-mdx-jsx: "npm:^3.0.0" mdast-util-mdxjs-esm: "npm:^2.0.0" - property-information: "npm:^6.0.0" + property-information: "npm:^7.0.0" space-separated-tokens: "npm:^2.0.0" - style-to-object: "npm:^1.0.0" + style-to-js: "npm:^1.0.0" unist-util-position: "npm:^5.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/3d72f83e2d8c29adc6576d2c6b41479902fd51fac8cfb2b67c35fd68fcb9c25c274699442e4dee901a7ab926a0ff6851713ed5d92448ac09ae0f10daf293476c + checksum: 10/111bd69f482952c7591cb4e1d3face25f1c18849b310a4d6cacc91e2d2cbc965d455fad35c059b8f0cfd762e933b826a7090b6f3098dece08307a6569de8f1d8 languageName: node linkType: hard @@ -2898,6 +3584,34 @@ __metadata: languageName: node linkType: hard +"html-dom-parser@npm:5.1.1": + version: 5.1.1 + resolution: "html-dom-parser@npm:5.1.1" + dependencies: + domhandler: "npm:5.0.3" + htmlparser2: "npm:10.0.0" + checksum: 10/85bbaa8699d40d54fd64f5472088199178a6c3dd6a907358ac476d9c511cb8ab10bff1469a785411e8b831a73ac08348392e56076eab6d100a3ec19dccc722ad + languageName: node + linkType: hard + +"html-react-parser@npm:^5.2.5": + version: 5.2.8 + resolution: "html-react-parser@npm:5.2.8" + dependencies: + domhandler: "npm:5.0.3" + html-dom-parser: "npm:5.1.1" + react-property: "npm:2.0.2" + style-to-js: "npm:1.1.19" + peerDependencies: + "@types/react": 0.14 || 15 || 16 || 17 || 18 || 19 + react: 0.14 || 15 || 16 || 17 || 18 || 19 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/492d44f65c2a8647bb7d6db3865363739a00696687024b978f5f5e29475c40bd470c91e9ddefe0f1a846c85761f046e9a92fa3fe0e5581df43ac587787703b31 + languageName: node + linkType: hard + "html-void-elements@npm:^3.0.0": version: 3.0.0 resolution: "html-void-elements@npm:3.0.0" @@ -2905,20 +3619,75 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.2.0, ignore@npm:^5.3.1": +"htmlparser2@npm:10.0.0": + version: 10.0.0 + resolution: "htmlparser2@npm:10.0.0" + dependencies: + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + domutils: "npm:^3.2.1" + entities: "npm:^6.0.0" + checksum: 10/768870f0e020dca19dc45df206cb6ac466c5dba6566c8fca4ca880347eed409f9977028d08644ac516bca8628ac9c7ded5a3847dc3ee1c043f049abf9e817154 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.2.0 + resolution: "http-cache-semantics@npm:4.2.0" + checksum: 10/4efd2dfcfeea9d5e88c84af450b9980be8a43c2c8179508b1c57c7b4421c855f3e8efe92fa53e0b3f4a43c85824ada930eabbc306d1b3beab750b6dcc5187693 + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: 10/d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:4" + checksum: 10/784b628cbd55b25542a9d85033bdfd03d4eda630fb8b3c9477959367f3be95dc476ed2ecbb9836c359c7c698027fc7b45723a302324433590f45d6c1706e8c13 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"ignore@npm:^5.2.0": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10/cceb6a457000f8f6a50e1196429750d782afce5680dd878aa4221bd79972d68b3a55b4b1458fc682be978f4d3c6a249046aa0880637367216444ab7b014cfc98 languageName: node linkType: hard +"ignore@npm:^7.0.0": + version: 7.0.5 + resolution: "ignore@npm:7.0.5" + checksum: 10/f134b96a4de0af419196f52c529d5c6120c4456ff8a6b5a14ceaaa399f883e15d58d2ce651c9b69b9388491d4669dda47285d307e827de9304a53a1824801bc6 + languageName: node + linkType: hard + "import-fresh@npm:^3.2.1": - version: 3.3.0 - resolution: "import-fresh@npm:3.3.0" + version: 3.3.1 + resolution: "import-fresh@npm:3.3.1" dependencies: parent-module: "npm:^1.0.0" resolve-from: "npm:^4.0.0" - checksum: 10/2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa + checksum: 10/a06b19461b4879cc654d46f8a6244eb55eb053437afd4cbb6613cad6be203811849ed3e4ea038783092879487299fda24af932b86bdfff67c9055ba3612b8c87 languageName: node linkType: hard @@ -2946,10 +3715,10 @@ __metadata: languageName: node linkType: hard -"inline-style-parser@npm:0.2.4": - version: 0.2.4 - resolution: "inline-style-parser@npm:0.2.4" - checksum: 10/80814479d1f3c9cbd102f9de4cd6558cf43cc2e48640e81c4371c3634f1e8b6dfeb2f21063cfa31d46cc83e834c20cd59ed9eeed9bfd45ef5bc02187ad941faf +"inline-style-parser@npm:0.2.6": + version: 0.2.6 + resolution: "inline-style-parser@npm:0.2.6" + checksum: 10/0be8356fcd766b7b170991293c9ad953f057ac9719960f51f4eb54af1a79c34638f591691f2ab43f57bef2e28e9c1239b8ae5f6b72bff2c652f828ccc621c08c languageName: node linkType: hard @@ -2964,6 +3733,13 @@ __metadata: languageName: node linkType: hard +"ip-address@npm:^10.0.1": + version: 10.0.1 + resolution: "ip-address@npm:10.0.1" + checksum: 10/09731acda32cd8e14c46830c137e7e5940f47b36d63ffb87c737331270287d631cf25aa95570907a67d3f919fdb25f4470c404eda21e62f22e0a55927f4dd0fb + languageName: node + linkType: hard + "is-alphabetical@npm:^2.0.0": version: 2.0.1 resolution: "is-alphabetical@npm:2.0.1" @@ -3002,15 +3778,23 @@ __metadata: languageName: node linkType: hard +"is-arrayish@npm:^0.3.1": + version: 0.3.2 + resolution: "is-arrayish@npm:0.3.2" + checksum: 10/81a78d518ebd8b834523e25d102684ee0f7e98637136d3bdc93fd09636350fa06f1d8ca997ea28143d4d13cb1b69c0824f082db0ac13e1ab3311c10ffea60ade + languageName: node + linkType: hard + "is-async-function@npm:^2.0.0": - version: 2.1.0 - resolution: "is-async-function@npm:2.1.0" + version: 2.1.1 + resolution: "is-async-function@npm:2.1.1" dependencies: + async-function: "npm:^1.0.0" call-bound: "npm:^1.0.3" get-proto: "npm:^1.0.1" has-tostringtag: "npm:^1.0.2" safe-regex-test: "npm:^1.1.0" - checksum: 10/865f0e915b7d9aa5577327e7550bf77a4bb2b7bca497d32564e1d32dbe0ccb7eca1c9c56dd679b6dd2bd7feddb91574e773922276871a5958e53ae8473db4742 + checksum: 10/7c2ac7efdf671e03265e74a043bcb1c0a32e226bc2a42dfc5ec8644667df668bbe14b91c08e6c1414f392f8cf86cd1d489b3af97756e2c7a49dd1ba63fd40ca6 languageName: node linkType: hard @@ -3023,22 +3807,31 @@ __metadata: languageName: node linkType: hard -"is-boolean-object@npm:^1.2.1": - version: 1.2.1 - resolution: "is-boolean-object@npm:1.2.1" +"is-binary-path@npm:~2.1.0": + version: 2.1.0 + resolution: "is-binary-path@npm:2.1.0" dependencies: - call-bound: "npm:^1.0.2" - has-tostringtag: "npm:^1.0.2" - checksum: 10/5a15524635c9334ebbd668f20a6cbf023adceed5725ec96a50056d21ae65f52759d04a8fa7d7febf00ff3bc4e6d3837638eb84be572f287bcfd15f8b8facde43 + binary-extensions: "npm:^2.0.0" + checksum: 10/078e51b4f956c2c5fd2b26bb2672c3ccf7e1faff38e0ebdba45612265f4e3d9fc3127a1fa8370bbf09eab61339203c3d3b7af5662cbf8be4030f8fac37745b0e languageName: node linkType: hard -"is-bun-module@npm:^1.0.2": - version: 1.3.0 - resolution: "is-bun-module@npm:1.3.0" +"is-boolean-object@npm:^1.2.1": + version: 1.2.2 + resolution: "is-boolean-object@npm:1.2.2" dependencies: - semver: "npm:^7.6.3" - checksum: 10/b23d9ec7b4d4bfd89e4e72b5cd52e1bc153facad59fdd7394c656f8859a78740ef35996a2066240a32f39cc9a9da4b4eb69e68df3c71755a61ebbaf56d3daef0 + call-bound: "npm:^1.0.3" + has-tostringtag: "npm:^1.0.2" + checksum: 10/051fa95fdb99d7fbf653165a7e6b2cba5d2eb62f7ffa81e793a790f3fb5366c91c1b7b6af6820aa2937dd86c73aa3ca9d9ca98f500988457b1c59692c52ba911 + languageName: node + linkType: hard + +"is-bun-module@npm:^2.0.0": + version: 2.0.0 + resolution: "is-bun-module@npm:2.0.0" + dependencies: + semver: "npm:^7.7.1" + checksum: 10/cded5a1a58368b847872d08617975d620ad94426d76a932f3e08d55b4574d199e0a62a4fb024fa2dc444200b71719eb0bffc5d3d1e1cc82e29b293bb8d66a990 languageName: node linkType: hard @@ -3049,7 +3842,7 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1, is-core-module@npm:^2.16.0": +"is-core-module@npm:^2.13.0, is-core-module@npm:^2.16.0, is-core-module@npm:^2.16.1": version: 2.16.1 resolution: "is-core-module@npm:2.16.1" dependencies: @@ -3130,7 +3923,7 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" dependencies: @@ -3153,6 +3946,13 @@ __metadata: languageName: node linkType: hard +"is-negative-zero@npm:^2.0.3": + version: 2.0.3 + resolution: "is-negative-zero@npm:2.0.3" + checksum: 10/8fe5cffd8d4fb2ec7b49d657e1691889778d037494c6f40f4d1a524cadd658b4b53ad7b6b73a59bcb4b143ae9a3d15829af864b2c0f9d65ac1e678c4c80f17e5 + languageName: node + linkType: hard + "is-number-object@npm:^1.1.1": version: 1.1.1 resolution: "is-number-object@npm:1.1.1" @@ -3212,7 +4012,7 @@ __metadata: languageName: node linkType: hard -"is-string@npm:^1.0.7, is-string@npm:^1.1.1": +"is-string@npm:^1.1.1": version: 1.1.1 resolution: "is-string@npm:1.1.1" dependencies: @@ -3249,12 +4049,12 @@ __metadata: languageName: node linkType: hard -"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.0": - version: 1.1.0 - resolution: "is-weakref@npm:1.1.0" +"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1": + version: 1.1.1 + resolution: "is-weakref@npm:1.1.1" dependencies: - call-bound: "npm:^1.0.2" - checksum: 10/89e627cc1763ea110574bb408fcf060ede47e70437d9278858bc939e3b3f7e4b7c558610b733da5f2ad6084d9f12b9c714b011ccf3fa771ec87e221c22bed910 + call-bound: "npm:^1.0.3" + checksum: 10/543506fd8259038b371bb083aac25b16cb4fd8b12fc58053aa3d45ac28dfd001cd5c6dffbba7aeea4213c74732d46b6cb2cfb5b412eed11f2db524f3f97d09a0 languageName: node linkType: hard @@ -3291,6 +4091,13 @@ __metadata: languageName: node linkType: hard +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 10/7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + "iterator.prototype@npm:^1.1.4": version: 1.1.5 resolution: "iterator.prototype@npm:1.1.5" @@ -3305,20 +4112,20 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.3.5": - version: 2.3.6 - resolution: "jackspeak@npm:2.3.6" +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" dependencies: "@isaacs/cliui": "npm:^8.0.2" "@pkgjs/parseargs": "npm:^0.11.0" dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: 10/6e6490d676af8c94a7b5b29b8fd5629f21346911ebe2e32931c2a54210134408171c24cee1a109df2ec19894ad04a429402a8438cbf5cc2794585d35428ace76 + checksum: 10/96f8786eaab98e4bf5b2a5d6d9588ea46c4d06bbc4f2eb861fdd7b6b182b16f71d8a70e79820f335d52653b16d4843b29dd9cdcf38ae80406756db9199497cf3 languageName: node linkType: hard -"js-tokens@npm:^3.0.0 || ^4.0.0": +"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" checksum: 10/af37d0d913fb56aec6dc0074c163cc71cd23c0b8aad5c2350747b6721d37ba118af35abdd8b33c47ec2800de07dedb16a527ca9c530ee004093e04958bd0cbf2 @@ -3337,9 +4144,9 @@ __metadata: linkType: hard "jsdoc-type-pratt-parser@npm:^4.0.0": - version: 4.1.0 - resolution: "jsdoc-type-pratt-parser@npm:4.1.0" - checksum: 10/30d88f95f6cbb4a1aa6d4b0d0ae46eb1096e606235ecaf9bab7a3ed5da860516b5d1cd967182765002f292c627526db918f3e56d34637bcf810e6ef84d403f3f + version: 4.8.0 + resolution: "jsdoc-type-pratt-parser@npm:4.8.0" + checksum: 10/1844ef7848f5d0c3c60af95629197f97ff8603c12b99d750aaf7511724ee0d41989c5d24ea5f8d22078a5a8034337a272c9c22f49a8f07a857946417f3c84cfb languageName: node linkType: hard @@ -3422,91 +4229,91 @@ __metadata: languageName: node linkType: hard -"lightningcss-darwin-arm64@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-darwin-arm64@npm:1.29.3" +"lightningcss-darwin-arm64@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-darwin-arm64@npm:1.30.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"lightningcss-darwin-x64@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-darwin-x64@npm:1.29.3" +"lightningcss-darwin-x64@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-darwin-x64@npm:1.30.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"lightningcss-freebsd-x64@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-freebsd-x64@npm:1.29.3" +"lightningcss-freebsd-x64@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-freebsd-x64@npm:1.30.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"lightningcss-linux-arm-gnueabihf@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-arm-gnueabihf@npm:1.29.3" +"lightningcss-linux-arm-gnueabihf@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.30.1" conditions: os=linux & cpu=arm languageName: node linkType: hard -"lightningcss-linux-arm64-gnu@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-arm64-gnu@npm:1.29.3" +"lightningcss-linux-arm64-gnu@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-arm64-gnu@npm:1.30.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"lightningcss-linux-arm64-musl@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-arm64-musl@npm:1.29.3" +"lightningcss-linux-arm64-musl@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-arm64-musl@npm:1.30.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"lightningcss-linux-x64-gnu@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-x64-gnu@npm:1.29.3" +"lightningcss-linux-x64-gnu@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-x64-gnu@npm:1.30.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"lightningcss-linux-x64-musl@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-x64-musl@npm:1.29.3" +"lightningcss-linux-x64-musl@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-x64-musl@npm:1.30.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"lightningcss-win32-arm64-msvc@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-win32-arm64-msvc@npm:1.29.3" +"lightningcss-win32-arm64-msvc@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-win32-arm64-msvc@npm:1.30.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"lightningcss-win32-x64-msvc@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-win32-x64-msvc@npm:1.29.3" +"lightningcss-win32-x64-msvc@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-win32-x64-msvc@npm:1.30.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "lightningcss@npm:^1.28.2": - version: 1.29.3 - resolution: "lightningcss@npm:1.29.3" + version: 1.30.1 + resolution: "lightningcss@npm:1.30.1" dependencies: detect-libc: "npm:^2.0.3" - lightningcss-darwin-arm64: "npm:1.29.3" - lightningcss-darwin-x64: "npm:1.29.3" - lightningcss-freebsd-x64: "npm:1.29.3" - lightningcss-linux-arm-gnueabihf: "npm:1.29.3" - lightningcss-linux-arm64-gnu: "npm:1.29.3" - lightningcss-linux-arm64-musl: "npm:1.29.3" - lightningcss-linux-x64-gnu: "npm:1.29.3" - lightningcss-linux-x64-musl: "npm:1.29.3" - lightningcss-win32-arm64-msvc: "npm:1.29.3" - lightningcss-win32-x64-msvc: "npm:1.29.3" + lightningcss-darwin-arm64: "npm:1.30.1" + lightningcss-darwin-x64: "npm:1.30.1" + lightningcss-freebsd-x64: "npm:1.30.1" + lightningcss-linux-arm-gnueabihf: "npm:1.30.1" + lightningcss-linux-arm64-gnu: "npm:1.30.1" + lightningcss-linux-arm64-musl: "npm:1.30.1" + lightningcss-linux-x64-gnu: "npm:1.30.1" + lightningcss-linux-x64-musl: "npm:1.30.1" + lightningcss-win32-arm64-msvc: "npm:1.30.1" + lightningcss-win32-x64-msvc: "npm:1.30.1" dependenciesMeta: lightningcss-darwin-arm64: optional: true @@ -3528,7 +4335,7 @@ __metadata: optional: true lightningcss-win32-x64-msvc: optional: true - checksum: 10/90933a666975f8e4f2b1bed1ec698a0072f96d2cd118e358932456a46105d62b72b701e4a5da5bd66f0b6e3beac2c65d0be2306acdf3f30603d86143502cce88 + checksum: 10/6c921135216cc498dfcb87e35dffe8432e99306cbd58009c598b1daf20c81cc14535abbd4c1066e5d1faf4080ed44a2995e8ecc343633db4897a2d041b76fb05 languageName: node linkType: hard @@ -3555,7 +4362,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -3566,13 +4373,32 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.2.0": +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" checksum: 10/e6e90267360476720fa8e83cc168aa2bf0311f3f2eea20a6ba78b90a885ae72071d9db132f40fda4129c803e7dcec3a6b6a6fbb44ca90b081630b810b5d6a41a languageName: node linkType: hard +"make-fetch-happen@npm:^14.0.3": + version: 14.0.3 + resolution: "make-fetch-happen@npm:14.0.3" + dependencies: + "@npmcli/agent": "npm:^3.0.0" + cacache: "npm:^19.0.1" + http-cache-semantics: "npm:^4.1.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^4.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^1.0.0" + proc-log: "npm:^5.0.0" + promise-retry: "npm:^2.0.1" + ssri: "npm:^12.0.0" + checksum: 10/fce0385840b6d86b735053dfe941edc2dd6468fda80fe74da1eeff10cbd82a75760f406194f2bc2fa85b99545b2bc1f84c08ddf994b21830775ba2d1a87e8bdf + languageName: node + linkType: hard + "markdown-extensions@npm:^2.0.0": version: 2.0.0 resolution: "markdown-extensions@npm:2.0.0" @@ -3622,8 +4448,8 @@ __metadata: linkType: hard "mdast-util-mdx-jsx@npm:^3.0.0": - version: 3.1.3 - resolution: "mdast-util-mdx-jsx@npm:3.1.3" + version: 3.2.0 + resolution: "mdast-util-mdx-jsx@npm:3.2.0" dependencies: "@types/estree-jsx": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" @@ -3637,7 +4463,7 @@ __metadata: stringify-entities: "npm:^4.0.0" unist-util-stringify-position: "npm:^4.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/6c14f271f1380fd512038247f45887b7aa71bbf4acd8881651a317b61706b114f2582f62f7777d0eacd42c4a7b979802825c2a2fd8bb7c46a1ab931ccb1ddf3e + checksum: 10/62cd650a522e5d72ea6afd6d4a557fc86525b802d097a29a2fbe17d22e7b97c502a580611873e4d685777fe77c6ff8d39fb6e37d026b3acbc86c3b24927f4ad9 languageName: node linkType: hard @@ -3654,7 +4480,7 @@ __metadata: languageName: node linkType: hard -"mdast-util-mdxjs-esm@npm:^2.0.0": +"mdast-util-mdxjs-esm@npm:^2.0.0, mdast-util-mdxjs-esm@npm:^2.0.1": version: 2.0.1 resolution: "mdast-util-mdxjs-esm@npm:2.0.1" dependencies: @@ -3729,8 +4555,8 @@ __metadata: linkType: hard "micromark-core-commonmark@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-core-commonmark@npm:2.0.2" + version: 2.0.3 + resolution: "micromark-core-commonmark@npm:2.0.3" dependencies: decode-named-character-reference: "npm:^1.0.0" devlop: "npm:^1.0.0" @@ -3748,13 +4574,13 @@ __metadata: micromark-util-subtokenize: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10/eafa6b9cd6fd9f51efa7795824af9a765e24a4519855a5b6dfcb0f619a93d90599d39a261f626bfcc1dfa64f22430f7a677a83cb6ce4bd8e4eeabc892610c016 + checksum: 10/2b98b9eba1463850ebd8f338f966bd2113dafe764b490ebee3dccab3764d3c48b53fe67673297530e56bf54f58de27dfd1952ed79c5b4e32047cb7f29bd807f2 languageName: node linkType: hard "micromark-extension-mdx-expression@npm:^3.0.0": - version: 3.0.0 - resolution: "micromark-extension-mdx-expression@npm:3.0.0" + version: 3.0.1 + resolution: "micromark-extension-mdx-expression@npm:3.0.1" dependencies: "@types/estree": "npm:^1.0.0" devlop: "npm:^1.0.0" @@ -3764,15 +4590,14 @@ __metadata: micromark-util-events-to-acorn: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10/a5592160319d4617362f6b72a6fc44b5570466afa07419d44bcfdd9398a77a5693d7c5f8da7b3ff4682edf6209d4781835f5d2e3166fdf6bba37db456fd2d091 + checksum: 10/a185e1787fe6d49d0e435690affd4b83ce319f88a08c57d2460d37d5c0a75ea64aa49a4a116b6d37f91389dc04351e1826aa834519a9f25fc31e1424962c6eb7 languageName: node linkType: hard "micromark-extension-mdx-jsx@npm:^3.0.0": - version: 3.0.1 - resolution: "micromark-extension-mdx-jsx@npm:3.0.1" + version: 3.0.2 + resolution: "micromark-extension-mdx-jsx@npm:3.0.2" dependencies: - "@types/acorn": "npm:^4.0.0" "@types/estree": "npm:^1.0.0" devlop: "npm:^1.0.0" estree-util-is-identifier-name: "npm:^3.0.0" @@ -3783,7 +4608,7 @@ __metadata: micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/2cc0277d91c3c85d52e88755d17d021b5eab6fa03a578a9965f9d3d2c184dbc1accce63e7f8437a092ceeb602840ef451d4dce6dc9e8c13df0bc76e741080a89 + checksum: 10/a85cdb7c972fbb2cc8f0a64adc808b2b62bc2d79dbdd31fcd3208ff15aafa0198b002022840b2c65b5bff6f2a8c2c4a59a32a89f3482e6e183114b476e98e25c languageName: node linkType: hard @@ -3853,8 +4678,8 @@ __metadata: linkType: hard "micromark-factory-mdx-expression@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-factory-mdx-expression@npm:2.0.2" + version: 2.0.3 + resolution: "micromark-factory-mdx-expression@npm:2.0.3" dependencies: "@types/estree": "npm:^1.0.0" devlop: "npm:^1.0.0" @@ -3865,7 +4690,7 @@ __metadata: micromark-util-types: "npm:^2.0.0" unist-util-position-from-estree: "npm:^2.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/d5285fa98018f14a058c7cd4a961aacedd2d3c4f4fddd4c58c16f1e640d1284a8f581f4d00fa3e18c06ed302ce23bca23f6a01edd66064c23c9057e65385a62d + checksum: 10/afadae88a18f31afa564747101e076011c56457454b30294ae55aeea7efee8626ddc3bad0f0f43649008f89b8784782b5adec143fdf477fb352354d76f08db55 languageName: node linkType: hard @@ -3972,10 +4797,9 @@ __metadata: linkType: hard "micromark-util-events-to-acorn@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-util-events-to-acorn@npm:2.0.2" + version: 2.0.3 + resolution: "micromark-util-events-to-acorn@npm:2.0.3" dependencies: - "@types/acorn": "npm:^4.0.0" "@types/estree": "npm:^1.0.0" "@types/unist": "npm:^3.0.0" devlop: "npm:^1.0.0" @@ -3983,7 +4807,7 @@ __metadata: micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/475367e716c4d24f2a57464a7f2c8aa507ae36c05b7767fd652895525f3f0a1179ea3219cabccc0f3038bb5e4f9cce5390d530dc56decaa5f1786bda42739810 + checksum: 10/0d87e49b897636dc0e84b4bd06b6fa9e6abcd40ab90c9431e36737c85c444d3db1e4f9b8f51433422b1bedc46f086890ce96671b5a795230c6b7b09cb53d9aba languageName: node linkType: hard @@ -4024,14 +4848,14 @@ __metadata: linkType: hard "micromark-util-subtokenize@npm:^2.0.0": - version: 2.0.3 - resolution: "micromark-util-subtokenize@npm:2.0.3" + version: 2.1.0 + resolution: "micromark-util-subtokenize@npm:2.1.0" dependencies: devlop: "npm:^1.0.0" micromark-util-chunked: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10/57b26f129f46424a4670bb47c50f13c7309bb1bc557c02150a788d1634337c1bb25a3523af3d6dffc29aaec873b3bd88fd931bfff34e64284e6436e23873ca22 + checksum: 10/5f18c70cb952a414a4d161f5d6a5254d33c7dfcd56577e592ef2e172a0414058d3531a3554f43538f14e243592fffbc2e68ddaf6a41c54577b3ba7beb555d3dc languageName: node linkType: hard @@ -4043,15 +4867,15 @@ __metadata: linkType: hard "micromark-util-types@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-types@npm:2.0.1" - checksum: 10/69c5e18e6ba4e12473d6fe5f1a7cc113ac1d4bfc23c7ad57b16a5e4bfd09ef48b7c17a40c39d43996f2078ad898efd3f1945007c14f395abd55f2af03d413acd + version: 2.0.2 + resolution: "micromark-util-types@npm:2.0.2" + checksum: 10/a9eb067bd9384eab61942285d53738aa22f3fef4819eaf20249bec6ec13f1e4da2800230fd0ceb7e705108987aa9062fe3e9a8e5e48aa60180db80b9489dc3e2 languageName: node linkType: hard "micromark@npm:^4.0.0": - version: 4.0.1 - resolution: "micromark@npm:4.0.1" + version: 4.0.2 + resolution: "micromark@npm:4.0.2" dependencies: "@types/debug": "npm:^4.0.0" debug: "npm:^4.0.0" @@ -4070,11 +4894,11 @@ __metadata: micromark-util-subtokenize: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10/b948b1b239e589826bdaf2835daa9e88873e23d4b9148cd22109a86d4af55b96345cf9fc9059b6b19ae828f64d55e66f376ca3aeb4af3d2b0241560125f5dae6 + checksum: 10/1b85e49c8f71013df2d07a59e477deb72cd325d41cc15f35b2aa52b8b7a93fed45498ce3e18ed34464a9afa9ba8a9210b2509454b2a2d16ac06c7429f562bfac languageName: node linkType: hard -"micromatch@npm:^4.0.8": +"micromatch@npm:^4.0.4, micromatch@npm:^4.0.8": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -4093,7 +4917,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1, minimatch@npm:^9.0.4": +"minimatch@npm:^9.0.4": version: 9.0.5 resolution: "minimatch@npm:9.0.5" dependencies: @@ -4109,34 +4933,112 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0": +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10/b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^4.0.0": + version: 4.0.1 + resolution: "minipass-fetch@npm:4.0.1" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^3.0.1" + dependenciesMeta: + encoding: + optional: true + checksum: 10/7ddfebdbb87d9866e7b5f7eead5a9e3d9d507992af932a11d275551f60006cf7d9178e66d586dbb910894f3e3458d27c0ddf93c76e94d49d0a54a541ddc1263d + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/40982d8d836a52b0f37049a0a7e5d0f089637298e6d9b45df9c115d4f0520682a78258905e5c8b180fb41b593b0a82cc1361d2c74b45f7ada66334f84d1ecfdd + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10/a5c6ef069f70d9a524d3428af39f2b117ff8cd84172e19b754e7264a33df460873e6eb3d6e55758531580970de50ae950c496256bb4ad3691a2974cddff189f0 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2": version: 7.1.2 resolution: "minipass@npm:7.1.2" checksum: 10/c25f0ee8196d8e6036661104bacd743785b2599a21de5c516b32b3fa2b83113ac89a2358465bc04956baab37ffb956ae43be679b2262bf7be15fce467ccd7950 languageName: node linkType: hard -"motion-dom@npm:^12.5.0": - version: 12.5.0 - resolution: "motion-dom@npm:12.5.0" +"minizlib@npm:^3.0.1": + version: 3.0.2 + resolution: "minizlib@npm:3.0.2" dependencies: - motion-utils: "npm:^12.5.0" - checksum: 10/289e3d5567053e9b84223df9b482bb9180732c0cb6276e7982a73ddad0f76e47f8e0f69e4cdf93d7a689ad021fce837fa8a19c8b61bf56d71bdfc0e590bc3e7e + minipass: "npm:^7.1.2" + checksum: 10/c075bed1594f68dcc8c35122333520112daefd4d070e5d0a228bd4cf5580e9eed3981b96c0ae1d62488e204e80fd27b2b9d0068ca9a5ef3993e9565faf63ca41 languageName: node linkType: hard -"motion-utils@npm:^12.5.0": - version: 12.5.0 - resolution: "motion-utils@npm:12.5.0" - checksum: 10/f2d754a9e1c4cd829f0703ce47bbeb3e9967994a9cb35e759f34de16af6c520a4959b04ff6998211ca67dc7bfe0002d9b2465858167b1971b0403f63289f97fc +"mkdirp@npm:^3.0.1": + version: 3.0.1 + resolution: "mkdirp@npm:3.0.1" + bin: + mkdirp: dist/cjs/src/bin.js + checksum: 10/16fd79c28645759505914561e249b9a1f5fe3362279ad95487a4501e4467abeb714fd35b95307326b8fd03f3c7719065ef11a6f97b7285d7888306d1bd2232ba + languageName: node + linkType: hard + +"motion-dom@npm:^12.23.23": + version: 12.23.23 + resolution: "motion-dom@npm:12.23.23" + dependencies: + motion-utils: "npm:^12.23.6" + checksum: 10/6bec34c28b478622bd23ce919c0d64e7f372cbc3f88e665f1e34fbf590e9bb53eebea086fb28f4e0c31941bd5274e086dc9b5360b68c4976891b94c4e92ca01a + languageName: node + linkType: hard + +"motion-utils@npm:^12.23.6": + version: 12.23.6 + resolution: "motion-utils@npm:12.23.6" + checksum: 10/fae741319e72389eca8f3e73e644ffe6501409d00c7febb2f9b836629ae86ef735e73d670d0591706ca5e93ce10228ddbcff0ecdeb09b4cd8df14df7007aedd9 languageName: node linkType: hard "motion@npm:^12.4.1": - version: 12.5.0 - resolution: "motion@npm:12.5.0" + version: 12.23.24 + resolution: "motion@npm:12.23.24" dependencies: - framer-motion: "npm:^12.5.0" + framer-motion: "npm:^12.23.24" tslib: "npm:^2.4.0" peerDependencies: "@emotion/is-prop-valid": "*" @@ -4149,7 +5051,7 @@ __metadata: optional: true react-dom: optional: true - checksum: 10/15910d37a14b91236c27c8cc6d12ae157cd1e6b55700fc58a0d271954236fae8e676b1ac9f705cb770c235892925fc6bbdb1f612dfb4018a5d4c0171964f5b3a + checksum: 10/d63d951676058001c6f234a6bdf8ed5a8fd222a38c1871ef209ed1fd87f2a288ec0e267fa616d80ac8837d0836a5f93ae85a80d773314517f19f304f25b81c3d languageName: node linkType: hard @@ -4161,11 +5063,20 @@ __metadata: linkType: hard "nanoid@npm:^3.3.6": - version: 3.3.8 - resolution: "nanoid@npm:3.3.8" + version: 3.3.11 + resolution: "nanoid@npm:3.3.11" bin: nanoid: bin/nanoid.cjs - checksum: 10/2d1766606cf0d6f47b6f0fdab91761bb81609b2e3d367027aff45e6ee7006f660fb7e7781f4a34799fe6734f1268eeed2e37a5fdee809ade0c2d4eb11b0f9c40 + checksum: 10/73b5afe5975a307aaa3c95dfe3334c52cdf9ae71518176895229b8d65ab0d1c0417dd081426134eb7571c055720428ea5d57c645138161e7d10df80815527c48 + languageName: node + linkType: hard + +"napi-postinstall@npm:^0.3.0": + version: 0.3.3 + resolution: "napi-postinstall@npm:0.3.3" + bin: + napi-postinstall: lib/cli.js + checksum: 10/8e3d1ab7bb324491eb20b7548e05033139e6c48c9cf2d8cd3ae0c17c43716751a8cda0a2e740bb09c822dfc1a0dca207e34c107067b4f66842e30c60c599c901 languageName: node linkType: hard @@ -4176,31 +5087,55 @@ __metadata: languageName: node linkType: hard -"next@npm:14.2.26": - version: 14.2.26 - resolution: "next@npm:14.2.26" +"negotiator@npm:^1.0.0": + version: 1.0.0 + resolution: "negotiator@npm:1.0.0" + checksum: 10/b5734e87295324fabf868e36fb97c84b7d7f3156ec5f4ee5bf6e488079c11054f818290fc33804cef7b1ee21f55eeb14caea83e7dafae6492a409b3e573153e5 + languageName: node + linkType: hard + +"next-mdx-remote-client@npm:^2.1.2": + version: 2.1.7 + resolution: "next-mdx-remote-client@npm:2.1.7" dependencies: - "@next/env": "npm:14.2.26" - "@next/swc-darwin-arm64": "npm:14.2.26" - "@next/swc-darwin-x64": "npm:14.2.26" - "@next/swc-linux-arm64-gnu": "npm:14.2.26" - "@next/swc-linux-arm64-musl": "npm:14.2.26" - "@next/swc-linux-x64-gnu": "npm:14.2.26" - "@next/swc-linux-x64-musl": "npm:14.2.26" - "@next/swc-win32-arm64-msvc": "npm:14.2.26" - "@next/swc-win32-ia32-msvc": "npm:14.2.26" - "@next/swc-win32-x64-msvc": "npm:14.2.26" - "@swc/helpers": "npm:0.5.5" - busboy: "npm:1.6.0" + "@babel/code-frame": "npm:^7.27.1" + "@mdx-js/mdx": "npm:^3.1.1" + "@mdx-js/react": "npm:^3.1.1" + remark-mdx-remove-esm: "npm:^1.2.1" + serialize-error: "npm:^12.0.0" + vfile: "npm:^6.0.3" + vfile-matter: "npm:^5.0.1" + peerDependencies: + react: ^19.1 + react-dom: ^19.1 + checksum: 10/8aaf6c2f11b0ed398703165c35c0355d1f058521780191684e6fe7e45698effe50ba68b154bae9db84b13e82dff98f380224d588acca6e389aeb73062ecdd31d + languageName: node + linkType: hard + +"next@npm:15.4.7": + version: 15.4.7 + resolution: "next@npm:15.4.7" + dependencies: + "@next/env": "npm:15.4.7" + "@next/swc-darwin-arm64": "npm:15.4.7" + "@next/swc-darwin-x64": "npm:15.4.7" + "@next/swc-linux-arm64-gnu": "npm:15.4.7" + "@next/swc-linux-arm64-musl": "npm:15.4.7" + "@next/swc-linux-x64-gnu": "npm:15.4.7" + "@next/swc-linux-x64-musl": "npm:15.4.7" + "@next/swc-win32-arm64-msvc": "npm:15.4.7" + "@next/swc-win32-x64-msvc": "npm:15.4.7" + "@swc/helpers": "npm:0.5.15" caniuse-lite: "npm:^1.0.30001579" - graceful-fs: "npm:^4.2.11" postcss: "npm:8.4.31" - styled-jsx: "npm:5.1.1" + sharp: "npm:^0.34.3" + styled-jsx: "npm:5.1.6" peerDependencies: "@opentelemetry/api": ^1.1.0 - "@playwright/test": ^1.41.2 - react: ^18.2.0 - react-dom: ^18.2.0 + "@playwright/test": ^1.51.1 + babel-plugin-react-compiler: "*" + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 sass: ^1.3.0 dependenciesMeta: "@next/swc-darwin-arm64": @@ -4217,20 +5152,60 @@ __metadata: optional: true "@next/swc-win32-arm64-msvc": optional: true - "@next/swc-win32-ia32-msvc": - optional: true "@next/swc-win32-x64-msvc": optional: true + sharp: + optional: true peerDependenciesMeta: "@opentelemetry/api": optional: true "@playwright/test": optional: true + babel-plugin-react-compiler: + optional: true sass: optional: true bin: next: dist/bin/next - checksum: 10/9bd8b2ef40076b251d036c6d3a3b435095ff941bab7166ebc3c75bd832c1812eb368f8dae1e56ef4bf600a81d0ad8190d778d610aa062ffa7c4c4f126cae7f13 + checksum: 10/e611751247d5cfff9337a84979918bcd61919d7b66a411c982569336c3dba7e7a8704eead7e082e579807200fa8bc80602a3e2ce4423a8b5387aab3353400918 + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 11.3.0 + resolution: "node-gyp@npm:11.3.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^14.0.3" + nopt: "npm:^8.0.0" + proc-log: "npm:^5.0.0" + semver: "npm:^7.3.5" + tar: "npm:^7.4.3" + tinyglobby: "npm:^0.2.12" + which: "npm:^5.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10/e7fb17ba72172d743ee791ea470cba1a579d1c37bcaa67a45d221d07df055baf1367d0684b3c7ee2b9b61f260cea77b2016aaac47027dbc0f43030c90b21527d + languageName: node + linkType: hard + +"nopt@npm:^8.0.0": + version: 8.1.0 + resolution: "nopt@npm:8.1.0" + dependencies: + abbrev: "npm:^3.0.0" + bin: + nopt: bin/nopt.js + checksum: 10/26ab456c51a96f02a9e5aa8d1b80ef3219f2070f3f3528a040e32fb735b1e651e17bdf0f1476988d3a46d498f35c65ed662d122f340d38ce4a7e71dd7b20c4bc + languageName: node + linkType: hard + +"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": + version: 3.0.0 + resolution: "normalize-path@npm:3.0.0" + checksum: 10/88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20 languageName: node linkType: hard @@ -4241,10 +5216,10 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.13.3": - version: 1.13.3 - resolution: "object-inspect@npm:1.13.3" - checksum: 10/14cb973d8381c69e14d7f1c8c75044eb4caf04c6dabcf40ca5c2ce42dc2073ae0bb2a9939eeca142b0c05215afaa1cd5534adb7c8879c32cba2576e045ed8368 +"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": + version: 1.13.4 + resolution: "object-inspect@npm:1.13.4" + checksum: 10/aa13b1190ad3e366f6c83ad8a16ed37a19ed57d267385aa4bfdccda833d7b90465c057ff6c55d035a6b2e52c1a2295582b294217a0a3a1ae7abdd6877ef781fb languageName: node linkType: hard @@ -4269,14 +5244,15 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.8": - version: 1.1.8 - resolution: "object.entries@npm:1.1.8" +"object.entries@npm:^1.1.9": + version: 1.1.9 + resolution: "object.entries@npm:1.1.9" dependencies: - call-bind: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10/2301918fbd1ee697cf6ff7cd94f060c738c0a7d92b22fd24c7c250e9b593642c9707ad2c44d339303c1439c5967d8964251cdfc855f7f6ec55db2dd79e8dc2a7 + es-object-atoms: "npm:^1.1.1" + checksum: 10/24163ab1e1e013796693fc5f5d349e8b3ac0b6a34a7edb6c17d3dd45c6a8854145780c57d302a82512c1582f63720f4b4779d6c1cfba12cbb1420b978802d8a3 languageName: node linkType: hard @@ -4303,7 +5279,7 @@ __metadata: languageName: node linkType: hard -"object.values@npm:^1.1.6, object.values@npm:^1.2.0, object.values@npm:^1.2.1": +"object.values@npm:^1.1.6, object.values@npm:^1.2.1": version: 1.2.1 resolution: "object.values@npm:1.2.1" dependencies: @@ -4324,14 +5300,21 @@ __metadata: languageName: node linkType: hard -"oniguruma-to-es@npm:0.10.0": - version: 0.10.0 - resolution: "oniguruma-to-es@npm:0.10.0" +"oniguruma-parser@npm:^0.12.1": + version: 0.12.1 + resolution: "oniguruma-parser@npm:0.12.1" + checksum: 10/2e7e308ec222f377b4be21e87f009729ce1cc014511d35a50440e7270a17413e4859b8c7ad1985123abe1089bda5ad2d0feccc75f7de25d9cb272b7cc34b4f3c + languageName: node + linkType: hard + +"oniguruma-to-es@npm:^4.3.3": + version: 4.3.3 + resolution: "oniguruma-to-es@npm:4.3.3" dependencies: - emoji-regex-xs: "npm:^1.0.0" - regex: "npm:^5.1.1" - regex-recursion: "npm:^5.1.1" - checksum: 10/09756001a74218b26d18940bea3ebb00d1949aa7ac142def3a94a4d256371fea169f52088ea32a6a23ca21338be56427fd9f0264907cee663e7ab147152638f7 + oniguruma-parser: "npm:^0.12.1" + regex: "npm:^6.0.1" + regex-recursion: "npm:^6.0.2" + checksum: 10/49b372569d335077c32bda066ac1da4a3f15dd25b717025cf43417fabd71d56e1152debcd8a832596e180d721b808822c88e65eb12abb26665ab8fe017f3c861 languageName: node linkType: hard @@ -4389,6 +5372,20 @@ __metadata: languageName: node linkType: hard +"p-map@npm:^7.0.2": + version: 7.0.3 + resolution: "p-map@npm:7.0.3" + checksum: 10/2ef48ccfc6dd387253d71bf502604f7893ed62090b2c9d73387f10006c342606b05233da0e4f29388227b61eb5aeface6197e166520c465c234552eeab2fe633 + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 10/58ee9538f2f762988433da00e26acc788036914d57c71c246bf0be1b60cdbd77dd60b6a3e1a30465f0b248aeb80079e0b34cb6050b1dfa18c06953bb1cbc7602 + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -4441,7 +5438,7 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.10.1": +"path-scurry@npm:^1.11.1": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" dependencies: @@ -4451,24 +5448,31 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 languageName: node linkType: hard -"picomatch@npm:^2.3.1": +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" checksum: 10/60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc languageName: node linkType: hard +"picomatch@npm:^4.0.2": + version: 4.0.3 + resolution: "picomatch@npm:4.0.3" + checksum: 10/57b99055f40b16798f2802916d9c17e9744e620a0db136554af01d19598b96e45e2f00014c91d1b8b13874b80caa8c295b3d589a3f72373ec4aaf54baa5962d5 + languageName: node + linkType: hard + "possible-typed-array-names@npm:^1.0.0": - version: 1.0.0 - resolution: "possible-typed-array-names@npm:1.0.0" - checksum: 10/8ed3e96dfeea1c5880c1f4c9cb707e5fb26e8be22f14f82ef92df20fd2004e635c62ba47fbe8f2bb63bfd80dac1474be2fb39798da8c2feba2815435d1f749af + version: 1.1.0 + resolution: "possible-typed-array-names@npm:1.1.0" + checksum: 10/2f44137b8d3dd35f4a7ba7469eec1cd9cfbb46ec164b93a5bc1f4c3d68599c9910ee3b91da1d28b4560e9cc8414c3cd56fedc07259c67e52cc774476270d3302 languageName: node linkType: hard @@ -4490,6 +5494,13 @@ __metadata: languageName: node linkType: hard +"proc-log@npm:^5.0.0": + version: 5.0.0 + resolution: "proc-log@npm:5.0.0" + checksum: 10/35610bdb0177d3ab5d35f8827a429fb1dc2518d9e639f2151ac9007f01a061c30e0c635a970c9b00c39102216160f6ec54b62377c92fac3b7bfc2ad4b98d195c + languageName: node + linkType: hard + "process@npm:^0.11.10": version: 0.11.10 resolution: "process@npm:0.11.10" @@ -4497,6 +5508,16 @@ __metadata: languageName: node linkType: hard +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 10/96e1a82453c6c96eef53a37a1d6134c9f2482f94068f98a59145d0986ca4e497bf110a410adf73857e588165eab3899f0ebcf7b3890c1b3ce802abc0d65967d4 + languageName: node + linkType: hard + "prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" @@ -4508,10 +5529,10 @@ __metadata: languageName: node linkType: hard -"property-information@npm:^6.0.0": - version: 6.5.0 - resolution: "property-information@npm:6.5.0" - checksum: 10/fced94f3a09bf651ad1824d1bdc8980428e3e480e6d01e98df6babe2cc9d45a1c52eee9a7736d2006958f9b394eb5964dedd37e23038086ddc143fc2fd5e426c +"property-information@npm:^7.0.0": + version: 7.1.0 + resolution: "property-information@npm:7.1.0" + checksum: 10/896d38a52ad7170de73f832d277c69e76a9605d941ebb3f0d6e56271414a7fdf95ff6d2819e68036b8a0c7d2d4d88bf1d4a5765c032cb19c2343567ee3a14b15 languageName: node linkType: hard @@ -4529,26 +5550,14 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^18.0.2": - version: 18.3.1 - resolution: "react-dom@npm:18.3.1" +"react-dom@npm:19.1.1": + version: 19.1.1 + resolution: "react-dom@npm:19.1.1" dependencies: - loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.2" + scheduler: "npm:^0.26.0" peerDependencies: - react: ^18.3.1 - checksum: 10/3f4b73a3aa083091173b29812b10394dd06f4ac06aff410b74702cfb3aa29d7b0ced208aab92d5272919b612e5cda21aeb1d54191848cf6e46e9e354f3541f81 - languageName: node - linkType: hard - -"react-frame-component@npm:^5.2.7": - version: 5.2.7 - resolution: "react-frame-component@npm:5.2.7" - peerDependencies: - prop-types: ^15.5.9 - react: ">= 16.3" - react-dom: ">= 16.3" - checksum: 10/bedee0c25075cbfb6d592991937640a9c8680f9017284e73ced338cc07348b3efc99121052b60ba0923d3d4ec1ed050348ddec452f059e0b947f6bff1d5bfe24 + react: ^19.1.1 + checksum: 10/9005415d2175b1f1eb4a544ad04afb29691bb7b6dd43bbdaa09932146b310b73bd4552bc772ad78fa481f409eada1560cf887606c83c1a53a922c1e30f1b3a34 languageName: node linkType: hard @@ -4559,25 +5568,39 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.0.2": - version: 18.3.1 - resolution: "react@npm:18.3.1" +"react-property@npm:2.0.2": + version: 2.0.2 + resolution: "react-property@npm:2.0.2" + checksum: 10/3a4bc1951b2b7992cb8a2d3f12016dd0920d1c06eb58b456204a6ae1210401d62baece098d3200ed8a0513dde247a5d96ffdb24f354e32ce5a9b26fbd8552668 + languageName: node + linkType: hard + +"react@npm:19.1.1": + version: 19.1.1 + resolution: "react@npm:19.1.1" + checksum: 10/9801530fdc939e1a7a499422e930515b2400809cb39c2872984e99f832d233f61659a693871183dac3155c2f9b2c9dcf4440a56bd18983277ae92860e38c3a61 + languageName: node + linkType: hard + +"readdirp@npm:~3.6.0": + version: 3.6.0 + resolution: "readdirp@npm:3.6.0" dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10/261137d3f3993eaa2368a83110466fc0e558bc2c7f7ae7ca52d94f03aac945f45146bd85e5f481044db1758a1dbb57879e2fcdd33924e2dde1bdc550ce73f7bf + picomatch: "npm:^2.2.1" + checksum: 10/196b30ef6ccf9b6e18c4e1724b7334f72a093d011a99f3b5920470f0b3406a51770867b3e1ae9711f227ef7a7065982f6ee2ce316746b2cb42c88efe44297fe7 languageName: node linkType: hard "recast@npm:^0.23.5": - version: 0.23.9 - resolution: "recast@npm:0.23.9" + version: 0.23.11 + resolution: "recast@npm:0.23.11" dependencies: ast-types: "npm:^0.16.1" esprima: "npm:~4.0.0" source-map: "npm:~0.6.1" tiny-invariant: "npm:^1.3.3" tslib: "npm:^2.0.1" - checksum: 10/d60584be179d81a82fbe58b5bbe009aa42831ee114a21a3e3a22bda91334e0b8a1a4610dca8ecb7f9ea1426da4febc08134d3003085ad6ecee478d1808eb8796 + checksum: 10/a622b7848efe13a59a40c9a1a3a8178433eae1048780e04d7392406e2d67fc29e3efa84b3aa8cfda28fd58989f4b59fa968bed295b739987a666bd11cc57a5b2 languageName: node linkType: hard @@ -4593,15 +5616,17 @@ __metadata: linkType: hard "recma-jsx@npm:^1.0.0": - version: 1.0.0 - resolution: "recma-jsx@npm:1.0.0" + version: 1.0.1 + resolution: "recma-jsx@npm:1.0.1" dependencies: acorn-jsx: "npm:^5.0.0" estree-util-to-js: "npm:^2.0.0" recma-parse: "npm:^1.0.0" recma-stringify: "npm:^1.0.0" unified: "npm:^11.0.0" - checksum: 10/dd9183f1f053bff136d710e62429ee7ca3ab5f41598ab6ea6a07cc00103b0ed356cb8ece578c0e9d19cba6dbfd6ecaace644cd0d9bf40d8af2fbe059d26c5d80 + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 10/eebbdc4e08e03f259dcd80387e51559d792de2dcb3f553c5d5a29d1ef4385e985c377cf60eabf408b1ead923a8eff85f157797a196e8262078a21dce247bbf0f languageName: node linkType: hard @@ -4645,20 +5670,12 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.14.0": - version: 0.14.1 - resolution: "regenerator-runtime@npm:0.14.1" - checksum: 10/5db3161abb311eef8c45bcf6565f4f378f785900ed3945acf740a9888c792f75b98ecb77f0775f3bf95502ff423529d23e94f41d80c8256e8fa05ed4b07cf471 - languageName: node - linkType: hard - -"regex-recursion@npm:^5.1.1": - version: 5.1.1 - resolution: "regex-recursion@npm:5.1.1" +"regex-recursion@npm:^6.0.2": + version: 6.0.2 + resolution: "regex-recursion@npm:6.0.2" dependencies: - regex: "npm:^5.1.1" regex-utilities: "npm:^2.3.0" - checksum: 10/9ec7e677743e00c14c3d5c63de1d15e5126a69c58da43e60b2c49abf940981f0269442c919e03f66d6837d0ac55ccf7981581e9d1be2a332a968c016edee226e + checksum: 10/ce25d54bdf79e38ae663c26a7f265754047b918e8b771b4ed3c871e9a926b85b195dcd0dd7a6444c82d2c9db9b2cbcaf51a353a807b469a3ad7a2172f27f21d4 languageName: node linkType: hard @@ -4669,16 +5686,16 @@ __metadata: languageName: node linkType: hard -"regex@npm:^5.1.1": - version: 5.1.1 - resolution: "regex@npm:5.1.1" +"regex@npm:^6.0.1": + version: 6.0.1 + resolution: "regex@npm:6.0.1" dependencies: regex-utilities: "npm:^2.3.0" - checksum: 10/956d0f34afa8086551dc9a0e2c575cb6d7ed5122d6d440a72cfbcd1f9adb5a3dcce4dcb61ec69eaecfcbc508cfd25075ac60d011bab5f28f1b2a36220e09a245 + checksum: 10/8f8c35ce0a74b65ce29495b8c18767a4b2724ca4a4b4acfc4d45a2851a5afdbc4daae447a1a762f8faf06a1efe3d7dd8cfc4ebbee9f7c55411d4bd30f6976026 languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.3": +"regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": version: 1.5.4 resolution: "regexp.prototype.flags@npm:1.5.4" dependencies: @@ -4703,6 +5720,19 @@ __metadata: languageName: node linkType: hard +"remark-mdx-remove-esm@npm:^1.2.1": + version: 1.2.1 + resolution: "remark-mdx-remove-esm@npm:1.2.1" + dependencies: + "@types/mdast": "npm:^4.0.4" + mdast-util-mdxjs-esm: "npm:^2.0.1" + unist-util-remove: "npm:^4.0.0" + peerDependencies: + unified: ^11 + checksum: 10/092e95ca0649cfe08c47900d9922172b531e1d60b0f90955f51a7282620a1ae53a95dddde3f8d789cdd114a2d515a9372bc72b3e46200ff6f930bd89f0985982 + languageName: node + linkType: hard + "remark-mdx@npm:^3.0.0": version: 3.1.0 resolution: "remark-mdx@npm:3.1.0" @@ -4726,15 +5756,15 @@ __metadata: linkType: hard "remark-rehype@npm:^11.0.0": - version: 11.1.1 - resolution: "remark-rehype@npm:11.1.1" + version: 11.1.2 + resolution: "remark-rehype@npm:11.1.2" dependencies: "@types/hast": "npm:^3.0.0" "@types/mdast": "npm:^4.0.0" mdast-util-to-hast: "npm:^13.0.0" unified: "npm:^11.0.0" vfile: "npm:^6.0.0" - checksum: 10/39404bd19c57b2b69660be7e3d587ddb2240495845d42fad3bcc506c9c132d07abacb0a20182b73c530857b2da0c463ad5658382b448243ce432152ab49af08d + checksum: 10/b5374a0bf08398431c92740d0cd9b20aea9df44cee12326820ddcc1b7ee642706604006461ea9799554c347e7caf31e7432132a03b97c508e1f77d29c423bd86 languageName: node linkType: hard @@ -4804,10 +5834,17 @@ __metadata: languageName: node linkType: hard +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 10/1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6 + languageName: node + linkType: hard + "reusify@npm:^1.0.4": - version: 1.0.4 - resolution: "reusify@npm:1.0.4" - checksum: 10/14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + version: 1.1.0 + resolution: "reusify@npm:1.1.0" + checksum: 10/af47851b547e8a8dc89af144fceee17b80d5beaf5e6f57ed086432d79943434ff67ca526e92275be6f54b6189f6920a24eace75c2657eed32d02c400312b21ec languageName: node linkType: hard @@ -4865,12 +5902,17 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.2": - version: 0.23.2 - resolution: "scheduler@npm:0.23.2" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10/e8d68b89d18d5b028223edf090092846868a765a591944760942b77ea1f69b17235f7e956696efbb62c8130ab90af7e0949bfb8eba7896335507317236966bc9 +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 10/7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + languageName: node + linkType: hard + +"scheduler@npm:^0.26.0": + version: 0.26.0 + resolution: "scheduler@npm:0.26.0" + checksum: 10/1ecf2e5d7de1a7a132796834afe14a2d589ba7e437615bd8c06f3e0786a3ac3434655e67aac8755d9b14e05754c177e49c064261de2673aaa3c926bc98caa002 languageName: node linkType: hard @@ -4883,12 +5925,21 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3": - version: 7.6.3 - resolution: "semver@npm:7.6.3" +"semver@npm:^7.3.5, semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.7.1, semver@npm:^7.7.2": + version: 7.7.2 + resolution: "semver@npm:7.7.2" bin: semver: bin/semver.js - checksum: 10/36b1fbe1a2b6f873559cd57b238f1094a053dbfd997ceeb8757d79d1d2089c56d1321b9f1069ce263dc64cfa922fa1d2ad566b39426fe1ac6c723c1487589e10 + checksum: 10/7a24cffcaa13f53c09ce55e05efe25cd41328730b2308678624f8b9f5fc3093fc4d189f47950f0b811ff8f3c3039c24a2c36717ba7961615c682045bf03e1dda + languageName: node + linkType: hard + +"serialize-error@npm:^12.0.0": + version: 12.0.0 + resolution: "serialize-error@npm:12.0.0" + dependencies: + type-fest: "npm:^4.31.0" + checksum: 10/733ddb9a2bd86515d18ef43f6bcb1f55a9d9b900944420e5606725668e64b752e5da971071d8fe1562961a926796257d2edb9fad828ec90a35cc6c32a75449bb languageName: node linkType: hard @@ -4929,6 +5980,84 @@ __metadata: languageName: node linkType: hard +"sharp@npm:^0.34.3": + version: 0.34.3 + resolution: "sharp@npm:0.34.3" + dependencies: + "@img/sharp-darwin-arm64": "npm:0.34.3" + "@img/sharp-darwin-x64": "npm:0.34.3" + "@img/sharp-libvips-darwin-arm64": "npm:1.2.0" + "@img/sharp-libvips-darwin-x64": "npm:1.2.0" + "@img/sharp-libvips-linux-arm": "npm:1.2.0" + "@img/sharp-libvips-linux-arm64": "npm:1.2.0" + "@img/sharp-libvips-linux-ppc64": "npm:1.2.0" + "@img/sharp-libvips-linux-s390x": "npm:1.2.0" + "@img/sharp-libvips-linux-x64": "npm:1.2.0" + "@img/sharp-libvips-linuxmusl-arm64": "npm:1.2.0" + "@img/sharp-libvips-linuxmusl-x64": "npm:1.2.0" + "@img/sharp-linux-arm": "npm:0.34.3" + "@img/sharp-linux-arm64": "npm:0.34.3" + "@img/sharp-linux-ppc64": "npm:0.34.3" + "@img/sharp-linux-s390x": "npm:0.34.3" + "@img/sharp-linux-x64": "npm:0.34.3" + "@img/sharp-linuxmusl-arm64": "npm:0.34.3" + "@img/sharp-linuxmusl-x64": "npm:0.34.3" + "@img/sharp-wasm32": "npm:0.34.3" + "@img/sharp-win32-arm64": "npm:0.34.3" + "@img/sharp-win32-ia32": "npm:0.34.3" + "@img/sharp-win32-x64": "npm:0.34.3" + color: "npm:^4.2.3" + detect-libc: "npm:^2.0.4" + semver: "npm:^7.7.2" + dependenciesMeta: + "@img/sharp-darwin-arm64": + optional: true + "@img/sharp-darwin-x64": + optional: true + "@img/sharp-libvips-darwin-arm64": + optional: true + "@img/sharp-libvips-darwin-x64": + optional: true + "@img/sharp-libvips-linux-arm": + optional: true + "@img/sharp-libvips-linux-arm64": + optional: true + "@img/sharp-libvips-linux-ppc64": + optional: true + "@img/sharp-libvips-linux-s390x": + optional: true + "@img/sharp-libvips-linux-x64": + optional: true + "@img/sharp-libvips-linuxmusl-arm64": + optional: true + "@img/sharp-libvips-linuxmusl-x64": + optional: true + "@img/sharp-linux-arm": + optional: true + "@img/sharp-linux-arm64": + optional: true + "@img/sharp-linux-ppc64": + optional: true + "@img/sharp-linux-s390x": + optional: true + "@img/sharp-linux-x64": + optional: true + "@img/sharp-linuxmusl-arm64": + optional: true + "@img/sharp-linuxmusl-x64": + optional: true + "@img/sharp-wasm32": + optional: true + "@img/sharp-win32-arm64": + optional: true + "@img/sharp-win32-ia32": + optional: true + "@img/sharp-win32-x64": + optional: true + checksum: 10/b8ca871c99b48601c47f5dfabf32e38e60071a93e359b3c765d398f708a7cf3735d1bd804b72a957246a3b215fd281a17f887d9c36ebfa690c90fa5fe142d2cd + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -4945,19 +6074,19 @@ __metadata: languageName: node linkType: hard -"shiki@npm:^1.26.1": - version: 1.26.1 - resolution: "shiki@npm:1.26.1" +"shiki@npm:^3.13.0": + version: 3.13.0 + resolution: "shiki@npm:3.13.0" dependencies: - "@shikijs/core": "npm:1.26.1" - "@shikijs/engine-javascript": "npm:1.26.1" - "@shikijs/engine-oniguruma": "npm:1.26.1" - "@shikijs/langs": "npm:1.26.1" - "@shikijs/themes": "npm:1.26.1" - "@shikijs/types": "npm:1.26.1" - "@shikijs/vscode-textmate": "npm:^10.0.1" + "@shikijs/core": "npm:3.13.0" + "@shikijs/engine-javascript": "npm:3.13.0" + "@shikijs/engine-oniguruma": "npm:3.13.0" + "@shikijs/langs": "npm:3.13.0" + "@shikijs/themes": "npm:3.13.0" + "@shikijs/types": "npm:3.13.0" + "@shikijs/vscode-textmate": "npm:^10.0.2" "@types/hast": "npm:^3.0.4" - checksum: 10/10b54241b2c58b0af228dbd00ebf2f7f820ec3527933c7fcbe7c1b634893fe003703f660cbf3ab4d0bdf61d2062590d3c7af5be57cd3192ebb4e5f2900d32f58 + checksum: 10/8d7cd039ac8df548f724047b4ba81cd84c09e8b96f411eb7c781d3d105c96ff2ec6f64e1bac724fd6fc56ac2926322bc2466124ea279d04c5ef668d5a04219bb languageName: node linkType: hard @@ -5016,6 +6145,43 @@ __metadata: languageName: node linkType: hard +"simple-swizzle@npm:^0.2.2": + version: 0.2.2 + resolution: "simple-swizzle@npm:0.2.2" + dependencies: + is-arrayish: "npm:^0.3.1" + checksum: 10/c6dffff17aaa383dae7e5c056fbf10cf9855a9f79949f20ee225c04f06ddde56323600e0f3d6797e82d08d006e93761122527438ee9531620031c08c9e0d73cc + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 10/927484aa0b1640fd9473cee3e0a0bcad6fce93fd7bbc18bac9ad0c33686f5d2e2c422fba24b5899c184524af01e11dd2bd051c2bf2b07e47aff8ca72cbfc60d2 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: "npm:^7.1.2" + debug: "npm:^4.3.4" + socks: "npm:^2.8.3" + checksum: 10/ee99e1dacab0985b52cbe5a75640be6e604135e9489ebdc3048635d186012fbaecc20fbbe04b177dee434c319ba20f09b3e7dfefb7d932466c0d707744eac05c + languageName: node + linkType: hard + +"socks@npm:^2.8.3": + version: 2.8.7 + resolution: "socks@npm:2.8.7" + dependencies: + ip-address: "npm:^10.0.1" + smart-buffer: "npm:^4.2.0" + checksum: 10/d19366c95908c19db154f329bbe94c2317d315dc933a7c2b5101e73f32a555c84fb199b62174e1490082a593a4933d8d5a9b297bde7d1419c14a11a965f51356 + languageName: node + linkType: hard + "source-map-js@npm:^1.0.2": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" @@ -5024,9 +6190,9 @@ __metadata: linkType: hard "source-map@npm:^0.7.0": - version: 0.7.4 - resolution: "source-map@npm:0.7.4" - checksum: 10/a0f7c9b797eda93139842fd28648e868a9a03ea0ad0d9fa6602a0c1f17b7fb6a7dcca00c144476cccaeaae5042e99a285723b1a201e844ad67221bf5d428f1dc + version: 0.7.6 + resolution: "source-map@npm:0.7.6" + checksum: 10/c8d2da7c57c14f3fd7568f764b39ad49bbf9dd7632b86df3542b31fed117d4af2fb74a4f886fc06baf7a510fee68e37998efc3080aacdac951c36211dc29a7a3 languageName: node linkType: hard @@ -5044,18 +6210,37 @@ __metadata: languageName: node linkType: hard -"stable-hash@npm:^0.0.4": - version: 0.0.4 - resolution: "stable-hash@npm:0.0.4" - checksum: 10/21c039d21c1cb739cf8342561753a5e007cb95ea682ccd452e76310bbb9c6987a89de8eda023e320b019f3e4691aabda75079cdbb7dadf7ab9013e931f2f23cd +"ssri@npm:^12.0.0": + version: 12.0.0 + resolution: "ssri@npm:12.0.0" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10/7024c1a6e39b3f18aa8f1c8290e884fe91b0f9ca5a6c6d410544daad54de0ba664db879afe16412e187c6c292fd60b937f047ee44292e5c2af2dcc6d8e1a9b48 languageName: node linkType: hard -"storybook@npm:^8.6.8": - version: 8.6.12 - resolution: "storybook@npm:8.6.12" +"stable-hash@npm:^0.0.5": + version: 0.0.5 + resolution: "stable-hash@npm:0.0.5" + checksum: 10/9222ea2c558e37c4a576cb4e406966b9e6aa05b93f5c4f09ef4aaabe3577439b9b8fbff407b16840b63e2ae83de74290c7b1c2da7360d571e480e46a4aec0a56 + languageName: node + linkType: hard + +"stop-iteration-iterator@npm:^1.1.0": + version: 1.1.0 + resolution: "stop-iteration-iterator@npm:1.1.0" dependencies: - "@storybook/core": "npm:8.6.12" + es-errors: "npm:^1.3.0" + internal-slot: "npm:^1.1.0" + checksum: 10/ff36c4db171ee76c936ccfe9541946b77017f12703d4c446652017356816862d3aa029a64e7d4c4ceb484e00ed4a81789333896390d808458638f3a216aa1f41 + languageName: node + linkType: hard + +"storybook@npm:^8.6.12": + version: 8.6.14 + resolution: "storybook@npm:8.6.14" + dependencies: + "@storybook/core": "npm:8.6.14" peerDependencies: prettier: ^2 || ^3 peerDependenciesMeta: @@ -5065,14 +6250,7 @@ __metadata: getstorybook: ./bin/index.cjs sb: ./bin/index.cjs storybook: ./bin/index.cjs - checksum: 10/babd1d086eb02ba25ee659e02e619f7797a6b91028ad74d2da0ab77e72021cd5c2ac4f239668f15156aabf00bd97066a774370dceadf178b1e649bf971160a26 - languageName: node - linkType: hard - -"streamsearch@npm:^1.1.0": - version: 1.1.0 - resolution: "streamsearch@npm:1.1.0" - checksum: 10/612c2b2a7dbcc859f74597112f80a42cbe4d448d03da790d5b7b39673c1197dd3789e91cd67210353e58857395d32c1e955a9041c4e6d5bae723436b3ed9ed14 + checksum: 10/104932fe29ebf49bef24c90285741cec964d1c36b3f0b38da1dace31ac664be457f2a510e41ba69fe8aa0d90c20e3446fec27d1ced41e5eefb3a9ca713d99e79 languageName: node linkType: hard @@ -5155,7 +6333,7 @@ __metadata: languageName: node linkType: hard -"string.prototype.trimend@npm:^1.0.8, string.prototype.trimend@npm:^1.0.9": +"string.prototype.trimend@npm:^1.0.9": version: 1.0.9 resolution: "string.prototype.trimend@npm:1.0.9" dependencies: @@ -5227,28 +6405,37 @@ __metadata: languageName: node linkType: hard -"style-to-object@npm:^1.0.0": - version: 1.0.8 - resolution: "style-to-object@npm:1.0.8" +"style-to-js@npm:1.1.19, style-to-js@npm:^1.0.0": + version: 1.1.19 + resolution: "style-to-js@npm:1.1.19" dependencies: - inline-style-parser: "npm:0.2.4" - checksum: 10/530b067325e3119bfaf75bdbe25cc86b02b559db00d881a74b98a2d5bb10ac953d1b455ed90c825963cf3b4bdaa1bda45f406d78d987391434b8d8ab3835df4e + style-to-object: "npm:1.0.12" + checksum: 10/c25f3a96368f258c90a886ec20b8a15ae035664e46eeea6c36f105fbc1e099ee81eaac355b7f5f948d8bb9d103c048a97b3d09e785c680ff2b4dd6d77cb76a95 languageName: node linkType: hard -"styled-jsx@npm:5.1.1": - version: 5.1.1 - resolution: "styled-jsx@npm:5.1.1" +"style-to-object@npm:1.0.12": + version: 1.0.12 + resolution: "style-to-object@npm:1.0.12" + dependencies: + inline-style-parser: "npm:0.2.6" + checksum: 10/97b91c2056f4fedb573224accba080aaa96b48a7b120a007b83415c9b18b727d0d6588b9168a1b85da06dd1abacc328f6dd774e907721901e40503a2e7a78c89 + languageName: node + linkType: hard + +"styled-jsx@npm:5.1.6": + version: 5.1.6 + resolution: "styled-jsx@npm:5.1.6" dependencies: client-only: "npm:0.0.1" peerDependencies: - react: ">= 16.8.0 || 17.x.x || ^18.0.0-0" + react: ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" peerDependenciesMeta: "@babel/core": optional: true babel-plugin-macros: optional: true - checksum: 10/4f6a5d0010770fdeea1183d919d528fd46c484e23c0535ef3e1dd49488116f639c594f3bd4440e3bc8a8686c9f8d53c5761599870ff039ede11a5c3bfe08a4be + checksum: 10/ba01200e8227fe1441a719c2e7da96c8aa7ef61d14211d1500e1abce12efa118479bcb6e7e12beecb9e1db76432caad2f4e01bbc0c9be21c134b088a4ca5ffe0 languageName: node linkType: hard @@ -5268,10 +6455,17 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.2.0": - version: 2.2.1 - resolution: "tapable@npm:2.2.1" - checksum: 10/1769336dd21481ae6347611ca5fca47add0962fd8e80466515032125eca0084a4f0ede11e65341b9c0018ef4e1cf1ad820adbb0fba7cc99865c6005734000b0a +"tar@npm:^7.4.3": + version: 7.4.3 + resolution: "tar@npm:7.4.3" + dependencies: + "@isaacs/fs-minipass": "npm:^4.0.0" + chownr: "npm:^3.0.0" + minipass: "npm:^7.1.2" + minizlib: "npm:^3.0.1" + mkdirp: "npm:^3.0.1" + yallist: "npm:^5.0.0" + checksum: 10/12a2a4fc6dee23e07cc47f1aeb3a14a1afd3f16397e1350036a8f4cdfee8dcac7ef5978337a4e7b2ac2c27a9a6d46388fc2088ea7c80cb6878c814b1425f8ecf languageName: node linkType: hard @@ -5289,6 +6483,16 @@ __metadata: languageName: node linkType: hard +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.13": + version: 0.2.14 + resolution: "tinyglobby@npm:0.2.14" + dependencies: + fdir: "npm:^6.4.4" + picomatch: "npm:^4.0.2" + checksum: 10/3d306d319718b7cc9d79fb3f29d8655237aa6a1f280860a217f93417039d0614891aee6fc47c5db315f4fcc6ac8d55eb8e23e2de73b2c51a431b42456d9e5764 + languageName: node + linkType: hard + "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -5312,12 +6516,12 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^2.0.0": - version: 2.0.0 - resolution: "ts-api-utils@npm:2.0.0" +"ts-api-utils@npm:^2.1.0": + version: 2.1.0 + resolution: "ts-api-utils@npm:2.1.0" peerDependencies: typescript: ">=4.8.4" - checksum: 10/485bdf8bbba98d58712243d958f4fd44742bbe49e559cd77882fb426d866eec6dd05c67ef91935dc4f8a3c776f235859735e1f05be399e4dc9e7ffd580120974 + checksum: 10/02e55b49d9617c6eebf8aadfa08d3ca03ca0cd2f0586ad34117fdfc7aa3cd25d95051843fde9df86665ad907f99baed179e7a117b11021417f379e4d2614eacd languageName: node linkType: hard @@ -5333,7 +6537,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.1, tslib@npm:^2.4.0": +"tslib@npm:^2.0.1, tslib@npm:^2.4.0, tslib@npm:^2.8.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10/3e2e043d5c2316461cb54e5c7fe02c30ef6dccb3384717ca22ae5c6b5bc95232a6241df19c622d9c73b809bea33b187f6dbc73030963e29950c2141bc32a79f7 @@ -5356,6 +6560,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^4.31.0": + version: 4.41.0 + resolution: "type-fest@npm:4.41.0" + checksum: 10/617ace794ac0893c2986912d28b3065ad1afb484cad59297835a0807dc63286c39e8675d65f7de08fafa339afcb8fe06a36e9a188b9857756ae1e92ee8bda212 + languageName: node + linkType: hard + "typed-array-buffer@npm:^1.0.3": version: 1.0.3 resolution: "typed-array-buffer@npm:1.0.3" @@ -5410,22 +6621,22 @@ __metadata: linkType: hard "typescript@npm:^5": - version: 5.8.3 - resolution: "typescript@npm:5.8.3" + version: 5.9.3 + resolution: "typescript@npm:5.9.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/65c40944c51b513b0172c6710ee62e951b70af6f75d5a5da745cb7fab132c09ae27ffdf7838996e3ed603bb015dadd099006658046941bd0ba30340cc563ae92 + checksum: 10/c089d9d3da2729fd4ac517f9b0e0485914c4b3c26f80dc0cffcb5de1719a17951e92425d55db59515c1a7ddab65808466debb864d0d56dcf43f27007d0709594 languageName: node linkType: hard "typescript@patch:typescript@npm%3A^5#optional!builtin": - version: 5.8.3 - resolution: "typescript@patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5" + version: 5.9.3 + resolution: "typescript@patch:typescript@npm%3A5.9.3#optional!builtin::version=5.9.3&hash=5786d5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/b9b1e73dabac5dc730c041325dbd9c99467c1b0d239f1b74ec3b90d831384af3e2ba973946232df670519147eb51a2c20f6f96163cea2b359f03de1e2091cc4f + checksum: 10/696e1b017bc2635f4e0c94eb4435357701008e2f272f553d06e35b494b8ddc60aa221145e286c28ace0c89ee32827a28c2040e3a69bdc108b1a5dc8fb40b72e3 languageName: node linkType: hard @@ -5441,10 +6652,10 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.19.2": - version: 6.19.8 - resolution: "undici-types@npm:6.19.8" - checksum: 10/cf0b48ed4fc99baf56584afa91aaffa5010c268b8842f62e02f752df209e3dea138b372a60a963b3b2576ed932f32329ce7ddb9cb5f27a6c83040d8cd74b7a70 +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10/ec8f41aa4359d50f9b59fa61fe3efce3477cc681908c8f84354d8567bb3701fafdddf36ef6bff307024d3feb42c837cf6f670314ba37fc8145e219560e473d14 languageName: node linkType: hard @@ -5463,6 +6674,24 @@ __metadata: languageName: node linkType: hard +"unique-filename@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-filename@npm:4.0.0" + dependencies: + unique-slug: "npm:^5.0.0" + checksum: 10/6a62094fcac286b9ec39edbd1f8f64ff92383baa430af303dfed1ffda5e47a08a6b316408554abfddd9730c78b6106bef4ca4d02c1231a735ddd56ced77573df + languageName: node + linkType: hard + +"unique-slug@npm:^5.0.0": + version: 5.0.0 + resolution: "unique-slug@npm:5.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 10/beafdf3d6f44990e0a5ce560f8f881b4ee811be70b6ba0db25298c31c8cf525ed963572b48cd03be1c1349084f9e339be4241666d7cf1ebdad20598d3c652b27 + languageName: node + linkType: hard + "unist-util-is@npm:^6.0.0": version: 6.0.0 resolution: "unist-util-is@npm:6.0.0" @@ -5490,6 +6719,17 @@ __metadata: languageName: node linkType: hard +"unist-util-remove@npm:^4.0.0": + version: 4.0.0 + resolution: "unist-util-remove@npm:4.0.0" + dependencies: + "@types/unist": "npm:^3.0.0" + unist-util-is: "npm:^6.0.0" + unist-util-visit-parents: "npm:^6.0.0" + checksum: 10/24a84224720f4c2d2ffce1d570c00b83ef545de80ec32a246698feff880446af6c410fc94deec4b4daafe09851d59f17cd1770e20f66d68092e3cd60c2147fb8 + languageName: node + linkType: hard + "unist-util-stringify-position@npm:^4.0.0": version: 4.0.0 resolution: "unist-util-stringify-position@npm:4.0.0" @@ -5520,6 +6760,73 @@ __metadata: languageName: node linkType: hard +"unrs-resolver@npm:^1.6.2": + version: 1.11.1 + resolution: "unrs-resolver@npm:1.11.1" + dependencies: + "@unrs/resolver-binding-android-arm-eabi": "npm:1.11.1" + "@unrs/resolver-binding-android-arm64": "npm:1.11.1" + "@unrs/resolver-binding-darwin-arm64": "npm:1.11.1" + "@unrs/resolver-binding-darwin-x64": "npm:1.11.1" + "@unrs/resolver-binding-freebsd-x64": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm64-musl": "npm:1.11.1" + "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.11.1" + "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-x64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-x64-musl": "npm:1.11.1" + "@unrs/resolver-binding-wasm32-wasi": "npm:1.11.1" + "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.11.1" + "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.11.1" + "@unrs/resolver-binding-win32-x64-msvc": "npm:1.11.1" + napi-postinstall: "npm:^0.3.0" + dependenciesMeta: + "@unrs/resolver-binding-android-arm-eabi": + optional: true + "@unrs/resolver-binding-android-arm64": + optional: true + "@unrs/resolver-binding-darwin-arm64": + optional: true + "@unrs/resolver-binding-darwin-x64": + optional: true + "@unrs/resolver-binding-freebsd-x64": + optional: true + "@unrs/resolver-binding-linux-arm-gnueabihf": + optional: true + "@unrs/resolver-binding-linux-arm-musleabihf": + optional: true + "@unrs/resolver-binding-linux-arm64-gnu": + optional: true + "@unrs/resolver-binding-linux-arm64-musl": + optional: true + "@unrs/resolver-binding-linux-ppc64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-musl": + optional: true + "@unrs/resolver-binding-linux-s390x-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-musl": + optional: true + "@unrs/resolver-binding-wasm32-wasi": + optional: true + "@unrs/resolver-binding-win32-arm64-msvc": + optional: true + "@unrs/resolver-binding-win32-ia32-msvc": + optional: true + "@unrs/resolver-binding-win32-x64-msvc": + optional: true + checksum: 10/4de653508cbaae47883a896bd5cdfef0e5e87b428d62620d16fd35cd534beaebf08ebf0cf2f8b4922aa947b2fe745180facf6cc3f39ba364f7ce0f974cb06a70 + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -5542,17 +6849,27 @@ __metadata: languageName: node linkType: hard -"vfile-message@npm:^4.0.0": - version: 4.0.2 - resolution: "vfile-message@npm:4.0.2" +"vfile-matter@npm:^5.0.1": + version: 5.0.1 + resolution: "vfile-matter@npm:5.0.1" dependencies: - "@types/unist": "npm:^3.0.0" - unist-util-stringify-position: "npm:^4.0.0" - checksum: 10/1a5a72bf4945a7103750a3001bd979088ce42f6a01efa8590e68b2425e1afc61ddc5c76f2d3c4a7053b40332b24c09982b68743223e99281158fe727135719fc + vfile: "npm:^6.0.0" + yaml: "npm:^2.0.0" + checksum: 10/5eddf848617050df7b539b68c60f4850d4f87e848accb44eb541719cece48a170897fae759023d0f3a87bcfc65fc2183a9875f11c7b3dc9ceaab7b4d739f74d6 languageName: node linkType: hard -"vfile@npm:^6.0.0": +"vfile-message@npm:^4.0.0": + version: 4.0.3 + resolution: "vfile-message@npm:4.0.3" + dependencies: + "@types/unist": "npm:^3.0.0" + unist-util-stringify-position: "npm:^4.0.0" + checksum: 10/7ba3dbeb752722a7913de8ea77c56be58cf805b5e5ccff090b2c4f8a82a32d91e058acb94d1614a40aa28191a5db99fb64014c7dfcad73d982f5d9d6702d2277 + languageName: node + linkType: hard + +"vfile@npm:^6.0.0, vfile@npm:^6.0.3": version: 6.0.3 resolution: "vfile@npm:6.0.3" dependencies: @@ -5615,7 +6932,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18, which-typed-array@npm:^1.1.2": +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19, which-typed-array@npm:^1.1.2": version: 1.1.19 resolution: "which-typed-array@npm:1.1.19" dependencies: @@ -5641,6 +6958,17 @@ __metadata: languageName: node linkType: hard +"which@npm:^5.0.0": + version: 5.0.0 + resolution: "which@npm:5.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: 10/6ec99e89ba32c7e748b8a3144e64bfc74aa63e2b2eacbb61a0060ad0b961eb1a632b08fb1de067ed59b002cec3e21de18299216ebf2325ef0f78e0f121e14e90 + languageName: node + linkType: hard + "word-wrap@npm:^1.2.5": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" @@ -5678,8 +7006,8 @@ __metadata: linkType: hard "ws@npm:^8.2.3": - version: 8.18.1 - resolution: "ws@npm:8.18.1" + version: 8.18.3 + resolution: "ws@npm:8.18.3" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -5688,7 +7016,30 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10/3f38e9594f2af5b6324138e86b74df7d77bbb8e310bf8188679dd80bac0d1f47e51536a1923ac3365f31f3d8b25ea0b03e4ade466aa8292a86cd5defca64b19b + checksum: 10/725964438d752f0ab0de582cd48d6eeada58d1511c3f613485b5598a83680bedac6187c765b0fe082e2d8cc4341fc57707c813ae780feee82d0c5efe6a4c61b6 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 10/4cb02b42b8a93b5cf50caf5d8e9beb409400a8a4d85e83bb0685c1457e9ac0b7a00819e9f5991ac25ffabb56a78e2f017c1acc010b3a1babfe6de690ba531abd + languageName: node + linkType: hard + +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: 10/1884d272d485845ad04759a255c71775db0fac56308764b4c77ea56a20d56679fad340213054c8c9c9c26fcfd4c4b2a90df993b7e0aaf3cdb73c618d1d1a802a + languageName: node + linkType: hard + +"yaml@npm:^2.0.0": + version: 2.8.1 + resolution: "yaml@npm:2.8.1" + bin: + yaml: bin.mjs + checksum: 10/eae07b3947d405012672ec17ce27348aea7d1fa0534143355d24a43a58f5e05652157ea2182c4fe0604f0540be71f99f1173f9d61018379404507790dff17665 languageName: node linkType: hard diff --git a/docs/architecture-decisions/adr000-template.md b/docs/architecture-decisions/adr000-template.md index f16ae7d39f..267eceab44 100644 --- a/docs/architecture-decisions/adr000-template.md +++ b/docs/architecture-decisions/adr000-template.md @@ -1,7 +1,6 @@ --- id: adrs-adr000 title: 'ADR000: [TITLE]' -# prettier-ignore description: Architecture Decision Record (ADR) for [TITLE] [DESCRIPTION] --- diff --git a/docs/architecture-decisions/adr001-add-adr-log.md b/docs/architecture-decisions/adr001-add-adr-log.md index de4283319a..8ad0fa3748 100644 --- a/docs/architecture-decisions/adr001-add-adr-log.md +++ b/docs/architecture-decisions/adr001-add-adr-log.md @@ -1,7 +1,6 @@ --- id: adrs-adr001 title: 'ADR001: Architecture Decision Record (ADR) log' -# prettier-ignore description: Architecture Decision Record (ADR) logs as a reference point for the team --- diff --git a/docs/architecture-decisions/adr002-default-catalog-file-format.md b/docs/architecture-decisions/adr002-default-catalog-file-format.md index 3b606cf46b..eb84913313 100644 --- a/docs/architecture-decisions/adr002-default-catalog-file-format.md +++ b/docs/architecture-decisions/adr002-default-catalog-file-format.md @@ -1,7 +1,6 @@ --- id: adrs-adr002 title: 'ADR002: Default Software Catalog File Format' -# prettier-ignore description: Architecture Decision Record (ADR) log on Default Software Catalog File Format --- diff --git a/docs/architecture-decisions/adr003-avoid-default-exports.md b/docs/architecture-decisions/adr003-avoid-default-exports.md index 24445f0be1..8ba37914df 100644 --- a/docs/architecture-decisions/adr003-avoid-default-exports.md +++ b/docs/architecture-decisions/adr003-avoid-default-exports.md @@ -1,7 +1,6 @@ --- id: adrs-adr003 title: 'ADR003: Avoid Default Exports and Prefer Named Exports' -# prettier-ignore description: Architecture Decision Record (ADR) log on Avoid Default Exports and Prefer Named Exports --- diff --git a/docs/architecture-decisions/adr004-module-export-structure.md b/docs/architecture-decisions/adr004-module-export-structure.md index 95d0f27811..507859ef01 100644 --- a/docs/architecture-decisions/adr004-module-export-structure.md +++ b/docs/architecture-decisions/adr004-module-export-structure.md @@ -1,7 +1,6 @@ --- id: adrs-adr004 title: 'ADR004: Module Export Structure' -# prettier-ignore description: Architecture Decision Record (ADR) log on Module Export Structure --- diff --git a/docs/architecture-decisions/adr005-catalog-core-entities.md b/docs/architecture-decisions/adr005-catalog-core-entities.md index 1206d9e83d..ca65425645 100644 --- a/docs/architecture-decisions/adr005-catalog-core-entities.md +++ b/docs/architecture-decisions/adr005-catalog-core-entities.md @@ -1,7 +1,6 @@ --- id: adrs-adr005 title: 'ADR005: Catalog Core Entities' -# prettier-ignore description: Architecture Decision Record (ADR) log on Catalog Core Entities --- diff --git a/docs/architecture-decisions/adr006-avoid-react-fc.md b/docs/architecture-decisions/adr006-avoid-react-fc.md index 6a7c431655..0630718763 100644 --- a/docs/architecture-decisions/adr006-avoid-react-fc.md +++ b/docs/architecture-decisions/adr006-avoid-react-fc.md @@ -1,7 +1,6 @@ --- id: adrs-adr006 title: 'ADR006: Avoid React.FC and React.SFC' -# prettier-ignore description: Architecture Decision Record (ADR) log on Avoid React.FC and React.SFC --- diff --git a/docs/architecture-decisions/adr007-use-msw-to-mock-service-requests.md b/docs/architecture-decisions/adr007-use-msw-to-mock-service-requests.md index a61bb78787..535adea8cb 100644 --- a/docs/architecture-decisions/adr007-use-msw-to-mock-service-requests.md +++ b/docs/architecture-decisions/adr007-use-msw-to-mock-service-requests.md @@ -1,7 +1,6 @@ --- id: adrs-adr007 title: 'ADR007: Use MSW to mock http requests' -# prettier-ignore description: Architecture Decision Record (ADR) log on Use MSW to mock http requests --- diff --git a/docs/architecture-decisions/adr008-default-catalog-file-name.md b/docs/architecture-decisions/adr008-default-catalog-file-name.md index fca65c8355..1f00c19b7e 100644 --- a/docs/architecture-decisions/adr008-default-catalog-file-name.md +++ b/docs/architecture-decisions/adr008-default-catalog-file-name.md @@ -1,7 +1,6 @@ --- id: adrs-adr008 title: 'ADR008: Default Catalog File Name' -# prettier-ignore description: Architecture Decision Record (ADR) log on Default Catalog File Name --- diff --git a/docs/architecture-decisions/adr009-entity-references.md b/docs/architecture-decisions/adr009-entity-references.md index 7cac946388..5779503113 100644 --- a/docs/architecture-decisions/adr009-entity-references.md +++ b/docs/architecture-decisions/adr009-entity-references.md @@ -1,7 +1,6 @@ --- id: adrs-adr009 title: 'ADR009: Entity References' -# prettier-ignore description: Architecture Decision Record (ADR) log on Entity References --- diff --git a/docs/architecture-decisions/adr010-luxon-date-library.md b/docs/architecture-decisions/adr010-luxon-date-library.md index a7b287ae0d..262a468fa9 100644 --- a/docs/architecture-decisions/adr010-luxon-date-library.md +++ b/docs/architecture-decisions/adr010-luxon-date-library.md @@ -1,7 +1,6 @@ --- id: adrs-adr010 title: 'ADR010: Use the Luxon Date Library' -# prettier-ignore description: Architecture Decision Record (ADR) for Luxon Date Library --- diff --git a/docs/architecture-decisions/adr011-plugin-package-structure.md b/docs/architecture-decisions/adr011-plugin-package-structure.md index 8e4b5435f9..323483e2d9 100644 --- a/docs/architecture-decisions/adr011-plugin-package-structure.md +++ b/docs/architecture-decisions/adr011-plugin-package-structure.md @@ -1,7 +1,6 @@ --- id: adrs-adr011 title: 'ADR011: Plugin Package Structure' -# prettier-ignore description: Architecture Decision Record (ADR) for Plugin Package Structure --- diff --git a/docs/architecture-decisions/adr012-use-luxon-locale-and-date-presets.md b/docs/architecture-decisions/adr012-use-luxon-locale-and-date-presets.md index 25bb6c1833..423e2c58f6 100644 --- a/docs/architecture-decisions/adr012-use-luxon-locale-and-date-presets.md +++ b/docs/architecture-decisions/adr012-use-luxon-locale-and-date-presets.md @@ -1,7 +1,6 @@ --- id: adrs-adr012 title: 'ADR012: Use Luxon.toLocaleString and date/time presets' -# prettier-ignore description: Architecture Decision Record (ADR) for using Luxon's toLocaleString method and date/time presets for displaying dates and times --- diff --git a/docs/architecture-decisions/adr013-use-node-fetch.md b/docs/architecture-decisions/adr013-use-node-fetch.md index e65cf0a97b..664faed1db 100644 --- a/docs/architecture-decisions/adr013-use-node-fetch.md +++ b/docs/architecture-decisions/adr013-use-node-fetch.md @@ -1,7 +1,6 @@ --- id: adrs-adr013 title: 'ADR013: [superseded] Proper use of HTTP fetching libraries' -# prettier-ignore description: Architecture Decision Record (ADR) for the proper use of fetchApiRef, node-fetch, and cross-fetch for data fetching. --- diff --git a/docs/architecture-decisions/adr014-use-fetch.md b/docs/architecture-decisions/adr014-use-fetch.md index 8454e69e7c..9faa6c9ead 100644 --- a/docs/architecture-decisions/adr014-use-fetch.md +++ b/docs/architecture-decisions/adr014-use-fetch.md @@ -1,7 +1,6 @@ --- id: adrs-adr014 title: 'ADR014: Proper use of HTTP fetching libraries' -# prettier-ignore description: Architecture Decision Record (ADR) for the proper use of fetchApiRef, native fetch, and cross-fetch for data fetching. --- diff --git a/docs/architecture-decisions/adr015-jsx-loader-structure.md b/docs/architecture-decisions/adr015-jsx-loader-structure.md new file mode 100644 index 0000000000..b50ccb90e4 --- /dev/null +++ b/docs/architecture-decisions/adr015-jsx-loader-structure.md @@ -0,0 +1,77 @@ +--- +id: adrs-adr015 +title: 'ADR015: Types and naming for element and component options' +description: Architecture Decision Record (ADR) for the proper types and naming for element and component options +--- + +## Context + +Until now there hasn't been a clear standard for how to define options that are intended to provide JSX elements or components. This led to a mix of different patterns in public APIs, which this ADR aims to standardize. + +## Decision + +We will use one of the following option property names and types when defining options that are intended to provide JSX elements or components: + +### Simple element + +This option is used when a simple synchronous JSX element is provided. It must only be used in areas where lazy-loading is not needed. + +```tsx +{ + element: JSX.Element; +} +``` + +### Simple component + +This option is used when a simple synchronous component is provided. It must only be used in areas where lazy-loading is not needed. + +```tsx +{ + component: (props: { ... }) => JSX.Element | null +} +``` + +### Async element loader + +This option is used when a simple asynchronous JSX element is provided. It is the preferred option when only producing a single instance and there is no need to pass properties to the component. This format simplifies the creation of closures for passing additional properties in the loader implementation. + +```tsx +{ + loader: () => Promise; +} +``` + +### Async component loader + +This option is used when a simple asynchronous component is provided. It is the preferred option when properties need to be passed to the component or multiple instance are needed, and lazy-loading is required. + +```tsx +{ + loader: () => Promise<(props: { ... }) => JSX.Element | null> +} +``` + +### Any component loader + +This option is used in the same cases as the async component loader, but when the option of synchronous loading is also needed. The structure of always having the outer loader function, even in the synchronous case, makes it possible to determine the type of the loader at runtime. + +```tsx +{ + loader: (() => props => JSX.Element | null) | (() => Promise JSX.Element | null>) +} +``` + +Note that when consuming this loader we'll need to unconditionally wrap it with `React.lazy`. This is because you can't delay the call to `React.lazy` until rendering, because you're not allowed to call it within a render function. This means that we can't first call the loader to check whether the returned value is a promise or not, and we must instead unconditionally wrap it with `React.lazy`. Therefore the implementation of accepting one of these loaders as an option needs to look something like this: + +```tsx +const LazyComponent = React.lazy(() => + Promise.resolve(options.loader()).then(loaded => ({ default: loaded })), +); +``` + +## Consequences + +We will update all APIs for the new frontend system in the `@backstage/frontend-*` packages. + +We will not update any of the existing APIs for the old frontend system in the `@backstage/core-*` packages. diff --git a/docs/architecture-decisions/index.md b/docs/architecture-decisions/index.md index b4ba84da0e..eddbdbe81e 100644 --- a/docs/architecture-decisions/index.md +++ b/docs/architecture-decisions/index.md @@ -2,13 +2,12 @@ id: adrs-overview title: Architecture Decision Records (ADR) sidebar_label: Overview -# prettier-ignore description: Overview of Architecture Decision Records (ADR) --- The substantial architecture decisions made in the Backstage project live here. For more information about ADRs, when to write them, and why, please see -[this blog post](https://engineering.atspotify.com/2020/04/14/when-should-i-write-an-architecture-decision-record/). +[this blog post](https://engineering.atspotify.com/2020/04/when-should-i-write-an-architecture-decision-record/). Records are never deleted but can be marked as superseded by new decisions or deprecated. diff --git a/docs/assets/architecture-overview/backstage-front-back-arch.jpeg b/docs/assets/architecture-overview/backstage-front-back-arch.jpeg new file mode 100644 index 0000000000..1cca115c95 Binary files /dev/null and b/docs/assets/architecture-overview/backstage-front-back-arch.jpeg differ diff --git a/docs/assets/architecture-overview/simplified-service-based-plugin-architecture.jpeg b/docs/assets/architecture-overview/simplified-service-based-plugin-architecture.jpeg new file mode 100644 index 0000000000..e8f5144c9a Binary files /dev/null and b/docs/assets/architecture-overview/simplified-service-based-plugin-architecture.jpeg differ diff --git a/docs/assets/architecture-overview/simplified-standalone-plugin-architecture.jpeg b/docs/assets/architecture-overview/simplified-standalone-plugin-architecture.jpeg new file mode 100644 index 0000000000..bf96367b17 Binary files /dev/null and b/docs/assets/architecture-overview/simplified-standalone-plugin-architecture.jpeg differ diff --git a/docs/assets/architecture-overview/simplified-third-party-plugin-architecture.jpeg b/docs/assets/architecture-overview/simplified-third-party-plugin-architecture.jpeg new file mode 100644 index 0000000000..4b9fd1d35f Binary files /dev/null and b/docs/assets/architecture-overview/simplified-third-party-plugin-architecture.jpeg differ diff --git a/docs/assets/technical-overview/backstage-ui-group-ownership.png b/docs/assets/technical-overview/backstage-ui-group-ownership.png new file mode 100644 index 0000000000..607aa7ad47 Binary files /dev/null and b/docs/assets/technical-overview/backstage-ui-group-ownership.png differ diff --git a/docs/assets/user-interface/css-classname-structure.png b/docs/assets/user-interface/css-classname-structure.png new file mode 100644 index 0000000000..c241b182cc Binary files /dev/null and b/docs/assets/user-interface/css-classname-structure.png differ diff --git a/docs/auth/autologout.md b/docs/auth/autologout.md index b85f6f486d..e2462522f4 100644 --- a/docs/auth/autologout.md +++ b/docs/auth/autologout.md @@ -1,7 +1,6 @@ --- id: autologout title: Auto Logout -# prettier-ignore description: This section describes how to setup the Auto Logout mechanism in Backstage --- @@ -69,7 +68,7 @@ These are the available settings: | Configuration Key | Component Property | Description | Allowed Values | Default Value | | ----------------------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | --------------------------- | | `auth.autologout.enabled` | `enabled` | Enable/disable the Auto Logout feature. | `true`/`false` | Default is enabled (`true`) | -| `auth.autologout.idleTimeoutMinutes` | `idleTimeoutMinutes` | Sets the idle time (in minutes) after which the user will be logged out. | `>= 0.5` minutes | `60` | +| `auth.autologout.idleTimeoutMinutes` | `idleTimeoutMinutes` | Sets the idle time (in minutes) after which the user will be logged out. | `>= 0.5` minutes | `0.5` | | `auth.autologout.promptBeforeIdleSeconds` | `promptBeforeIdleSeconds` | Determines the time (in seconds) prior to idle state when a prompt will appear. A value of 0 disables the prompt. This must be less than the value of `idleTimeoutMinutes`. | `>= 0` seconds | `10` | | `auth.autologout.useWorkerTimers` | `useWorkerTimers` | Enables or disables the use of Node's worker thread timers instead of main thread timers. This can be beneficial if the browser is terminating timers in inactive tabs, like those used by auto logout. In case of browser incompatibility, try setting this to false. | `true`/`false` | `true` | | `auth.autologout.logoutIfDisconnected` | `logoutIfDisconnected` | Enable/disable auto logout for disconnected users. Disconnected users are those who are logged in but do not have any active Backstage tabs open in their browsers. If enabled, such users will be automatically logged out after `idleTimeoutMinutes`. | `true`/`false` | `true` | diff --git a/docs/auth/google/gcp-iap-auth.md b/docs/auth/google/gcp-iap-auth.md index 6fe8b56d9e..386fab383f 100644 --- a/docs/auth/google/gcp-iap-auth.md +++ b/docs/auth/google/gcp-iap-auth.md @@ -2,7 +2,6 @@ id: gcp-iap-auth title: Google Identity-Aware Proxy Provider sidebar_label: Google IAP -# prettier-ignore description: Adding Google Identity-Aware Proxy as an authentication provider in Backstage --- diff --git a/docs/auth/index.md b/docs/auth/index.md index 9f4c229e7f..bff1f3df26 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -34,6 +34,7 @@ Backstage comes with many common authentication providers in the core library: - [Okta](okta/provider.md) - [OAuth 2 Custom Proxy](oauth2-proxy/provider.md) - [OneLogin](onelogin/provider.md) +- [OpenShift](openshift/provider.md) - [VMware Cloud](vmware-cloud/provider.md) These built-in providers handle the authentication flow for a particular service, including required scopes, callbacks, etc. These providers are each added to a diff --git a/docs/auth/oauth.md b/docs/auth/oauth.md index fbd87d653b..06b204fdaf 100644 --- a/docs/auth/oauth.md +++ b/docs/auth/oauth.md @@ -1,7 +1,6 @@ --- id: oauth title: OAuth and OpenID Connect -# prettier-ignore description: This section describes how Backstage allows plugins to request OAuth Access Tokens and OpenID Connect ID Tokens on behalf of the user, to be used for auth to various third party APIs --- diff --git a/docs/auth/oauth2-proxy/provider.md b/docs/auth/oauth2-proxy/provider.md index 2fa027e0ad..0c28acadc2 100644 --- a/docs/auth/oauth2-proxy/provider.md +++ b/docs/auth/oauth2-proxy/provider.md @@ -11,7 +11,7 @@ The Backstage `@backstage/plugin-auth-backend` package comes with an actual Backstage instance. This enables to reuse existing authentications within a cluster. In general the `oauth2-proxy` supports all OpenID Connect providers, for more details check this -[list of supported providers](https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider). +[list of supported providers](https://oauth2-proxy.github.io/oauth2-proxy/configuration/providers/). :::note Note diff --git a/docs/auth/oidc.md b/docs/auth/oidc.md index 250736cec7..7c4b09d9bf 100644 --- a/docs/auth/oidc.md +++ b/docs/auth/oidc.md @@ -1,7 +1,7 @@ --- id: oidc title: OIDC provider from scratch -description: This section shows how to use an OIDC provider from scratch, same steps apply for custom providers. +description: This section shows how to enable and use the Backstage OIDC provider. --- :::info @@ -11,78 +11,65 @@ system, you may want to read [its own article](https://github.com/backstage/back instead, and [consider migrating](../backend-system/building-backends/08-migrating.md)! ::: -This section shows how to use an OIDC provider from scratch, same steps apply for custom -providers. Please note these steps are for using a provider, not how to implement one, -and Backstage recommends creating custom providers specific to the IDP, so we'll use a -`azureOIDC` provider throughout this example, feel free to change any of those refs -to your provider name. +This section shows how to enable and use the Backstage OIDC provider. ## Summary -To add providers not enabled by default like OIDC, we need to follow some steps, we -assume you already have a sign-in page to which we'll add the provider so users can -sign in through the provider. In simple steps here's how you enable the provider: +OIDC is a protocol which has numerous implementations. It's likely that many of your users won't know what the OIDC **protocol** is, but they will recognise your OIDC **implementation**. Backstage supplies a generic `oidc` authorization strategy. You should re-badge this with the name and branding of your OIDC implementation, so that your users will recognise it on the Backstage sign-in page. + +For example, if your organization uses [Keycloak](https://www.keycloak.org), you would re-badge the OIDC provider as `Keycloak` and tell users to `Sign In using Keycloak`. + +## Steps + +The Backstage OIDC provider is not enabled by default. You need to manually enable the provider, and tell it which OIDC server you want to use. + +To enable the Backstage OIDC provider: - Create an API reference to identify the provider. - Create the API factory that will handle the authentication. - Add or reuse an auth provider so you can authenticate. - Add or reuse a resolver to handle the result from the authentication. - Configure the provider to access your 3rd party auth solution. -- Add the provider to sign in page so users can login with it. +- Add the provider to the Backstage sign-in page. + +For simplicity, we assume that you only have a single OIDC provider in your Backstage installation. (If you need to have multiple OIDC providers in Backstage, the steps will be different.) We'll explain each step more in detail next. -### The API reference +### The API Reference -An API reference exist for the sake of **Dependency Injection**, check [Utility APIs][4] -for extended explanation. +An API reference exists to enable **Dependency Injection**. (See [Utility APIs][4] for an extended explanation.) -In this OIDC example, we'll create the API reference directly in the -`packages/app/src/apis.ts` file, it is not a requirement to put the reference in this -file. Any location will do as long as it's available to be imported to where the API -factory is, as well as easily accessible to the rest of the application so any package -and plugin can inject the API instance when necessary. - -An example of such would be when you use an auth provider from a library installed with -NPM, or any other library repository, you would import the API ref from the library. +In this example, we'll create the API ref directly in the `packages/app/src/apis.ts` file. It is not a requirement to put the ref in this file. Any location will do as long as it's available to be imported to where the API factory is, as well as easily accessible to the rest of the application so any package and plugin can inject the API instance when necessary. ```ts -export const azureOIDCAuthApiRef: ApiRef< +export const keycloakAuthApiRef: ApiRef< OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi > = createApiRef({ - id: 'auth.my-custom-provider', + id: 'auth.keycloak', }); ``` -Please note a few things, the ID can be anything you want as long as it doesn't conflict -with other refs, backstage recommends to use a custom name that references your custom -provider, for example we are using OIDC protocol with Azure, so we could use something -like `auth.azure.oidc` as well. +The `id` of the API ref can be anything you want, as long as it doesn't conflict with other refs. Backstage recommends to use a custom name that references your custom provider. -Also we're exporting this reference, as well as the `typings`, we need to -be able to import this reference anywhere in the app, and the `typings` will tell typescript +:::note TypeScript Note +As we're exporting this API reference, as well as the TypeScript types, we need to +be able to import this reference anywhere in the app. The types will tell TypeScript what instance we're getting from DI when injecting the API. In this case we are defining an API for authentication, so we tell TS that this instance complies with 4 API interfaces: -- The OICD API that will handle authentication. +- The OIDC API that will handle authentication. - Profile API for requesting user profile info from the auth provider in question. - Backstage identity API to handle and associate the user profile with backstage identity. -- Session API, to handle the session the user will have while logged in. +- Session API, to handle the session the user will have while signed in. + ::: -### The API Factory +### The API Factory (and auth provider) -A factory is a function that can take some parameters or dependencies and return an -instance of something, in our case it will be a function that requests some backstage -APIs and use them to create an instance of an OIDC API provider. +The Backstage API factories are part of the Backstage Dependency Injection system. The factory function runs once, when something in your Backstage app first attempts to use an instance of the API it provides. The instance is then cached by the DI system for subsequent lookups. -Please note that this function only runs (creates the instance) when somewhere else in -the app you request the DI to give you an instance of the OIDC provider using the API ref -defined above, and the DI will only run this function the first time, from then on any -other DI injection will just receive the same instance created the first time, basically -the instance is cached by the DI library, a singleton. - -Let's add our OIDC API factory to the APIs array in the `packages/app/src/apis.ts` file: +Let's add a new API factory to the `apis` array in the `packages/app/src/apis.ts` file. We will tell it to use the OIDC auth provider internally. ```ts title="packages/app/src/apis.ts" /* highlight-add-next-line */ @@ -91,26 +78,29 @@ import { OAuth2 } from '@backstage/core-app-api'; export const apis: AnyApiFactory[] = [ /* highlight-add-start */ createApiFactory({ - api: azureOIDCAuthApiRef, + api: keycloakAuthApiRef, deps: { discoveryApi: discoveryApiRef, oauthRequestApi: oauthRequestApiRef, configApi: configApiRef, }, factory: ({ discoveryApi, oauthRequestApi, configApi }) => + // delegate auth to the OAuth2 strategy OAuth2.create({ configApi, discoveryApi, oauthRequestApi, provider: { - id: 'my-auth-provider', - title: 'My custom auth provider', + // this value MUST be 'oidc' + // it maps our Keycloak-branded sign-in provider onto Backstage's generic OIDC auth strategy + id: 'oidc', + title: 'Keycloak', icon: () => null, }, environment: configApi.getOptionalString('auth.environment'), defaultScopes: ['openid', 'profile', 'email'], popupOptions: { - // optional, used to customize login in popup size + // optional, used to customize sign-in window size size: { fullscreen: true, }, @@ -125,27 +115,14 @@ export const apis: AnyApiFactory[] = [ }), }), /* highlight-add-end */ - // .. ]; ``` -Please note we're importing the `OAuth2` class from `@backstage/core-app-api` effectively -delegating the authentication to it. Also we're using the `my-auth-provider` ID to tell -`OAuth2` to use the auth provider we'll define in the next section, and added the default -scopes to request ID, profile, email and user read permissions. - -## The Auth Provider - -The Auth Provider is responsible for authenticating with the 3rd party service, and give -us back the credentials, here's where you pick which protocol to use, be it Auth0, OAuth2, -OIDC, SAML or any other that your 3rd party IDP provider supports. - ### The Resolver -Resolvers exist to map user identity from the 3rd party (in this case an azure IDP -provider) to the backstage user identity. +Resolvers exist to map the user identity from the 3rd party (in this case Keycloak) to the Backstage user identity. -The default OIDC provider has built-in resolvers, here is how you configure them: +The default OIDC provider has a choice of built-in resolvers, here is how you configure them: ```yaml title="app-config.yaml" auth: @@ -159,7 +136,7 @@ auth: - resolver: emailMatchingUserEntityProfileEmail ``` -But you can also write a custom resolver as well, see an example below: +If none of the built-in resolvers are suitable, you can alternatively write a custom resolver. See an example below: ```ts title="in packages/backend/src/index.ts" /* highlight-add-start */ @@ -174,15 +151,15 @@ const myAuthProviderModule = createBackendModule({ // This ID must be exactly "auth" because that's the plugin it targets pluginId: 'auth', // This ID must be unique, but can be anything - moduleId: 'my-auth-provider', + moduleId: 'keycloak-auth-provider', register(reg) { reg.registerInit({ deps: { providers: authProvidersExtensionPoint }, async init({ providers }) { providers.registerProvider({ // This ID must match the actual provider config, e.g. addressing - // auth.providers.azure means that this must be "azure". - providerId: 'my-auth-provider', + // auth.providers.keycloak means that this must be "keycloak". + providerId: 'keycloak', // Use createProxyAuthProviderFactory instead if it's one of the proxy // based providers rather than an OAuth based one factory: createOAuthProviderFactory({ @@ -215,76 +192,85 @@ backend.add(myAuthProviderModule); //... ``` -For a more a detailed explanation about resolvers check the -[Identity Resolver][1] page. +For a more detailed explanation about resolvers check the [Identity Resolver][1] page. -### The configuration +### The Configuration -Since we are using our custom OIDC Auth Provider, we need to add a configuration based -on the provider used, in this case based on OIDC protocol (remember the 3rd party has to -support the protocol). +We will now configure our Keycloak-branded OIDC Auth Provider in Backstage, so that it can talk to our Keycloak server. -In this example we'll configure OIDC with `my-auth-provider`, to do so we need to -[Create app registration][2] in the Azure console, the only difference is that the -`http://localhost:7007/api/auth/microsoft/handler/frame` URL needs to change to -`http://localhost:7007/api/auth/my-auth-provider/handler/frame`. +The first step is to register an OIDC client app for Backstage in your Keycloak server. -Then we need to configure the env variables for the provider, based on the provider's code -in `plugins/auth-backend/src/providers/oidc/provider.ts` we need the following variables -in the `app-config.yaml`: +Then we need to configure the provider. Based on the provider's code in `plugins/auth-backend/src/providers/oidc/provider.ts` we need the following parameters in the `app-config.yaml`: ```yaml title="app-config.yaml" auth: environment: development - ### Providing an auth.session.secret will enable session support in the auth-backend session: - secret: ${SESSION_SECRET} + secret: ${AUTH_SESSION_SECRET} providers: - my-auth-provider: + oidc: development: metadataUrl: https://example.com/.well-known/openid-configuration - clientId: ${AUTH_MY_CLIENT_ID} - clientSecret: ${AUTH_MY_CLIENT_SECRET} + clientId: ${AUTH_OIDC_CLIENT_ID} + clientSecret: ${AUTH_OIDC_CLIENT_SECRET} ``` -Anything enclosed in `${}` can be replaced directly in the yaml, or provided as -environment variables, the way you obtain all these except `scope` and `prompt` is to -check the App Registration you created: +Anything enclosed in `${}` can be replaced directly in the YAML, or provided as environment variables. + +#### Required Parameters + +These parameters must always be set. - `clientId`: Grab from the Overview page. - `clientSecret`: Can only be seen when creating the secret, if you lose it you'll need a new secret. - `metadataUrl`: In Overview > Endpoints tab, grab OpenID Connect metadata document URL. + +The OIDC provider **also** requires the `auth.session.secret` to be set. + +#### Optional Parameters + +These parameters have implicit default values. Don't override them unless you know what you're doing. + - `authorizationUrl` and `tokenUrl`: Open the `metadataUrl` in a browser, that json will hold these 2 urls somewhere in there. -- `tokenEndpointAuthMethod`: Don't define it, use the default unless you know what it does. -- `tokenSignedResponseAlg`: Don't define it, use the default unless you know what it does. +- `tokenEndpointAuthMethod` +- `tokenSignedResponseAlg` - `scope`: Only used if we didn't specify `defaultScopes` in the provider's factory, basically the same thing. -- `prompt`: Recommended to use `auto` so the browser will request login to the IDP if the +- `prompt`: Recommended to use `auto` so the browser will request sign-in to the IDP if the user has no active session. -- `sessionDuration` (optional): Lifespan of the user session. +- `sessionDuration`: Lifespan of the user session. -Note that for the time being, any change in this yaml file requires a restart of the app, -also you need to have the `session.secret` part to use OIDC (some other providers might -need this as well) to support user sessions. +:::note Config Reloading +Backstage does not yet support hot reloading of auth provider configuration. Any changes to this YAML file require a restart of Backstage. +::: -### The Sign In provider +### The Sign-In Page -The last step is to add the provider to the `SignInPage` so users can sign in with your -new provider, please follow the [Sign In Configuration][3] docs, here's where you import -and use the API reference we defined earlier. +The last step is to add the provider to the sign-in page, so users can sign in with your new provider. + +If you are using the standard Backstage [`SignInPage`][3] component, you can just add it to the `providers` array like this: + +```ts title="in packages/app/src/identityProviders.ts" +export const providers = [ + // other providers... + { + id: 'keycloak-auth-provider', + title: 'Keycloak', + message: 'Sign In using Keycloak', + apiRef: keycloakAuthApiRef, + }, +]; +``` :::note Note - -These steps apply to most if not all the providers, including custom providers, the main -difference between different providers will be the contents of the API factory, the code +These steps apply to most auth providers. The main +difference between providers will be the contents of the API factory, the code in the Auth Provider Factory, the resolver, and the different variables each provider needs in the YAML config or env variables. - ::: [1]: https://backstage.io/docs/auth/identity-resolver -[2]: https://backstage.io/docs/auth/microsoft/provider#create-an-app-registration-on-azure [3]: https://backstage.io/docs/auth/#sign-in-configuration [4]: https://backstage.io/docs/api/utility-apis diff --git a/docs/auth/openshift/provider.md b/docs/auth/openshift/provider.md new file mode 100644 index 0000000000..37c5064580 --- /dev/null +++ b/docs/auth/openshift/provider.md @@ -0,0 +1,130 @@ +--- +id: provider +title: OpenShift Authentication Provider +sidebar_label: OpenShift +description: Adding OpenShift OAuth as an authentication provider in Backstage +--- + +The Backstage `core-plugin-api` package comes with a OpenShift authentication +provider that can authenticate users using OpenShift OAuth. + +## Use Case + +This setup enables the [Kubernetes plugin](../../features/kubernetes/index.md) to access OpenShift clusters using the user's permissions, +leveraging OAuth 2.0 _On-Behalf-Of_ flow via the [Kubernetes Client Side Provider](../../features/kubernetes/authentication.md). + +To make this work, the corresponding `User` entities must exist in the Backstage catalog, +and their names must match the OpenShift users. + +Although the OpenShift authentication provider does not support OIDC natively, +you can still configure it for use with the Kubernetes integration by treating it as an OIDC provider +in the `KubernetesAuthProviders` configuration. + +```ts title="packages/app/src/apis.ts" +import { + KubernetesAuthProviders, + kubernetesAuthProvidersApiRef, +} from '@backstage/plugin-kubernetes'; +import { + googleAuthApiRef, + microsoftAuthApiRef, + openshiftAuthApiRef, +} from '@backstage/core-plugin-api'; + +export const apis: AnyApiFactory[] = [ + // ... + createApiFactory({ + api: kubernetesAuthProvidersApiRef, + deps: { + microsoftAuthApi: microsoftAuthApiRef, + googleAuthApi: googleAuthApiRef, + openshiftAuthApi: openshiftAuthApiRef, + }, + factory({ microsoftAuthApi, googleAuthApi, openshiftAuthApi }) { + return new KubernetesAuthProviders({ + microsoftAuthApi, + googleAuthApi, + oidcProviders: { + openshift: { + async getIdToken(_) { + return await openshiftAuthApi.getAccessToken('user:full'); + }, + }, + }, + }); + }, + }), + //... +]; +``` + +:::note Note + +The OpenShift auth API does **not** implement the `OpenIdConnectApi` interface. In other words, it does **not** return an ID token. +Instead, it returns an **access token**, which is used by the Kubernetes integration in place of an ID token. +This is the only functional difference from the standard OIDC-based authentication flow. + +::: + +## Create an OAuth client in OpenShift + +Make sure that an OAuth client exists in the OpenShift cluster. + +To configure the OpenShift integration, create an [`OAuthClient`](https://docs.redhat.com/en/documentation/openshift_container_platform/latest/html/authentication_and_authorization/configuring-oauth-clients). + +The redirect URI must be in the following format: `https:///api/auth/openshift/handler/frame`. + +## Configuration + +The provider configuration can then be added to your `app-config.yaml` under the +root `auth` configuration: + +```yaml +auth: + environment: development + providers: + openshift: + development: + clientId: ${AUTH_OPENSHIFT_CLIENT_ID} + clientSecret: ${AUTH_OPENSHIFT_CLIENT_SECRET} + authorizationUrl: ${AUTH_OPENSHIFT_AUTHORIZATION_URL} + tokenUrl: ${AUTH_OPENSHIFT_TOKEN_URL} + openshiftApiServerUrl: ${OPENSHIFT_API_SERVER_URL} + ## uncomment to set lifespan of user session + # sessionDuration: { hours: 24 } # supports `ms` library format (e.g. '24h', '2 days'), ISO duration, "human duration" as used in code + # sessionDuration: 1d + signIn: + resolvers: + - resolver: displayNameMatchingUserEntityName +``` + +The OpenShift provider is a structure with these configuration keys: + +- `clientId`: The client ID of your OpenShift OAuth client, e.g., `my-backstage` +- `clientSecret`: The client secret tied to the OpenShift OAuth client. +- `authorizationUrl`: The OpenShift OAuth client auth endpoint, format: `https:///oauth/authorize`. +- `tokenUrl`: The OpenShift OAuth client token endpoint, format: `https:///oauth/token`. +- `openshiftApiServerUrl`: The OpenShift API server endpoint, format: `https://`. +- `sessionDuration`: (optional): Lifespan of the user session. +- `signIn`: The configuration for the sign-in process, including the **resolvers** + that should be used to match the user from the auth provider with the user + entity in the Backstage catalog (typically a single resolver is sufficient). + +The provider needs to use the scope **user:full**. + +## Backend Installation + +To add the provider to the backend we will first need to install the package by running this command: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-auth-backend-module-openshift-provider +``` + +Then we will need to add this line: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-auth-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-auth-backend-module-openshift-provider')); +/* highlight-add-end */ +``` diff --git a/docs/auth/service-to-service-auth.md b/docs/auth/service-to-service-auth.md index fecb3f5191..1423fa92f7 100644 --- a/docs/auth/service-to-service-auth.md +++ b/docs/auth/service-to-service-auth.md @@ -1,7 +1,6 @@ --- id: service-to-service-auth title: Service to Service Auth -# prettier-ignore description: This section describes service to service authentication works, both internally within Backstage plugins and when external callers want to make requests. --- @@ -415,9 +414,13 @@ Each entry has one or more of the following fields: ## Adding custom or logic for validation and issuing of tokens -The `pluginTokenHandlerDecoratorServiceRef` can be used to decorate the existing token handler without having to re-implement the entire `AuthService` implementation. +The `pluginTokenHandlerDecoratorServiceRef` and `externalTokenHandlersServiceRef` can be used to extend the existing token handler without having to re-implement the entire `AuthService` implementation. This is particularly useful when you want to add additional logic to the handler, such as logging or metrics or custom token validation. +### PluginTokenHandler decoration + +The `pluginTokenHandlerDecoratorServiceRef` can be used to decorate the default PluginTokenHandler used for create and verify tokens from plugins. + The `PluginTokenHandler` interface has two methods: - `issueToken`: This method is used to issue a token for a plugin. It takes in the `pluginId` and `targetPluginId` as arguments, and an optional `limitedUserToken` object which can be used to issue a token on behalf of another user. The method returns a promise that resolves to an object containing the issued token. @@ -440,3 +443,109 @@ const decoratedPluginTokenHandler = createServiceFactory({ }, }); ``` + +### Adding custom ExternalTokenHandler + +The `externalTokenHandlersServiceRef` can be used to add custom external token handlers to the default implementation. + +Your service factory must return an object with a `type` property that matches the token type in your configuration (e.g., 'custom', 'api-key'). When Backstage encounters tokens of this type, it calls your `initialize` method with all the configuration entries that match this type. Your factory can return either a single token handler or an array of handlers to process and validate these tokens. + +:::note Note + +During token verification, all the token handlers are tested. Consider this when adding many token handlers, as it may impact performance. + +::: + +For example, if we want to add a custom external token handler for the `custom` type: + +our config would look like this: + +```yaml title="in e.g. app-config.production.yaml" +backend: + auth: + externalAccess: + - type: custom + options: + customOptions: additional-value + accessRestrictions: + - plugin: events + - type: custom + options: + customOptions: another-value + accessRestrictions: + - plugin: events +``` + +And we can implement the custom token handler like this: + +```ts +import { + ExternalTokenHandler, + externalTokenHandlersServiceRef, + createExternalTokenHandler, +} from '@backstage/backend-defaults/auth'; +import { createServiceFactory } from '@backstage/backend-plugin-api'; + +const customExternalTokenHandlers = createServiceFactory({ + service: externalTokenHandlersServiceRef, + deps: {}, + async factory() { + return createExternalTokenHandler({ + type: 'custom', + initialize({ options }) { + // Initialize your handler context from config + const customOptions = options.getString('customOptions'); + return { customOptions }; + }, + async verifyToken(token, context) { + // Your custom token validation logic here + // Return undefined if token is invalid + // Return { subject: 'your-subject' } if token is valid + + if (token === 'valid-token') { + return { subject: `custom:${context.customOptions}` }; + } + return undefined; + }, + }); + }, +}); +``` + +The `createExternalTokenHandler` helper simplifies creating external token handlers with the new API: + +- **`type`**: A string identifier for your token handler type that matches the config +- **`initialize`**: Called once for each config entry of this type, receives the config options and returns a context object that will be passed to `verifyToken` +- **`verifyToken`**: Called for each token verification with the token and context, returns the subject if valid or `undefined` if not + +```ts +// Example of a more complex handler with external API call +const apiTokenHandler = createExternalTokenHandler({ + type: 'api-validation', + initialize({ options }) { + const apiBaseUrl = options.getString('apiBaseUrl'); + const apiKey = options.getString('apiKey'); + return { apiBaseUrl, apiKey }; + }, + async verifyToken(token, { apiBaseUrl, apiKey }) { + try { + const response = await fetch(`${apiBaseUrl}/validate-token`, { + method: 'POST', + headers: { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ token }), + }); + + if (response.ok) { + const { userId } = await response.json(); + return { subject: `api:${userId}` }; + } + } catch (error) { + // Log error but don't throw - return undefined for invalid tokens + } + return undefined; + }, +}); +``` diff --git a/docs/backend-system/architecture/01-index.md b/docs/backend-system/architecture/01-index.md index 968ff2f001..293a46b7ca 100644 --- a/docs/backend-system/architecture/01-index.md +++ b/docs/backend-system/architecture/01-index.md @@ -2,7 +2,6 @@ id: index title: Backend System Architecture sidebar_label: Overview -# prettier-ignore description: The structure and architecture of the new Backend System and its component parts --- diff --git a/docs/backend-system/architecture/02-backends.md b/docs/backend-system/architecture/02-backends.md index 1310453a3f..8f903eb7a8 100644 --- a/docs/backend-system/architecture/02-backends.md +++ b/docs/backend-system/architecture/02-backends.md @@ -2,7 +2,6 @@ id: backends title: Backend Instances sidebar_label: Backend -# prettier-ignore description: Backend instances --- diff --git a/docs/backend-system/architecture/03-services.md b/docs/backend-system/architecture/03-services.md index ad437e471e..022aab202b 100644 --- a/docs/backend-system/architecture/03-services.md +++ b/docs/backend-system/architecture/03-services.md @@ -2,7 +2,6 @@ id: services title: Backend Services sidebar_label: Services -# prettier-ignore description: Services for backend plugins --- @@ -224,6 +223,35 @@ export const customFooServiceFactory = createServiceFactory({ This allows you to provide more advanced options for the service implementation that couldn't be expressed through static configuration. It also gives users of the service implementation access to other services through dependency injection, which can be useful for their customizations. +## Multiton + +By default the service reference will point to a singleton instance of the service. This mean if a new service factory uses this reference it will override the previous one. This is the most common use-case, but in some cases you may want to have multiple instances of the same service. +For some services, it is desirable to extend the functionality instead of overriding it. For example, some services could have many handlers to address specific events, and you may want to add a new handler instead of overriding the previous one. In this case, you can use the `multiton` option when creating the service reference: + +```ts +// example-service-ref.ts +import { createServiceRef } from '@backstage/backend-plugin-api'; + +export interface FooService { + foo(options: FooOptions): Promise; +} + +export const fooServiceRef = createServiceRef({ + id: 'example.foo', + multiton: true, // this service ref will be an array of instances +}); +``` + +When adding this `serviceRef` as a dependency to a factory, the factory will receive an array of instances instead of a single instance: + +```ts +deps: {fooServices: fooServiceRef}, + factory(fooServices) { + // fooServices is an array of instances + return new Bar(fooServices); + }, +``` + ## Service Factory Options Pattern :::note Note diff --git a/docs/backend-system/architecture/04-plugins.md b/docs/backend-system/architecture/04-plugins.md index f2a6b856b9..fdb5012569 100644 --- a/docs/backend-system/architecture/04-plugins.md +++ b/docs/backend-system/architecture/04-plugins.md @@ -2,7 +2,6 @@ id: plugins title: Backend Plugins sidebar_label: Plugins -# prettier-ignore description: Backend plugins --- diff --git a/docs/backend-system/architecture/05-extension-points.md b/docs/backend-system/architecture/05-extension-points.md index 12c4ec75f5..2e11d2763f 100644 --- a/docs/backend-system/architecture/05-extension-points.md +++ b/docs/backend-system/architecture/05-extension-points.md @@ -2,7 +2,6 @@ id: extension-points title: Backend Plugin Extension Points sidebar_label: Extension Points -# prettier-ignore description: Extension points of backend plugins --- diff --git a/docs/backend-system/architecture/06-modules.md b/docs/backend-system/architecture/06-modules.md index 010f36109c..e8905808ee 100644 --- a/docs/backend-system/architecture/06-modules.md +++ b/docs/backend-system/architecture/06-modules.md @@ -2,7 +2,6 @@ id: modules title: Plugin Modules sidebar_label: Modules -# prettier-ignore description: Modules for backend plugins --- diff --git a/docs/backend-system/architecture/07-feature-loaders.md b/docs/backend-system/architecture/07-feature-loaders.md index b2cc574bf9..0a2d611b7b 100644 --- a/docs/backend-system/architecture/07-feature-loaders.md +++ b/docs/backend-system/architecture/07-feature-loaders.md @@ -2,7 +2,6 @@ id: feature-loaders title: Backend Feature Loaders sidebar_label: Feature Loaders -# prettier-ignore description: Backend feature loaders --- diff --git a/docs/backend-system/architecture/08-naming-patterns.md b/docs/backend-system/architecture/08-naming-patterns.md index 32ed1d9035..585a9fe87c 100644 --- a/docs/backend-system/architecture/08-naming-patterns.md +++ b/docs/backend-system/architecture/08-naming-patterns.md @@ -2,7 +2,6 @@ id: naming-patterns title: Backend System Naming Patterns sidebar_label: Naming Patterns -# prettier-ignore description: Naming patterns in the backend system --- diff --git a/docs/backend-system/building-backends/01-index.md b/docs/backend-system/building-backends/01-index.md index ec95e57973..0f0a8e01ea 100644 --- a/docs/backend-system/building-backends/01-index.md +++ b/docs/backend-system/building-backends/01-index.md @@ -2,7 +2,6 @@ id: index title: Building Backends sidebar_label: Overview -# prettier-ignore description: Building backends using the new backend system --- diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index a827171ff7..a638516165 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -2,7 +2,6 @@ id: migrating title: Migrating your Backend to the New Backend System sidebar_label: Migration Guide -# prettier-ignore description: How to migrate existing backends to the new backend system --- @@ -212,7 +211,7 @@ argument of `createBackend`. ## Removing `@backstage/backend-common` -The `@backstage/backend-common` package has been deprecated as part of moving to the new backend system, an you will need to replace existing usage of it. All exports from the package have been marked as deprecated in the last few releases of the package, and each export has its own deprecation message that explains how to replace that particular export. +The `@backstage/backend-common` package has been deprecated as part of moving to the new backend system, and you will need to replace existing usage of it. All exports from the package have been marked as deprecated in the last few releases of the package, and each export has its own deprecation message that explains how to replace that particular export. These are the deprecation messages for the most common replacements: diff --git a/docs/backend-system/building-plugins-and-modules/01-index.md b/docs/backend-system/building-plugins-and-modules/01-index.md index db78faaced..53bf4af8ef 100644 --- a/docs/backend-system/building-plugins-and-modules/01-index.md +++ b/docs/backend-system/building-plugins-and-modules/01-index.md @@ -2,7 +2,6 @@ id: index title: Building Backend Plugins and Modules sidebar_label: Overview -# prettier-ignore description: Building backend plugins and modules using the new backend system --- diff --git a/docs/backend-system/building-plugins-and-modules/02-testing.md b/docs/backend-system/building-plugins-and-modules/02-testing.md index f72d2de49b..67fb3d4f22 100644 --- a/docs/backend-system/building-plugins-and-modules/02-testing.md +++ b/docs/backend-system/building-plugins-and-modules/02-testing.md @@ -2,7 +2,6 @@ id: testing title: Testing Backend Plugins and Modules sidebar_label: Testing -# prettier-ignore description: Learn how to test your backend plugins and modules --- @@ -190,7 +189,7 @@ describe('MyDatabaseClass', () => { // "physical" databases to test against is much costlier than creating the // "logical" databases within them that the individual tests use. const databases = TestDatabases.create({ - ids: ['POSTGRES_17', 'POSTGRES_13', 'SQLITE_3', 'MYSQL_8'], + ids: ['POSTGRES_18', 'POSTGRES_14', 'SQLITE_3', 'MYSQL_8'], }); // Just an example of how to conveniently bundle up the setup code diff --git a/docs/backend-system/building-plugins-and-modules/08-migrating.md b/docs/backend-system/building-plugins-and-modules/08-migrating.md index 5da443328c..f48c5579f6 100644 --- a/docs/backend-system/building-plugins-and-modules/08-migrating.md +++ b/docs/backend-system/building-plugins-and-modules/08-migrating.md @@ -2,7 +2,6 @@ id: migrating title: Migrating your Backend Plugin to the New Backend System sidebar_label: Migration Guide -# prettier-ignore description: How to migrate existing backend plugins to the new backend system --- diff --git a/docs/backend-system/core-services/01-index.md b/docs/backend-system/core-services/01-index.md index 3be12b2e26..50ebea0e4f 100644 --- a/docs/backend-system/core-services/01-index.md +++ b/docs/backend-system/core-services/01-index.md @@ -2,7 +2,6 @@ id: index title: Core Backend Service APIs sidebar_label: Overview -# prettier-ignore description: Core backend service APIs --- diff --git a/docs/backend-system/core-services/actions-registry.md b/docs/backend-system/core-services/actions-registry.md new file mode 100644 index 0000000000..9e493e6bb2 --- /dev/null +++ b/docs/backend-system/core-services/actions-registry.md @@ -0,0 +1,177 @@ +--- +id: actions-registry +title: Actions Registry (alpha) +sidebar_label: Actions Registry (alpha) +description: Documentation for the Actions Registry Service +--- + +## Overview + +The Actions Registry Service is a core service designed to provide a distributed registry for actions that can be executed within Backstage backend plugins. This service allows plugins to register reusable actions with well-defined schemas and execution logic, promoting consistency and reusability across the Backstage ecosystem. + +## Action Structure + +Each action registered with the service must conform to the `ActionsRegistryActionOptions` type, which includes: + +### Required Properties + +- **`name`:** A unique identifier for the action (string) +- **`title`:** A human-readable title for the action (string) +- **`description`:** A detailed description of what the action does (string) +- **`schema`:** Object containing input and output schema definitions + - **`input`:** Function that returns a Zod schema for validating input + - **`output`:** Function that returns a Zod schema for validating output +- **`action`:** The async function that executes the action logic + +### Optional Properties + +- **`attributes`:** Object containing behavioral flags: + - **`destructive`:** Boolean indicating if the action modifies or deletes data + - **`idempotent`:** Boolean indicating if running the action multiple times produces the same result + - **`readOnly`:** Boolean indicating if the action only reads data without modifications + +### Action Context + +When an action is executed, it receives a context object (`ActionsRegistryActionContext`) containing: + +- **`input`:** The validated input data matching the defined input schema +- **`logger`:** A LoggerService instance for logging within the action +- **`credentials`:** BackstageCredentials for authentication and authorization + +## Using the Service + +### Registering an Action + +Here's an example of how to register an action with the Actions Registry Service: + +```typescript +import { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha'; + +export function registerMyActions(actionsRegistry: ActionsRegistryService) { + // Register a simple read-only action + actionsRegistry.register({ + name: 'fetch-user-info', + title: 'Fetch User Information', + description: 'Retrieves user information from the catalog', + schema: { + input: z => + z.object({ + userRef: z.string(), + includeGroups: z.boolean().optional(), + }), + output: z => + z.object({ + user: z.object({ + name: z.string(), + email: z.string(), + groups: z.array(z.string()).optional(), + }), + }), + }, + attributes: { + readOnly: true, + idempotent: true, + }, + action: async ({ input, logger, credentials }) => { + logger.info(`Fetching user info for ${input.userRef}`); + + // Perform the action logic here + const user = await fetchUserFromCatalog(input.userRef, credentials); + + return { + output: { + user: { + name: user.name, + email: user.email, + groups: input.includeGroups ? user.groups : undefined, + }, + }, + }; + }, + }); + + // Register a destructive action + actionsRegistry.register({ + name: 'delete-entity', + title: 'Delete Entity', + description: 'Removes an entity from the catalog', + schema: { + input: z => + z.object({ + entityRef: z.string(), + force: z.boolean().optional(), + }), + output: z => + z.object({ + deletedEntities: z.array(z.string()), + }), + }, + attributes: { + destructive: true, + idempotent: false, + }, + action: async ({ input, logger, credentials }) => { + logger.warn(`Deleting entity ${input.entityRef}`); + + // Perform the deletion logic here + const { deletedEntities } = await deleteEntityFromCatalog( + input.entityRef, + input.force, + credentials, + ); + + return { + output: deletedEntities, + }; + }, + }); +} +``` + +### Accessing the Service in a Plugin + +To use the Actions Registry Service in your plugin, access it through dependency injection: + +```typescript +import { + createBackendPlugin, + coreServices, +} from '@backstage/backend-plugin-api'; +import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha'; + +export const myPlugin = createBackendPlugin({ + pluginId: 'my-plugin', + register(env) { + env.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + logger: coreServices.logger, + }, + async init({ actionsRegistry, logger }) { + logger.info('Registering actions...'); + registerMyActions(actionsRegistry); + logger.info('Actions registered successfully'); + }, + }); + }, +}); +``` + +## Best Practices + +### Naming Conventions + +- **Use kebab-case:** Action names should be in kebab-case (e.g., `fetch-user-info`, `create-repository`) +- **Be Descriptive:** Choose names that clearly describe what the action does +- **Avoid Redundancy:** Don't include plugin names in action names since the plugin context is separate +- **Use Verbs:** Start action names with verbs that describe the operation (e.g., `fetch`, `create`, `delete`, `update`) + +## Action Attributes Reference + +| Attribute | Type | Default | Description | +| ------------- | ------- | ------- | ------------------------------------------------------------------- | +| `destructive` | boolean | `true` | Indicates the action modifies or deletes data. Use with caution. | +| `idempotent` | boolean | `false` | Indicates the action can be run multiple times with the same result | +| `readOnly` | boolean | `false` | Indicates the action only reads data without making modifications | + +These attributes help consumers of actions understand their behavior and implement appropriate safeguards, retries, or optimizations based on the action's characteristics. diff --git a/docs/backend-system/core-services/actions.md b/docs/backend-system/core-services/actions.md new file mode 100644 index 0000000000..ddb28b4da7 --- /dev/null +++ b/docs/backend-system/core-services/actions.md @@ -0,0 +1,131 @@ +--- +id: actions +title: Actions (alpha) +sidebar_label: Actions (alpha) +description: Documentation for the Actions Service +--- + +## Overview + +The Actions Service is a core service that provides a standardized interface for discovering and executing registered actions within Backstage backend plugins. This service acts as the consumer-facing API for actions that have been registered through the Actions Registry Service, allowing plugins to list available actions and invoke them with proper authentication and input validation. + +## How it Works + +The Actions Service implements the `ActionsService` interface, which provides two primary methods: + +- **`list()`:** Retrieves all available actions with their complete metadata +- **`invoke()`:** Executes a specific action by ID with provided input data + +The service works in conjunction with the [Actions Registry Service](./actions-registry.md), where actions are registered by plugins and then made available for discovery and execution through this service. + +## Action Identification + +Actions are identified using a unique ID that follows a specific format: + +- All action IDs are prefixed with the plugin ID that registered them, following the pattern `pluginId:actionName` +- An action named `fetch-user-info` registered by the `catalog` plugin would have the ID `catalog:fetch-user-info` +- When using the `actionsRegistryServiceMock`, the plugin ID prefix will be `test:` + +This naming convention ensures that action names are globally unique across all plugins and provides clear ownership identification. + +## Configuration + +The Actions Service can be configured to control which plugins' actions are available: + +```yaml +backend: + actions: + pluginSources: + - catalog +``` + +## Using the Service + +### Listing Available Actions + +Here's an example of how to list all available actions: + +```typescript +import { ActionsService } from '@backstage/backend-plugin-api'; + +export async function listAvailableActions( + actionsService: ActionsService, + credentials: BackstageCredentials, +) { + try { + const { actions } = await actionsService.list({ credentials }); + + console.log(`Found ${actions.length} available actions:`); + + actions.forEach(action => { + console.log(`- ${action.id}: ${action.title}`); + console.log(` Description: ${action.description}`); + console.log(` Attributes: ${JSON.stringify(action.attributes)}`); + + if (action.schema.input) { + console.log( + ` Input Schema: ${JSON.stringify(action.schema.input, null, 2)}`, + ); + } + }); + + return actions; + } catch (error) { + console.error('Failed to list actions:', error); + throw error; + } +} +``` + +### Invoking an Action + +Here's an example of how to execute a specific action: + +```typescript +import { ActionsService } from '@backstage/backend-plugin-api'; + +export async function executeAction( + actionsService: ActionsService, + actionId: string, + input: JsonObject, + credentials: BackstageCredentials, +) { + try { + const { output } = await actionsService.invoke({ + id: actionId, + input, + credentials, + }); + + console.log(`Action ${actionId} executed successfully`); + console.log('Output:', JSON.stringify(output, null, 2)); + + return output; + } catch (error) { + console.error(`Failed to execute action ${actionId}:`, error); + throw error; + } +} + +// Example usage +async function fetchUserInfo( + actionsService: ActionsService, + credentials: BackstageCredentials, +) { + const output = await executeAction( + actionsService, + 'catalog:fetch-user-info', // Note: Action ID includes plugin prefix + { + userRef: 'user:default/john.doe', + includeGroups: true, + }, + credentials, + ); + + return output; +} +``` + +## Best Practices + +For comprehensive guidance on action design, naming conventions, and schema design, see the [Actions Registry Best Practices](./actions-registry.md#best-practices) documentation. diff --git a/docs/backend-system/core-services/cache.md b/docs/backend-system/core-services/cache.md index 0e26e8e1f5..ad4d04b50a 100644 --- a/docs/backend-system/core-services/cache.md +++ b/docs/backend-system/core-services/cache.md @@ -7,6 +7,39 @@ description: Documentation for the Cache service This service lets your plugin interact with a cache. It is bound to your plugin too, so that you will only set and get values in your plugin's private namespace. +## Configuration + +The cache service can be configured using the `backend.cache` section in your `app-config.yaml`: + +```yaml +backend: + cache: + store: redis # or 'valkey', 'memcache', 'memory' + connection: redis://localhost:6379 + + # Store-specific configuration (Redis/Valkey only) + redis: + client: + # Optional: Global namespace prefix for all cache keys + namespace: 'my-app' + # Optional: Separator used between namespace and plugin ID (default: ':') + keyPrefixSeparator: ':' + # Other Redis-specific options... + clearBatchSize: 1000 + useUnlink: false +``` + +### Namespace Configuration + +For Redis and Valkey stores, you can configure a global namespace that will be prefixed to all cache keys: + +- **Without namespace**: Cache keys use only the plugin ID (e.g., `catalog:some-key`) +- **With namespace**: Cache keys use the format `namespace:pluginId:key` (e.g., `my-app:catalog:some-key`) + +The `keyPrefixSeparator` controls what character is used between the namespace and plugin ID (defaults to `:`). + +**Note**: Memory and Memcache stores do not support namespace configuration and will always use the plugin ID directly. + ## Using the service The following example shows how to get a cache client in your `example` backend plugin and setting and getting values from the cache. diff --git a/docs/backend-system/core-services/http-auth.md b/docs/backend-system/core-services/http-auth.md index f3ce96fb25..ea667b144c 100644 --- a/docs/backend-system/core-services/http-auth.md +++ b/docs/backend-system/core-services/http-auth.md @@ -104,7 +104,7 @@ or [contribute](https://github.com/backstage/backstage/blob/master/CONTRIBUTING. ### Custom token extraction logic -In some cases, you might want to customize how tokens are extracted from incoming requests. It might be that you want to extract tokens from a different location in the request. To support this you can supply your own slightly modified httpAuth service. The `DefaultHttpAuthService` class is exported from `@backstage/backend-defaults/httpAuth` and it's static `create` method can be used to pass in a custom `getTokenFromRequest` extraction function. +In some cases, you might want to customize how tokens are extracted from incoming requests. It might be that you want to extract tokens from a different location in the request. To support this you can supply your own slightly modified `httpAuth` service. The `DefaultHttpAuthService` class is exported from `@backstage/backend-defaults/httpAuth` and it's static `create` method can be used to pass in a custom `getTokenFromRequest` extraction function. ```ts import { DefaultHttpAuthService } from '@backstage/backend-defaults/httpAuth'; diff --git a/docs/backend-system/core-services/http-router.md b/docs/backend-system/core-services/http-router.md index d7658d9a67..6de394f549 100644 --- a/docs/backend-system/core-services/http-router.md +++ b/docs/backend-system/core-services/http-router.md @@ -68,6 +68,60 @@ For those routes you will also have to specify `allowLimitedAccess: true` when using the [`auth`](./auth.md) and [`httpAuth`](./http-auth.md) services to access the incoming credentials. +## Rate limiting + +Rate limiting allows you to limit the amount of requests users can send to you backend. +This is useful for blocking various network attacks, such as DDOS. + +To enable rate limiting, add the following to your config: + +```yaml +backend: + rateLimit: true +``` + +You can additionally configure the rate limiting parameters, also by plugin: + +```yaml +backend: + rateLimit: + global: true # Enables or disables rate limit for all plugins + window: 6s # Time window for rate limiting for single client + incomingRequestLimit: 100 # Number of requests to accept from one client during time window + ipAllowList: ['127.0.0.1'] # IPs to bypass rate limiting + skipSuccesfulRequests: false # Rate limit successful requests + skipFailedRequests: false # Rate limit failed requests + plugin: + # Plugin specific rate limiting + catalog: + window: 3s + incomingRequestLimit: 50 +``` + +By default, the rate limiting is per instance and the request counts are stored into memory. +If you want to share this information across all your backstage instances, you have to configure +the rate limiting store: + +```yaml +backend: + rateLimit: + global: true + store: + type: redis + connection: redis://127.0.0.1:16379 +``` + +If your instance is working behind a proxy, you have to configure the backend to trust the proxy +for the rate limiting being able to distinguish clients. + +```yaml +backend: + trustProxy: true +``` + +For more information about the trust proxy configuration and available options, +please refer to [express documentation](https://expressjs.com/en/guide/behind-proxies.html). + ## Configuring the service For more advanced customization, there are several APIs from the `@backstage/backend-defaults/httpRouter` package that allow you to customize the implementation of the config service. The default implementation uses all of the middleware exported from `@backstage/backend-defaults/httpRouter`, including `createLifecycleMiddleware`, `createAuthIntegrationRouter`, `createCredentialsBarrier` and `createCookieAuthRefreshMiddleware`. You can use these to create your own `httpRouter` service implementation, for example - here's how you would add a custom health check route to all plugins: @@ -78,8 +132,15 @@ import { createCookieAuthRefreshMiddleware, createCredentialsBarrier, createAuthIntegrationRouter, + createRateLimitMiddleware, } from '@backstage/backend-defaults/httpRouter'; -import { createServiceFactory } from '@backstage/backend-plugin-api'; +import PromiseRouter from 'express-promise-router'; +import { Handler } from 'express'; +import { + createServiceFactory, + coreServices, + HttpRouterServiceAuthPolicy, +} from '@backstage/backend-plugin-api'; const backend = createBackend(); @@ -105,6 +166,11 @@ backend.add( }) { const router = PromiseRouter(); + // Optional rate limiting middleware + router.use( + createRateLimitMiddleware({ pluginId: plugin.getId(), config }), + ); + rootHttpRouter.use(`/api/${plugin.getId()}`, router); const credentialsBarrier = createCredentialsBarrier({ diff --git a/docs/backend-system/core-services/root-health.md b/docs/backend-system/core-services/root-health.md index fa147499a6..ae279d46e8 100644 --- a/docs/backend-system/core-services/root-health.md +++ b/docs/backend-system/core-services/root-health.md @@ -12,7 +12,11 @@ The Root Health service provides some health check endpoints for the backend. By The following example shows how you can override the root health service implementation. ```ts -import { RootHealthService, coreServices } from '@backstage/backend-plugin-api'; +import { + RootHealthService, + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; const backend = createBackend(); diff --git a/docs/backend-system/core-services/root-http-router.md b/docs/backend-system/core-services/root-http-router.md index 7a268e27fc..9c2c60957f 100644 --- a/docs/backend-system/core-services/root-http-router.md +++ b/docs/backend-system/core-services/root-http-router.md @@ -40,6 +40,10 @@ createBackendPlugin({ }); ``` +## Rate limiting + +Please refer to the [HTTP Router documentation](./http-router.md#rate-limiting). + ## Configuring the service ### Via `app-config.yaml` @@ -60,7 +64,21 @@ backend: # - A string in the format of '1d', '2 seconds' etc. as supported by the `ms` library. # - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M'. # - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }`. - serverShutdownTimeout: { seconds: 20 } + serverShutdownDelay: { seconds: 20 } + server: + # (Optional) HTTP server configuration, Node.js defaults apply otherwise + # Timeout values support multiple formats: + # - Numbers (milliseconds): 30000 + # - Duration strings: '30s', '1 minute', '2 hours' + # - ISO duration strings: 'PT30S', 'PT1M', 'PT2H' + # - Duration objects: { seconds: 30 }, { minutes: 1 }, { hours: 2 } + headersTimeout: 60000 + requestTimeout: '30s' + keepAliveTimeout: { seconds: 5 } + timeout: 'PT30S' + # Numeric-only settings + maxHeadersCount: 2000 + maxRequestsPerSocket: 100 ``` ### Via Code @@ -121,6 +139,11 @@ backend.add( app.use(middleware.cors()); app.use(middleware.compression()); + // Optional rate limiting middleware + app.use(middleware.rateLimit()); + // If you are using rate limiting behind a proxy, you should set the `trust proxy` setting to true + app.set('trust proxy', true); + app.use(healthRouter); // you can add you your own middleware in here @@ -139,7 +162,7 @@ backend.add( Note that requests towards `/api/*` will never be handled by the `routes` handler unless a matching plugin exists, and will instead typically falling through to the `middleware.notFound()` handler. That is the case regardless of whether there is a configured `indexPath` or not. -The root HTTP Router service also allows for configuration of the underlying Node.js HTTP server object. This is useful for modifying settings on the HTTP server itself, such as server [timeout](https://nodejs.org/api/http.html#servertimeout), [keepAliveTimeout](https://nodejs.org/api/http.html#serverkeepalivetimeout), and [headersTimeout](https://nodejs.org/api/http.html#serverheaderstimeout). +The root HTTP Router service also allows for configuration of the underlying Node.js HTTP server object. This is useful for modifying settings on the HTTP server itself, such as server [`timeout`](https://nodejs.org/api/http.html#servertimeout), [`keepAliveTimeout`](https://nodejs.org/api/http.html#serverkeepalivetimeout), and [`headersTimeout`](https://nodejs.org/api/http.html#serverheaderstimeout). A `applyDefaults` helper is also made available to use the default app/router configuration while still enabling custom server configuration @@ -161,3 +184,52 @@ backend.add( }), ); ``` + +## Defining Content Security Policy (CSP) Configuration + +Content Security Policy (CSP) is a crucial security feature that helps protect your Backstage instance from various attacks, particularly Cross-Site Scripting (XSS). Backstage provides a flexible way to configure CSP directives through your `app-config.yaml` file. + +### Basic Configuration + +CSP directives can be defined under the `backend.csp` section in your configuration: + +```yaml +backend: + csp: + default-src: ["'self'"] + script-src: ["'self'", "'unsafe-inline'", 'example.com'] + connect-src: ["'self'", 'http:', 'https:'] + img-src: ["'self'", 'data:', 'https://backstage.io'] + style-src: ["'self'", "'unsafe-inline'"] + frame-src: ['https://some-analytics-provider.com'] +``` + +### Available Directives + +You can configure any CSP directive supported by modern browsers. Common directives include: + +- `default-src`: The fallback for other CSP directives +- `script-src`: Controls which scripts can be executed +- `style-src`: Controls which styles can be applied +- `img-src`: Controls which images can be loaded +- `connect-src`: Controls which URLs can be loaded using fetch, WebSocket, etc. +- `frame-src`: Controls which URLs can be embedded in iframes +- `font-src`: Controls which fonts can be loaded +- `object-src`: Controls which URLs can be loaded as plugins +- `media-src`: Controls which media (audio, video) can be loaded +- `upgrade-insecure-requests`: Instructs browsers to upgrade HTTP to HTTPS + +### Special Values + +- Common special values within directive arrays: + - `self`: Allows content from the same origin + - `unsafe-inline`: Allows inline scripts/styles + - `unsafe-eval`: Allows dynamic code evaluation + - `none`: Blocks all content for that directive + - `data:`: Allows data: URIs (commonly used for images) + - `https:`: Allows any content over HTTPS + +For more information on available CSP options, refer to: + +- [MDN Content Security Policy documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) +- [Helmet Content Security Policy](https://helmetjs.github.io/#content-security-policy) diff --git a/docs/backend-system/core-services/root-instance-metadata.md b/docs/backend-system/core-services/root-instance-metadata.md new file mode 100644 index 0000000000..109042f1a5 --- /dev/null +++ b/docs/backend-system/core-services/root-instance-metadata.md @@ -0,0 +1,44 @@ +--- +id: root-instance-metadata +title: Root Instance Metadata Service +sidebar_label: Root Instance Metadata +description: Documentation for the Root Instance Metadata service +--- + +The root instance metadata service provides information about the running Backstage backend instance. Currently, it provides a list of all installed backend plugins. + +:::note Note + +The root instance metadata service only provides information about the specific Backstage instance you're running on. In more complex deployments with multiple Backstage instances, this service will not provide a complete list of all plugins across all instances. + +::: + +## Using the service + +The following example shows how to use the root instance metadata service in your `example` backend plugin to access the list of installed backend plugins. + +```ts +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; + +createBackendPlugin({ + pluginId: 'example', + register(env) { + env.registerInit({ + deps: { + instanceMetadata: coreServices.rootInstanceMetadata, + }, + async init({ instanceMetadata }) { + const plugins = instanceMetadata.getInstalledPlugins(); + console.log('Installed plugins:', plugins); + }, + }); + }, +}); +``` + +## Dynamic plugin registration + +The root instance metadata service picks up plugins that are registered at start time through a `backend.start()` call. You need to restart the running backend instance to pick up newly installed plugins. diff --git a/docs/backend-system/core-services/root-logger.md b/docs/backend-system/core-services/root-logger.md index 36bb276920..d2405bce0a 100644 --- a/docs/backend-system/core-services/root-logger.md +++ b/docs/backend-system/core-services/root-logger.md @@ -13,6 +13,70 @@ If you want to override the implementation for logging across all of the backend ## Configuring the service +### Configuration parameters + +The Root Logger Service can be configured with the `backend.logger` section of your `app-config.yaml`. + +The following parameters are available: + +- `level` (string, optional): Sets the global log level. Possible values are `debug`, `info`, `warn`, or `error`. Only messages at or above this level will be logged. This can also be set via the `LOG_LEVEL` environment variable, which takes precedence. Defaults to `info`. See [Modifying the log level](#modifying-the-log-level). + +- `meta` (object, optional): Additional metadata to include with every log entry. + +- `overrides` (array, optional): Allows to specify logger overrides for specific plugins or messages. Each override can match on plugin names, message patterns, or any field contained in the log, and set a custom log level for those matches. + +Log level overrides are useful for controlling the volume of logs generated in Backstage. +They allow you to apply a global log level, `info` for example, while setting a stricter level, such as `warn`, for specific verbose plugins. + +The reverse is also possible: you can set a global log level of `warn` while enabling a more detailed level, such as `debug`, for certain logs. + +Example: + +```yaml +backend: + logger: + meta: + env: prod # Every log message will have `env="prod"` + + level: info # Set the global log level to info (the default) + + overrides: + # Set the log level to 'debug' for the catalog plugin logs + - matchers: + plugin: catalog + level: debug + + # Ignore 'info' incoming HTTP requests logs from the rootHttpRouter service + - matchers: + service: rootHttpRouter + type: incomingRequest + level: warn + + # Ignore logs starting with "Registered scheduled task", unless they're warnings or errors + - matchers: + message: ['/^Registered scheduled task/'] + level: warn +``` + +### Modifying the log level + +The available log levels, in order of decreasing verbosity, are: + +- `debug`: Detailed information, typically useful only when troubleshooting. +- `info`: General information about the application's operation. This is the default level. +- `warn`: Indicates potential issues or situations that may require attention. +- `error`: Indicates errors that have occurred but may not necessarily prevent the application from continuing. + +The verbosity of the logging can be controlled by setting the log level. The log level determines the minimum severity level of events that will be output to the console. For example, if the log level is set to `info`, events with a severity level of `debug` will be ignored. + +To increase the log level, you can set the `LOG_LEVEL` environment variable to a higher severity level, such as `warn` or `error`. However, be aware that increasing the log level might not result in more output if the existing code primarily emits logs at lower severity levels (e.g., `debug` or `info`). In such cases, you may need to adjust the logging statements within the code to use higher severity levels to see more output. + +No additional steps are required beyond setting the `LOG_LEVEL` environment variable, but the effectiveness depends on the existing logging statements in the code. + +To learn more, see the [Debugging Backstage](https://backstage.io/docs/tooling/local-dev/debugging) guide. + +### Overriding the default implementation + The following example is how you can override the root logger service to add additional metadata to all log lines. ```ts diff --git a/docs/backend-system/core-services/scheduler.md b/docs/backend-system/core-services/scheduler.md index eb25692698..f61f77cc7e 100644 --- a/docs/backend-system/core-services/scheduler.md +++ b/docs/backend-system/core-services/scheduler.md @@ -129,3 +129,24 @@ Responds with - `200 OK` if successful - `404 Not Found` if there was no such registered task for this plugin - `409 Conflict` if the task was already in a running state + +## Testing + +The `@backstage/backend-test-utils` package provides `mockServices.scheduler`, which provides a mocked implementation of the scheduler service that can be used in tests. This mocked implementation is used by default in `startTestBackend`, and it will immediately run any registered tasks on startup as long as they're not configured to run manually or with an initial delay. + +A dedicated instance can be used for more control during testing: + +```ts +it('should trigger a task', async () => { + const scheduler = mockServices.scheduler(); + + const { server } = await startTestBackend({ + features: [scheduler.factory()], + }); + + await scheduler.triggerTask('some-task-id'); + + // Next verify that the plugin state is updated accordingly + // e.g. by calling the API or verifying database state +}); +``` diff --git a/docs/backend-system/index.md b/docs/backend-system/index.md index b8cf5048be..2eb7f158ef 100644 --- a/docs/backend-system/index.md +++ b/docs/backend-system/index.md @@ -2,12 +2,29 @@ id: index title: The Backend System sidebar_label: Introduction -# prettier-ignore -description: The Backend System +description: Introduction to Backstage's backend system and its documentation --- -## Status +## Overview -The new backend system is released and ready for production use, and many plugins and modules have already been migrated. We recommend all plugins and deployments to migrate to the new system. +The Backstage backend system provides a flexible foundation for building and extending Backstage backends. It uses a modular architecture where you can create and customize plugins, modules, and service implementations. It's focused both around building your own features as well as installing third-party plugins and modules available in the Backstage ecosystem. The system is designed to be scalable and maintainable, making it work well for organizations of all sizes. -You can find an example backend setup in [the `backend` package](https://github.com/backstage/backstage/tree/master/packages/backend). +## Documentation Sections + +This documentation is organized into several key areas, each focusing on different aspects of the backend system: + +### [Architecture](./architecture/01-index.md) + +The Architecture section explains the core building blocks and concepts of the Backstage backend system. It starts with backend instances, which serve as the main entry point for creating and wiring together backend features. You'll learn about plugins that provide the base features and operate independently as microservices, modules that extend plugins with additional capabilities through extension points, and services that provide shared functionality across plugins and modules. The section also covers feature loaders that enable programmatic selection and installation of features, as well as important naming patterns and conventions used throughout the backend system. + +### [Building Backends](./building-backends/01-index.md) + +This section covers how to set up and customize your own Backstage backend. You'll learn about the basic structure of a backend package, how to install plugins and modules, and ways to customize your installation through configuration and custom service implementations. The section also explains how to split your backend into multiple deployments for better scalability and security isolation. + +### [Building Plugins and Modules](./building-plugins-and-modules/01-index.md) + +The Building Plugins and Modules section shows you how to create and test backend plugins and modules. It covers creating new plugins using `yarn new`, implementing plugin functionality with services and extension points, and building modules that extend existing plugins. You'll learn how to test your plugins and modules using the test utilities in `@backstage/backend-test-utils`, including mocking services, testing HTTP endpoints, and working with databases. The section also explains how to enable users of your plugin to customize it through static configuration and extension points. + +### [Core Services](./core-services/01-index.md) + +The Core Services section documents the essential services that are available to all backend plugins. These include fundamental services like logging, configuration, and HTTP routing that plugins can depend on. Each service is documented with its interface, implementation details, and usage examples. diff --git a/docs/conf/index.md b/docs/conf/index.md index 659ffccfe3..029c5b88fd 100644 --- a/docs/conf/index.md +++ b/docs/conf/index.md @@ -16,10 +16,24 @@ allowing for customization. ## Supplying Configuration Configuration is stored in YAML files where the defaults are `app-config.yaml` -and `app-config.local.yaml` for local overrides. Other sets of files can by -loaded by passing `--config ` flags. The configuration files themselves -contain plain YAML, but with support for loading in data and secrets from -various sources using for example `$env` and `$file` keys. +and `app-config.local.yaml` for local overrides. Additionally, it is possible +to define environment based configuration files with `BACKSTAGE_ENV` +environment variable, which will load `app-config..yaml`. + +Loading order of these files is as follows: + +1. `app-config.yaml` +2. `app-config..yaml` +3. `app-config.local.yaml` +4. `app-config..local.yaml` + +Other sets of files can by loaded by passing `--config ` flags. +Read more about the configuration loading order in the +[Configuration Files](./writing.md#configuration-files) section. + +The configuration files themselves contain plain YAML, but with support for +loading in data and secrets from various sources using for example +`$env` and `$file` keys. It is also possible to supply configuration through environment variables, for example `APP_CONFIG_app_baseUrl=https://staging.example.com`. However these diff --git a/docs/conf/user-interface/icons.md b/docs/conf/user-interface/icons.md new file mode 100644 index 0000000000..26a6f11096 --- /dev/null +++ b/docs/conf/user-interface/icons.md @@ -0,0 +1,124 @@ +--- +id: icons +title: Customizing Icons +sidebar_label: Icons +description: Customizing Icons +--- + +So far you've seen how to create your own theme and add your own logo, in the following sections you'll be shown how to override the existing icons and how to add more icons + +## Custom Icons + +You can also customize the Project's _default_ icons. + +You can change the following [icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx). + +### Requirements + +- Files in `.svg` format +- React components created for the icons + +### Create React Component + +In your front-end application, locate the `src` folder. We suggest creating the `assets/icons` directory and `customIcons.tsx` file. + +```tsx title="customIcons.tsx" +import { SvgIcon, SvgIconProps } from '@material-ui/core'; + +export const ExampleIcon = (props: SvgIconProps) => ( + + + +); +``` + +### Using the custom icon + +Supply your custom icon in `packages/app/src/App.tsx` + +```tsx title="packages/app/src/App.tsx" +/* highlight-add-next-line */ +import { ExampleIcon } from './assets/icons/CustomIcons' + + +const app = createApp({ + apis, + components: { + {/* ... */} + }, + themes: [ + {/* ... */} + ], + /* highlight-add-start */ + icons: { + github: ExampleIcon, + }, + /* highlight-add-end */ + bindRoutes({ bind }) { + {/* ... */} + } +}) +``` + +## Adding Icons + +You can add more icons, if the [default icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx) do not fit your needs, so that they can be used in other places like for Links in your entities. For this example we'll be using icons from[Material UI](https://v4.mui.com/components/material-icons/) and specifically the `AlarmIcon`. Here's how to do that: + +1. First you will want to open your `App.tsx` in `/packages/app/src` +2. Then you want to import your icon, add this to the rest of your imports: `import AlarmIcon from '@material-ui/icons/Alarm';` +3. Next you want to add the icon like this to your `createApp`: + + ```tsx title="packages/app/src/App.tsx" + const app = createApp({ + apis: ..., + plugins: ..., + /* highlight-add-start */ + icons: { + alert: AlarmIcon, + }, + /* highlight-add-end */ + themes: ..., + components: ..., + }); + ``` + +4. Now we can reference `alert` for our icon in our entity links like this: + + ```yaml + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: artist-lookup + description: Artist Lookup + links: + - url: https://example.com/alert + title: Alerts + icon: alert + ``` + + And this is the result: + + ![Example Link with Alert icon](../../assets/getting-started/add-icons-links-example.png) + + Another way you can use these icons is from the `AppContext` like this: + + ```ts + import { useApp } from '@backstage/core-plugin-api'; + + const app = useApp(); + const alertIcon = app.getSystemIcon('alert'); + ``` + + You might want to use this method if you have an icon you want to use in several locations. + +:::note Note + +If the icon is not available as one of the default icons or one you've added then it will fall back to Material UI's `LanguageIcon` + +::: diff --git a/docs/conf/user-interface/index.md b/docs/conf/user-interface/index.md new file mode 100644 index 0000000000..81acfdf720 --- /dev/null +++ b/docs/conf/user-interface/index.md @@ -0,0 +1,621 @@ +--- +id: index +title: Customizing Your App's UI +sidebar_label: Introduction +description: Learn how to customize the look and feel of your Backstage app, including theming and branding options. +--- + +Backstage offers built-in support for both light and dark themes, making it easy to get started with a professional look and feel. But many teams want to go further—tailoring the interface to reflect their organization’s unique brand, identity, and experience. + +This section explores the different ways you can customize the appearance of your Backstage instance. You'll learn how the theming system is structured today, how to work with the two coexisting UI systems, and how to define themes that align with your visual language. + +## Theming architecture overview + +Backstage currently supports two parallel UI systems. The original theming and component model is built on Material UI (MUI), a popular React-based framework. More recently, Backstage introduced Backstage UI (BUI), a custom-designed, CSS-first system developed to meet the platform’s evolving needs. Both systems are supported today, with many parts of the ecosystem still using MUI while new components adopt BUI. + +
    +
    +

    MUI (Legacy)

    +
      +
    • Theming: JS-based with UnifiedThemeProvider
    • +
    • Coverage: Most existing plugins
    • +
    • Documentation: mui.com
    • +
    +
    +
    +

    Backstage UI (New)

    +
      +
    • Theming: CSS variables and tokens
    • +
    • Coverage: Growing, focused on new work
    • +
    • Documentation: ui.backstage.io
    • +
    +
    +
    + +:::info +We recognize that maintaining two separate theming systems is not ideal. Because of the fundamental architectural differences between MUI and Backstage UI, it can be challenging to automate theme updates or know exactly which theme to modify for a given component. Our recommendation is to inspect the component’s code and check its class names: if you see a class name starting with `bui`, you should use the Backstage UI theming approach to style it. +::: + +## Creating custom themes + +During the transition to Backstage UI, you will need to maintain themes in two places: some components and plugins still rely on MUI, while others use Backstage UI. We are working on a plugin that will make help you convert your existing MUI theme into a Backstage UI CSS file you can add to your application. We'll update this page when the plugin is available but for now you can follow progress on this PR [#31140](https://github.com/backstage/backstage/pull/31140). + +```tsx title="packages/app/src/App.tsx" +/* highlight-add-start */ +import { lightTheme, darkTheme } from './themes'; // MUI themes +import './styles.css'; // Backstage UI (BUI) theme +/* highlight-add-end */ + +const app = createApp({ + apis, + components, + /* highlight-add-start */ + themes: [ + { + id: 'light', + title: 'Light theme', + variant: 'light', + icon: , + Provider: ({ children }) => ( + + ), + }, + { + id: 'dark', + title: 'Dark theme', + variant: 'dark', + icon: , + Provider: ({ children }) => ( + + ), + }, + ], + /* highlight-add-end */ +}); +``` + +| Name | Description | +| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | Each theme has a unique `id` | +| `title` | This will be shown in the settings page to select the right theme. | +| `variant` | This can be either `light` or `dark`. This is also referred to as `mode`. On the `body` of your app we are inserting a data attribute to set the theme based on this value: `data-theme-mode="light"`. | +| `icon` | This will be shown in the settings page as a visual element to complement the title. | +| `Provider` | This is needed to set the legacy theme with MUI only. This will be become redundant later on when we fully replace with BUI but for now you need to have it for MUI to work. BUI is based on CSS and don't rely on any global providers. | + +:::note +Your list of custom themes overrides the default themes. If you still want to use the default themes, they are exported as `themes.light` and `themes.dark` from [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). Be sure to provide both `light` and `dark` modes so users can choose their preference. +::: + +## Create a theme for Backstage UI (New) + +Backstage UI is built entirely using CSS. By default we are providing a default theme that include all our core CSS variables and component styles. To start customising Backstage UI to match your brand you need to create a new CSS file and import it directly in `packages/app/src/App.tsx`. All styles declared in this file will override the default styles. As your file grow you can organise it the way you want or even import multiple files. + +Backstage UI is using light by default under `:root` but you can target it more specifically using the data attribute for mode + +```css title="packages/app/src/styles.css" +:root { + /* Use :root to set styles for both light and dark themes */ + .bui-Button { + background-color: #000; + color: #fff; + } +} + +[data-theme-mode='light'] { + /* Light theme specific styles */ +  --bui-bg: #f8f8f8; + --bui-fg-primary: #000; +} + +[data-theme-mode='dark'] { + /* Dark theme specific styles */ +  --bui-bg: #333333; + --bui-fg-primary: #fff; +} +``` + +### CSS variables + +By adjusting just a few theme variables, you can easily transform the look and feel of your Backstage instance to align with your brand identity. All colors are defined using these variables, ensuring they adapt seamlessly to both light and dark modes. + +We recommend starting with a core set of CSS variables to quickly achieve a branded experience. You’ll also find a complete list of available variables below, giving you full flexibility to fine-tune the design to your needs. + +And if you’d like to go even further, you can target specific component class names for advanced customization. + +| Token Name | Description | +| -------------------- | ----------------------------------------------------------------------------------- | +| `--bui-bg` | This is used to define the background color of your app. It will only be used once. | +| `--bui-bg-surface-1` | We ar using this color to sit on top of `--bui-bg` mostly for `Card`, `Dialog`, ... | +| `--bui-bg-surface-2` | This is for content inside elevated components. This colour is less common. | +| `--bui-bg-solid` | This is used for main actions like primary buttons. | +| `--bui-fg-solid` | This is for texts or icons on top of a solid backgrounds. | +| `--bui-fg-primary` | Your primary text or icon colours. | +| `--bui-fg-secondary` | Your secondary text or icon colours. | +| `--bui-fg-link` | Used for links. | +| `--bui-border` | Main borders around surfaces like `Card`, `Dialog`, ... | +| `--bui-font-regular` | The main font of your app. | + +
    + All available CSS variables + +#### Base colors + +These colors are used for special purposes like ring, scrollbar, ... + +| Token Name | Description | +| -------------- | ----------------------------------------------------------------------- | +| `--bui-black` | Pure black color. This one should be the same in light and dark themes. | +| `--bui-white` | Pure white color. This one should be the same in light and dark themes. | +| `--bui-gray-1` | You can use these mostly for backgrounds colors. | +| `--bui-gray-2` | You can use these mostly for backgrounds colors. | +| `--bui-gray-3` | You can use these mostly for backgrounds colors. | +| `--bui-gray-4` | You can use these mostly for backgrounds colors. | +| `--bui-gray-5` | You can use these mostly for backgrounds colors. | +| `--bui-gray-6` | You can use these mostly for backgrounds colors. | +| `--bui-gray-7` | You can use these mostly for backgrounds colors. | +| `--bui-gray-8` | You can use these mostly for backgrounds colors. | + +#### Core background colors + +These colors are used for the background of your application. We are mostly using for now a single elevated background for panels. `--bui-bg` should mostly use as the main background color of your app. + +| Token Name | Description | +| ------------------------- | ------------------------------------------------ | +| `--bui-bg` | The background color of your Backstage instance. | +| `--bui-bg-surface-1` | Use for any panels or elevated surfaces. | +| `--bui-bg-surface-2` | Use for any panels or elevated surfaces. | +| `--bui-bg-solid` | Used for solid background colors. | +| `--bui-bg-solid-hover` | Used for solid background colors when hovered. | +| `--bui-bg-solid-pressed` | Used for solid background colors when pressed. | +| `--bui-bg-solid-disabled` | Used for solid background colors when disabled. | +| `--bui-bg-tint` | Used for tint background colors. | +| `--bui-bg-tint-hover` | Used for tint background colors when hovered. | +| `--bui-bg-tint-focus` | Used for tint background colors when active. | +| `--bui-bg-tint-disabled` | Used for tint background colors when disabled. | +| `--bui-bg-danger` | Used to show errors information. | +| `--bui-bg-warning` | Used to show warnings information. | +| `--bui-bg-success` | Used to show success information. | + +#### Foreground colors + +Foreground colours are meant to work in pair with a background colours. Typically this would work for icons, texts, shapes, ... Use a matching name to know what foreground color to use. These colors are prefixed with `fg` to make it easier to identify. + +| Token Name | Description | +| ------------------------ | ----------------------------------------------------------------- | +| `--bui-fg-primary` | It should be used on top of main background surfaces. | +| `--bui-fg-secondary` | It should be used on top of main background surfaces. | +| `--bui-fg-link` | It should be used on top of main background surfaces. | +| `--bui-fg-link-hover` | It should be used on top of main background surfaces. | +| `--bui-fg-disabled` | It should be used on top of main background surfaces. | +| `--bui-fg-solid` | It should be used on top of solid background colors. | +| `--bui-fg-tint` | It should be used on top of tint background colors. | +| `--bui-fg-tint-disabled` | It should be used on top of tint background colors when disabled. | +| `--bui-fg-danger` | It should be used on top of danger background colors. | +| `--bui-fg-warning` | It should be used on top of warning background colors. | +| `--bui-fg-success` | It should be used on top of success background colors. | + +#### Border colors + +These border colors are mostly meant to be used as borders on top of any components with low contrast to help as a separator with the different background colors. + +| Token Name | Description | +| ----------------------- | --------------------------------------------------- | +| `--bui-border` | It should be used on top of `--bui-bg-surface-1`. | +| `--bui-border-hover` | Used when the component is interactive and hovered. | +| `--bui-border-pressed` | Used when the component is interactive and hovered. | +| `--bui-border-disabled` | Used when the component is disabled. | +| `--bui-border-danger` | It should be used on top of `--bui-bg-danger`. | +| `--bui-border-warning` | It should be used on top of `--bui-bg-warning`. | +| `--bui-border-success` | It should be used on top of `--bui-bg-success`. | + +#### Special colors + +These colors are used for special purposes like ring, scrollbar, ... + +| Token Name | Description | +| ----------------------- | --------------------------------- | +| `--bui-ring` | The color of the ring. | +| `--bui-scrollbar` | The color of the scrollbar. | +| `--bui-scrollbar-thumb` | The color of the scrollbar thumb. | + +#### Font families + +We have two fonts that we use across Backstage UI. The first one is the sans-serif font that we use for the body of the application. The second one is the monospace font that we use for code blocks and tables. + +| Token Name | Description | +| -------------------- | ---------------------------------- | +| `--bui-font-regular` | The sans-serif font for the theme. | +| `--bui-font-mono` | The monospace font for the theme. | + +#### Font weights + +We have two font weights that we use across Backstage UI. Regular or Bold. + +| Token Name | Description | +| --------------------------- | -------------------------------------- | +| `--bui-font-weight-regular` | The regular font weight for the theme. | +| `--bui-font-weight-bold` | The bold font weight for the theme. | + +#### Spacing + +We built a spacing system based on a single value `--bui-space`. This value is used to calculate the spacing for all the components. By default if you would like to increase or decrease the spacing between your components you can do it simply by updating `--bui-space` and it will apply to all spacing values. + +`--bui-space` is not used directly in any components but serve as an easy way to calculate the other values. + +| Token Name | Description | +| ------------- | ----------------------------------------------------------------- | +| `--bui-space` | The base unit for the spacing system. Default value is `0.25rem.` | + +#### Radius + +We use a radius system to make sure that the components have a consistent look and feel. + +| Token Name | Description | +| ------------------- | --------------------------------------------------------- | +| `--bui-radius-1` | The radius of the component. Default value is `0.125rem`. | +| `--bui-radius-2` | The radius of the component. Default value is `0.25rem`. | +| `--bui-radius-3` | The radius of the component. Default value is `0.5rem`. | +| `--bui-radius-4` | The radius of the component. Default value is `0.75rem`. | +| `--bui-radius-5` | The radius of the component. Default value is `1rem`. | +| `--bui-radius-6` | The radius of the component. Default value is `1.25rem`. | +| `--bui-radius-full` | The radius of the component. Default value is `9999px`. | + +
    + +### Component class names + +All Backstage UI components come with a set of CSS classes that you can use to style them. To make it easier to identify the class name you can use, we use a specific structure for the class names. + +![classname-structure](../../assets/user-interface/css-classname-structure.png) + +Every component has a unique prefix `.bui-` followed by the component name. Component props are represented using the `data-` attribute. That way, class names are easily identifiable. + +## Create a theme for MUI (Legacy) + +To customize the appearance of your Backstage app using the legacy MUI theming system, you can define your own theme by extending the built-in light or dark themes. This is done using the createUnifiedTheme utility provided by the [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme) package. This function allows you to override key aspects of the theme—such as color palette, typography, spacing, and shape—while preserving Backstage’s base configuration and component compatibility. + +The example below shows how to create a new theme based on the default light theme: + +```ts title="packages/app/src/themes.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; + +export const lightTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + }), + fontFamily: 'Comic Sans MS', + defaultPageTheme: 'home', +}); + +export const darkTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.dark, + }), + fontFamily: 'Comic Sans MS', + defaultPageTheme: 'home', +}); +``` + +You can also create a theme from scratch that matches the `BackstageTheme` type exported by [`@backstage/theme`](https://www.npmjs.com/package/@backstage/theme). See the +[Material UI docs on theming](https://material-ui.com/customization/theming/) for more information about how that can be done. + +
    + Example of a custom MUI theme + +For a more complete example of a custom theme including Backstage and Material UI component overrides, see the [Aperture theme](https://github.com/backstage/demo/blob/master/packages/app/src/theme/aperture.ts) from the [Backstage demo site](https://demo.backstage.io). + +```ts title="packages/app/src/themes.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + genPageTheme, + palettes, + shapes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: { + ...palettes.light, + primary: { + main: '#343b58', + }, + secondary: { + main: '#565a6e', + }, + error: { + main: '#8c4351', + }, + warning: { + main: '#8f5e15', + }, + info: { + main: '#34548a', + }, + success: { + main: '#485e30', + }, + background: { + default: '#d5d6db', + paper: '#d5d6db', + }, + banner: { + info: '#34548a', + error: '#8c4351', + text: '#343b58', + link: '#565a6e', + }, + errorBackground: '#8c4351', + warningBackground: '#8f5e15', + infoBackground: '#343b58', + navigation: { + background: '#343b58', + indicator: '#8f5e15', + color: '#d5d6db', + selectedColor: '#ffffff', + }, + }, + }), + defaultPageTheme: 'home', + fontFamily: 'Comic Sans MS', + /* below drives the header colors */ + pageTheme: { + home: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + documentation: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave2, + }), + tool: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.round }), + service: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave, + }), + website: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave, + }), + library: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave, + }), + other: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + app: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + apis: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + }, +}); +``` + +
    + +
    + Custom Typography + +When creating a custom theme you can also customize various aspects of the default typography, here's an example using simplified theme: + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + typography: { + htmlFontSize: 16, + fontFamily: 'Arial, sans-serif', + h1: { + fontSize: 54, + fontWeight: 700, + marginBottom: 10, + }, + h2: { + fontSize: 40, + fontWeight: 700, + marginBottom: 8, + }, + h3: { + fontSize: 32, + fontWeight: 700, + marginBottom: 6, + }, + h4: { + fontWeight: 700, + fontSize: 28, + marginBottom: 6, + }, + h5: { + fontWeight: 700, + fontSize: 24, + marginBottom: 4, + }, + h6: { + fontWeight: 700, + fontSize: 20, + marginBottom: 2, + }, + }, + defaultPageTheme: 'home', + }), +}); +``` + +If you wanted to only override a sub-set of the typography setting, for example just `h1` then you would do this: + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + defaultTypography, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + typography: { + ...defaultTypography, + htmlFontSize: 16, + fontFamily: 'Roboto, sans-serif', + h1: { + fontSize: 72, + fontWeight: 700, + marginBottom: 10, + }, + }, + defaultPageTheme: 'home', + }), +}); +``` + +
    + +
    + Custom Fonts + +To add custom fonts, you first need to store the font so that it can be imported. We suggest creating the `assets/fonts` directory in your front-end application `src` folder. + +You can then declare the font style following the `@font-face` syntax from [Material UI Typography](https://mui.com/material-ui/customization/typography/). + +After that you can then utilize the `styleOverrides` of `MuiCssBaseline` under components to add a font to the `@font-face` array. + +```ts title="packages/app/src/theme/myTheme.ts" +import MyCustomFont from '../assets/fonts/My-Custom-Font.woff2'; + +const myCustomFont = { + fontFamily: 'My-Custom-Font', + fontStyle: 'normal', + fontDisplay: 'swap', + fontWeight: 300, + src: ` + local('My-Custom-Font'), + url(${MyCustomFont}) format('woff2'), + `, +}; + +export const myTheme = createUnifiedTheme({ + fontFamily: 'My-Custom-Font', + palette: palettes.light, + components: { + MuiCssBaseline: { + styleOverrides: { + '@font-face': [myCustomFont], + }, + }, + }, +}); +``` + +If you want to utilize different or multiple fonts, then you can set the top level `fontFamily` to what you want for your body, and then override `fontFamily` in `typography` to control fonts for various headings. + +```ts title="packages/app/src/theme/myTheme.ts" +import MyCustomFont from '../assets/fonts/My-Custom-Font.woff2'; +import myAwesomeFont from '../assets/fonts/My-Awesome-Font.woff2'; + +const myCustomFont = { + fontFamily: 'My-Custom-Font', + fontStyle: 'normal', + fontDisplay: 'swap', + fontWeight: 300, + src: ` + local('My-Custom-Font'), + url(${MyCustomFont}) format('woff2'), + `, +}; + +const myAwesomeFont = { + fontFamily: 'My-Awesome-Font', + fontStyle: 'normal', + fontDisplay: 'swap', + fontWeight: 300, + src: ` + local('My-Awesome-Font'), + url(${myAwesomeFont}) format('woff2'), + `, +}; + +export const myTheme = createUnifiedTheme({ + fontFamily: 'My-Custom-Font', + components: { + MuiCssBaseline: { + styleOverrides: { + '@font-face': [myCustomFont, myAwesomeFont], + }, + }, + }, + ...createBaseThemeOptions({ + palette: palettes.light, + typography: { + ...defaultTypography, + htmlFontSize: 16, + fontFamily: 'My-Custom-Font', + h1: { + fontSize: 72, + fontWeight: 700, + marginBottom: 10, + fontFamily: 'My-Awesome-Font', + }, + }, + defaultPageTheme: 'home', + }), +}); +``` + +
    + +
    + Overriding Backstage and Material UI components styles + +When creating a custom theme you would be applying different values to component's CSS rules that use the theme object. For example, a Backstage component's styles might look like this: + +```tsx +const useStyles = makeStyles( + theme => ({ + header: { + padding: theme.spacing(3), + boxShadow: '0 0 8px 3px rgba(20, 20, 20, 0.3)', + backgroundImage: theme.page.backgroundImage, + }, + }), + { name: 'BackstageHeader' }, +); +``` + +Notice how the `padding` is getting its value from `theme.spacing`, that means that setting a value for spacing in your custom theme would affect this component padding property and the same goes for `backgroundImage` which uses `theme.page.backgroundImage`. However, the `boxShadow` property doesn't reference any value from the theme, that means that creating a custom theme wouldn't be enough to alter the `box-shadow` property or to add css rules that aren't already defined like a margin. For these cases you should also create an override. + +Here's how you would do that: + +```ts title="packages/app/src/theme/myTheme.ts" +import { + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; + +export const myTheme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.light, + }), + fontFamily: 'Comic Sans MS', + defaultPageTheme: 'home', + components: { + BackstageHeader: { + styleOverrides: { + header: ({ theme }) => ({ + width: 'auto', + margin: '20px', + boxShadow: 'none', + borderBottom: `4px solid ${theme.palette.primary.main}`, + }), + }, + }, + }, +}); +``` + +
    diff --git a/docs/conf/user-interface/logo.md b/docs/conf/user-interface/logo.md new file mode 100644 index 0000000000..35789d6330 --- /dev/null +++ b/docs/conf/user-interface/logo.md @@ -0,0 +1,25 @@ +--- +id: logo +title: Customizing Your Logo +sidebar_label: Logo +description: Learn how to customize your logo. +--- + +In addition to a custom theme, you can also customize the logo displayed at the far top left of the site. + +In your frontend app, locate `src/components/Root/` folder. You'll find two components: + +- `LogoFull.tsx` - A larger logo used when the Sidebar navigation is opened. +- `LogoIcon.tsx` - A smaller logo used when the Sidebar navigation is closed. + +To replace the images, you can simply replace the relevant code in those components with raw SVG definitions. + +You can also use another web image format such as PNG by importing it. To do this, place your new image into a new subdirectory such as `src/components/Root/logo/my-company-logo.png`, and then add this code: + +```tsx +import MyCustomLogoFull from './logo/my-company-logo.png'; + +const LogoFull = () => { + return ; +}; +``` diff --git a/docs/conf/user-interface/sidebar.md b/docs/conf/user-interface/sidebar.md new file mode 100644 index 0000000000..f66e6bd106 --- /dev/null +++ b/docs/conf/user-interface/sidebar.md @@ -0,0 +1,93 @@ +--- +id: sidebar +title: Customizing Your Sidebar +sidebar_label: Sidebar +description: Learn how to customize the look and feel of your Sidebar. +--- + +As you've seen there are many ways that you can customize your Backstage app. The following section will show you how you can customize the sidebar. + +## Sidebar Sub-menu + +For this example we'll show you how you can expand the sidebar with a sub-menu: + +1. Open the `Root.tsx` file located in `packages/app/src/components/Root` as this is where the sidebar code lives +2. Then we want to add the following import for `useApp`: + + ```tsx title="packages/app/src/components/Root/Root.tsx" + import { useApp } from '@backstage/core-plugin-api'; + ``` + +3. Then update the `@backstage/core-components` import like this: + + ```tsx title="packages/app/src/components/Root/Root.tsx" + import { + Sidebar, + sidebarConfig, + SidebarDivider, + SidebarGroup, + SidebarItem, + SidebarPage, + SidebarScrollWrapper, + SidebarSpace, + useSidebarOpenState, + Link, + /* highlight-add-start */ + GroupIcon, + SidebarSubmenu, + SidebarSubmenuItem, + /* highlight-add-end */ + } from '@backstage/core-components'; + ``` + +4. Finally replace `` with this: + + ```tsx title="packages/app/src/components/Root/Root.tsx" + + + + + + + + + + + + + + ``` + +When you startup your Backstage app and hover over the Home option on the sidebar you'll now see a nice sub-menu appear with links to the various Kinds in your Catalog. It would look like this: + +![Sidebar sub-menu example](./../../assets/getting-started/sidebar-submenu-example.png) + +You can see more ways to use this in the [Storybook Sidebar examples](https://backstage.io/storybook/?path=/story/layout-sidebar--sample-scalable-sidebar) diff --git a/docs/contribute/getting-involved.md b/docs/contribute/getting-involved.md index 4b8c4dfc6f..696b73b7d4 100644 --- a/docs/contribute/getting-involved.md +++ b/docs/contribute/getting-involved.md @@ -1,7 +1,6 @@ --- id: getting-involved title: Getting Involved -# prettier-ignore description: How can you help us build Backstage? We welcome contributions of all kinds, from documentation to code to design. --- diff --git a/docs/contribute/index.md b/docs/contribute/index.md index 627a2ff0d0..dbdf126b20 100644 --- a/docs/contribute/index.md +++ b/docs/contribute/index.md @@ -1,7 +1,6 @@ --- id: index title: Contributors -# prettier-ignore description: Documentation on how to get set up for doing development on the Backstage repository --- diff --git a/docs/contribute/project-structure.md b/docs/contribute/project-structure.md index 984cfe98d6..f58afedee8 100644 --- a/docs/contribute/project-structure.md +++ b/docs/contribute/project-structure.md @@ -1,7 +1,6 @@ --- id: project-structure title: Backstage Project Structure -# prettier-ignore description: Introduction to files and folders in the Backstage Project repository --- @@ -157,10 +156,10 @@ are separated out into their own folder, see further down. - [`integration/`](https://github.com/backstage/backstage/tree/master/packages/integration) - Common functionalities of integrations like GitHub, GitLab, etc. -- [`storybook/`](https://github.com/backstage/backstage/tree/master/storybook) - - This folder contains only the Storybook config which helps visualize our - reusable React components. Stories are within the core package, and are - published in the [Backstage Storybook](https://backstage.io/storybook). +- [`.storybook/`](https://github.com/backstage/backstage/tree/master/.storybook) - + This folder contains the Storybook configuration which helps visualize our + reusable React components. Stories are scanned from packages and plugins across + the monorepo, and are published in the [Backstage Storybook](https://backstage.io/storybook). - [`techdocs-node/`](https://github.com/backstage/backstage/tree/master/plugins/techdocs-node) - Common node.js functionalities for TechDocs, to be shared between @@ -222,7 +221,3 @@ future. - [`catalog-info.yaml`](https://github.com/backstage/backstage/tree/master/catalog-info.yaml) - Description of Backstage in the Backstage Entity format. - -- [`lerna.json`](https://github.com/backstage/backstage/tree/master/lerna.json) - - [Lerna](https://github.com/lerna/lerna) monorepo config. We are using - `yarn workspaces`, so this will only be used for executing scripts. diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 8f83acfc51..04b72da445 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -5,30 +5,26 @@ sidebar_label: Docker description: How to build a Backstage Docker image for deployment --- -:::note Note -Before you start this section, it would be good to have a basic understanding of Docker and how it works. If you are new to Docker, you can start with the [Docker overview](https://docs.docker.com/get-started/overview/) guide. +## Summary + +This section describes how to build a Backstage App into a deployable Docker image. It is split into three sections, first covering the host build approach, which is recommended due to its speed and more efficient and often simpler caching. The second section covers a full multi-stage Docker build, and the last section covers how to deploy the frontend and backend as separate images. + +## Prerequisites + +This guide assumes your have a basic understanding of Docker and how it works. If you are new to Docker, you can start with the [Docker overview](https://docs.docker.com/get-started/overview/) guide. + +You'll also want to complete the following prerequisites: + +1. Created an app following the [Getting Started guide](../getting-started/index.md) +2. Setup an auth provider, the [Authentication guide](../getting-started/config/authentication.md) is a good starting point for this, the default [Guest auth provider](../auth/guest/provider.md) is not intended for use in containerized environments +3. A Postgres database setup that you are able to connect to, the [Database guide](../getting-started/config/database.md) can help you with this + +:::warning + +Moving forward without addressing these prerequisites is very likely to cause undesirable results, the most common being not having a proper auth provider setup as the default [Guest auth provider](../auth/guest/provider.md) is not intended for use in containerized environments. + ::: -This section describes how to build a Backstage App into a deployable Docker -image. It is split into three sections, first covering the host build approach, -which is recommended due to its speed and more efficient and often simpler -caching. The second section covers a full multi-stage Docker build, and the last -section covers how to deploy the frontend and backend as separate images. - -Something that goes for all of these docker deployment strategies is that they -are stateless, so for a production deployment you will want to set up and -connect to an external PostgreSQL instance where the backend plugins can store -their state, rather than using SQLite. - -This section assumes that an [app](https://backstage.io/docs/getting-started/) -has already been created with `@backstage/create-app`, in which the frontend is -bundled and served from the backend. This is done using the -`@backstage/plugin-app-backend` plugin, which also injects the frontend -configuration into the app. This means that you only need to build and deploy a -single container in a minimal setup of Backstage. If you wish to separate the -serving of the frontend out from the backend, see the -[separate frontend](#separate-frontend) topic below. - ## Host Build This section describes how to build a Docker image from a Backstage repo with @@ -57,7 +53,7 @@ Once the host build is complete, we are ready to build our image. The following `Dockerfile` is included when creating a new app with `@backstage/create-app`: ```dockerfile -FROM node:20-bookworm-slim +FROM node:22-bookworm-slim # Set Python interpreter for `node-gyp` to use ENV PYTHON=/usr/bin/python3 @@ -182,7 +178,7 @@ the repo root: ```dockerfile # Stage 1 - Create yarn install skeleton layer -FROM node:20-bookworm-slim AS packages +FROM node:22-bookworm-slim AS packages WORKDIR /app COPY backstage.json package.json yarn.lock ./ @@ -197,7 +193,7 @@ COPY plugins plugins RUN find packages \! -name "package.json" -mindepth 2 -maxdepth 2 -exec rm -rf {} \+ # Stage 2 - Install dependencies and build packages -FROM node:20-bookworm-slim AS build +FROM node:22-bookworm-slim AS build # Set Python interpreter for `node-gyp` to use ENV PYTHON=/usr/bin/python3 @@ -235,7 +231,7 @@ RUN mkdir packages/backend/dist/skeleton packages/backend/dist/bundle \ && tar xzf packages/backend/dist/bundle.tar.gz -C packages/backend/dist/bundle # Stage 3 - Build the actual backend image and install production dependencies -FROM node:20-bookworm-slim +FROM node:22-bookworm-slim # Set Python interpreter for `node-gyp` to use ENV PYTHON=/usr/bin/python3 diff --git a/docs/deployment/k8s.md b/docs/deployment/k8s.md index aae49b6069..3be791dc59 100644 --- a/docs/deployment/k8s.md +++ b/docs/deployment/k8s.md @@ -112,7 +112,7 @@ YmFja3N0YWdl Secrets are base64-encoded, but not encrypted. Be sure to enable [Encryption at Rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/) for the cluster. For storing secrets in Git, consider -[SealedSecrets or other solutions](https://learnk8s.io/kubernetes-secrets-in-git). +[SealedSecrets or other solutions](https://learnkube.com/kubernetes-secrets-in-git) ::: diff --git a/docs/dls/component-design-guidelines.md b/docs/dls/component-design-guidelines.md index 35e2f987d2..fddffd9fd9 100644 --- a/docs/dls/component-design-guidelines.md +++ b/docs/dls/component-design-guidelines.md @@ -103,6 +103,4 @@ accessibility. [7]: https://v4.mui.com/components/cards/ [8]: https://v4.mui.com/customization/palette/#default-values [9]: https://v4.mui.com/customization/typography/ -[10]: https://backstage.io/docs/getting-started/app-custom-theme -[11]: https://backstage.io/docs/getting-started/app-custom-theme#overriding-backstage-and-material-ui-components-styles -[12]: https://v4.mui.com/customization/default-theme/#explore +[10]: https://backstage.io/docs/conf/user-interface diff --git a/docs/dls/design.md b/docs/dls/design.md index 7e2ae90528..e988d1032f 100644 --- a/docs/dls/design.md +++ b/docs/dls/design.md @@ -127,7 +127,7 @@ your own plugin for Backstage. **[Discord](https://discord.gg/backstage-687207715902193673)** - all design questions should be directed to the _#design_ channel. -**[Customize Backstage's look and feel](https://backstage.io/docs/getting-started/app-custom-theme)** - +**[Customizing Your App's UI](https://backstage.io/docs/conf/user-interface)** - How to customize the look and feel of your Backstage instance by extending the theme. diff --git a/docs/dls/figma.md b/docs/dls/figma.md index 21a05d2818..738d607439 100644 --- a/docs/dls/figma.md +++ b/docs/dls/figma.md @@ -1,7 +1,6 @@ --- id: figma title: Figma -# prettier-ignore description: Documentation on using Figma to build your own plugins for Backstage --- diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index a22a7d94d9..6a3f3760bf 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -2,7 +2,6 @@ id: configuration title: Configuring Kubernetes integration sidebar_label: Configuration -# prettier-ignore description: Configuring the Kubernetes integration for Backstage expose your entity's objects --- @@ -203,6 +202,28 @@ or the [`AwsEKSClusterProcessor`](https://backstage.io/docs/reference/plugin-catalog-backend-module-aws.awseksclusterprocessor/) to automatically update the set of clusters tracked by Backstage. +For this method to work any entity that would be using this `Resource` to help drive the Kubernetes details in the Catalog's Entity pages needs to have a `dependsOn` relationship setup. Here's a quick example: + +```yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + annotations: + backstage.io/kubernetes-id: dice-roller + backstage.io/kubernetes-namespace: default + name: dice-roller + description: It rolls dice + tags: + - go +spec: + type: service + lifecycle: production + owner: guest + dependsOn: ['resource:my-cluster'] +``` + +This example assumes it's using the default namespace, if that's not the case for you then make sure to include it like this: `resource:my-namespace/my-cluster`. + #### `config` This cluster locator method will read cluster information from your app-config @@ -420,7 +441,7 @@ Base64-encoded certificate authority bundle in PEM format. The Kubernetes client will verify that the TLS certificate presented by the API server is signed by this CA. -This value could be obtained via inspecting the kubeconfig file (usually +This value could be obtained via inspecting the `kubeconfig` file (usually at `~/.kube/config`) under `clusters[*].cluster.certificate-authority-data`. For GKE, execute the following command to obtain the value @@ -598,7 +619,7 @@ The custom resource's group. #### `customResources.\*.apiVersion` -The custom resource's apiVersion. +The custom resource's `apiVersion`. #### `customResources.\*.plural` @@ -677,6 +698,7 @@ rules: - '*' resources: - pods + - pods/log - configmaps - services - deployments diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index a99bd0b429..fa37253cd6 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -87,6 +87,7 @@ import { ClusterDetails, KubernetesClustersSupplier, kubernetesClusterSupplierExtensionPoint, + kubernetesServiceLocatorExtensionPoint, } from '@backstage/plugin-kubernetes-node'; export class CustomClustersSupplier implements KubernetesClustersSupplier { @@ -119,12 +120,26 @@ export const kubernetesModuleCustomClusterDiscovery = createBackendModule({ register(env) { env.registerInit({ deps: { - kubernetes: kubernetesClusterSupplierExtensionPoint, + clusterSupplier: kubernetesClusterSupplierExtensionPoint, + serviceLocator: kubernetesServiceLocatorExtensionPoint, }, - async init({ kubernetes }) { - kubernetes.addClusterSupplier( + async init({ clusterSupplier, serviceLocator }) { + // simple replace of the internal dependency + clusterSupplier.addClusterSupplier( CustomClustersSupplier.create(Duration.fromObject({ minutes: 60 })), ); + + // there's also the ability to get access to some of the default implementations of the extension points where + // neccessary: + serviceLocator.addServiceLocator( + async ({ getDefault, clusterSupplier }) => { + // get access to the default service locator: + const defaultImplementation = await getDefault(); + + // build your own with the clusterSupplier dependency: + return new MyNewServiceLocator({ clusterSupplier }); + }, + ); }, }); }, diff --git a/docs/features/search/README.md b/docs/features/search/README.md index 93aa22ebe1..eb5d12080c 100644 --- a/docs/features/search/README.md +++ b/docs/features/search/README.md @@ -2,7 +2,6 @@ id: search-overview title: Search Documentation sidebar_label: Overview -# prettier-ignore description: Backstage Search lets you find the right information you are looking for in the Backstage ecosystem. --- diff --git a/docs/features/search/collators.md b/docs/features/search/collators.md index d87258f65b..f2ad982812 100644 --- a/docs/features/search/collators.md +++ b/docs/features/search/collators.md @@ -170,7 +170,7 @@ export const exampleCustomCatalogFiltering = createBackendModule({ Here are some of the known Search Collators available in from the Backstage Community: -- [`@backstage/plugin-search-backend-module-explore`](https://github.com/backstage/backstage/tree/master/plugins/search-backend-module-explore): will index content from the [Explore plugin](https://github.com/backstage/community-plugins/tree/main/workspaces/explore/plugins/explore). +- [`@backstage-community/plugin-search-backend-module-explore`](https://github.com/backstage/community-plugins/tree/main/workspaces/explore/plugins/search-backend-module-explore): will index content from the [Explore plugin](https://github.com/backstage/community-plugins/tree/main/workspaces/explore/plugins/explore). - [`@backstage/plugin-search-backend-module-stack-overflow-collator`](https://github.com/backstage/backstage/tree/master/plugins/search-backend-module-stack-overflow-collator): will index content from Stack Overflow. - [`@backstage-community/search-backend-module-adr`](https://github.com/backstage/community-plugins/tree/main/workspaces/adr/plugins/search-backend-module-adr): will index content from the [ADR plugin](https://github.com/backstage/community-plugins/tree/main/workspaces/adr/plugins/adr). diff --git a/docs/features/search/declarative-integration.md b/docs/features/search/declarative-integration.md index c331d810ef..74d16d7c57 100644 --- a/docs/features/search/declarative-integration.md +++ b/docs/features/search/declarative-integration.md @@ -161,13 +161,13 @@ The `createSearchResultItemExtension` function returns a Backstage's extension r In this object, you can see exactly what will happen once the custom extension is installed: -- **[1] $$type**: declares that the object represents an extension; -- **[2] id**: Is a unique identification for the extension, the `plugin.search.result.item.techdocs` is the key used to configure the extension in the `app-config.yaml` file; -- **[3] at**: It represents the extension attachment point, so the value `plugin.search.page/items` says that the `TechDocs`'s search result item output will be injected as input on the "items" attachment expected by the search page extension; -- **[4] inputs**: in this case is an empty object because this extension doesn't expect inputs; -- **[5] output**: Object representing the artifact produced by the `TechDocs` result item extension, on the example, it is a react component reference; -- **[6] configSchema**: represents the `TechDocs` search result item configuration definition, this is the same schema that adopters will use for customizing the extension via `app-config.yaml` file; -- **[7] disable**: Says that the result item extension will be enable by default when the `TechDocs` plugin is installed in the app. +- **[1] `$$type`**: declares that the object represents an extension; +- **[2] `id`**: Is a unique identification for the extension, the `plugin.search.result.item.techdocs` is the key used to configure the extension in the `app-config.yaml` file; +- **[3] `at`**: It represents the extension attachment point, so the value `plugin.search.page/items` says that the `TechDocs`'s search result item output will be injected as input on the "items" attachment expected by the search page extension; +- **[4] `inputs`**: in this case is an empty object because this extension doesn't expect inputs; +- **[5] `output`**: Object representing the artifact produced by the `TechDocs` result item extension, on the example, it is a react component reference; +- **[6] `configSchema`**: represents the `TechDocs` search result item configuration definition, this is the same schema that adopters will use for customizing the extension via `app-config.yaml` file; +- **[7] `disable`**: Says that the result item extension will be enable by default when the `TechDocs` plugin is installed in the app. To complete the development cycle for creating a custom search result item extension, we should provide the extension via `TechDocs` plugin: @@ -182,7 +182,7 @@ export default createPlugin({ }) ``` -Here is the `plugins/techdocs/alpha.tsx` final version, and you can also take a look at the [actual implementation](https://github.com/backstage/backstage/blob/master/plugins/techdocs/src/alpha.tsx) of a custom `TechDocs` search result item: +Here is the `plugins/techdocs/alpha/index.tsx` final version, and you can also take a look at the [actual implementation](https://github.com/backstage/backstage/blob/master/plugins/techdocs/src/alpha/index.tsx) of a custom `TechDocs` search result item: ```tsx // plugins/techdocs/alpha.tsx diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md index 7055db1138..f0823ac47e 100644 --- a/docs/features/search/how-to-guides.md +++ b/docs/features/search/how-to-guides.md @@ -116,7 +116,7 @@ indexBuilder.addCollator({ The default highlighting styling for matched terms in search results is your browsers default styles for the `` HTML tag. If you want to customize how highlighted terms look you can follow Backstage's guide on how to -[Customize the look-and-feel of your App](https://backstage.io/docs/getting-started/app-custom-theme) +[Customizing Your App's UI](https://backstage.io/docs/conf/user-interface) to create an override with your preferred styling. For example, using the new MUI V4+V5 unified theming method, the following will result diff --git a/docs/features/search/search-engines.md b/docs/features/search/search-engines.md index b61be1e0c8..07cf11aae5 100644 --- a/docs/features/search/search-engines.md +++ b/docs/features/search/search-engines.md @@ -239,6 +239,26 @@ search: > You can also increase the batch size if you are using a large ES instance. +### Elasticsearch batch key field + +By default, during bulk uploads with the Elasticsearch indexer, each document is assigned an auto-generated `_id` unless a `batchKeyField` is explicitly set. This configuration is optional and most users won’t need to customize it. However, if your use case involves frequent lookups or updates to existing documents, setting `batchKeyField` can be beneficial. It allows you to define a consistent identifier for each document, helping to streamline updates and prevent duplicate entries. Be aware that if the value provided for `batchKeyField` is not unique across documents, Elasticsearch will overwrite any existing document with the same `_id`. + +**Using `batchKeyField` (Custom `_id`)** + +```yaml +search: + elasticsearch: + batchKeyField: document_id +``` + +**Default Behavior (Auto-generated `_id`)** + +```yaml +search: + elasticsearch: + # No batchKeyField specified — Elasticsearch will autogenerate _id +``` + ### Elasticsearch Index Name Customization By default, the Elasticsearch indexer creates index names based on their type, a separator, and the current date as a postfix. You can configure a custom prefix for all indices by adding the following section to your app configuration. @@ -267,7 +287,7 @@ Fuzziness allows you to define the maximum Levenshtein distance, AUTO is the def ```yaml search: elasticsearch: - queryConfig: + queryOptions: fuzziness: AUTO prefixLength: 3; ``` diff --git a/docs/features/software-catalog/api.md b/docs/features/software-catalog/api.md index 2a431d337b..96420cd37e 100644 --- a/docs/features/software-catalog/api.md +++ b/docs/features/software-catalog/api.md @@ -175,7 +175,7 @@ Some more real world usable examples: #### Ordering -By default the entities are returned ordered by their internal uid. You can +By default the entities are returned ordered by their internal `uid`. You can customize the `orderField` query parameters to affect that ordering. For example, to return entities by their name: diff --git a/docs/features/software-catalog/catalog-customization.md b/docs/features/software-catalog/catalog-customization.md index 1c36301605..a828e6591a 100644 --- a/docs/features/software-catalog/catalog-customization.md +++ b/docs/features/software-catalog/catalog-customization.md @@ -1,7 +1,6 @@ --- id: catalog-customization title: Catalog Customization -# prettier-ignore description: How to add custom filters or interface elements to the Backstage software catalog --- @@ -572,10 +571,8 @@ Finally, entity predicates also support value operators that can be used in plac ```json { "filter": { - { - "kind": "component", - "spec.type": { "$in": ["service", "website"] } - }, + "kind": "component", + "spec.type": { "$in": ["service", "website"] } } } ``` @@ -696,6 +693,6 @@ filter: relations: $contains: type: ownedBy - target: + targetRef: $in: [group:default/admins, group:default/viewers] ``` diff --git a/docs/features/software-catalog/configuration.md b/docs/features/software-catalog/configuration.md index f8de3034fd..5b293cce1c 100644 --- a/docs/features/software-catalog/configuration.md +++ b/docs/features/software-catalog/configuration.md @@ -90,6 +90,35 @@ also write a _custom processor_ to convert between the existing system and Backstage's descriptor format. This is documented in [External Integrations](external-integrations.md). +### Processor configuration + +You can configure processors under the `catalog.processorOptions` key. You can define +options for each processor by its name. With the processor options you can disable +a processor or set its priority. + +```yaml +catalog: + processorOptions: + processorName: + disabled: false # Defaults to false + priority: 100 +``` + +The priority is a number defining the order in which processors are executed. The lower the number, +the higher the priority. The default priority is `20`. + +## Provider configuration + +It's possible to also disable entity providers using the config. You can configure providers +under the `catalog.providerOptions` key. The key is the provider name. + +```yaml +catalog: + providerOptions: + providerName: + disabled: true +``` + ## Catalog Rules By default, the catalog will only allow the ingestion of entities with the kind diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 28ddfae282..ac8baadad5 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -2,7 +2,6 @@ id: descriptor-format title: Descriptor Format of Catalog Entities sidebar_label: YAML File Format -# prettier-ignore description: Documentation on Descriptor Format of Catalog Entities which describes the default data shape and semantics of catalog entities --- @@ -240,18 +239,33 @@ Example: `visits-tracking-service`, `CircleciBuildsDumpV2_avro_gcs` ### `namespace` [optional] The ID of a namespace that the entity belongs to. This field is optional, and -currently has no special semantics apart from bounding the name uniqueness -constraint if specified. It is reserved for future use and may get broader -semantic implication later. +has no special semantics apart from bounding the name uniqueness constraint if +specified. -For now, it is recommended to not specify a namespace unless you have specific -need to do so. This means the entity belongs to the `"default"` namespace. +This can be used for ingesting entities (of the same kind) from different +contexts where their names might otherwise end up overlapping. An example of +this is to import users and groups from your HR system into the default +namespace, but also wanting to ingest users from your GitHub enterprise +installation and those potentially having the same names as the HR system users. +Then you could set up your GitHub enterprise ingestion to place those users in a +`"ghe"` namespace to avoid collisions. + +If you do not specify a namespace, it assumes the value `"default"`. Namespaces must be sequences of `[a-zA-Z0-9]`, possibly separated by `-`, at -most 63 characters in total. Namespace names are case insensitive and will be rendered as lower case in most places. +most 63 characters in total. Namespace names are case insensitive and will be +rendered as lower case in most places. Example: `tracking-services`, `payment` +Note that using namespaces typically means that you need to explicitly specify +the namespace when referring to the entity. In some contexts, notably in entity +catalog-info definition YAML files, you often refer to other entities by name. +When they are in a different namespace, you need to use the syntax +`/`, while if they are in the default namespace you can omit +that part as a shorthand. Therefore it's practical to use the default namespace +for simplicity until it's necessary to use supplemental ones. See [the references article](references.md) for more information. + ### `uid` [output] Each entity gets an automatically generated globally unique ID when it first @@ -728,7 +742,6 @@ spec: name: Publish action: publish:github input: - allowedHosts: ['github.com'] description: 'This is {{ parameters.name }}' repoUrl: '{{ parameters.repoUrl }}' diff --git a/docs/features/software-catalog/extending-the-model--old.md b/docs/features/software-catalog/extending-the-model--old.md index 668d1d8311..c39561d11b 100644 --- a/docs/features/software-catalog/extending-the-model--old.md +++ b/docs/features/software-catalog/extending-the-model--old.md @@ -1,7 +1,6 @@ --- id: extending-the-model--old title: Extending the model -# prettier-ignore description: Documentation on extending the catalog model --- @@ -29,23 +28,23 @@ Backstage comes with a number of catalog concepts out of the box: We'll list different possibilities for extending this below. -## Adding a New apiVersion of an Existing Kind +## Adding a New `apiVersion` of an Existing Kind Example intents: > "I want to evolve this core kind, tweaking the semantics a bit so I will bump -> the apiVersion a step" +> the `apiVersion` a step" > "This core kind is a decent fit but we want to evolve it at will so we'll move -> it to our own company's apiVersion space and use that instead of +> it to our own company's `apiVersion` space and use that instead of > `backstage.io`." -The `backstage.io` apiVersion space is reserved for use by the Backstage +The `backstage.io` `apiVersion` space is reserved for use by the Backstage maintainers. Please do not change or add versions within that space. -If you add an [apiVersion](descriptor-format.md#apiversion-and-kind-required) +If you add an [`apiVersion`](descriptor-format.md#apiversion-and-kind-required) space of your own, you are effectively branching out from the underlying kind -and making your own. An entity kind is identified by the apiVersion + kind pair, +and making your own. An entity kind is identified by the `apiVersion` + `kind` pair, so even though the resulting entity may be similar to the core one, there will be no guarantees that plugins will be able to parse or understand its data. See below about adding a new kind. @@ -58,7 +57,7 @@ Example intents: > thing that is a poor fit for either of the builtins." > "This core kind is a decent fit but we want to evolve it at will so we'll move -> it to our own company's apiVersion space and use that instead of +> it to our own company's `apiVersion` space and use that instead of > `backstage.io`." A [kind](descriptor-format.md#apiversion-and-kind-required) is an overarching @@ -68,7 +67,7 @@ variety of needs that one may want to model in Backstage. The primary ambition is to map things to these kinds, but sometimes you may want or need to extend beyond them. -Introducing a new apiVersion is basically the same as adding a new kind. Bear in +Introducing a new `apiVersion` is basically the same as adding a new kind. Bear in mind that most plugins will be compiled against the builtin `@backstage/catalog-model` package and have expectations that kinds align with that. diff --git a/docs/features/software-catalog/extending-the-model.md b/docs/features/software-catalog/extending-the-model.md index d289886a09..7300f4f969 100644 --- a/docs/features/software-catalog/extending-the-model.md +++ b/docs/features/software-catalog/extending-the-model.md @@ -1,7 +1,6 @@ --- id: extending-the-model title: Extending the model -# prettier-ignore description: Documentation on extending the catalog model --- @@ -29,23 +28,23 @@ Backstage comes with a number of catalog concepts out of the box: We'll list different possibilities for extending this below. -## Adding a New apiVersion of an Existing Kind +## Adding a New `apiVersion` of an Existing Kind Example intents: > "I want to evolve this core kind, tweaking the semantics a bit so I will bump -> the apiVersion a step" +> the `apiVersion` a step" > "This core kind is a decent fit but we want to evolve it at will so we'll move -> it to our own company's apiVersion space and use that instead of +> it to our own company's `apiVersion` space and use that instead of > `backstage.io`." -The `backstage.io` apiVersion space is reserved for use by the Backstage +The `backstage.io` `apiVersion` space is reserved for use by the Backstage maintainers. Please do not change or add versions within that space. -If you add an [apiVersion](descriptor-format.md#apiversion-and-kind-required) +If you add an [`apiVersion`](descriptor-format.md#apiversion-and-kind-required) space of your own, you are effectively branching out from the underlying kind -and making your own. An entity kind is identified by the apiVersion + kind pair, +and making your own. An entity kind is identified by the `apiVersion` + `kind` pair, so even though the resulting entity may be similar to the core one, there will be no guarantees that plugins will be able to parse or understand its data. See below about adding a new kind. @@ -58,7 +57,7 @@ Example intents: > thing that is a poor fit for either of the builtins." > "This core kind is a decent fit but we want to evolve it at will so we'll move -> it to our own company's apiVersion space and use that instead of +> it to our own company's `apiVersion` space and use that instead of > `backstage.io`." A [kind](descriptor-format.md#apiversion-and-kind-required) is an overarching @@ -68,7 +67,7 @@ variety of needs that one may want to model in Backstage. The primary ambition is to map things to these kinds, but sometimes you may want or need to extend beyond them. -Introducing a new apiVersion is basically the same as adding a new kind. Bear in +Introducing a new `apiVersion` is basically the same as adding a new kind. Bear in mind that most plugins will be compiled against the builtin `@backstage/catalog-model` package and have expectations that kinds align with that. diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 8938fefdf6..298c686bea 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -1,7 +1,6 @@ --- id: external-integrations title: External integrations -# prettier-ignore description: Documentation on External integrations to integrate systems with Backstage --- @@ -776,7 +775,7 @@ sent. Luckily many external systems provide ETag support to check for changes which usually doesn't count towards the quota and saves resources both internally and externally. -The catalog has built in support for leveraging ETags when refreshing external +The catalog has built in support for leveraging `ETag`s when refreshing external locations in GitHub. This example aims to demonstrate how to add the same behavior for `system-x` that we implemented earlier. diff --git a/docs/features/software-catalog/index.md b/docs/features/software-catalog/index.md index ac1d0ee8cd..53afb5205e 100644 --- a/docs/features/software-catalog/index.md +++ b/docs/features/software-catalog/index.md @@ -2,7 +2,6 @@ id: software-catalog-overview title: Backstage Software Catalog sidebar_label: Overview -# prettier-ignore description: The Backstage Software Catalog --- @@ -127,7 +126,7 @@ _starring_ of components: The software catalog is a great way to organize the infrastructure tools you use to manage the software. This is how Backstage creates one developer portal for all your tools. Rather than asking teams to jump between different -infrastructure UIs (and incurring additional cognitive overhead each time they +infrastructure user interfaces (and incurring additional cognitive overhead each time they make a context switch), most of these tools can be organized around the entities in the catalog. diff --git a/docs/features/software-catalog/life-of-an-entity.md b/docs/features/software-catalog/life-of-an-entity.md index 1489688720..c16fb8d523 100644 --- a/docs/features/software-catalog/life-of-an-entity.md +++ b/docs/features/software-catalog/life-of-an-entity.md @@ -2,7 +2,6 @@ id: life-of-an-entity title: The Life of an Entity sidebar_label: The Life of an Entity -# prettier-ignore description: The life cycle of entities, from being introduced into the catalog, through processing, to being removed again --- @@ -126,6 +125,19 @@ all of the processors' contributions to one step are run in the order that the processors were registered, then all of their contributions to the next step in the same order, and so on. +:::note Technical note + +Processors registered from the same catalog module always run +in the registration order, but this does not apply over multiple catalog modules as +the order of registration depends on the order in which the modules are loaded +by the framework. + +It's possible to customize the order of the processors by modifying the +`catalog.processorOptions..priority` configuration option. +The default priority is `20`, and lower value means that the processor runs earlier. + +::: + Each step has the opportunity to optionally modify the entity, and to optionally emit other information. For example, the processor might look at information in the `spec` field of the entity, and emit relations that correspond to those @@ -183,6 +195,19 @@ The diagram shows how the stitcher reads from several sources: The last part is noteworthy: This is how the stitcher is able to collect all of the relation edges, both incoming and outgoing, no matter who produced them. +:::note Technical note + +Whether the entity will be stitched depends on the entity hash value, +which is calculated based on the entity body, relations, errors, referred entities, +and entity parents after the processing. The hash value changes if any of these components +change. The hash value is then compared to hash value from the previous processing of the +entity and if they are different, the entity is stitched again. +In entity body, changes in array order, for example `metadata.tags`, changes the hash +value. It is a good idea to monitor the stitched entities count in the catalog as it +might cause performance issues if the number of entities gets too high. + +::: + The stitching is currently a fixed process, that cannot be modified or extended. This means that any modifications you want to make on the final result, has to happen during ingestion or processing. diff --git a/docs/features/software-catalog/well-known-annotations.md b/docs/features/software-catalog/well-known-annotations.md index 974fa80993..d8a2e1d232 100644 --- a/docs/features/software-catalog/well-known-annotations.md +++ b/docs/features/software-catalog/well-known-annotations.md @@ -2,7 +2,6 @@ id: well-known-annotations title: Well-known Annotations on Catalog Entities sidebar_label: Well-known Annotations -# prettier-ignore description: Documentation that lists a number of well known Annotations, that have defined semantics. They can be attached to catalog entities and consumed by plugins as needed. --- @@ -115,6 +114,20 @@ the TechDocs in the TechDocs page or needing multiple builds of the same docs. This is for situations where you have complex systems where they share a single repo, and likely a single TechDoc location. +### backstage.io/techdocs-entity-path + +```yaml +# Example: +metadata: + annotations: + backstage.io/techdocs-entity: component:default/example + backstage.io/techdocs-entity-path: /path/to/this/component +``` + +The value of this annotation informs of the path to this component's TechDocs within an external entity that owns the TechDocs. +In conjunction with [backstage.io/techdocs-entity](#backstageiotechdocs-entity) this allows for deep linking into the TechDocs of +another entity, not just linking to the root of another entity's TechDocs. + ### backstage.io/view-url, backstage.io/edit-url ```yaml diff --git a/docs/features/software-catalog/well-known-relations.md b/docs/features/software-catalog/well-known-relations.md index 6d61847a15..740dbe0df2 100644 --- a/docs/features/software-catalog/well-known-relations.md +++ b/docs/features/software-catalog/well-known-relations.md @@ -2,7 +2,6 @@ id: well-known-relations title: Well-known Relations between Catalog Entities sidebar_label: Well-known Relations -# prettier-ignore description: Documentation that lists a number of well known Relations, that have defined semantics. They can be attached to catalog entities and consumed by plugins as needed. --- diff --git a/docs/features/software-catalog/well-known-statuses.md b/docs/features/software-catalog/well-known-statuses.md index d293ae5062..6829b1ccdf 100644 --- a/docs/features/software-catalog/well-known-statuses.md +++ b/docs/features/software-catalog/well-known-statuses.md @@ -2,7 +2,6 @@ id: well-known-statuses title: Well-known Status fields of Catalog Entities sidebar_label: Well-known Statuses -# prettier-ignore description: Lists a number of well known entity statuses, that have defined semantics. They can be attached to catalog entities and consumed by plugins as needed. --- diff --git a/docs/features/software-templates/adding-templates.md b/docs/features/software-templates/adding-templates.md index 674ee8788b..55c99aa694 100644 --- a/docs/features/software-templates/adding-templates.md +++ b/docs/features/software-templates/adding-templates.md @@ -49,7 +49,7 @@ spec: # here's the steps that are executed in series in the scaffolder backend steps: - - id: fetch-base + - id: fetchBase name: Fetch Base action: fetch:template input: @@ -57,7 +57,7 @@ spec: values: name: ${{ parameters.name }} - - id: fetch-docs + - id: fetchDocs name: Fetch Docs action: fetch:plain input: @@ -68,7 +68,6 @@ spec: name: Publish action: publish:github input: - allowedHosts: ['github.com'] description: This is ${{ parameters.name }} repoUrl: ${{ parameters.repoUrl }} defaultBranch: 'main' diff --git a/docs/features/software-templates/authorizing-scaffolder-template-details.md b/docs/features/software-templates/authorizing-scaffolder-template-details.md index d4798b2540..7ff2cd9377 100644 --- a/docs/features/software-templates/authorizing-scaffolder-template-details.md +++ b/docs/features/software-templates/authorizing-scaffolder-template-details.md @@ -73,7 +73,7 @@ class ExamplePermissionPolicy implements PermissionPolicy { isPermission(request.permission, templateParameterReadPermission) || isPermission(request.permission, templateStepReadPermission) ) { - if (user?.info.userEntityRef === 'user:default/spiderman') + if (user?.info.userEntityRef === 'user:default/bob') return createScaffolderTemplateConditionalDecision(request.permission, { not: scaffolderTemplateConditions.hasTag({ tag: 'secret' }), }); @@ -87,7 +87,7 @@ class ExamplePermissionPolicy implements PermissionPolicy { } ``` -In this example, the user `spiderman` is not authorized to read parameters or steps marked with the `secret` tag. +In this example, the user `bob` is not authorized to read parameters or steps marked with the `secret` tag. By combining this feature with restricting the ingestion of templates in the Catalog as recommended in our threat model, you can create a solid system to restrict certain actions. @@ -113,7 +113,7 @@ class ExamplePermissionPolicy implements PermissionPolicy { ): Promise { /* highlight-add-start */ if (isPermission(request.permission, actionExecutePermission)) { - if (user?.info.userEntityRef === 'user:default/spiderman') { + if (user?.info.userEntityRef === 'user:default/alice') { return createScaffolderActionConditionalDecision(request.permission, { not: scaffolderActionConditions.hasActionId({ actionId: 'debug:log', @@ -130,10 +130,10 @@ class ExamplePermissionPolicy implements PermissionPolicy { } ``` -With this permission policy, the user `spiderman` won't be able to execute the `debug:log` action. +With this permission policy, the user `alice` won't be able to execute the `debug:log` action. You can also restrict the input provided to the action by combining multiple rules. -In the example below, `spiderman` won't be able to execute `debug:log` when passing `{ "message": "not-this!" }` as action input: +In the example below, `alice` won't be able to execute `debug:log` when passing `{ "message": "not-this!" }` as action input: ```ts title="packages/backend/src/plugins/permission.ts" /* highlight-add-start */ @@ -151,7 +151,7 @@ class ExamplePermissionPolicy implements PermissionPolicy { ): Promise { /* highlight-add-start */ if (isPermission(request.permission, actionExecutePermission)) { - if (user?.info.userEntityRef === 'user:default/spiderman') { + if (user?.info.userEntityRef === 'user:default/alice') { return createScaffolderActionConditionalDecision(request.permission, { not: { allOf: [ @@ -176,7 +176,9 @@ class ExamplePermissionPolicy implements PermissionPolicy { ### Authorizing scaffolder tasks -The scaffolder plugin also exposes permissions that can restrict access to tasks, task logs, task creation, and task cancellation. This can be useful if you want to control who has access to these areas of the scaffolder. +The scaffolder plugin also exposes permissions that can restrict access to tasks, task logs, task creation, and task cancellation. This can be useful if you want to control who has access to these areas of the scaffolder. You can configure policies to restrict access to tasks to only their creators, while also granting specific users the permission to view all tasks. + +The following is a simple example of how to do this: ```ts title="packages/src/backend/plugins/permissions.ts" /* highlight-add-start */ @@ -185,6 +187,20 @@ import { taskCreatePermission, taskReadPermission, } from '@backstage/plugin-scaffolder-common/alpha'; +import { + AuthorizeResult, + isPermission, + PolicyDecision, +} from '@backstage/plugin-permission-common'; +import { + PermissionPolicy, + PolicyQuery, + PolicyQueryUser, +} from '@backstage/plugin-permission-node'; +import { + createScaffolderTaskConditionalDecision, + scaffolderTaskConditions, +} from '@backstage/plugin-scaffolder-backend/alpha'; /* highlight-add-end */ class ExamplePermissionPolicy implements PermissionPolicy { @@ -193,26 +209,58 @@ class ExamplePermissionPolicy implements PermissionPolicy { user?: PolicyQueryUser, ): Promise { /* highlight-add-start */ - if (isPermission(request.permission, taskCreatePermission)) { - if (user?.info.userEntityRef === 'user:default/spiderman') { + if (isPermission(request.permission, taskReadPermission)) { + // Allow alice to read any task + if (user?.info.userEntityRef === 'user:default/alice') { return { result: AuthorizeResult.ALLOW, }; } + + // Allow users to read tasks they created + return createScaffolderTaskConditionalDecision( + request.permission, + scaffolderTaskConditions.isTaskOwner({ + createdBy: user?.info.userEntityRef ? [user?.info.userEntityRef] : [], + }), + ); + } + + if (isPermission(request.permission, taskCreatePermission)) { + const userArray = ['user:default/bob', 'user:default/alice']; + const allowed = userArray.some( + allowedUser => user?.info.userEntityRef === allowedUser, + ); + if (allowed) { + return { + result: AuthorizeResult.ALLOW, + }; + } + return { + result: AuthorizeResult.DENY, + }; } if (isPermission(request.permission, taskCancelPermission)) { - if (user?.info.userEntityRef === 'user:default/spiderman') { - return { - result: AuthorizeResult.ALLOW, - }; - } - } - if (isPermission(request.permission, taskReadPermission)) { - if (user?.info.userEntityRef === 'user:default/spiderman') { + // Allow bob to cancel only his tasks + if (user?.info.userEntityRef === 'user:default/bob') { + return createScaffolderTaskConditionalDecision( + request.permission, + scaffolderTaskConditions.isTaskOwner({ + createdBy: user?.info.userEntityRef + ? [user?.info.userEntityRef] + : [], + }), + ); + } + // Allow alice to cancel any task + if (user?.info.userEntityRef === 'user:default/alice') { return { result: AuthorizeResult.ALLOW, }; } + return { + result: AuthorizeResult.DENY, + }; } /* highlight-add-end */ @@ -223,13 +271,21 @@ class ExamplePermissionPolicy implements PermissionPolicy { } ``` -In the provided example permission policy, we only grant the `spiderman` user permissions to perform/access the following actions/resources: +In the provided example permission policy, we only grant the user `bob` permissions to perform/access the following actions/resources: -- Read all scaffolder tasks and their associated events/logs. -- Cancel any ongoing scaffolder tasks. +- Read scaffolder tasks and their associated events/logs for tasks created by `bob`. +- Cancel ongoing scaffolder tasks created by `bob`. - Trigger software templates, which effectively creates new scaffolder tasks. -Any other user would be denied access to these actions/resources. +On the other hand, the user `alice` is granted: + +- Read access to all scaffolder tasks and their associated events/logs. +- The ability to cancel any ongoing scaffolder task. +- The ability to trigger software templates. + +All other users are granted permissions to perform/access the following actions/resources: + +- Read scaffolder tasks and their associated events/logs for tasks created by the user. Although the rules exported by the scaffolder are simple, combining them can help you achieve more complex use cases. diff --git a/docs/features/software-templates/builtin-actions.md b/docs/features/software-templates/builtin-actions.md index d732bd8a27..22d8ef6454 100644 --- a/docs/features/software-templates/builtin-actions.md +++ b/docs/features/software-templates/builtin-actions.md @@ -78,7 +78,7 @@ allow most templates built for `fetch:cookiecutter` to work without any changes. ```yaml title="template.yaml" steps: - - id: fetch-base + - id: fetchBase name: Fetch Base # highlight-remove-next-line action: fetch:cookiecutter diff --git a/docs/features/software-templates/experimental.md b/docs/features/software-templates/experimental.md index 929fe088cf..ff40120d8c 100644 --- a/docs/features/software-templates/experimental.md +++ b/docs/features/software-templates/experimental.md @@ -1,7 +1,6 @@ --- id: experimental title: Experimental Features -# prettier-ignore description: Information on Experimental Features that are currently available in the Scaffolder --- @@ -101,7 +100,7 @@ metadata: name: my-template spec: EXPERIMENTAL_formDecorators: - - id: my-decorator + - id: myDecorator input: test: something funky @@ -116,7 +115,7 @@ You can create a decorator using the simple helper method `createScaffolderFormD ```ts export const mockDecorator = createScaffolderFormDecorator({ // give the decorator a name - id: 'mock-decorator', + id: 'mockDecorator', // define the schema for the input that can be provided in `template.yaml` schema: { diff --git a/docs/features/software-templates/index.md b/docs/features/software-templates/index.md index 10550f7c01..58da85c6eb 100644 --- a/docs/features/software-templates/index.md +++ b/docs/features/software-templates/index.md @@ -2,7 +2,6 @@ id: software-templates-index title: Backstage Software Templates sidebar_label: Overview -# prettier-ignore description: The Software Templates part of Backstage is a tool that can help you create Components inside Backstage --- @@ -11,6 +10,16 @@ Components inside Backstage. By default, it has the ability to load skeletons of code, template in some variables, and then publish the template to some locations like GitHub or GitLab. +:::warning Important + +When creating custom scaffolder actions, **use camelCase for action IDs** instead of kebab-case. Action IDs with dashes (like `fetch-component-id`) will cause template expressions like `${{ steps.fetch-component-id.output.componentId }}` to return `NaN` because the dashes are evaluated as subtraction operators in JavaScript expressions. + +:::note + +See the [Writing Custom Actions guide](./writing-custom-actions.md#naming-conventions) and [Template Migration guide](./migrating-from-v1beta2-to-v1beta3.md#watch-out-for-dash-case) for more details. + +::: + ## Prerequisites :::note Note diff --git a/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md b/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md index bd8d4bdb72..91fc34f978 100644 --- a/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md +++ b/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md @@ -1,7 +1,6 @@ --- id: migrating-from-v1beta2-to-v1beta3 title: Migrating to v1beta3 templates -# prettier-ignore description: How to migrate your existing templates to beta3 syntax --- @@ -80,7 +79,6 @@ writing nice `yaml` files that just work. spec: steps: input: - allowedHosts: ['github.com'] # highlight-remove-next-line description: 'This is {{ parameters.name }}' # highlight-add-next-line diff --git a/docs/features/software-templates/migrating-to-rjsf-v5.md b/docs/features/software-templates/migrating-to-rjsf-v5.md index 8357d7567b..d35eb166f0 100644 --- a/docs/features/software-templates/migrating-to-rjsf-v5.md +++ b/docs/features/software-templates/migrating-to-rjsf-v5.md @@ -1,7 +1,6 @@ --- id: migrating-to-rjsf-v5 title: 'Migrating to react-jsonschema-form@v5' -# prettier-ignore description: Docs on migrating to `react-jsonschema-form`@v5 and the new designs --- diff --git a/docs/features/software-templates/templating-extensions.md b/docs/features/software-templates/templating-extensions.md index 91d0343ae9..242966ae5f 100644 --- a/docs/features/software-templates/templating-extensions.md +++ b/docs/features/software-templates/templating-extensions.md @@ -6,16 +6,16 @@ description: Templating extensions system Backstage templating is powered by [Nunjucks][]. The basics: -# Template Filters +# Templating Filters The [filter][] is a critical mechanism for the rendering of Nunjucks templates, providing a means of transforming values in a familiar [piped][] fashion. -Template filters are functions that help you transform data, extract specific -information, and perform various operations in Scaffolder Templates. +Templating filters are functions that help you transform data, extract specific +information, and perform various operations in Scaffolder templates. ## Built-in -Backstage provides out of the box the following set of "built-in" template +Backstage provides out of the box the following set of "built-in" templating filters (to create your own custom filters, look to the section [Custom Filter](#custom-filter) hereafter): ### parseRepoUrl @@ -103,7 +103,7 @@ The `projectSlug` filter generates a project slug from a repository URL. - **Input**: `github.com?repo=backstage&owner=backstage` - **Output**: `backstage/backstage` -# Template Globals +# Templating Globals In addition to its powerful filtering functionality, the Nunjucks engine allows access from the template expression context to specified globally-accessible @@ -112,7 +112,7 @@ plugin, which we shall soon see in action. # Customizing the templating environment -Custom plugins make it possible to install your own template extensions, which +Custom plugins make it possible to install your own templating extensions, which may be any combination of filters, global functions and global values. With the new backend you would use a scaffolder plugin module for this; later we will demonstrate the analogous approach with the old backend. @@ -127,29 +127,51 @@ Start by using the `yarn backstage-cli new` command to generate a scaffolder mod ``` $ yarn backstage-cli new ? What do you want to create? -> backend-module - A new backend module that extends an existing backend plugin with additional features + frontend-plugin - A new frontend plugin backend-plugin - A new backend plugin - plugin - A new frontend plugin - node-library - A new node-library package, exporting shared functionality for backend plugins and modules - plugin-common - A new isomorphic common plugin package - plugin-node - A new Node.js library plugin package - plugin-react - A new web library plugin package - scaffolder-module - An module exporting custom actions for @backstage/plugin-scaffolder-backend +❯ backend-plugin-module - A new backend module that extends an existing backend plugin + plugin-web-library - A new web library plugin package + plugin-node-library - A new Node.js library plugin package + plugin-common-library - A new isomorphic common plugin package + web-library - A library package, exporting shared functionality for web environments ``` -When prompted, select the option to generate a backend module. -Since we want to extend the Scaffolder backend, enter `scaffolder` when prompted for the plugin to extend. -Next, enter a name for your module (relative to the generated `scaffolder-backend-module-` prefix), -and the CLI will generate the required files and directory structure. +When prompted, use the arrow keys to select the option to generate a `backend-plugin-module`. +Since we want to extend the Scaffolder backend, enter `scaffolder` when prompted for the ID of the plugin to extend. +Next, enter the ID (name) of your module. This will be appended to the `scaffolder-backend-module-` prefix. The CLI will then generate the required files and directory structure, for example: + +``` +? Enter the ID of the plugin [required] scaffolder +? Enter the ID of the module [required] foo-bar + templating plugins/scaffolder-backend-module-foo-bar ✔ + backend adding @internal/plugin-scaffolder-backend-module-foo-bar ✔ + executing yarn install ✔ + executing yarn lint --fix ✔ + +🎉 Successfully created backend-plugin-module +``` + +**Directory Structure** + +``` +plugins +├── README.md +├── scaffolder-backend-module-foo-bar +│   ├── package.json +│   ├── README.md +│   └── src +│   ├── index.ts +│   └── module.ts +``` ## Writing your Module Once the CLI has generated the essential structure for your new scaffolder -module, it's time to implement our template extensions. Here we'll demonstrate +module, it's time to implement our templating extensions. Here we'll demonstrate how to create each of the supported extension types. -`src/module.ts` is where the magic happens. First we prepare to utilize the -associated (_**alpha** phase_) API extension point by adding: +`src/module.ts` is where the magic happens. First, we prepare to utilize the +associated (_**alpha** phase_) API extension point by adding the below import to `src/module.ts`: ```ts import { scaffolderTemplatingExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; @@ -213,7 +235,7 @@ async init({ }, ``` -This demonstrates the bare minimum: a TypeScript `Record` of named template +This demonstrates the bare minimum: a TypeScript `Record` of named templating filter implementations to register. However, by adopting an alternate structure we can document our filter with additional metadata; to utilize this capability we begin by adding a new import: @@ -405,7 +427,7 @@ Then modify: #### Schema Declaring a global function schema is quite like the schema declaration for a -template filter: +templating filter: ```ts createTemplateGlobal({ @@ -415,7 +437,7 @@ template filter: }), ``` -#### Template Global Function Example Documentation +#### Global Function Example Documentation Again, this works in the same way as filter examples: @@ -441,7 +463,7 @@ Again, this works in the same way as filter examples: ### Custom Global Value -Alternatively, your template may need access to a simple JSON value, which can +Alternatively, you may need to provide templates access to a simple JSON value, which can be registered in this manner: ```ts @@ -468,7 +490,7 @@ async init({ templating.addTemplateGlobals([ ..., createTemplateGlobalValue({ - id: 'preferredMetasyntacticVariable', + id: 'preferredMetasyntacticIdentifier', value: 'foo', description: 'This description is as contrived as the global value it documents', @@ -477,15 +499,15 @@ async init({ }, ``` -## Register Template Extensions with the Legacy Backend System +## Register Templating Extensions with the Legacy Backend System -Users of the original Backstage backend can register template extensions by +Users of the original Backstage backend can register templating extensions by specifying options to the scaffolder backend plugin's `createRouter` function (customarily called in `packages/backend/src/plugins/scaffolder.ts`): - `additionalTemplateFilters` - either of: - object mapping filter name to implementation function, or - - array of documented template filters as returned by the + - array of documented templating filters as returned by the utility function `createTemplateFilter` - `additionalTemplateGlobals` - either of: - object mapping global name to value or function, or diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index 26773c15c6..1a64406b04 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -12,7 +12,7 @@ by writing custom actions which can be used alongside our When adding custom actions, the actions array will **replace the built-in actions too**. Meaning, you will no longer be able to use them. -If you want to continue using the builtin actions, include them in the actions +If you want to continue using the builtin actions, include them in the `actions` array when registering your custom actions, as seen below. ::: @@ -52,19 +52,20 @@ its generated unit test. We will replace the existing placeholder code with our import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import fs from 'fs-extra'; -import { z } from 'zod'; +import { type z } from 'zod'; export const createNewFileAction = () => { return createTemplateAction({ id: 'acme:file:create', description: 'Create an Acme file.', schema: { - input: z.object({ - contents: z.string().describe('The contents of the file'), - filename: z - .string() - .describe('The filename of the file that will be created'), - }), + input: { + contents: z => z.string({ description: 'The contents of the file' }), + filename: z => + z.string({ + description: 'The filename of the file that will be created', + }), + }, }, async handler(ctx) { @@ -95,53 +96,11 @@ The `createTemplateAction` takes an object which specifies the following: function using `ctx.output` - `handler` - the actual code which is run as part of the action, with a context -You can also choose to define your custom action using JSON schema instead of `zod`: - -```ts title="With JSON Schema" -import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import { writeFile } from 'fs'; - -export const createNewFileAction = () => { - return createTemplateAction<{ contents: string; filename: string }>({ - id: 'acme:file:create', - description: 'Create an Acme file.', - schema: { - input: { - required: ['contents', 'filename'], - type: 'object', - properties: { - contents: { - type: 'string', - title: 'Contents', - description: 'The contents of the file', - }, - filename: { - type: 'string', - title: 'Filename', - description: 'The filename of the file that will be created', - }, - }, - }, - }, - async handler(ctx) { - const { signal } = ctx; - await writeFile( - resolveSafeChildPath(ctx.workspacePath, ctx.input.filename), - ctx.input.contents, - { signal }, - _ => {}, - ); - }, - }); -}; -``` - ### Naming Conventions Try to keep names consistent for both your own custom actions, and any actions contributed to open source. We've found that a separation of `:` and using a verb as the last part of the name works well. -We follow `provider:entity:verb` or as close to this as possible for our built in actions. For example, +We follow `provider:entity:verb` or as close to this as possible for our built-in actions. For example, `github:actions:create` or `github:repo:create`. Also feel free to use your company name to namespace them if you prefer too, for example `acme:file:create` like above. @@ -151,14 +110,14 @@ and writing of template entity definitions. ### Adding a TemplateExample -A TemplateExample is a way to document different ways that your custom action can be used. Once added it will be visible +A TemplateExample is a way to document different ways that your custom action can be used. Once added, it will be visible in your Backstage instance under the [/create/actions](https://demo.backstage.io/create/actions) path. You can have multiple examples for one action that can demonstrate different combinations of inputs and how to use them. #### Define TemplateExamples Below is a sample TemplateExample that is used for `publish:github`. The source code is available -on [github](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-github/src/actions/github.examples.ts) +on [GitHub](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-github/src/actions/github.examples.ts) and preview on [demo.backstage.io/create/actions](https://demo.backstage.io/create/actions#publish-github) ```ts title="With JSON Schema" @@ -222,7 +181,7 @@ return createTemplateAction({ #### Test TemplateAction examples It is also possible to test your example TemplateActions. You can see a sample test -on [github](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts) +on [GitHub](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts) ### The context object @@ -234,13 +193,12 @@ argument. It looks like the following: implement [idempotency of the actions](https://github.com/backstage/backstage/tree/master/beps/0004-scaffolder-task-idempotency) by not re-running the same function again if it was executed successfully on the previous run. -- `ctx.logger` - a Winston logger for additional logging inside your action -- `ctx.logStream` - a stream version of the logger if needed +- `ctx.logger` - a [LoggerService](../../backend-system/core-services/logger.md) instance for additional logging inside your action - `ctx.workspacePath` - a string of the working directory of the template run - `ctx.input` - an object which should match the `zod` or JSON schema provided in the `schema.input` part of the action definition - `ctx.output` - a function which you can call to set outputs that match the - JSON schema or `zod` in `schema.output` for ex. `ctx.output('downloadUrl', myDownloadUrl)` + `zod` schema in `schema.output` for ex. `ctx.output('downloadUrl', myDownloadUrl)` - `createTemporaryDirectory` a function to call to give you a temporary directory somewhere on the runner, so you can store some files there rather than polluting the `workspacePath` @@ -249,7 +207,7 @@ argument. It looks like the following: ## Registering Custom Actions -To register your new custom action in the Backend System you will need to create a backend module. Here is a very +To register your new custom action in the Backend System, you will need to create a backend module. Here is a very simplified example of how to do that: ```ts title="packages/backend/src/index.ts" @@ -327,8 +285,8 @@ const res = await ctx.checkpoint?.({ }); ``` -You have to define the unique key in scope of the scaffolder task for your checkpoint. During the execution task engine -will check if the checkpoint with such key was already executed or not, if yes, and the run was successful, the callback +You have to define the unique key in the scope of the scaffolder task for your checkpoint. During the execution task engine +will check if the checkpoint with such a key was already executed or not, if yes, and the run was successful, the callback will be skipped and instead the stored value will be returned. Whenever you change the return type of the checkpoint, we encourage you to change the ID. diff --git a/docs/features/software-templates/writing-templates.md b/docs/features/software-templates/writing-templates.md index eeaa4ad203..32f17f945f 100644 --- a/docs/features/software-templates/writing-templates.md +++ b/docs/features/software-templates/writing-templates.md @@ -59,7 +59,7 @@ spec: # here's the steps that are executed in series in the scaffolder backend steps: - - id: fetch-base + - id: fetchBase name: Fetch Base action: fetch:template input: @@ -68,7 +68,7 @@ spec: name: ${{ parameters.name }} owner: ${{ parameters.owner }} - - id: fetch-docs + - id: fetchDocs name: Fetch Docs action: fetch:plain input: @@ -79,7 +79,6 @@ spec: name: Publish action: publish:github input: - allowedHosts: ['github.com'] description: This is ${{ parameters.name }} repoUrl: ${{ parameters.repoUrl }} defaultBranch: 'main' @@ -88,7 +87,7 @@ spec: name: Register action: catalog:register input: - repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }} + repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }} catalogInfoPath: '/catalog-info.yaml' # some outputs which are saved along with the job for use in the frontend @@ -274,6 +273,58 @@ spec: password: ${{ secrets.password }} ``` +You can also consume secrets within `each` step of the template. + +```yaml +apiVersion: scaffolder.backstage.io/v1beta3 +kind: Template +metadata: + name: v1beta3-demo + title: Test Action template + description: scaffolder v1beta3 template demo +spec: + owner: backstage/techdocs-core + type: service + + parameters: + - title: Authentication + description: Provide authentication for the resource + required: + - service1 + - token1 + - service2 + - token2 + properties: + service1: + type: string + token1: + type: string + ui:field: Secret + service2: + type: string + token2: + type: string + ui:field: Secret + + steps: + - id: setupAuthentication + action: auth:create + each: + [ + { + name: '${{ parameters.service1 }}', + token: '${{ secrets.token1 }}', + }, + { + name: '${{ parameters.service2 }}', + token: '${{ secrets.token2 }}', + }, + ] + input: + name: ${{ each.value.name }} + token: ${{ each.value.token }} +``` + ### Custom step layouts If you find that the default layout of the form used in a particular step does not meet your needs then you can supply your own [custom step layout](./writing-custom-step-layouts.md). @@ -315,7 +366,7 @@ your first set of parameter fields would be shown. The same goes for the nested spec. Make sure to use the key `backstage:featureFlag` in your templates if you want to use this functionality. -Feature Flags cannot be used in `spec.steps[].if`(the conditional on whether to execute an step/action). But you can use feature flags to display parameters that allow for skipping steps. +Feature Flags cannot be used in `spec.steps[].if`(the conditional on whether to execute a step/action). But you can use feature flags to display parameters that allow for skipping steps. ```yaml spec: @@ -453,7 +504,6 @@ spec: name: Publish action: publish:github input: - allowedHosts: ['github.com'] description: This is ${{ parameters.name }} repoUrl: ${{ parameters.repoUrl }} # here's where the secret can be used @@ -572,7 +622,7 @@ The `steps` is an array of the things that you want to happen part of this template. These follow the same standard format: ```yaml -- id: fetch-base # A unique id for the step +- id: fetchBase # A unique id for the step name: Fetch Base # A title displayed in the frontend if: ${{ parameters.name }} # Optional condition, skip the step if not truthy each: ${{ parameters.iterable }} # Optional iterable, run the same step multiple times @@ -583,6 +633,14 @@ template. These follow the same standard format: name: ${{ parameters.name }} ``` +:::warning Action ID Naming + +When using custom actions, **use camelCase for action IDs** to avoid issues with template expressions. Action IDs with dashes will cause expressions like `${{ steps.my-action.output.value }}` to return `NaN` instead of the expected value. + +Use `myAction` instead of `my-action`, or access outputs with bracket notation: `${{ steps['my-action'].output.value }}`. + +::: + By default we ship some [built in actions](./builtin-actions.md) that you can take a look at, or you can [create your own custom actions](./writing-custom-actions.md). @@ -674,7 +732,7 @@ spec: default: false ... steps: - - id: fetch-base + - id: fetchBase name: Fetch Base action: fetch:template input: @@ -749,7 +807,7 @@ Have in mind that changes in this form will not be saved on the template and is ### Custom Field Explorer -The custom filed explorer allows you to select any custom field loaded on the backstage instance and test different values and configurations. +The custom field explorer allows you to select any custom field loaded on the backstage instance and test different values and configurations. ## Presentation diff --git a/docs/features/techdocs/FAQ.md b/docs/features/techdocs/FAQ.md index 117471f749..9c78e3e123 100644 --- a/docs/features/techdocs/FAQ.md +++ b/docs/features/techdocs/FAQ.md @@ -12,6 +12,8 @@ This page answers frequently asked questions about [TechDocs](README.md). - [What static site generator is TechDocs using?](#what-static-site-generator-is-techdocs-using) - [What is the mkdocs-techdocs-core plugin?](#what-is-the-mkdocs-techdocs-core-plugin) - [Does TechDocs support file formats other than Markdown (e.g. RST, AsciiDoc)?](#does-techdocs-support-file-formats-other-than-markdown-eg-rst-asciidoc-) +- [What should be the value of `backstage.io/techdocs-ref` when using external build and storage?](#what-should-be-the-value-of-backstageiotechdocs-ref-when-using-external-build-and-storage) +- [Is it possible for users to suggest changes or provide feedback on a TechDocs page?](#is-it-possible-for-users-to-suggest-changes-or-provide-feedback-on-a-techdocs-page) #### What static site generator is TechDocs using? @@ -46,6 +48,10 @@ annotation should still be present in entity descriptor file (e.g. `catalog-info.yaml`) for Backstage to know that TechDocs is enabled for the entity. +#### What happens when you navigate to a TechDocs URL for an entity uses the `backstage.io/techdocs-entity` annotation? + +If you navigate to a TechDocs URL in the format `docs/{namespace}/{kind}/{name}` for an entity that has the `backstage.io/techdocs-entity` annotation (instead of the `backstage.io/techdocs-ref` annotation), then Backstage will redirect to the TechDocs page of the entity referenced in the value of that annotation. + #### Is it possible for users to suggest changes or provide feedback on a TechDocs page? This is supported for TechDocs sites whose source code is hosted in either diff --git a/docs/features/techdocs/README.md b/docs/features/techdocs/README.md index beec6d1fad..0306a9746b 100644 --- a/docs/features/techdocs/README.md +++ b/docs/features/techdocs/README.md @@ -2,7 +2,6 @@ id: techdocs-overview title: TechDocs Documentation sidebar_label: Overview -# prettier-ignore description: TechDocs is Spotify’s homegrown docs-like-code solution built directly into Backstage --- diff --git a/docs/features/techdocs/addons--new.md b/docs/features/techdocs/addons--new.md index 07138d4b8e..8c58eb892c 100644 --- a/docs/features/techdocs/addons--new.md +++ b/docs/features/techdocs/addons--new.md @@ -1,11 +1,11 @@ --- -id: addons +id: addons--new title: TechDocs Addons description: How to find, use, or create TechDocs Addons. --- :::info -This documentation is written for [the new frontend system](../../frontend-system/index.md) which is still in alpha and is only supported by a small number of plugins. +This documentation is written for [the new frontend system](../../frontend-system/index.md) which is still in alpha and is only supported by a small number of plugins. If you are on the [old frontend system](./getting-started.md#adding-techdocs-frontend-plugin) you may want to read [its own article](./addons.md) instead. ::: ## Concepts diff --git a/docs/features/techdocs/cli.md b/docs/features/techdocs/cli.md index 517b2a3547..a52730d335 100644 --- a/docs/features/techdocs/cli.md +++ b/docs/features/techdocs/cli.md @@ -1,7 +1,6 @@ --- id: cli title: TechDocs CLI -# prettier-ignore description: TechDocs CLI - a utility command line interface for managing TechDocs sites in Backstage. --- diff --git a/docs/features/techdocs/concepts.md b/docs/features/techdocs/concepts.md index 2944197dfb..f427f0cd2b 100644 --- a/docs/features/techdocs/concepts.md +++ b/docs/features/techdocs/concepts.md @@ -1,7 +1,6 @@ --- id: concepts title: Concepts -# prettier-ignore description: Documentation on concepts that are introduced with Spotify's docs-like-code solution in Backstage --- diff --git a/docs/features/techdocs/configuration.md b/docs/features/techdocs/configuration.md index 05f184e90f..e21e452b7c 100644 --- a/docs/features/techdocs/configuration.md +++ b/docs/features/techdocs/configuration.md @@ -1,7 +1,6 @@ --- id: configuration title: TechDocs Configuration Options -# prettier-ignore description: Reference documentation for configuring TechDocs using app-config.yaml --- diff --git a/docs/features/techdocs/configuring-ci-cd.md b/docs/features/techdocs/configuring-ci-cd.md index 20a73798a4..d818c129a4 100644 --- a/docs/features/techdocs/configuring-ci-cd.md +++ b/docs/features/techdocs/configuring-ci-cd.md @@ -1,7 +1,6 @@ --- id: configuring-ci-cd title: Configuring CI/CD to generate and publish TechDocs sites -# prettier-ignore description: Configuring CI/CD to generate and publish TechDocs sites to cloud storage --- diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 8a95c86533..755d88b163 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -606,6 +606,25 @@ techdocs: This way, custom element like `` will be allowed in the result HTML. +## How to allow additional URI protocols in TechDocs + +TechDocs uses the [DOMPurify](https://github.com/cure53/DOMPurify) library to +sanitize HTML and prevent XSS attacks. + +It's possible to allow additional URI protocols based on a list of protocols. To do +this, add the allowed protocols in the `techdocs.sanitizer.additionalAllowedURIProtocols` +and `additionalAllowedURIProtocols` configuration of your `app-config.yaml`. + +For example: + +```yaml +techdocs: + sanitizer: + additionalAllowedURIProtocols: ["vscode"], +``` + +This way, links like `VSCode Settings` will be allowed in the result HTML + ## How to render PlantUML diagram in TechDocs PlantUML allows you to create diagrams from plain text language. Each diagram description begins with the keyword - (@startXYZ and @endXYZ, depending on the kind of diagram). For UML Diagrams, Keywords @startuml & @enduml should be used. Further details for all types of diagrams can be found at [PlantUML Language Reference Guide](https://plantuml.com/guide). @@ -942,6 +961,35 @@ metadata: backstage.io/techdocs-entity: system:default/example ``` +### Deep linking into TechDocs + +The `backstage.io/techdocs-entity-path` annotation can be use to deep link into a specific page within the components TechDocs. +This can be used in conjunction with `backstage.io/techdocs-entity` or standalone. + +```yaml +apiVersion: backstage.io/v1alpha1 +kind: System +metadata: + name: example + namespace: default + title: Example + description: This is the parent entity + annotations: + backstage.io/techdocs-ref: dir:. + +--- +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: example-platfrom + title: Example Application Platform + namespace: default + description: This is the child entity + annotations: + backstage.io/techdocs-entity: system:default/example + backstage.io/techdocs-entity-path: /path/to/component/docs +``` + ## How to resolve broken links from moved or renamed pages in your documentation site TechDocs supports using the [mkdocs-redirects](https://github.com/mkdocs/mkdocs-redirects/tree/master) plugin to create a redirect map for any TechDocs site. This allows broken links from renamed or moved pages in your site to be redirected to their specified replacement. diff --git a/docs/features/techdocs/using-cloud-storage.md b/docs/features/techdocs/using-cloud-storage.md index bdafb3532c..42024ffbb2 100644 --- a/docs/features/techdocs/using-cloud-storage.md +++ b/docs/features/techdocs/using-cloud-storage.md @@ -355,31 +355,53 @@ techdocs: **3a. (Recommended) Authentication using environment variable** -If you do not prefer (3a) and optionally like to use a service account, you can -set the config `techdocs.publisher.azureBlobStorage.credentials.accountName` in -your `app-config.yaml` to the your account name. +The Azure Blob Storage client in Backstage supports all credential types +provided by +[DefaultAzureCredential](https://azuresdkdocs.z19.web.core.windows.net/javascript/azure-identity/4.10.1/classes/DefaultAzureCredential.html). +This means you can authenticate using environment variables for a service +principal, managed identity, and other methods in the default credential +chain. -The storage blob client will automatically use the environment variable -`AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET` to authenticate with -Azure Blob Storage. -[Steps to create the service where the variables can be retrieved from](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal). +For deployment on Kubernetes, you can use +[Azure Workload Identity Federation](https://learn.microsoft.com/en-us/azure/active-directory/workload-identities/workload-identity-federation-overview) +to grant your Backstage workload access to the storage account without +managing secrets. +If running in Azure Virtual Machines or Azure Kubernetes Service (AKS) with managed +identity, no additional configuration apart from the `accountName` and +`containerName` may be needed. +For other scenarios, you can use a +[service principal](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal) +by setting: -https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad for more -details. +- `AZURE_CLIENT_ID` +- `AZURE_TENANT_ID` +- `AZURE_CLIENT_SECRET` + +Example configuration in `app-config.yaml`: ```yaml techdocs: publisher: type: 'azureBlobStorage' azureBlobStorage: - containerName: 'name-of-techdocs-storage-bucket' + containerName: 'name-of-techdocs-storage-container' credentials: accountName: ${TECHDOCS_AZURE_BLOB_STORAGE_ACCOUNT_NAME} ``` +> **Note:** The account or credentials used must have the +> `Storage Blob Data Owner` role on the container to read, write, and +> delete objects as needed. If you use an external publisher, the +> `Storage Blob Data Reader` role is sufficient. + +For more details, see the +[Azure Identity documentation](https://azuresdkdocs.z19.web.core.windows.net/javascript/azure-identity/4.10.1/classes/DefaultAzureCredential.html) +and +[Workload Identity Federation for Kubernetes](https://learn.microsoft.com/en-us/azure/active-directory/workload-identities/workload-identity-federation-overview). + **3b. Authentication using app-config.yaml** -If you do not prefer (3a) and optionally like to use a service account, you can +If you do not prefer (3a) and optionally like to use key-based access, you can follow these steps. To get credentials, access the Azure Portal and go to "Settings > Access Keys", @@ -400,7 +422,9 @@ techdocs: In either case, the account or credentials used to access your container and all TechDocs objects underneath it should have the `Storage Blog Data Owner` role -applied, in order to read, write, and delete objects as needed. +applied, in order to read, write, and delete objects as needed, unless you use +an external publisher, in this case the `Storage Blob Data Reader` role is +sufficient. **4. That's it!** diff --git a/docs/frontend-system/architecture/00-index.md b/docs/frontend-system/architecture/00-index.md index 20a12ba1e8..5e90e305cf 100644 --- a/docs/frontend-system/architecture/00-index.md +++ b/docs/frontend-system/architecture/00-index.md @@ -2,12 +2,9 @@ id: index title: Frontend System Architecture sidebar_label: Overview -# prettier-ignore description: The structure and architecture of the new Frontend System --- -> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** - ## Building Blocks This section introduces the high-level building blocks upon which this new diff --git a/docs/frontend-system/architecture/10-app.md b/docs/frontend-system/architecture/10-app.md index d1c3820f09..0303dd5e70 100644 --- a/docs/frontend-system/architecture/10-app.md +++ b/docs/frontend-system/architecture/10-app.md @@ -2,12 +2,9 @@ id: app title: App Instances sidebar_label: App -# prettier-ignore description: App instances --- -> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** - ## The App Instance The app instance is the main entry point for creating a frontend app. It doesn't do much on its own, but is instead responsible for wiring things together that have been provided as features from other parts of the system. @@ -30,7 +27,7 @@ const root = app.createRoot(); // Just like any other React we need a root element. No server side rendering is used. const rootEl = document.getElementById('root')!; -ReactDOM.createRoot(rootEl).render(app); +ReactDOM.createRoot(rootEl).render(root); ``` We call `createApp` to create a new app instance, which is responsible for wiring together all of the features that we provide to the app. It also provides a set of built-in [Extensions](./20-extensions.md) that help build out the foundations of the app, as well as defaults for many other systems such as [Utility API](./33-utility-apis.md) implementations, components, icons, themes, and how to load configuration. No real work is done at the point of creating the app though, it's all deferred to the rendering of the element returned from `app.createRoot()`. @@ -49,31 +46,123 @@ App feature discovery lets you automatically discover and install features provi Because feature discovery needs to interact with the compilation process, it is only available when using the `@backstage/cli` to build your app. It is hooked into the WebPack compilation process by scanning your app package for compatible dependencies, which are then made part of the app compilation bundle. -Since the `@backstage/cli` is a more stable component than the new frontend system, feature discovery is currently marked as an experimental feature of the CLI and needs to be enabled manually. To enable it, add the following configuration to your `app-config.yaml`: +To enable frontend feature discovery, add the following configuration to your `app-config.yaml`: ```yaml app: - experimental: - packages: all + packages: all ``` This will cause all dependencies in your app package to be installed automatically. If this is not desired, you can use include or exclude filters to narrow down the set of packages: ```yaml app: - experimental: - packages: - # Only the following packages will be included - include: - - '@backstage/plugin-catalog' - - '@backstage/plugin-scaffolder' + packages: + # Only the following packages will be included + include: + - '@backstage/plugin-catalog' + - '@backstage/plugin-scaffolder' --- app: - experimental: - packages: - # All but the following package will be included - exclude: - - '@backstage/plugin-catalog' + packages: + # All but the following package will be included + exclude: + - '@backstage/plugin-catalog' ``` Note that you do not need to manually exclude packages that you also import explicitly in code, since plugin instances are deduplicated by the app. You will never end up with duplicate plugin installations except if they are in fact two different plugin instances with different IDs. + +## Plugin Info Resolution + +When a plugin is installed in an app it may provide sources of information about the plugin that can be useful to end users and admins. This includes things like what version of a plugin is running, what team owns the plugin, and who to contact for support. You can read more about how the plugins provide this information in the [plugins `info` option section](./15-plugins.md#info). + +By default the app will pick a few common fields from `package.json` files, and assume that the opaque manifests are `catalog-info.yaml` files that some information can be gathered from too. This information will then be available via the `info()` method on plugin instances, returning a structure of the `FrontendPluginInfo` type. + +### Extending Plugin Info + +The default plugin info is intended as a base to build upon. As part of setting up an app you can both customize the way that the plugin info is resolved, as well as extend the `FrontendPluginInfo` type to include more information. + +In order to extend the `FrontendPluginInfo` type you use [TypeScript module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation). This makes it possible to extend the `FrontendPluginInfo` interface with additional fields, which you can then add custom resolution logic for as well as access within the app. For example, you might add a `slackChannel` field as follows: + +```ts +declare module '@backstage/frontend-plugin-api' { + interface FrontendPluginInfo { + /** + * The slack channel to use for support requests for this plugin. + */ + slackChannel?: string; + } +} +``` + +### Customizing Plugin Info Resolution + +With the new `slackChannel` field in place, we now need to provide a custom resolver that knows how to extract this information from the plugin information sources. This is done by passing a custom `pluginInfoResolver` to `createApp`, which in our example is declared like this: + +```ts title="pluginInfoResolver.ts" +import { createPluginInfoResolver } from '@backstage/frontend-plugin-api'; + +// It is recommended to keep the above module augmentation in this file too + +export const pluginInfoResolver: FrontendPluginInfoResolver = async ctx => { + // In our particular example app we assume that all plugin manifests are catalog-info.yaml files + const manifest = (await ctx.manifest?.()) as Entity | undefined; + + // Call the default resolver to populate common fields + const { info } = await ctx.defaultResolver({ + packageJson: await ctx.packageJson(), + manifest: manifest, + }); + + // In this example the catalog model has been extended with a metadata.slackChannel field + const slackChannel = manifest?.metadata?.slackChannel?.toString(); + + if (slackChannel) { + info.slackChannel = slackChannel; + info.links = [ + ...(info.links ?? []), + { + title: 'Slack Channel', + url: `https://our-workspace.enterprise.slack.com/archives/${slackChannel}`, + }, + ]; + } + + return { info }; +}; +``` + +And included in the app as follows: + +```ts title="App.tsx" +import { pluginInfoResolver } from './pluginInfoResolver'; + +const app = createApp({ + pluginInfoResolver, + // ... other options +}); +``` + +### Overriding Plugin Info + +Another way to customize the plugin info is to use the `app.pluginOverrides` static configuration key. These overrides are applied after the plugin info has been resolved as a final step before making it available to users. These overrides are particularly useful to override information in third-party plugins. For example, if your organization has an individual team that is responsible for the maintenance of the Software Catalog, you might configure the following override: + +```yaml +app: + pluginOverrides: + - match: + pluginId: catalog + info: + ownerEntityRefs: [catalog-owners] +``` + +You can match on both the `pluginId` and/or `packageName` of the plugin, although the `packageName` will only be supported if the plugin provides an loader for the `package.json` file. Using `//` you are also able to use a regex pattern for this matching. For example, if you wanted to override the owner for all plugins from the `@acme` namespace, you could do the following: + +```yaml +app: + pluginOverrides: + - match: + packageName: /@acme/.*/ + info: + ownerEntityRefs: [acme-owners] +``` diff --git a/docs/frontend-system/architecture/15-plugins.md b/docs/frontend-system/architecture/15-plugins.md index 825f2a3982..0918961c73 100644 --- a/docs/frontend-system/architecture/15-plugins.md +++ b/docs/frontend-system/architecture/15-plugins.md @@ -2,12 +2,9 @@ id: plugins title: Frontend Plugins sidebar_label: Plugins -# prettier-ignore description: Frontend plugins --- -> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** - ## Introduction Frontend plugins are a foundational building block in Backstage and the frontend system. They are used to encapsulate and provide functionality for a Backstage app, such as new pages, navigational elements, and APIs; as well as extensions and features for other plugins, such as entity page cards and content for the Software Catalog, or result list items for the search plugin. @@ -22,7 +19,7 @@ Frontend plugin instances are created with the `createFrontendPlugin` function, // This creates a new extension, see "Extension Blueprints" documentation for more details const myPage = PageBlueprint.make({ params: { - defaultPath: '/my-page', + path: '/my-page', loader: () => import('./MyPage').then(m => ), }, }); @@ -53,6 +50,35 @@ These are the routes that the plugin exposes to the app. The `routes` option dec This is a list of feature flag declarations that your plugin provides to the app. This makes sure that the feature flags are correctly registered and can be toggled in the app. To read a feature flag you can use the feature flags [Utility API](../architecture/33-utility-apis.md), accessible via `featureFlagsApiRef`. +### `info` option + +This options is used to provide loaders for different sources of information about the plugin that may be useful to users and admins. The two available loaders are `packageJson` and `manifest`, and a plugin can use either or both as needed. The resulting information is available via the `info()` method on the plugin instance once it is installed in an app, but it is up to each app to decide how to derive the information from the provided sources. + +The `info.packageJson` loader **MUST** be used by all plugins that are implemented within their own package, and it should load the `package.json` file for the plugin package. Typical usage looks like this: + +```ts +export default createFrontendPlugin({ + pluginId: 'my-plugin', + info: { + packageJson: () => import('../package.json'), + }, + extensions: [...], +}); +``` + +The `info.manifest` loader is used to point to an opaque plugin manifest. This **MUST ONLY** be used by plugins that are intended for use within a single organization. Plugins that are published to an open package registry should **NOT** use this loader. The loader is useful for adding additional internal metadata associated with the plugin, and it is up to the Backstage app to decide how these manifests are parsed and used. The default manifest parser in an app created with `createApp` from `@backstage/frontend-defaults` is able to parse the default `catalog-info.yaml` format and built-in fields such as `metadata.links` and `spec.owner`. + +Typical usage looks like this: + +```ts +export default createFrontendPlugin({ + pluginId: '...', + info: { + manifest: () => import('../catalog-info.yaml'), + }, +}); +``` + ## Installing a Plugin in an App A plugin instance is considered a frontend feature and can be installed directly in any Backstage frontend app. See the [app documentation](./10-app.md) for more information about the different ways in which you can install new features in an app. @@ -79,7 +105,7 @@ export default plugin.withOverrides({ // Override the catalog index page with a completely custom implementation PageBlueprint.make({ params: { - defaultPath: '/catalog', + path: '/catalog', routeRef: plugin.routes.catalogIndex, loader: () => import('./CustomCatalogIndexPage').then(m => ), }, diff --git a/docs/frontend-system/architecture/20-extensions.md b/docs/frontend-system/architecture/20-extensions.md index eae0405bda..24a5f24e12 100644 --- a/docs/frontend-system/architecture/20-extensions.md +++ b/docs/frontend-system/architecture/20-extensions.md @@ -2,12 +2,9 @@ id: extensions title: Frontend Extensions sidebar_label: Extensions -# prettier-ignore description: Frontend extensions --- -> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** - As mentioned in the [previous section](./10-app.md), Backstage apps are built up from a tree of extensions. This section will go into more detail about what extensions are, how to create and use them, and how to create your own extensibility patterns. ## Extension Structure diff --git a/docs/frontend-system/architecture/23-extension-blueprints.md b/docs/frontend-system/architecture/23-extension-blueprints.md index fb10749845..f6efccccbb 100644 --- a/docs/frontend-system/architecture/23-extension-blueprints.md +++ b/docs/frontend-system/architecture/23-extension-blueprints.md @@ -2,12 +2,9 @@ id: extension-blueprints title: Frontend Extension Blueprints sidebar_label: Extensions Blueprints -# prettier-ignore description: Frontend extensions --- -> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** - The `createExtension` function and related APIs is considered a low-level building and fairly advanced building block, and is not typically what you would use when building plugins and features. Instead, the core APIs and plugins provide extension blueprints that makes it easier to create extensions for specific usages. These blueprints accept a number of parameters that is up to each blueprint to define, and then creates a new extension using the provided parameters. New blueprints are created using the `createExtensionBlueprint` function, and are by convention exported with the symbol `Blueprint`. If you are curious about what blueprints are available from a plugin or package, look for `*Blueprint` exports in the package's API, for plugins these are typically found in the `*-react` package. ## Creating an extension from a blueprint @@ -19,7 +16,7 @@ The following is a simple example of how one might use the blueprint `make` meth ```tsx const myPageExtension = PageBlueprint.make({ params: { - defaultPath: '/my-page', + path: '/my-page', loader: () => import('./components/MyPage').then(m => ), }, }); @@ -27,7 +24,7 @@ const myPageExtension = PageBlueprint.make({ The returned `myPageExtension` is an extension which is ready to be used in a plugin. It is the same type of object as is returned by the lower level `createExtension` function. -## Creating an extension from a blueprint with overrides +### Creating an extension from a blueprint with overrides Every extension blueprint also provides a `makeWithOverrides` method. It is useful in cases where you want to provide additional integration points for an extension created with a blueprint. You might for example want to define additional inputs or configuration schema, or use the existing configuration to dynamically compute the parameters passed to the blueprint. @@ -35,22 +32,34 @@ The following is an example of how one might use the blueprint `makeWithOverride ```tsx const myPageExtension = PageBlueprint.makeWithOverrides({ + // This defines additional configuration options for the extension. config: { schema: { layout: z => z.enum(['grid', 'rows']).default('grid'), }, }, - // The original blueprint factory is provided as the first argument - factory(originalFactory, { config }) { + // This defines additional inputs for the extension. + inputs: { + content: createExtensionInput([coreExtensionData.reactElement], { + singleton: true, + optional: true, + }), + }, + // The original blueprint factory is provided as the first argument. + // By convention the name is `originalFactory`, but you can also pick a different name. + factory(originalFactory, { config, inputs }) { // Call and forward the result from the original factory, providing // the blueprint parameters as the first argument. return originalFactory({ - defaultPath: '/my-page', + path: '/my-page', loader: () => import('./components/MyPage').then(m => ( // We can now access values from the factory context when providing - // the blueprint parameters, such as config values. - + // the blueprint parameters, such as config values and inputs. + )), }); }, @@ -59,7 +68,40 @@ const myPageExtension = PageBlueprint.makeWithOverrides({ When using `makeWithOverrides`, we no longer pass the blueprint parameters directly. Instead, we provide a `factory` function that receives the original blueprint factory as the first argument, and the extension factory context as the second. We can then call the original blueprint factory with the blueprint parameters and forward the result as the return value of out factory. Notice that when passing the blueprint parameters using this pattern we have access to a lot more information than when using the `make` method, at the cost of being more complex. -Apart from the addition of the blueprint parameters of the first argument to the original factory function, the `makeWithOverrides` method works the same way as [extension overrides](./25-extension-overrides.md). All the same options and rules apply, including the ability to define additional inputs, override outputs, and so on. We therefore defer to the [extension overrides](./25-extension-overrides.md) documentation for more information on how to use the `makeWithOverrides` method. +Apart from the addition of the blueprint parameters of the first argument to the original factory function, the `makeWithOverrides` method works the same way as [extension overrides](./25-extension-overrides.md). All the same options and rules apply, including the ability to define additional inputs, override outputs, and so on. For more details and examples on how this works, please refer to the [extension overrides](./25-extension-overrides.md) documentation. The patterns in that section also apply to the creation of extensions with the `makeWithOverrides` method. + +### Creating an extension from a blueprint with advanced parameter types + +Some blueprints may be defined with something known as "advanced parameter types". This is a feature that enables type inference and transform of the blueprint parameters, and the way that you pass the parameters look a little bit different. Rather than passing the parameters directly, they are instead passed as a callback function of the form `defineParams => defineParams()`. + +An example of a blueprint that uses advanced parameter types is the `ApiBlueprint` blueprint. Using it to create a simple implementation for the `AlertApi` might look like this: + +```ts +const alertApiBlueprint = ApiBlueprint.make({ + params: defineParams => + defineParams({ + api: alertApiRef, + deps: {}, + factory: () => new MyAlertApi(), + }), +}); +``` + +This also works with `makeWithOverrides`, where the define callback is passed as the first argument to the original factory: + +```ts +const alertApiBlueprint = ApiBlueprint.makeWithOverrides({ + factory(originalFactory, { config }) { + return originalFactory(defineParams => + defineParams({ + api: alertApiRef, + deps: {}, + factory: () => new MyAlertApi(config), + }), + ); + }, +}); +``` ## Creating an extension blueprint @@ -69,7 +111,7 @@ The following is an example of how one might create a new extension blueprint: ```tsx export interface MyWidgetBlueprintParams { - defaultTitle: string; + title: string; element: JSX.Element; } @@ -87,7 +129,7 @@ export const MyWidgetBlueprint = createExtensionBlueprint({ // Note that while this is a valid pattern, you might often want to // return separate pieces of data instead, more on that below. coreExtensionData.reactElement( - + {params.element} , ), @@ -100,6 +142,41 @@ This is of course a quite bare-bones example blueprint, but still a very real ex Most of the options provided to `createExtensionBlueprint` can be overridden when using `makeWithOverrides` to create an extension from the blueprint. These overrides work the same way as [extension overrides](./25-extension-overrides.md), and we defer to that documentation for more information on how overrides work. +### Creating an extension blueprint with advanced parameter types + +In some cases you may want to use inferred type parameters in the definition of the blueprint parameters. For this you need to use something known as "advanced parameter types". This is a feature that enables type inference and transform of the blueprint parameters, and the way you define the parameter type is a bit different. Rather than defining the type of the parameters as part of the factory function, you instead provide a separate `defineParams` options. This is a function that takes the parameters as a single argument, and must then return the parameters wrapped with the `createExtensionBlueprintParams` function. + +The following is an example of how one might define a blueprint where the parameters make use of inferred types: + +```ts +export interface MyWidgetBlueprintParams { + defaultOptions: T; + elementFactory(options: T): JSX.Element; +} + +export const MyWidgetBlueprint = createExtensionBlueprint({ + kind: 'my-widget', + attachTo: { id: 'page:my-plugin', input: 'widgets' }, + output: [coreExtensionData.reactElement], + defineParams(params: MyWidgetBlueprintParams) { + return createExtensionBlueprintParams(params); + }, + // Note that we no longer define the parameters type here, they are inferred from the defineParams function + factory(params) { + return [ + coreExtensionData.reactElement( + , + ), + ]; + }, +}); +``` + +If you happen to ask yourself, "why can't I just define type parameters on the factory function instead?", this is a limitation in the TypeScript type system. We could technically support that in the blueprint definition, but there would be no way for that logic to be carried forward to the blueprint `.make` and `.makeWithOverrides` methods. + ### Blueprint-specific extension data references In some cases you may want to define and provide [extension data reference](./20-extensions.md#extension-data-references) that are specific to your blueprint. In the above example we might want to forward the `title` as data for example, rather than encapsulating it into the `MyWidgetContainer` component. This gives the parent extension more flexibility in the rendering for our example widget extensions. @@ -108,7 +185,7 @@ To do that, we create a new extension data reference for our widget title. This ```tsx export interface MyWidgetBlueprintParams { - defaultTitle: string; + title: string; element: JSX.Element; } @@ -127,7 +204,7 @@ export const MyWidgetBlueprint = createExtensionBlueprint({ output: [widgetTitleRef, coreExtensionData.reactElement], factory(params: MyWidgetBlueprintParams, { config }) { return [ - widgetTitleRef(config.title ?? params.defaultTitle), + widgetTitleRef(config.title ?? params.title), coreExtensionData.reactElement(params.element), ]; }, diff --git a/docs/frontend-system/architecture/25-extension-overrides.md b/docs/frontend-system/architecture/25-extension-overrides.md index faaf446f41..5e684476c8 100644 --- a/docs/frontend-system/architecture/25-extension-overrides.md +++ b/docs/frontend-system/architecture/25-extension-overrides.md @@ -2,12 +2,9 @@ id: extension-overrides title: Frontend Extension Overrides sidebar_label: Extension Overrides -# prettier-ignore description: Frontend extension overrides --- -> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** - ## Introduction An important customization point in the frontend system is the ability to override existing extensions. It can be used for anything from slight tweaks to the extension logic, to completely replacing an extension with a custom implementation. While extensions are encouraged to make themselves configurable, there are many situations where you need to override an extension to achieve the desired behavior. The ability to override extensions should be kept in mind when building plugins, and can be a powerful tool to allow for deeper customizations without the need to re-implement large parts of the plugin. @@ -90,7 +87,7 @@ const exampleExtension = PageBlueprint.make({ params: { loader: () => import('./components/ExamplePage').then(m => ), - defaultPath: '/example', + path: '/example', }, }); ``` @@ -319,7 +316,7 @@ import { const customSearchPage = PageBlueprint.make({ params: { - defaultPath: '/search', + path: '/search', loader: () => import('./CustomSearchPage').then(m => ), }, diff --git a/docs/frontend-system/architecture/30-references.md b/docs/frontend-system/architecture/30-references.md index 24a9e5df2a..93429802d6 100644 --- a/docs/frontend-system/architecture/30-references.md +++ b/docs/frontend-system/architecture/30-references.md @@ -2,12 +2,9 @@ id: references title: Value References sidebar_label: Value References -# prettier-ignore description: Value References --- -> **NOTE: The new frontend system is in alpha and is only supported by a small number of plugins.** - + +If you don't see your profile picture and name, check that you followed all of the steps in [the authentication tutorial](../../getting-started/config/authentication.md). If you have, search for similar issues on [the Discord server](https://discord.gg/backstage-687207715902193673). diff --git a/docs/golden-path/create-app/npx-create-app.md b/docs/golden-path/create-app/npx-create-app.md new file mode 100644 index 0000000000..8ee016f41f --- /dev/null +++ b/docs/golden-path/create-app/npx-create-app.md @@ -0,0 +1,117 @@ +--- +id: npx-create-app +title: '001 - Scaffolding' +--- + +Audience: Developers and Admins + +:::note Note +It is not required, although recommended to have a basic understanding of [Yarn](https://www.pluralsight.com/guides/yarn-a-package-manager-for-node-js) and [npm](https://docs.npmjs.com/about-npm) before starting this guide. +::: + +## Summary + +This guide walks through how to get started creating your very own Backstage customizable app. This is the first step in evaluating, developing on, or demoing Backstage. + +By the end of this guide, you will have a standalone Backstage installation running locally with a `SQLite` database and demo content. + +:::caution Organization customization + +To be clear, this is not a production-ready installation, and it does not contain information specific to your organization. You will learn how to customize Backstage for your use case through this guide. + +::: + +## Prerequisites + +This guide also assumes a basic understanding of working on a Linux based operating system and have some experience with the terminal, specifically, these commands: `npm`, `yarn`. + +- Access to a Unix-based operating system, such as Linux, macOS or + [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) +- A GNU-like build environment available at the command line. + For example, on Debian/Ubuntu you will want to have the `make` and `build-essential` packages installed. + On macOS, you will want to have run `xcode-select --install` to get the XCode command line build tooling in place. +- An account with elevated rights to install the dependencies +- `curl` or `wget` installed +- Node.js [Active LTS Release](../../overview/versioning-policy.md#nodejs-releases) installed using one of these + methods: + - Using `nvm` (recommended) + - [Installing nvm](https://github.com/nvm-sh/nvm#install--update-script) + - [Install and change Node version with nvm](https://nodejs.org/en/download/package-manager/#nvm) + - Node 20 is a good starting point, this can be installed using `nvm install lts/iron` + - [Binary download](https://nodejs.org/en/download/) + - [Package manager](https://nodejs.org/en/download/package-manager/) + - [Using NodeSource packages](https://github.com/nodesource/distributions/blob/master/README.md) +- `yarn` [Installation](https://yarnpkg.com/getting-started/install) + - Backstage currently uses Yarn 4.4.1, once you've ran `corepack enable` you'll want to then run `yarn set version 4.4.1` +- `git` [installation](https://github.com/git-guides/install-git) + +## Scaffold your new Backstage app + +## 1. Create your Backstage App + +To scaffold your new Backstage app, we'll be running an interactive command. Before you run the command, you should open a terminal and move your current working directory somewhere you're comfortable creating a new directory. + +The wizard for this command will ask what name you want to have for your new app. That name will match the folder that we create for you. + +When you run the command, you'll see an output like this. + +![create app](../../assets/getting-started/create-app-output.png) + +And when it finishes, you'll have a working Backstage app (with example data)! + +Now, that we know what it does, let's actually scaffold some code! + +```bash +npx @backstage/create-app@latest +``` + +This may take a few minutes to fully install everything. Don't stress if the loading seems to be spinning nonstop, there's a lot going on in the background. + +:::note + +If this fails on the `yarn install` step, it's likely that you will need to install some additional dependencies which are used to configure `isolated-vm`. You can find out more in their [requirements section](https://github.com/laverdet/isolated-vm#requirements), and then run `yarn install` manually again after you've completed those steps. + +::: + +## Structure of your app + +### General folder structure + +Below is a simplified layout of the files and folders generated when creating an app. + +``` +app +├── app-config.yaml +├── catalog-info.yaml +├── package.json +└── packages +   ├── app +   └── backend +``` + +- **app-config.yaml**: Main configuration file for the app. See + [Configuration](https://backstage.io/docs/conf/) for more information. +- **catalog-info.yaml**: Catalog Entities descriptors. See + [Descriptor Format of Catalog Entities](https://backstage.io/docs/features/software-catalog/descriptor-format) + to get started. +- **package.json**: Root package.json for the project. _Note: Be sure that you + don't add any npm dependencies here as they probably should be installed in + the intended workspace rather than in the root._ +- **packages/**: Lerna leaf packages or "workspaces". Everything here is going + to be a separate package, managed by lerna. +- **packages/app/**: A fully functioning Backstage frontend app that acts as a + good starting point for you to get to know Backstage. +- **packages/backend/**: We include a backend that helps power features such as + [Authentication](https://backstage.io/docs/auth/), + [Software Catalog](https://backstage.io/docs/features/software-catalog/), + [Software Templates](https://backstage.io/docs/features/software-templates/) + and [TechDocs](https://backstage.io/docs/features/techdocs/) + amongst other things. + +## Common Issues + +- App is not running on port X: Backstage uses ports `3000` and `7007` as its default frontend and backend ports. Make sure that your commands haven't exited with errors. For remote or containerized setups, make sure those ports above are accessible. + +## Next Steps + +Now that you have a scaffolded app, let's learn how to start it locally for development! diff --git a/docs/golden-path/plugins/backend/001-first-steps.md b/docs/golden-path/plugins/backend/001-first-steps.md new file mode 100644 index 0000000000..1850ba52c1 --- /dev/null +++ b/docs/golden-path/plugins/backend/001-first-steps.md @@ -0,0 +1,55 @@ +--- +id: 001-first-steps +sidebar_label: 001 - Scaffolding the plugin +title: How to scaffold a new plugin? +--- + +# Scaffolding a new plugin + + + +## `yarn new` + +A new, bare-bones backend plugin package can be created by issuing the following +command in your Backstage repository's root directory and selecting `backend-plugin`: + +```sh +yarn new +``` + +You will be asked to supply a name for the plugin. This is an identifier that +will be part of the NPM package name, so make it short and containing only +lowercase characters separated by dashes, for our example, you should provide `todo`. For plugins you may write in the future, this should be an easy to remember indicator of what this plugins does, like if it's a +package that adds an integration with a system named Carmen, you would want to name it `carmen`. + +This will create a new NPM package with a package name something like `@internal/plugin-carmen-backend`, depending on the other flags passed to the `new` command, and your settings for the `new` command in your root `package.json`. For future reference, we also support additional flags and configuration. Learn more at [the CLI docs](../../../tooling/cli/03-commands.md#new). + +Creating the plugin will take a little while, so be patient. If it runs with no issues, it will run the initial installation and build commands, so that your package is ready to be hacked on! + +Once the commands complete, you should see a new folder `plugins/todo-backend` with content like the below tree: + +``` +/ <- your Backstage app's root directory + /plugins/ + /todo-backend/ + package.json + README.md + eslintrc.js + /dev/ + index.ts + /src/ + plugin.ts + index.ts + router.ts + /services/ + /TodoListService/ + TodoListService.ts + types.ts + index.ts +``` + + + +### FAQs + + diff --git a/docs/golden-path/plugins/backend/002-poking-around.md b/docs/golden-path/plugins/backend/002-poking-around.md new file mode 100644 index 0000000000..35de3c4d47 --- /dev/null +++ b/docs/golden-path/plugins/backend/002-poking-around.md @@ -0,0 +1,34 @@ +--- +id: 002-poking-around +sidebar_label: 002 - Poking around +title: 002 - Poking around +--- + +## Default plugin functionality + +By default, that plugin that you just created hosts a simple todo list application. It exposes an HTTP API at `http://localhost:7007/api/todo/todos` that allows you to create TODOs, list existing TODOs, and get a specific TODO. It stores those TODOs in memory, which means that you would lose all of your TODOs if you restarted your application. It also allows you to tag TODOs with a Software Catalog entity, which will be useful for our frontend integration. + +To make this plugin production ready, we'll need to adjust a few things, + +1. Write our TODOs to a database so they don't get lost on restart. +2. Write some proper tests to make sure everything works the way we expect. +3. Get user feedback. + +## Testing locally + +Before we jump in to making this plugin ready to ship, let's walk through how to run it locally. If you open your backend plugin's manifest (`plugins/todo-backend/package.json`), and look at the `scripts` section, you'll notice a few important commands. The ones relevant to use right now are + +1. `yarn start` - Starts a local development server using the content in `dev/index.ts` as the backend. +2. `yarn test` - Runs all of the tests for your backend plugin. + +If you run `yarn start`, you should see a custom backend for just your plugin start up. This will simplify plugin development and iteration for you or your team by easily testing out new features in just your plugin - just make sure you add what you need to the global `packages/backend`. The important log for us to look for is + +``` +2025-06-08T16:14:53.229Z rootHttpRouter info Listening on :7007 +``` + +This indicates that your HTTP server is up and running and we can start sending test HTTP requests. Grab your favorite HTTP client and let's get testing! If you aren't sure what to use, I'd recommend the `humao.rest-client` VSCode extension which can easily be run in VSCode itself with very little extra set up. + +``` + +``` diff --git a/docs/golden-path/plugins/backend/meta.md b/docs/golden-path/plugins/backend/__meta__.md similarity index 76% rename from docs/golden-path/plugins/backend/meta.md rename to docs/golden-path/plugins/backend/__meta__.md index 4507a934d5..e261a8f970 100644 --- a/docs/golden-path/plugins/backend/meta.md +++ b/docs/golden-path/plugins/backend/__meta__.md @@ -88,44 +88,6 @@ After verifying everything, introduce the problem of persistence - the todos are Saving values to the database. Writing a migrations file. Plumbing through the database service. -## Integrations - -Now that our plugin is ready for prime time, let's see how we can really leverage the rest of the Backstage ecosystem. Backstage provides a set of core features out of the box, namely, the Software Catalog, Search, Permissions, and Notifications. - -### Catalog - -We want to show our todos as separate Catalog entities. How can we make this happen? - -### Search - -We want to make our todos searchable. - -### Permissions - -We only want users to be able to find their own todos. - -### Notifications - -We want to set an alarm time for todos that sends a notification when the time is met. - ## SCM Integrations Our users love the new plugin, and now they want it to automatically fetch todos from their source code. - -## Additional Resources and Further Reading - -- **Real-world Implementations and Lessons** - - - [Case studies and examples from the community](https://github.com/backstage/community#newsletters). - - Best practices derived from mature implementations. - - [Existing open-source community-maintained plugins](https://github.com/backstage/community-plugins). - -- **Resource Compendium** - - - [Backstage Glossary](https://backstage.io/docs/references/glossary) of key terms. - - Recommended readings and tools for advanced developers. - -- **Certification and Learning Pathways** - - Pathways to deepen your understanding and expertise in plugin development for Backstage. - -Stay tuned for detailed exploration and guidance in each of these modules. We're excited to accompany you on your plugin development journey! diff --git a/docs/golden-path/plugins/backend/recap.md b/docs/golden-path/plugins/backend/recap.md new file mode 100644 index 0000000000..94eca8fafe --- /dev/null +++ b/docs/golden-path/plugins/backend/recap.md @@ -0,0 +1,23 @@ +## Learning Recap + +With this golden path, you learned how to, + + + +## Additional Resources and Further Reading + +- **Real-world Implementations and Lessons** + + - [Case studies and examples from the community](https://github.com/backstage/community#newsletters). + - Best practices derived from mature implementations. + - [Existing open-source community-maintained plugins](https://github.com/backstage/community-plugins). + +- **Resource Compendium** + + - [Backstage Glossary](https://backstage.io/docs/references/glossary) of key terms. + - Recommended readings and tools for advanced developers. + +- **Certification and Learning Pathways** + - Pathways to deepen your understanding and expertise in plugin development for Backstage. + +Stay tuned for detailed exploration and guidance in each of these modules. We're excited to accompany you on your plugin development journey! diff --git a/docs/golden-path/plugins/backend/todo.http b/docs/golden-path/plugins/backend/todo.http new file mode 100644 index 0000000000..932dcb76e4 --- /dev/null +++ b/docs/golden-path/plugins/backend/todo.http @@ -0,0 +1,12 @@ +POST http://localhost:7007/api/todo/todos +Content-Type: application/json + +{ + "title": "My First TODO" +} + +### + +GET http://localhost:7007/api/todo/todos + +### \ No newline at end of file diff --git a/docs/golden-path/plugins/index.md b/docs/golden-path/plugins/index.md new file mode 100644 index 0000000000..616c2c0c36 --- /dev/null +++ b/docs/golden-path/plugins/index.md @@ -0,0 +1,33 @@ +--- +id: index +sidebar_label: Backstage Plugins! +title: How to create plugins with Backstage +--- + +### Prerequisites + +- We expect that you have finished the create-app golden path. + +### Scenario + +You have an awesome idea to create a todo list tracker in your Backstage instance at an upcoming company hackathon. Backstage is supposed to unify all of our information after all, it should track future tasks to complete as well! + +Many of the great Backstage plugins started in a similar way, a developer noticed that others on their team or in the company were: + +- Wasting time manually compiling spreadsheets filled with error-prone data +- Spending hours every week trying to find that one specific link from that one site +- A million other problems that impact developer flow or are just toil + + And they decided to create a shared plugin in Backstage to solve that problem. + +This guide will teach you how to deliver high-quality Backstage plugins with confidence. Both so you can impress everyone at the hackathon and set yourself up for success when you inevitably are asked to make your plugin production-ready. + +### Structure + +To start, this guide will walk through creating a backend plugin. You'll get your feet wet working with an HTTP API, a database and the Backstage backend system. Then, we'll move to the frontend, where we'll show you how to create a new page that's visible to your Backstage users as well as how to call your API. Finally, we'll walk through some common integrations you may want to consider as you write plugins. + +### Next Steps + +- [Why build plugins?](./why-build-plugins.md) +- [Sustainable plugin development](./sustainable-plugin-development.md) +- [Golden path: Backend plugins](./backend/001-first-steps.md) diff --git a/docs/golden-path/plugins/integrations/__meta__.md b/docs/golden-path/plugins/integrations/__meta__.md new file mode 100644 index 0000000000..2d8df8136e --- /dev/null +++ b/docs/golden-path/plugins/integrations/__meta__.md @@ -0,0 +1,19 @@ +## Integrations + +Now that our plugin is ready for prime time, let's see how we can really leverage the rest of the Backstage ecosystem. Backstage provides a set of core features out of the box, namely, the Software Catalog, Search, Permissions, and Notifications. + +### Catalog + +We want to show our todos as separate Catalog entities. How can we make this happen? + +### Search + +We want to make our todos searchable. + +### Permissions + +We only want users to be able to find their own todos. + +### Notifications + +We want to set an alarm time for todos that sends a notification when the time is met. diff --git a/docs/golden-path/plugins/sustainable-plugin-development.md b/docs/golden-path/plugins/sustainable-plugin-development.md new file mode 100644 index 0000000000..82d529d6e1 --- /dev/null +++ b/docs/golden-path/plugins/sustainable-plugin-development.md @@ -0,0 +1,29 @@ +--- +id: sustainable-plugin-development +sidebar_label: Sustainable plugin development +title: Sustainably developing plugins in Backstage +--- + +Plugins are not created in a vacuum, they generally solve a customer ask, be that + +- a business problem, like showing cloud spend +- a new integration, like showing data from an external vendor such as Pagerduty +- a developer pain point, like organizing information from disjoint or disorganized systems. + +To ensure that your plugin lives the test of time, you'll need to figure out how to keep it up-to-date, + +### Finding your stakeholders + + + +### Iterating on your plugin + +In many cases, your first version of a plugin will cut a few corners - this is a good sign, you're more focused on delivering a strong use case to continue development than over-indexing on your initial code. It may be temporary after all, if you don't get the response you're looking for! + +So, how do you decide when you should iterate on your plugin? + + + +### Ensuring the success of your plugin + + diff --git a/docs/golden-path/plugins/why-build-plugins.md b/docs/golden-path/plugins/why-build-plugins.md new file mode 100644 index 0000000000..b0e1be0a98 --- /dev/null +++ b/docs/golden-path/plugins/why-build-plugins.md @@ -0,0 +1,33 @@ +--- +id: why-build-plugins +sidebar_label: Why build plugins? +title: Introduction to the Value and Impact of Plugins within Backstage +--- + +Backstage plugins are essential components that enable the integration of various tools and services into a unified developer portal. Here’s a detailed look at why building plugins for Backstage can be highly beneficial: + +## Enhancing Developer Productivity + +Plugins in Backstage centralize and simplify access to tools, reducing the time developers spend switching between different systems. By providing a consistent interface and user experience, plugins minimize cognitive load and streamline workflows, allowing developers to focus more on coding and less on tool management. Plugins can leverage platform APIs and reusable UI components to integrate external data and services seamlessly. + +## Customizable and Extensible Platform + +Backstage's plugin architecture is designed to be highly flexible, enabling the integration of nearly any infrastructure or software development tool. This extensibility allows organizations to tailor Backstage to meet their specific needs, integrating internal tools, third-party services, and other custom functionalities seamlessly. For detailed guidelines on plugin development, refer to the [Backstage Plugin Development documentation](https://backstage.io/docs/plugins/plugin-development/). + +## Improved Collaboration and Knowledge Sharing + +Plugins facilitate better collaboration among teams by consolidating documentation, code repositories, CI/CD pipelines, and monitoring tools in one place. This centralization makes it easier for team members to find information, share insights, and collaborate on projects, enhancing overall team productivity and coherence. + +## Consistency and Best Practices + +By adhering to Backstage’s design guidelines, plugins ensure a consistent user experience across the platform. This consistency helps in maintaining usability and reducing the learning curve for new users, promoting the adoption of best practices within development teams. More details can be found in the [Introduction to Plugins](https://backstage.io/docs/plugins/) section. + +## Scalability and Maintenance + +Backstage plugins are designed to be modular and independent, allowing for easy updates and maintenance without affecting the overall system. This modularity supports horizontal scalability, where each plugin can be scaled independently according to the needs of the application, ensuring robust performance and reliability. For more on structuring and connecting plugins, see the [Structure of a Plugin](https://backstage.io/docs/plugins/structure-of-a-plugin) documentation. + +## Community and Ecosystem Growth + +Developing and contributing plugins to the Backstage community helps in expanding the ecosystem. Open-source contributions foster innovation and collaboration, allowing developers to leverage a wide range of existing plugins and avoid reinventing the wheel. This collaborative environment accelerates the development of new features and enhances the overall value of the Backstage platform. + +Building plugins for Backstage significantly enhances developer productivity, promotes best practices, supports scalability, and fosters community growth. These plugins transform Backstage into a comprehensive developer portal that can adapt to the unique needs of any organization. For more detailed information, refer to the [Backstage Plugin Development documentation](https://backstage.io/docs/plugins/plugin-development/) and the [Introduction to Plugins](https://backstage.io/docs/plugins/). diff --git a/docs/integrations/aws-codecommit/locations.md b/docs/integrations/aws-codecommit/locations.md index 35187b1b89..28e77769b2 100644 --- a/docs/integrations/aws-codecommit/locations.md +++ b/docs/integrations/aws-codecommit/locations.md @@ -2,7 +2,6 @@ id: locations sidebar_label: Locations title: Amazon Web Services CodeCommit Locations -# prettier-ignore description: Setting up an integration with Amazon Web Services CodeCommit --- diff --git a/docs/integrations/aws-s3/discovery.md b/docs/integrations/aws-s3/discovery.md index fa1eb017fc..fcba5ca04f 100644 --- a/docs/integrations/aws-s3/discovery.md +++ b/docs/integrations/aws-s3/discovery.md @@ -2,7 +2,6 @@ id: discovery title: AWS S3 Discovery sidebar_label: Discovery -# prettier-ignore description: Automatically discovering catalog entities from an AWS S3 Bucket --- diff --git a/docs/integrations/aws-s3/locations.md b/docs/integrations/aws-s3/locations.md index 9bac28f906..3ed6af62fe 100644 --- a/docs/integrations/aws-s3/locations.md +++ b/docs/integrations/aws-s3/locations.md @@ -2,7 +2,6 @@ id: locations sidebar_label: Locations title: Amazon Web Services S3 Locations -# prettier-ignore description: Setting up an integration with Amazon Web Services S3 --- diff --git a/docs/integrations/azure-blobStorage/discovery.md b/docs/integrations/azure-blobStorage/discovery.md index 32612daf75..bed97441f9 100644 --- a/docs/integrations/azure-blobStorage/discovery.md +++ b/docs/integrations/azure-blobStorage/discovery.md @@ -2,7 +2,6 @@ id: discovery title: Azure Blob Storage Discovery sidebar_label: Discovery -# prettier-ignore description: Automatically discovering catalog entities from an Azure Blob Storage account --- diff --git a/docs/integrations/azure-blobStorage/locations.md b/docs/integrations/azure-blobStorage/locations.md index 38d8555c2e..abe2a238ba 100644 --- a/docs/integrations/azure-blobStorage/locations.md +++ b/docs/integrations/azure-blobStorage/locations.md @@ -2,7 +2,6 @@ id: locations sidebar_label: Locations title: Azure Blob Storage account Locations -# prettier-ignore description: Setting up an integration with Azure Blob Storage account --- diff --git a/docs/integrations/azure/discovery.md b/docs/integrations/azure/discovery.md index b749f8e9ed..a4584ef338 100644 --- a/docs/integrations/azure/discovery.md +++ b/docs/integrations/azure/discovery.md @@ -2,7 +2,6 @@ id: discovery title: Azure DevOps Discovery sidebar_label: Discovery -# prettier-ignore description: Automatically discovering catalog entities from repositories in an Azure DevOps organization --- diff --git a/docs/integrations/azure/locations.md b/docs/integrations/azure/locations.md index 61c54287c9..3ea180f5bd 100644 --- a/docs/integrations/azure/locations.md +++ b/docs/integrations/azure/locations.md @@ -2,7 +2,6 @@ id: locations title: Azure DevOps Locations sidebar_label: Locations -# prettier-ignore description: Integrating source code stored in Azure DevOps into the Backstage catalog --- diff --git a/docs/integrations/azure/org.md b/docs/integrations/azure/org.md index 58c6c9f889..efcd8ae612 100644 --- a/docs/integrations/azure/org.md +++ b/docs/integrations/azure/org.md @@ -2,7 +2,6 @@ id: org title: Microsoft Entra Tenant Data sidebar_label: Org Data -# prettier-ignore description: Importing users and groups from Microsoft Entra ID into Backstage --- diff --git a/docs/integrations/bitbucketCloud/discovery.md b/docs/integrations/bitbucketCloud/discovery.md index 9560c5e06b..e0fab954ac 100644 --- a/docs/integrations/bitbucketCloud/discovery.md +++ b/docs/integrations/bitbucketCloud/discovery.md @@ -2,7 +2,6 @@ id: discovery title: Bitbucket Cloud Discovery sidebar_label: Discovery -# prettier-ignore description: Automatically discovering catalog entities from repositories in Bitbucket Cloud --- diff --git a/docs/integrations/bitbucketCloud/locations.md b/docs/integrations/bitbucketCloud/locations.md index 9b08a79c63..f0a032353c 100644 --- a/docs/integrations/bitbucketCloud/locations.md +++ b/docs/integrations/bitbucketCloud/locations.md @@ -2,7 +2,6 @@ id: locations title: Bitbucket Cloud Locations sidebar_label: Locations -# prettier-ignore description: Integrating source code stored in Bitbucket Cloud into the Backstage catalog --- diff --git a/docs/integrations/bitbucketServer/discovery.md b/docs/integrations/bitbucketServer/discovery.md index 36282b1f48..350bc33aed 100644 --- a/docs/integrations/bitbucketServer/discovery.md +++ b/docs/integrations/bitbucketServer/discovery.md @@ -2,7 +2,6 @@ id: discovery title: Bitbucket Server Discovery sidebar_label: Discovery -# prettier-ignore description: Automatically discovering catalog entities from repositories in Bitbucket Server --- @@ -67,6 +66,7 @@ catalog: projectKey: '^apis-.*$' # optional; RegExp repoSlug: '^service-.*$' # optional; RegExp skipArchivedRepos: true # optional; boolean + validateLocationsExist: false # optional; boolean schedule: # same options as in SchedulerServiceTaskScheduleDefinition # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } @@ -87,6 +87,10 @@ catalog: Regular expression used to filter results based on the repo slug. - **`skipArchivedRepos`** _(optional)_: Boolean flag to filter out archived repositories. +- **`validateLocationsExist`** _(optional)_: + Defaults to `false`. + Whether to validate locations that exist before emitting them. + This option avoids generating locations for catalog info files that do not exist in the source repository. - **`schedule`**: - **`frequency`**: How often you want the task to run. The system does its best to avoid overlapping invocations. diff --git a/docs/integrations/bitbucketServer/locations.md b/docs/integrations/bitbucketServer/locations.md index 7ff19b8b27..0c8b0e16b4 100644 --- a/docs/integrations/bitbucketServer/locations.md +++ b/docs/integrations/bitbucketServer/locations.md @@ -2,7 +2,6 @@ id: locations title: Bitbucket Server Locations sidebar_label: Locations -# prettier-ignore description: Integrating source code stored in Bitbucket Server into the Backstage catalog --- diff --git a/docs/integrations/datadog-rum/installation.md b/docs/integrations/datadog-rum/installation.md index 6659bec182..5b4fe8bd40 100644 --- a/docs/integrations/datadog-rum/installation.md +++ b/docs/integrations/datadog-rum/installation.md @@ -2,7 +2,6 @@ id: installation title: Datadog RUM Installation sidebar_label: Installation -# prettier-ignore description: Adding Datadog Real User Monitoring (RUM) to Your App --- diff --git a/docs/integrations/gerrit/discovery.md b/docs/integrations/gerrit/discovery.md index dbbc7ba7a4..06fb144e50 100644 --- a/docs/integrations/gerrit/discovery.md +++ b/docs/integrations/gerrit/discovery.md @@ -2,7 +2,6 @@ id: discovery title: Gerrit Discovery sidebar_label: Discovery -# prettier-ignore description: Automatically discovering catalog entities from Gerrit repositories --- diff --git a/docs/integrations/gitea/discovery.md b/docs/integrations/gitea/discovery.md index 6cae169b58..ce8ad9d360 100644 --- a/docs/integrations/gitea/discovery.md +++ b/docs/integrations/gitea/discovery.md @@ -30,7 +30,7 @@ backend.add(import('@backstage/plugin-catalog-backend-module-gitea')); ## Configuration -To use the discovery processor, you'll need a Gitea integration +To use the discovery provider, you'll need a Gitea integration [set up](locations.md). Then you can add any number of providers. ```yaml diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index 01567a7191..f245e960ea 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -2,8 +2,7 @@ id: discovery title: GitHub Discovery sidebar_label: Discovery -# prettier-ignore -description: Automatically discovering catalog entities from repositories in a GitHub organization +description: Automatically discovering catalog entities from repositories in a GitHub organization or App --- :::info @@ -13,8 +12,8 @@ This documentation is written for [the new backend system](../../backend-system/ ## GitHub Provider The GitHub integration has a discovery provider for discovering catalog -entities within a GitHub organization. The provider will crawl the GitHub -organization and register entities matching the configured path. This can be +entities within a GitHub organization or App. The provider will crawl the GitHub +organization or App and register entities matching the configured path. This can be useful as an alternative to static locations or manually adding things to the catalog. This is the preferred method for ingesting entities into the catalog. @@ -38,32 +37,149 @@ backend.add(import('@backstage/plugin-catalog-backend-module-github')); ## Events Support -The catalog module for GitHub comes with events support enabled. -This will make it subscribe to its relevant topics (`github.push`, -`github.repository`) and expects these events to be published -via the `EventsService`. +The catalog module for GitHub comes with events support enabled. This will make it subscribe to its relevant topics (`github.push`, `github.repository`) and expects these events to be published via the `EventsService`. -Additionally, you should install the -[event router by `events-backend-module-github`](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-github/README.md) -which will route received events from the generic topic `github` to more specific ones -based on the event type (e.g., `github.push`). +### Prerequisites -In order to receive Webhook events by GitHub, you have to decide how you want them -to be ingested into Backstage and published to its `EventsService`. -You can decide between the following options (extensible): +There are two Prerequisites to use the builtin events support: -- [via HTTP endpoint](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) -- [via an AWS SQS queue](https://github.com/backstage/backstage/tree/master/plugins/events-backend-module-aws-sqs/README.md) +1. Creating a webhook in GitHub +2. Installing and configuring `@backstage/plugin-events-backend-module-github` + +#### Configure Webhooks in GitHub You can check the official docs to [configure your webhook](https://docs.github.com/en/developers/webhooks-and-events/webhooks/creating-webhooks) and to [secure your request](https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks). -The webhook(s) will need to be configured to react to `push` and -`repository` events. +The webhook(s) will need to be configured to react to `push` and `repository` events. -Certain actions like `transferred` by the `repository` event type -will not be supported when you use repository webhooks. -Please check the GitHubs documentation for these event types and -its actions. +:::note + +To receive the `repository.transferred` event, the new owner account must have the GitHub App installed, and the App must be subscribed to `repository` events. This event is only sent to the account where the ownership is transferred. + +::: + +When creating the webhook in GitHub the "Payload URL" will looks something along these lines: `https:///api/events/http/github` and the "Content Type" should be `application/json`. + +The GitHub Webhooks UI will send a trial event to validate it can connect when you save your new Webhook. It is possible to retry this trial event if it fails and you want to send it again. Additionally there is a Recent Deliveries tab you can use to validate that the events are being fired should you need to do any later troubleshooting. + +#### Install and Configure GitHub Events Module + +In order to use the built-in events support you'll need to install and configure `@backstage/plugin-events-backend-module-github`. This module will route received events from the generic topic `github` to more specific ones based on the event type (e.g., `github.push`). These more specific events are what the builtin events support is expecting. + +First we need to add the package: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-events-backend-module-github +``` + +Then we need to add it to your backend: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-events-backend')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-events-backend-module-github')); +/* highlight-add-end */ +``` + +Finally you will want to configure it: + +```yaml title="app-config.yaml +events: + modules: + github: + webhookSecret: ${GITHUB_WEBHOOK_SECRET} +``` + +Though this last step is technically optional, you'll want to include it to be sure the events being received are from GitHub and not from an external bad actor. + +The value of `${GITHUB_WEBHOOK_SECRET}` in this example would be the same that you used when creating the webhook on GitHub. + +### Events Setup using HTTP endpoint + +Using the HTTP endpoint for events just requires adding some additional configuration to your `app-config.yaml` as it is a built in feature of the Events backend, here's what that would look like: + +```yaml title="app-config.yaml +events: + http: + topics: + - github +``` + +This will then expose an endpoint like this: + +### Events Setup using AWS SQS module + +Alternatively to using the HTTP endpoint you can use the AWS SQS module, here's how. + +First we need to add the package: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugins-events-backend-module-aws-sqs +``` + +Then we need to add it to your backend: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-events-backend')); +backend.add(import('@backstage/plugin-events-backend-module-github')); +/* highlight-add-start */ +backend.add(import('@backstage/plugins-events-backend-module-aws-sqs')); +/* highlight-add-end */ +``` + +Finally you will want to configure it: + +```yaml title="app-config.yaml +events: + modules: + awsSqs: + awsSqsConsumingEventPublisher: + topics: + github: + queue: + url: 'https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue' + region: us-east-2 +``` + +The [AWS SQS module `README`](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-aws-sqs/README.md#configuration) has more details on the configuration options, the example above includes on the required options. + +### Events Setup using Google Pub/Sub module + +Alternatively to using the HTTP endpoint you can use the Google Pub/Sub module, here's how. + +First we need to add the package: + +```bash title="from your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-events-backend-module-google-pubsub +``` + +Then we need to add it to your backend: + +```ts title="in packages/backend/src/index.ts" +backend.add(import('@backstage/plugin-events-backend')); +backend.add(import('@backstage/plugin-events-backend-module-github')); +/* highlight-add-start */ +backend.add(import('@backstage/plugin-events-backend-module-google-pubsub')); +/* highlight-add-end */ +``` + +Finally you will want to configure it: + +```yaml title="app-config.yaml +events: + modules: + googlePubSub: + googlePubSubConsumingEventPublisher: + subscriptions: + # A unique key for your subscription, to be used in logging and metrics + mySubscription: + # The fully qualified name of the subscription + subscriptionName: 'projects/my-google-project/subscriptions/github-enterprise-events' + # The event system topic to transfer to. This can also be just a plain string + targetTopic: 'github.{{ event.attributes.x-github-event }}' +``` + +The [Google Pub/Sub module `README`](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-google-pubsub/README.md#configuration) has more details on the configuration options, the example above includes on the required options. ## Configuration @@ -94,6 +210,8 @@ catalog: filters: # optional filters branch: 'develop' # optional string repository: '.*' # optional Regex + pageSizes: + repositories: 25 wildcardProviderId: organization: 'new-org' # string catalogPath: '/groups/**/*.yaml' # this will search all folders for files that end in .yaml @@ -136,7 +254,7 @@ catalog: catalogPath: '/catalog-info.yaml' # string ``` -This provider supports multiple organizations via unique provider IDs. +This provider supports multiple organizations and apps via unique provider IDs. :::note Note @@ -172,9 +290,11 @@ If you do so, `default` will be used as provider ID. Whether to include archived repositories. Defaults to `false`. - **`host`** _(optional)_: The hostname of your GitHub Enterprise instance. It must match a host defined in [integrations.github](locations.md). -- **`organization`**: +- **`organization`** _(required, unless `app` is set)_: Name of your organization account/workspace. - If you want to add multiple organizations, you need to add one provider config each. + If you want to add multiple organizations, you need to add one provider config each or specify `app` instead. +- **`app`** _(required, unless `organization` is set)_: + ID of your GitHub App. - **`validateLocationsExist`** _(optional)_: Whether to validate locations that exist before emitting them. This option avoids generating locations for catalog info files that do not exist in the source repository. @@ -190,6 +310,10 @@ If you do so, `default` will be used as provider ID. The amount of time that should pass before the first invocation happens. - **`scope`** _(optional)_: `'global'` or `'local'`. Sets the scope of concurrency control. +- **`pageSizes`** _(optional)_: + Configure page sizes for GitHub GraphQL API queries. This can help prevent `RESOURCE_LIMITS_EXCEEDED` errors. + - **`repositories`** _(optional)_: + Number of repositories to fetch per page. Defaults to `25`. Reduce this value if hitting API resource limits. ## GitHub API Rate Limits diff --git a/docs/integrations/github/org.md b/docs/integrations/github/org.md index 3d0e0a4221..6526183f2d 100644 --- a/docs/integrations/github/org.md +++ b/docs/integrations/github/org.md @@ -2,7 +2,6 @@ id: org title: GitHub Organizational Data sidebar_label: Org Data -# prettier-ignore description: Importing users and groups from a GitHub organization into Backstage --- @@ -80,6 +79,10 @@ catalog: initialDelay: { seconds: 30 } frequency: { hours: 1 } timeout: { minutes: 50 } + pageSizes: + teams: 25 + teamMembers: 50 + organizationMembers: 50 - id: ghe githubUrl: https://ghe.mycompany.com orgs: ['internal-1', 'internal-2', 'internal-3'] @@ -95,6 +98,13 @@ Directly under the `githubOrg` is a list of configurations, each entry is a stru - `githubUrl`: The target that this provider should consume - `orgs` (optional): The list of the GitHub orgs to consume. If you only list a single org the generated group entities will use the `default` namespace, otherwise they will use the org name as the namespace. By default the provider will consume all accessible orgs on the given GitHub instance (support for GitHub App integration only). - `schedule`: The refresh schedule to use, matches the structure of [`SchedulerServiceTaskScheduleDefinitionConfig`](https://backstage.io/docs/reference/backend-plugin-api.schedulerservicetaskscheduledefinitionconfig/) +- `pageSizes` (optional): Configure page sizes for GitHub GraphQL API queries to prevent `RESOURCE_LIMITS_EXCEEDED` errors. You can configure the following page sizes: + + - `teams`: Number of teams to fetch per page when querying organization teams (default: 25) + - `teamMembers`: Number of team members to fetch per page when querying team members (default: 50) + - `organizationMembers`: Number of organization members to fetch per page (default: 50) + + Reducing page sizes will result in more API calls and slightly longer sync times, but will prevent API resource limits for organizations with large number of teams and members. ### Events Support @@ -169,6 +179,7 @@ const backend = createBackend(); backend.add(import('@backstage/plugin-catalog-backend')); +backend.add(import('@backstage/plugin-catalog-backend-module-github-org')); backend.add(githubOrgModule); backend.start(); diff --git a/docs/integrations/gitlab/discovery.md b/docs/integrations/gitlab/discovery.md index de35fbcc96..5e02c853fa 100644 --- a/docs/integrations/gitlab/discovery.md +++ b/docs/integrations/gitlab/discovery.md @@ -2,7 +2,6 @@ id: discovery title: GitLab Discovery sidebar_label: Discovery -# prettier-ignore description: Automatically discovering catalog entities from repositories in GitLab --- @@ -28,7 +27,7 @@ yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gitlab Then add the following to your backend initialization: -```ts title="packages/backend/src/index.ts +```ts title="packages/backend/src/index.ts" // optional if you want HTTP endpoints to receive external events // backend.add(import('@backstage/plugin-events-backend')); // optional if you want to use AWS SQS instead of HTTP endpoints to receive external events @@ -50,7 +49,7 @@ Further documentation: - [Events Plugin](https://github.com/backstage/backstage/tree/master/plugins/events-backend/README.md) - [GitLab Module for the Events Plugin](https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md) -### Installation with Legacy Backend System +### Installation with Legacy Backend System (skip if you are using Backstage v1.31.0 or later) #### Installation without Events Support @@ -152,8 +151,11 @@ catalog: skipForkedRepos: false # Optional. If the project is a fork, skip repository includeArchivedRepos: false # Optional. If project is archived, include repository group: example-group # Optional. Group and subgroup (if needed) to look for repositories. If not present the whole instance will be scanned + groupPattern: # Optional. Filters for groups based on a list of RegEx. Default, no filters. + - '^somegroup$' + - 'anothergroup' entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml` - projectPattern: '[\s\S]*' # Optional. Filters found projects based on provided patter. Defaults to `[\s\S]*`, which means to not filter anything + projectPattern: '[\s\S]*' # Optional. Filters found projects based on provided pattern. Defaults to `[\s\S]*`, which means to not filter anything excludeRepos: [] # Optional. A list of project paths that should be excluded from discovery, e.g. group/subgroup/repo. Should not start or end with a slash. schedule: # Same options as in SchedulerServiceTaskScheduleDefinition. Optional for the Legacy Backend System # supports cron, ISO duration, "human duration" as used in code diff --git a/docs/integrations/google-cloud-storage/locations.md b/docs/integrations/google-cloud-storage/locations.md index 1f0334ff17..99bba9feb7 100644 --- a/docs/integrations/google-cloud-storage/locations.md +++ b/docs/integrations/google-cloud-storage/locations.md @@ -2,7 +2,6 @@ id: locations sidebar_label: Locations title: Google Cloud Storage Locations -# prettier-ignore description: Setting up an integration with Google Cloud Storage --- diff --git a/docs/integrations/harness/locations.md b/docs/integrations/harness/locations.md index a3d0e2cfd4..a497dfa63b 100644 --- a/docs/integrations/harness/locations.md +++ b/docs/integrations/harness/locations.md @@ -30,4 +30,4 @@ check out https://developer.harness.io/docs/platform/automation/api/add-and-mana - `host`: The host of the Harness Code instance that you want to match on. - `token` (optional): The password or api token to authenticate with. -- `apiKey` (optional): The apiKey to authenticate with. +- `apiKey` (optional): The API key to authenticate with. diff --git a/docs/integrations/index.md b/docs/integrations/index.md index b090d6d77e..00463a810f 100644 --- a/docs/integrations/index.md +++ b/docs/integrations/index.md @@ -2,8 +2,7 @@ id: index title: Integrations sidebar_label: Overview -# prettier-ignore -description: Configuring Backstage to read or publish data with external providers using integrations +description: Configuring Backstage to read or publish data with external providers using integrations --- Integrations allow Backstage to read or publish data using external providers diff --git a/docs/integrations/ldap/org--old.md b/docs/integrations/ldap/org--old.md index 448e9bbed1..03862d8625 100644 --- a/docs/integrations/ldap/org--old.md +++ b/docs/integrations/ldap/org--old.md @@ -2,7 +2,6 @@ id: org--old title: LDAP Organizational Data sidebar_label: Org Data -# prettier-ignore description: Setting up ingestion of organizational data from LDAP --- diff --git a/docs/integrations/ldap/org.md b/docs/integrations/ldap/org.md index 9913cf0729..8adc81184a 100644 --- a/docs/integrations/ldap/org.md +++ b/docs/integrations/ldap/org.md @@ -2,7 +2,6 @@ id: org title: LDAP Organizational Data sidebar_label: Org Data -# prettier-ignore description: Setting up ingestion of organizational data from LDAP --- diff --git a/docs/landing-page/doc-landing-page.md b/docs/landing-page/doc-landing-page.md new file mode 100644 index 0000000000..cb1b889851 --- /dev/null +++ b/docs/landing-page/doc-landing-page.md @@ -0,0 +1,109 @@ +--- +id: doc-landing-page +title: Documentation +description: Documentation landing page. +--- + +## Understand, try, and administer Backstage + + + + + + + + + + + + + + +
    Understand BackstageTry BackstageAdministrationAdditional Features
    Learn about Backstage.

    + +
    Build a customizable Backstage app.
    + +
    Configure, Deploy, & Upgrade.

    + +
    Additional Backstage Features

    + +
    + +## Plugin Development, references, and how to contribute + + + + + + + + + + + + +
    Plugin DevelopmentReferencesContribute to Backstage
    Creating and Configuring Plugins

    + +
    Glossary, FAQ, and other reference material.
    + +
    Contributions are welcome and greatly appreciated!
    + +
    diff --git a/docs/notifications/index.md b/docs/notifications/index.md index 2af8879ac0..59ff2962ed 100644 --- a/docs/notifications/index.md +++ b/docs/notifications/index.md @@ -33,6 +33,12 @@ Example of use-cases: ## Installation +:::note + +As of the `1.42.0` release of Backstage, Notifications and Signals are installed as part of the default `@backstage/create-app` instance which means you won't need to follow the installations steps outlined here. The only exception to this is adding the [Notifications tab to User Settings](#user-specific-notification-settings) to allow managing these settings. + +::: + The following sections will walk you through the installation of the various parts of the Backstage Notification System. ### Add Notifications Backend @@ -158,6 +164,67 @@ You can customize the origin names shown in the UI by passing an object where th Each notification processor will receive its own row in the settings page, where the user can enable or disable notifications from that processor. +### Automatic notification cleanup + +Notifications are deleted automatically after a certain period of time to prevent the database from growing indefinitely +and to keep the user interface clean. The default retention period is set to 1 year, meaning that notifications older +than that will be deleted automatically. + +The retention period can be configured by setting the `notifications.retention` in the `app-config.yaml` file. + +```yaml +notifications: + retention: 1y +``` + +If the retention is set to false, notifications will not be automatically deleted. + +## Scaffolder Action + +:::note + +As of the `1.42.0` release of Backstage, the Notifications Scaffolder action is installed as part of the default `@backstage/create-app` instance which means you won't need to follow the installations steps outlined here. Feel free to skip to the [Basic Example](#basic-example). + +::: + +There is also a Scaffolder action that you can use to send a notification as part of your Software Template. + +First we need to add the backend package: + +```bash title="From your Backstage root directory" +yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-notifications +``` + +Then we need to add it to our backend: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); +// ... +backend.add( + import('@backstage/plugin-scaffolder-backend-module-notifications'), +); +``` + +### Basic Example + +Here's an example of how you can use it in your Software Template, more details and examples can be found in the "Installed actions" screen in your Backstage instances: + +```yaml title="template.yaml" +steps: + - id: notify + name: Notify + action: notification:send + input: + recipients: entity + entityRefs: + - user:default/guest + title: 'Template executed' + info: 'Your template has been executed' + severity: 'normal' +``` + +The example above would send a notification to the Guest user (`user:default/guest`) + ## Additional info An example of a backend plugin sending notifications can be found in the [`@backstage/plugin-scaffolder-backend-module-notifications` package](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-notifications). diff --git a/docs/notifications/notificationSettings.png b/docs/notifications/notificationSettings.png index cdad63d764..e135a3f194 100644 Binary files a/docs/notifications/notificationSettings.png and b/docs/notifications/notificationSettings.png differ diff --git a/docs/notifications/processors.md b/docs/notifications/processors.md index ad3e427364..c25b669ed6 100644 --- a/docs/notifications/processors.md +++ b/docs/notifications/processors.md @@ -148,6 +148,7 @@ notifications: - token: xoxb-XXXXXXXXX broadcastChannels: # Optional, if you wish to support broadcast notifications. - C12345678 + username: 'Backstage Bot' # Optional, defaults to the name of the Slack App. ``` Multiple instances can be added in the `slack` array, allowing you to have multiple configurations if you need to send diff --git a/docs/notifications/usage.md b/docs/notifications/usage.md index 358426dc21..94de585d21 100644 --- a/docs/notifications/usage.md +++ b/docs/notifications/usage.md @@ -210,3 +210,68 @@ notificationsApi.getNotification(yourId); // or with connection to signals: notificationsApi.getNotification(lastSignal.notification_id); ``` + +## Metadata Field + +The metadata field is a freeform object that is designed to be used by processors. + +### Well-known Notification Metadata Fields + +Below are metadata fields that will be commonly used between processors and have defined schematics. + +#### backstage.io/body.markdown + +```ts +# Example: +const payload = { + title: 'Entities Require Attention', + description: 'Entities: Service A, Service B' + metadata: { + 'backstage.io/body.markdown': ` + # Entities + - Service A + - System B + ` + } +} +``` + +This value of this metadata field should be the notification message in markdown format. This allows additional formatting options for processors that support markdown. + +### Usage + +Below is an example of using the `backstage.io/body.markdown` metadata field in a custom processor. + +When sending a notification: + +```ts +notificationService.send({ + recipients: { type: 'entity', entityRef: 'group/default:team-a' }, + payload: { + title: 'Notification', + description: 'Description' + metadata: { + 'backstage.io/body.markdown': ` + ### Notification + Description + `, + }, + }, +}); +``` + +In the processor, you can then use the metadata field accordingly: + +```ts +async postProcess(notification: Notification): Promise { + // We suggest you parse the metadata field with a schema, i.e. Zod + const parseResult = CustomProcessorMetadataSchema.safeParse(notification.payload.metadata ?? {}); + const metadata = parseResult.success ? parseResult.data : {}; + + customNotificationSender.send({ + to: getUsers(notification.recipients), + subject: notification.payload.title, + markdownText: metadata['backstage.io/body.markdown'] ?? notification.payload.description, + }); +} +``` diff --git a/docs/overview/adopting.md b/docs/overview/adopting.md index a6053d0f85..8b5703288e 100644 --- a/docs/overview/adopting.md +++ b/docs/overview/adopting.md @@ -1,7 +1,6 @@ --- id: adopting title: Strategies for adopting -# prettier-ignore description: Documentation on some general best practices that have been key to Backstage's success inside Spotify --- @@ -86,7 +85,7 @@ Examples of tactics we have used to evangelize Backstage internally: as to send out weekly digest emails showing how usage metrics have changed for individual plugins. -- Pro-actively identify new plugins. Reach out to teams that own internal UIs or +- Pro-actively identify new plugins. Reach out to teams that own internal user interfaces or platforms that you think would make sense to consolidate into Backstage. ## KPIs and metrics diff --git a/docs/overview/architecture-overview.md b/docs/overview/architecture-overview.md index 035be95769..de283beec0 100644 --- a/docs/overview/architecture-overview.md +++ b/docs/overview/architecture-overview.md @@ -10,285 +10,232 @@ Backstage is organized into three main components, each catering to different gr - Core - This includes the base functionality developed by core developers within the open-source project. - App - The app represents a deployed instance of a Backstage application, customized and maintained by app developers, typically a productivity team within an organization. It integrates core functionalities with additional plugins. -- Plugins - These provide additional functionalities to enhance the usefulness of your Backstage app. Plugins can be company-specific or open-sourced and reusable. At Spotify, we have over 100 plugins created by more than 50 different teams, significantly enriching the unified developer experience by incorporating contributions from various infrastructure teams. +- Plugins - These provide additional functionalities to enhance the usefulness of your Backstage app. Plugins can be company-specific or open-sourced and reusable. ## Overview -The following diagram shows how Backstage might look when deployed inside a -company which uses the Tech Radar plugin, the Lighthouse plugin, the CircleCI -plugin and the software catalog. +The following diagram shows a high level view of the overall architecture of Backstage. Running this architecture in a real environment typically involves +containerizing the components. Various commands are provided for accomplishing this. There are 3 main components in this architecture: -1. The core Backstage UI -2. The UI plugins and their backing services -3. Databases +- The [frontend](#frontend-building-blocks) includes the core Backstage [UI](#user-interface) which is an [extension](#extensions) that interacts directly with the user to present the information from the integrated core feature plugins, and other plugins added by a user. +- The [backend](#backend-building-blocks) includes the backend plugins, [core services](https://backstage.io/docs/backend-system/core-services/index), and other services. This is the server-side part of Backstage that is responsible for wiring things together. You can deploy more than one backend, and more than one backend container, depending on your need to scale and isolate individual features. +- Databases host your Backstage data. -Running this architecture in a real environment typically involves -containerizing the components. Various commands are provided for accomplishing -this. +![The architecture of a basic Backstage application](../assets/architecture-overview/backstage-front-back-arch.jpeg) -![The architecture of a basic Backstage application](../assets/architecture-overview/backstage-typical-architecture.png) +## Frontend building blocks -## User Interface +The architectural diagram provides an overview of the different building blocks and the other blocks that each of them interacts with. -The UI is a thin, client-side wrapper around a set of plugins. It provides some -core UI components and libraries for shared activities such as config -management. [[live demo](https://demo.backstage.io/catalog)] +### App + +This is the app instance itself that you create and use as the root of your Backstage frontend application. It does not have any direct functionality in and of itself, but is simply responsible for wiring things together. + +### Extensions + +[Extensions](../frontend-system/architecture/20-extensions.md) are the building blocks that build out both the visual and non-visual structure of the application. There are both built-in extensions provided by the app itself as well as extensions provided by plugins. Each extension is attached to a parent with which it shares data and can have any number of children of its own. It is up to the app to wire together all extensions into a single tree known as the app extension tree. It is from this structure that the entire app can then be instantiated and rendered. + +#### User Interface + +The UI is one of the extensions in the frontend. It is a thin, client-side wrapper around a set of plugins. It provides some core UI components and libraries for shared activities such as config management. [[live demo](https://demo.backstage.io/catalog)] ![UI with different components highlighted](../assets/architecture-overview/core-vs-plugin-components-highlighted.png) -Each plugin typically makes itself available in the UI on a dedicated URL. For -example, the Lighthouse plugin is registered with the UI on `/lighthouse`. -[[learn more](https://backstage.io/blog/2020/04/06/lighthouse-plugin)] +Each plugin typically makes itself available in the UI on a dedicated URL. For example, the Service Catalog plugin is registered with the UI on `/catalog`. -![The lighthouse plugin UI](../assets/architecture-overview/lighthouse-plugin.png) +### Frontend plugins -The CircleCI plugin is available on `/circleci`. +Plugins provide the actual features inside an app. The size of a plugin can range from a tiny component to an entire new system in which other plugins can be composed and integrated. Plugins can be completely standalone or built on top of each other to extend existing plugins and augment their features. Plugins can communicate with each other by composing their extensions or by sharing Utility APIs and routes. -![CircleCI Plugin UI](../assets/architecture-overview/circle-ci.png) +Backstage includes the following set of core plugins: -## Plugins and plugin backends +- [Software Catalog](../features/software-catalog/index.md) - A centralized system that contains metadata for all your software, such as services, websites, libraries, ML models, data pipelines, and so on. It can also contain metadata for the physical or virtual infrastructure needed to operate a piece of software. The software catalog can be viewed and searched through a UI. +- [Software Templates](../features/software-templates/index.md) - A tool to help you create components inside Backstage. A template can load skeletons of code, include some variables, and then publish the template to a location, such as GitHub. +- [TechDocs](https://backstage.io/docs/features/techdocs/) - A docs-like-code solution built into Backstage. Documentation is written in Markdown files which lives together with the code. +- [Kubernetes](../features/kubernetes/index.md) - A tool that allows developers to check the health of their services whether it is on a local host or in production. +- [Search](https://backstage.io/docs/features/search/) - Search for information in the Backstage ecosystem. You can customize the look and feel of each search result and use your own search engine. -Each plugin is a client side application which mounts itself on the UI. Plugins -are written in TypeScript or JavaScript. They each live in their own directory -in the `plugins` folder. For example, the source code for the catalog plugin -is available at -[plugins/catalog](https://github.com/backstage/backstage/tree/master/plugins/catalog). +[Plugin architecture](#plugin-architecture) provides greater detail about the architecture of the plugins themselves. -### Installing plugins +### Extension Overrides -Plugins are typically installed as React components in your Backstage -application. For example, -[here](https://github.com/backstage/backstage/blob/master/packages/app/src/App.tsx) -is a file that imports many full-page plugins in the Backstage sample app. +In addition to the built-in extensions and extensions provided by plugins, it is also possible to install [extension overrides](../frontend-system/architecture/25-extension-overrides.md). This is a collection of extensions with high priority that can replace existing extensions. They can for example be used to override an individual extension provided by a plugin, or install a completely new extension, such as a new app theme. -An example of one of these plugin components is the `CatalogIndexPage`, which is -a full-page view that allows you to browse entities in the Backstage catalog. It -is installed in the app by importing it and adding it as an element like this: +### Utility APIs -```tsx -import { CatalogIndexPage } from '@backstage/plugin-catalog'; +[Utility APIs](../api/utility-apis.md) provide functionality that makes it easier to build plugins, make it possible for plugins to share functionality with other plugins, as well as serve as a customization point for integrators to change the behaviour of the app. Each Utility API is defined by a TypeScript interface as well as a reference used to access the implementations. The implementations of Utility APIs are defined by extensions that are provided and can be overridden the same as any other extension. -... +### Routes -const routes = ( - - ... - } /> - ... - -); -``` +The [Backstage routing system](../frontend-system/architecture/36-routes.md) adds a layer of indirection that makes it possible for plugins to route to each other's extensions without explicit knowledge of what URL paths the extensions are rendered at or if they even exist at all. It makes it possible for plugins to share routes with each other and dynamically generate concrete links at runtime. It is the responsibility of the app to resolve these links to actual URLs, but it is also possible for integrators to define their own route bindings that decide how the links should be resolved. The routing system also lets plugins define internal routes, aiding in the linking to different content in the same plugin. -Note that we use `"/catalog"` as our path to this plugin page, but we can choose -any route we want for the page, as long as it doesn't collide with the routes -that we choose for the other plugins in the app. +## Backend building blocks -These components that are exported from plugins are referred to as "Plugin -Extension Components", or "Extension Components". They are regular React -components, but in addition to being able to be rendered by React, they also -contain various pieces of metadata that is used to wire together the entire app. -Extension components are created using `create*Extension` methods, which you can -read more about in the -[composability documentation](../plugins/composability.md). +The architectural diagram provides an overview of the different building blocks, and the other blocks that each of them interact with. -As of this moment, there is no config based install procedure for plugins. Some -code changes are required. +### Backend -### Plugin architecture +This is the [backend instance](../backend-system/architecture/02-backends.md) itself, which you can think of as the unit of deployment. It does not have any functionality in and of itself, but is simply responsible for wiring things together. + +It is up to you to decide how many different backends you want to deploy. You can have all features in a single one, or split things out into multiple smaller deployments, depending on your need to scale and isolate individual features. + +### Backend plugins + +[Plugins](../backend-system/architecture/04-plugins.md) provide the actual features. They operate completely independently of each other. If plugins want to communicate with each other, they must do so over the wire. There can be no direct communication between plugins through code. Because of this constraint, each plugin can be considered to be its own microservice. + +[Plugin architecture](#plugin-architecture) provides greater detail about the architecture of the plugins themselves. + +### Services + +[Services](../backend-system/architecture/03-services.md) provide utilities to help make it simpler to implement plugins, so that each plugin doesn't need to implement everything from scratch. There are many built-in core services, such as the ones for logging, database access, and reading configuration, but you can also import third-party services, or create your own. + +Services are also a customization point for individual backend installations. You can override services with your own implementations, as well as make smaller customizations to existing services. + +### Extension Points + +Many plugins have ways in which you can extend them, for example entity providers for the Catalog, or custom actions for the Scaffolder. These extension patterns are now encoded into Extension Points. + +[Extension Points](../backend-system/architecture/05-extension-points.md) look a little bit like services, since you depend on them just like you would a service. A key difference is that extension points are registered and provided by plugins or modules themselves, based on what customizations each of them want to expose. + +Extension Points are exported separately from the plugin or module instance itself, and it is possible to expose multiple different extension points at once. This makes it easier to evolve and deprecate individual Extension Points over time, rather than dealing with a single large API surface. + +### Modules + +[Modules](../backend-system/architecture/06-modules.md) use Extension Points to add new features to other plugins or modules. They might for example add an individual Catalog Entity Provider, or one or more Scaffolder Actions. + +Each module may only use Extension Points that belong to a single plugin, and the module must be deployed together with that plugin in the same backend instance. Modules may only communicate with their plugin or other modules through the registered extension points. + +Just like plugins, modules also have access to services and can depend on their own service implementations. They will however share services with the plugin that they extend - there are no module-specific service implementations. + +## Databases + +The databases host your Backstage data. The Backstage backend and its built-in plugins are based on the [Knex](http://knexjs.org/) library, and set up a separate logical database per plugin. This gives great isolation and lets them perform migrations and evolve separately from each other. + +The Knex library supports a multitude of databases, but Backstage at this time of writing is tested primarily against two of them: + +- SQLite, which is mainly used as an in-memory mock/test database +- PostgreSQL, which is the preferred production database. + +Other databases such as the MySQL variants are reported to work but [aren't fully tested](https://github.com/backstage/backstage/issues/2460) yet. + +You can find instructions on setting up a PostgreSQL for your Backstage instance in [Database](../getting-started/config/database.md). [Configuring Plugin Databases](../tutorials/configuring-plugin-databases.md) provides information on how to configure a database for a plugin. + +## Plugin architecture Architecturally, plugins can take three forms: -1. Standalone -2. Service backed -3. Third-party backed +- [Standalone](#standalone-plugins) +- [Service backend](#service-backend-plugins) +- [Third-party backend](#third-party-backend-plugins) -#### Standalone plugins +### Standalone plugins -Standalone plugins run entirely in the browser. -[The Tech Radar plugin](https://demo.backstage.io/tech-radar), for example, -simply renders hard-coded information. It doesn't make any API requests to other -services. +Standalone plugins run entirely in the browser. [The Tech Radar plugin](https://demo.backstage.io/tech-radar), for example, simply renders hard-coded information. It doesn't make any API requests to other services. + +The architecture of the Tech Radar installed into a Backstage app is very simple. You just need to add Tech Radar as a frontend plugin into your app, as shown in the following diagram. + +> **NOTE:** +> The following diagram does not show the detailed contents of the frontend and backend containers in order to highlight the changes that pertain to the addition of the specified plugin. + +![ui and tech radar plugin connected together](../assets/architecture-overview/simplified-standalone-plugin-architecture.jpeg) + +Once the plugin has been added, then you can view the Tech Radar information in the Backstage UI. ![tech radar plugin ui](../assets/architecture-overview/tech-radar-plugin.png) -The architecture of the Tech Radar installed into a Backstage app is very -simple. +### Service backend plugins -![ui and tech radar plugin connected together](../assets/architecture-overview/tech-radar-plugin-architecture.png) +Service backend plugins make API requests to a service which is within the purview of the organization running Backstage. -#### Service backed plugins +The Lighthouse plugin, for example, makes requests to the [lighthouse-audit-service](https://github.com/spotify/lighthouse-audit-service). The `lighthouse-audit-service` is a microservice which runs a copy of Google's [Lighthouse library](https://github.com/GoogleChrome/lighthouse/) and stores the results in a PostgreSQL database. -Service backed plugins make API requests to a service which is within the -purview of the organisation running Backstage. +The Lighthouse plugin is added to the frontend. The lighthouse-audit-service container is already publicly available in Docker Hub and can be downloaded and run with -The Lighthouse plugin, for example, makes requests to the -[lighthouse-audit-service](https://github.com/spotify/lighthouse-audit-service). -The `lighthouse-audit-service` is a microservice which runs a copy of Google's -[Lighthouse library](https://github.com/GoogleChrome/lighthouse/) and stores the -results in a PostgreSQL database. +```bash +docker run spotify/lighthouse-audit-service:latest +``` -Its architecture looks like this: +> **NOTE:** +> The following diagram does not show the detailed contents of the frontend and backend, in order to highlight the changes that pertain to the addition of the specified plugin. -![lighthouse plugin backed to microservice and database](../assets/architecture-overview/lighthouse-plugin-architecture.png) +![lighthouse plugin backend to microservice and database](../assets/architecture-overview/simplified-service-based-plugin-architecture.jpeg) -The software catalog in Backstage is another example of a service backed plugin. -It retrieves a list of services, or "entities", from the Backstage Backend -service and renders them in a table for the user. +The software catalog in Backstage is another example of a service backend plugin. It retrieves a list of services, or "entities", from the Backstage Backend service and renders them in a table for the user. -### Third-party backed plugins +### Third-party backend plugins -Third-party backed plugins are similar to service backed plugins. The main -difference is that the service which backs the plugin is hosted outside of the -ecosystem of the company hosting Backstage. +Third-party backend plugins are similar to service backend plugins. The main difference is that the service which backs the plugin is hosted outside of the ecosystem of the company hosting Backstage. -The CircleCI plugin is an example of a third-party backed plugin. CircleCI is a -SaaS service which can be used without any knowledge of Backstage. It has an API -which a Backstage plugin consumes to display content. +The CircleCI plugin is an example of a third-party backend plugin. CircleCI is a SaaS service which can be used without any knowledge of Backstage. It has an API which a Backstage plugin consumes to display content. -Requests going to CircleCI from the user's browser are passed through a proxy -service that Backstage provides. Without this, the requests would be blocked by -Cross Origin Resource Sharing policies which prevent a browser page served at -[https://example.com](https://example.com) from serving resources hosted at -https://circleci.com. +Requests going to CircleCI from the user's browser are passed through a proxy service that Backstage provides. Without this, the requests would be blocked by Cross Origin Resource Sharing policies which prevent a browser page served at [https://example.com](https://example.com) from serving resources hosted at https://circleci.com. -![CircleCI plugin talking to proxy talking to SaaS Circle CI](../assets/architecture-overview/circle-ci-plugin-architecture.png) +> **NOTE:** +> The following diagram does not show the detailed contents of the frontend and backend, in order to highlight the changes that pertain to the addition of the specified plugin. + +![CircleCI plugin talking to proxy talking to SaaS Circle CI](../assets/architecture-overview/simplified-third-party-plugin-architecture.jpeg) ## Package Architecture -Backstage relies heavily on NPM packages, both for distribution of libraries, -and structuring of code within projects. While the way you structure your -Backstage project is up to you, there is a set of established patterns that we -encourage you to follow. These patterns can help set up a sound project -structure as well as provide familiarity between different Backstage projects. +Backstage relies heavily on NPM packages, both for distribution of libraries, and structuring of code within projects. While the way you structure your Backstage project is up to you, there is a set of established patterns that we encourage you to follow. These patterns can help set up a sound project structure as well as provide familiarity between different Backstage projects. -The following diagram shows an overview of the package architecture of -Backstage. It takes the point of view of an individual plugin and all of the -packages that it may contain, indicated by the thicker border and italic text. -Surrounding the plugin are different package groups which are the different -possible interface points of the plugin. Note that not all library package lists -are complete as packages have been omitted for brevity. +The following diagram shows an overview of the package architecture of Backstage. It takes the point of view of an individual plugin and all of the packages that it may contain, indicated by the thicker border and italic text. Surrounding the plugin are different package groups which are the different possible interface points of the plugin. Note that not all library package lists are complete as packages have been omitted for brevity. ![Package architecture](../assets/architecture-overview/package-architecture.drawio.svg) ### Overview -The arrows in the diagram above indicate a runtime dependency on the code of the -target package. This strict dependency graph only applies to runtime -`dependencies`, and there may be `devDependencies` that break the rules of this -table for the purpose of testing. While there are some arrows that show a -dependency on a collection of frontend, backend and isomorphic packages, those -still have to abide by important compatibility rules shown in the bottom left. +The arrows in the diagram above indicate a runtime dependency on the code of the target package. This strict dependency graph only applies to runtime +`dependencies`, and there may be `devDependencies` that break the rules of this table for the purpose of testing. While there are some arrows that show a dependency on a collection of frontend, backend and isomorphic packages, those still have to abide by important compatibility rules shown in the bottom left. -The `app` and `backend` packages are the entry points of a Backstage project. -The `app` package is the frontend application that brings together a collection -of frontend plugins and customizes them to fit an organization, while the -`backend` package is the backend service that powers the Backstage application. -Worth noting is that there can be more than one instance of each of these -packages within a project. Particularly the `backend` packages can benefit from -being split up into smaller deployment units that each serve their own purpose -with a smaller collection of plugins. +The `app` and `backend` packages are the entry points of a Backstage project. The `app` package is the frontend application that brings together a collection of frontend plugins and customizes them to fit an organization, while the `backend` package is the backend service that powers the Backstage application. Worth noting is that there can be more than one instance of each of these packages within a project. Particularly the `backend` packages can benefit from being split up into smaller deployment units that each serve their own purpose with a smaller collection of plugins. ### Plugin Packages -A typical plugin consists of up to five packages, two frontend ones, two -backend, and one isomorphic package. All packages within the plugin must share a -common prefix, typically of the form `@/plugin-`, but -alternatives like `backstage-plugin-` or -`@/backstage-plugin-` are also valid. Along with this prefix, -each of the packages have their own unique suffix that denotes their role. In -addition to these five plugin packages it's also possible for a plugin to have -additional frontend and backend modules that can be installed to enable optional -features. For a full list of suffixes and their roles, see the -[Plugin Package Structure ADR](../architecture-decisions/adr011-plugin-package-structure.md). +A typical plugin consists of up to five packages, two frontend ones, two backend, and one isomorphic package. All packages within the plugin must share a common prefix, typically of the form `@/plugin-`, but alternatives like `backstage-plugin-` or `@/backstage-plugin-` are also valid. Along with this prefix, each of the packages have their own unique suffix that denotes their role. In addition to these five plugin packages it's also possible for a plugin to have +additional frontend and backend modules that can be installed to enable optional features. For a full list of suffixes and their roles, see the [Plugin Package Structure ADR](../architecture-decisions/adr011-plugin-package-structure.md). -The `-react`, `-common`, and `-node` plugin packages together form the external -library of a plugin. The plugin library enables other plugins to build on top of -and extend a plugin, and likewise allows the plugin to depend on and extend -other plugins. Because of this, it is preferable that plugin library packages -allow duplicate installations of themselves, as you may end up with a mix of -versions being installed as dependencies of various plugins. It is also -forbidden for plugins to directly import non-library packages from other -plugins, all communication between plugins must be handled through libraries and -the application itself. +The `-react`, `-common`, and `-node` plugin packages together form the external library of a plugin. The plugin library enables other plugins to build on top of and extend a plugin, and likewise allows the plugin to depend on and extend other plugins. Because of this, it is preferable that plugin library packages allow duplicate installations of themselves, as you may end up with a mix of versions being installed as dependencies of various plugins. It is also forbidden for plugins to directly import non-library packages from other plugins, all communication between plugins must be handled through libraries and the application itself. ### Frontend Packages -The frontend packages are grouped into two main groups. The first one is -"Frontend App Core", which is the set of packages that are only used by the -`app` package itself. These packages help build up the core structure of the app -as well as provide a foundation for the plugin libraries to rely upon. +The frontend packages are grouped into two main groups. The first one is "Frontend App Core", which is the set of packages that are only used by the `app` package itself. These packages help build up the core structure of the app as well as provide a foundation for the plugin libraries to rely upon. -The second group is the rest of the shared packages, further divided into -"Frontend Plugin Core" and "Frontend Libraries". The core packages are -considered particularly stable and form the core of the frontend framework. -Their most important role is to form the boundary around each plugin and provide -a set of tools that helps you combine a collection of plugins into a running -application. The rest of the frontend packages are more traditional libraries -that serve as building blocks to create plugins. +The second group is the rest of the shared packages, further divided into "Frontend Plugin Core" and "Frontend Libraries". The core packages are considered particularly stable and form the core of the frontend framework. Their most important role is to form the boundary around each plugin and provide a set of tools that helps you combine a collection of plugins into a running application. The rest of the frontend packages are more traditional libraries that serve as building blocks to create plugins. ### Backend Packages -The backend library packages do not currently share a similar plugin -architecture as the frontend packages. They are instead simply a collection of -building blocks and patterns that help you build backend services. This is -however likely to change in the future. +The backend library packages do not currently share a similar plugin architecture as the frontend packages. They are instead simply a collection of building blocks and patterns that help you build backend services. This is however likely to change in the future. ### Common Packages -The common packages are the packages effectively depended on by all other pages. -This is a much smaller set of packages but they are also very pervasive. Because -the common packages are isomorphic and must execute both in the frontend and -backend, they are never allowed to depend on any of the frontend or backend -packages. +The common packages are the packages effectively depended on by all other pages. This is a much smaller set of packages but they are also very pervasive. Because the common packages are isomorphic and must execute both in the frontend and backend, they are never allowed to depend on any of the frontend or backend packages. -The Backstage CLI is in a category of its own and is depended on by virtually -all other packages. It's not a library in itself though, and must always be a -development dependency only. +The Backstage CLI is in a category of its own and is depended on by virtually all other packages. It's not a library in itself though, and must always be a development dependency only. ### Deciding where you place your code -It can sometimes be difficult to decide where to place your plugin code. For example -should it go directly in the `-backend` plugin package or in the `-node` package? -As a general guideline you should try to keep the exposure of your code as low -as possible. If it doesn't need to be public API, it's best to avoid. If you don't -need it to be used by other plugins, then keep it directly in the plugin packages. +It can sometimes be difficult to decide where to place your plugin code. For example, should it go directly in the `-backend` plugin package or in the `-node` package? As a general guideline you should try to keep the exposure of your code as low as possible. If it doesn't need to be public API, it's best to avoid. If you don't need it to be used by other plugins, then keep it directly in the plugin packages. Below is a chart to help you decide where to place your code. ![Package decision](../assets/architecture-overview/package-decision.drawio.svg) -## Databases - -As we have seen, both the `lighthouse-audit-service` and `catalog-backend` -require a database to work with. - -The Backstage backend and its built-in plugins are based on the -[Knex](http://knexjs.org/) library, and set up a separate logical database per -plugin. This gives great isolation and lets them perform migrations and evolve -separately from each other. - -The Knex library supports a multitude of databases, but Backstage at this time -of writing is tested primarily against two of them: SQLite, which is mainly used as -an in-memory mock/test database, and PostgreSQL, which is the preferred -production database. Other databases such as the MySQL variants are reported to -work but -[aren't fully tested](https://github.com/backstage/backstage/issues/2460) -yet. - ## Cache -The Backstage backend and its built-in plugins are also able to leverage cache -stores as a means of improving performance or reliability. Similar to how -databases are supported, plugins receive logically separated cache connections, -which are powered by [Keyv](https://github.com/lukechilds/keyv) under the hood. +The Backstage backend and its built-in plugins are also able to leverage cache stores as a means of improving performance or reliability. Similar to how databases are supported, plugins receive logically separated cache connections, which are powered by [Keyv](https://github.com/lukechilds/keyv) under the hood. -At this time of writing, Backstage can be configured to use one of three cache -stores: memory, which is mainly used for local testing, memcache or Redis, -which are cache stores better suited for production deployment. The right cache -store for your Backstage instance will depend on your own run-time constraints -and those required of the plugins you're running. +At this time of writing, Backstage can be configured to use one of five cache stores: + +- `memory` +- `memcache` +- `redis` +- `valkey` +- `infinispan` + +`memory` is primarily used for local development, for production deployments, we recommend using one of the other cache stores. The right cache store for your Backstage instance will depend on your own run-time constraints and those required of the plugins you're running. ### Use memory for cache @@ -316,31 +263,38 @@ backend: connection: redis://user:pass@cache.example.com:6379 ``` +### Use Infinispan for cache + +#### Minimal configuration + +- defaults, no `authentication`, expects cache named `cache` and host `127.0.0.1:11222`) + +```yaml +backend: + cache: + store: infinispan +``` + +#### Extended configuration + +- Unlike Redis, Infinispan will **not** create the cache for you. It's expected you've configured the cache in your infinispan server prior to configuration here. +- A full list of configuration items are available: https://docs.jboss.org/infinispan/hotrod-clients/javascript/1.0/apidocs/module-infinispan.html including support for backup clusters. + +```yaml +backend: + cache: + store: infinispan + infinispan: + servers: + - host: 127.0.0.1 + port: 11222 + cacheName: backstage-cache + mediaType: application/json + authentication: + enabled: true + userName: yourusername + password: yourpassword + saslMechanism: PLAIN +``` + Contributions supporting other cache stores are welcome! - -## Containerization - -The example Backstage architecture shown above would Dockerize into three -separate Docker images. - -1. The frontend container -2. The backend container -3. The Lighthouse audit service container - -![Boxes around the architecture to indicate how it is containerised](../assets/architecture-overview/containerised.png) - -The backend container can be built by running the following command: - -```bash -yarn run build -yarn run build-image -``` - -This will create a container called `example-backend`. - -The lighthouse-audit-service container is already publicly available in Docker -Hub and can be downloaded and run with - -```bash -docker run spotify/lighthouse-audit-service:latest -``` diff --git a/docs/overview/background.md b/docs/overview/background.md index 5e59967b21..147fe8ce7b 100644 --- a/docs/overview/background.md +++ b/docs/overview/background.md @@ -1,7 +1,6 @@ --- id: background title: The Spotify Story -# prettier-ignore description: Backstage was born out of necessity at Spotify. We found that as we grew, our infrastructure was becoming more fragmented, our engineers less productive. --- diff --git a/docs/overview/roadmap.md b/docs/overview/roadmap.md index a61455a313..d9a03d9668 100644 --- a/docs/overview/roadmap.md +++ b/docs/overview/roadmap.md @@ -17,7 +17,7 @@ The initiatives listed below are planned for release within the next half-year, ### New Frontend System - Ready for Adoption -The [new fronted system](../frontend-system/index.md) still needs more work, and +The [new frontend system](../frontend-system/index.md) still needs more work, and the next milestone is to improve it to the point where there is enough confidence in the design to start encouraging adoption in the community. You can follow along with this work in the [meta issue](https://github.com/backstage/backstage/issues/19545). diff --git a/docs/overview/technical-overview.md b/docs/overview/technical-overview.md new file mode 100644 index 0000000000..63c20dbf2f --- /dev/null +++ b/docs/overview/technical-overview.md @@ -0,0 +1,88 @@ +--- +id: technical-overview +title: Technical overview +description: Technical overview of Backstage +--- + +## Purpose + +Backstage is an open source framework for building developer portals that was created at Spotify to simplify end-to-end software development. As Spotify grew, their infrastructure became more fragmented and teams couldn't find the APIs they were supposed to use, or who owned a service, or documentation on anything. + +Backstage is powered by a centralized [software catalog](#software-catalog-system-model) and utilizes an abstraction layer that sits on top of all of your infrastructure and developer tooling, allowing you to manage all of your software, services, tooling, and testing in one place. + +Backstage uses a [plugin-architecture](#plugin-architecture-overview) which allows you customize the functionality of your Backstage application using a wide variety of available plugins or you can write your own. It also includes automated templates that your teams can use to create new microservices, helping to ensure consistency and adherence to your best practices. Backstage also provides the ability to create, maintain, and find the documentation for all of your software. + +Backstage is now a [CNCF incubation project](https://backstage.io/blog/2022/03/16/backstage-turns-two#out-of-the-sandbox-and-into-incubation). + +## Benefits + +- For _engineering managers_, it allows you to maintain standards and best practices across the organization, and can help you manage your whole tech ecosystem, from migrations to test certification. +- For _end users_ (developers), it makes it fast and simple to build software components in a standardized way, and it provides a central place to manage all projects and documentation. +- For _platform engineers_, it enables extensibility and scalability by letting you easily integrate new tools and services (via plugins), as well as extending the functionality of existing ones. +- For _everyone_, it is a single, consistent experience that ties all of your infrastructure tooling, resources, standards, owners, contributors, and administrators together in one place. + +If you have question or want support, please join our [Discord server](https://discord.gg/backstage-687207715902193673). + +## Core Features + +Backstage includes the following set of core features: + +- [Authentication and Identity](../auth/index.md) - Sign-in and identification of users, and delegating access to third-party resources, using built-in authentication providers. +- [Kubernetes](../features/kubernetes/index.md) - A tool that allows developers to check the health of their services whether it is on a local host or in production. +- [Notifications](../notifications/index.md) - Provides a means for plugins and external services to send messages to either individual users or groups. +- [Permissions](../permissions/overview.md) - Ability to enforce rules concerning the type of access a user is given to specific data, APIs, or interface actions. +- [Search](https://backstage.io/docs/features/search/) - Search for information in the Backstage ecosystem. You can customize the look and feel of each search result and use your own search engine. +- [Software Catalog](../features/software-catalog/index.md) - A centralized system that contains metadata for all your software, such as services, websites, libraries, ML models, data pipelines, and so on. It can also contain metadata for the physical or virtual infrastructure needed to operate a piece of software. The software catalog can be viewed and searched through a UI. +- [Software Templates](../features/software-templates/index.md) - A tool to help you create components inside Backstage. A template can load skeletons of code, include some variables, and then publish the template to a location, such as GitHub. +- [TechDocs](https://backstage.io/docs/features/techdocs/) - A docs-like-code solution built into Backstage. Documentation is written in Markdown files which lives together with the code. + +## Plugin Architecture Overview + +Plugins are client side applications which mount themselves on the Backstage UI. They allow you to incorporate a wide variety of infrastructure and software development tools into your Backstage application. Backstage uses a [plugin-architecture](../overview/architecture-overview.md#plugin-architecture) to provide a consistent user experience, in a single UI, around all of your plugins. + +The Backstage architecture supports three types of plugins: + +- Standalone - runs entirely in a browser and it does not make any API requests to other services. +- Service backed - makes API requests to a service within the ecosystem of the organization running Backstage. +- Third-party backed - similar to service-backed, but the service backing the plugin is hosted outside of the ecosystem of the company hosting Backstage. + +Many of the features available in Backstage are provided by plugins. For example, the Software Catalog is a service backed plugin. When you view the catalog, it retrieves a set of services ("[entities](#software-catalog-system-model)") from the Backstage Backend service and renders them in a table in the UI for you. + +## Software Catalog System Model + +The system model behind the software catalog is based on [_entities_](../references/glossary.md#entity) and it models two main types: + +- Core Entities +- Organizational Entities + +`Core Entities` include: + +- `Components` - Individual pieces of software that can be tracked in source control and can implement APIs for other components to consume. +- `APIs` - Implemented by components and form the boundaries between different components. The API can be either public, restricted, or private. +- `Resources` - The physical or virtual infrastructure needed to operate a component. + +![core entity relationships in the software model](../assets/software-catalog/software-model-core-entities.drawio.svg) + +`Organizational Entities` include: + +- `User` - A person, such as an employee, contractor, or similar. +- `Group` - An organizational entity, such as a team, business unit, and so on. + +When you have a large catalogue of components, APIs, and resources, it can be difficult to understand how they work together. Ecosystem modeling allows you to organize a large catalog of core entities into: + +- Systems - A collection of resources and components that cooperate to perform a function by exposing one or several public APIs. It hides the resources and private APIs between the components from the consumer. +- Domains - A collection of systems that share terminology, domain models, metrics, KPIs, business purpose, or documentation. + +There are three additional items that can be part of the system model: + +- `Location` - A marker that references other places to look for catalog data. +- `Type` - It has no set meaning. You can assign your own types and use them as desired. +- `Template` - Describes both the parameters that are rendered in the frontend part of the scaffolding wizard, and the steps that are executed when scaffolding that component. + +The following diagram illustrates an example of ecosystem modeling, and provides sample relationships between a domain, system, core entities, and organization entities. + +![ecosystem modeling example](../assets/software-catalog/software-model-entities.drawio.svg) + +The following shows an example of viewing all of the components, APIs, and resources that are managed by your group after setting up the relationships to create a group organizational entity. + +![sample ui showing group ownership](../assets/technical-overview/backstage-ui-group-ownership.png) diff --git a/docs/overview/vision.md b/docs/overview/vision.md index f6d6af90dd..aab5eaa9b8 100644 --- a/docs/overview/vision.md +++ b/docs/overview/vision.md @@ -1,7 +1,6 @@ --- id: vision title: Vision -# prettier-ignore description: Goal is to provide engineers with the best developer experience in the world --- diff --git a/docs/overview/what-is-backstage.md b/docs/overview/what-is-backstage.md index ef452d5d15..fa1c75de44 100644 --- a/docs/overview/what-is-backstage.md +++ b/docs/overview/what-is-backstage.md @@ -1,7 +1,6 @@ --- id: what-is-backstage title: What is Backstage? -# prettier-ignore description: Backstage is an open source framework for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure --- diff --git a/docs/permissions/custom-rules.md b/docs/permissions/custom-rules.md index 61b9a5326a..7bfcd1220a 100644 --- a/docs/permissions/custom-rules.md +++ b/docs/permissions/custom-rules.md @@ -184,7 +184,7 @@ To install custom rules in a plugin, we need to use the [`PermissionsRegistrySer import('@backstage/plugin-catalog-backend-module-scaffolder-entity-model'), ); /* highlight-add-next-line */ - backend.add(import('./extensions/catalogPermissionRules')); + backend.add(import('./modules/catalogPermissionRules')); ``` 5. Now when you run you Backstage instance - `yarn start` - the rule will be added to the catalog plugin. diff --git a/docs/permissions/frontend-integration.md b/docs/permissions/frontend-integration.md index 1e83f8ad7d..d5329eca96 100644 --- a/docs/permissions/frontend-integration.md +++ b/docs/permissions/frontend-integration.md @@ -4,6 +4,10 @@ title: Frontend Integration description: How to place your Backstage frontend components behind authorization --- +:::info +Starting with a [fresh Backstage installation](https://backstage.io/docs/getting-started/), the code example below is already implemented, so there are no actual code changes required. +::: + Now that we understand how to [author a permission policy](./writing-a-policy.md), let's consider cases where we'll need to supplement our policy with authorization checks on the frontend. In most cases, actual functionality that live within various plugins will already have been placed behind authorization by the plugin authors. The permission backend will use your permission policy to return an authorization result, and the plugin frontend will correspondingly show/hide/disable the relevant UI component. @@ -13,25 +17,20 @@ However, there are some cases where the integrator needs to supplement the polic If your Backstage permission policy may return a `DENY` for users requesting the `catalogEntityCreatePermission`, it may make sense, for example, to remove access to the `/catalog-import` page entirely: ```tsx title="packages/app/src/App.tsx" -/* highlight-add-start */ import { RequirePermission } from '@backstage/plugin-permission-react'; -import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common'; -/* highlight-add-end */ +import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; const routes = ( - {/* highlight-remove-next-line */} - } /> - {/* highlight-add-start */} } /> - {/* highlight-add-end */} {/* ... */} ); diff --git a/docs/permissions/writing-a-policy.md b/docs/permissions/writing-a-policy.md index a479684287..576afcac21 100644 --- a/docs/permissions/writing-a-policy.md +++ b/docs/permissions/writing-a-policy.md @@ -92,6 +92,13 @@ import { catalogEntityDeletePermission, } from '@backstage/plugin-catalog-common/alpha'; /* highlight-add-end */ +import { + PermissionPolicy, + PolicyQuery, + /* highlight-add-next-line */ + PolicyQueryUser, +} from '@backstage/plugin-permission-node'; + class CustomPermissionPolicy implements PermissionPolicy { /* highlight-remove-next-line */ @@ -143,8 +150,8 @@ import { PolicyDecision, /* highlight-remove-next-line */ isPermission, - isResourcePermission, /* highlight-add-next-line */ + isResourcePermission, } from '@backstage/plugin-permission-common'; import { catalogConditions, @@ -155,6 +162,11 @@ import { catalogEntityDeletePermission, } from '@backstage/plugin-catalog-common/alpha'; /* highlight-remove-end */ +import { + PermissionPolicy, + PolicyQuery, + PolicyQueryUser, +} from '@backstage/plugin-permission-node'; class CustomPermissionPolicy implements PermissionPolicy { async handle( diff --git a/docs/plugins/analytics.md b/docs/plugins/analytics.md index 0a6bac81a0..f383e8881c 100644 --- a/docs/plugins/analytics.md +++ b/docs/plugins/analytics.md @@ -101,6 +101,25 @@ export const apis: AnyApiFactory[] = [ }, }), ]; + +// Or, when building for the new frontend system: +import { AnalyticsImplementationBlueprint } from '@backstage/frontend-plugin-api'; + +export const acmeAnalyticsImplementation = + AnalyticsImplementationBlueprint.make({ + name: 'acme', + params: define => + define({ + deps: {}, + factory() { + return { + captureEvent: event => { + window._AcmeAnalyticsQ.push(event); + }, + }; + }, + }), + }); ``` In reality, you would likely want to encapsulate instantiation logic and pull @@ -140,6 +159,19 @@ export const apis: AnyApiFactory[] = [ factory: ({ configApi }) => AcmeAnalytics.fromConfig(configApi), }), ]; + +// Or, when building for the new frontend system: +import { AnalyticsImplementationBlueprint } from '@backstage/frontend-plugin-api'; + +export const acmeAnalyticsImplementation = + AnalyticsImplementationBlueprint.make({ + name: 'acme', + params: define => + define({ + deps: { configApi: configApiRef }, + factory: ({ configApi }) => AcmeAnalytics.fromConfig(configApi), + }), + }); ``` If you are integrating with an analytics service (as opposed to an internal diff --git a/docs/plugins/call-existing-api.md b/docs/plugins/call-existing-api.md index 065427b9ee..35a6d8d599 100644 --- a/docs/plugins/call-existing-api.md +++ b/docs/plugins/call-existing-api.md @@ -1,7 +1,6 @@ --- id: call-existing-api title: Call Existing API -# prettier-ignore description: Describes the various options that Backstage frontend plugins have, in communicating with service APIs that already exist --- @@ -20,11 +19,18 @@ such as `axios`. Example: -```ts -// Inside your component -fetch('https://api.frobsco.com/v1/list') - .then(response => response.json()) - .then(payload => setFrobs(payload as Frob[])); +```ts title="plugins/my-awesome-plugin/src/components/AwesomeUsersTable.tsx" +import useAsync from 'react-use/esm/useAsync'; + +function AwesomeUsersTable() { + const { value, loading, error } = useAsync(async () => { + const response = await fetch('https://api.frobsco.com/v1/list'); + return response.json(); + }, []); + + + ... +} ``` Internally at Spotify, this has not been a very common choice. Third party APIs @@ -76,12 +82,26 @@ proxy: '/frobs': http://api.frobsco.com/v1 ``` -```ts -// Inside your component -const backendUrl = config.getString('backend.baseUrl'); -fetch(`${backendUrl}/api/proxy/frobs/list`) - .then(response => response.json()) - .then(payload => setFrobs(payload as Frob[])); +```tsx title="plugins/frobs-aggregator/src/components/FrobsAggregator.tsx" +import { + useApi, + discoveryApiRef, + fetchApiRef, +} from '@backstage/core-plugin-api'; +import useAsync from 'react-use/esm/useAsync'; + +function FrobsAggregator() { + const fetchApi = useApi(fetchApiRef); + const discoveryApi = useApi(discoveryApiRef); + + const { value, loading, error } = useAsync(async () => { + const baseUrl = await discoveryApi.getBaseUrl('proxy'); + const response = await fetchApi.fetch(`${baseUrl}/frobs`); + return response.json(); + }, [fetchApi, discoveryApi]); + + // ... +} ``` The proxy is powered by the `http-proxy-middleware` package. See @@ -112,28 +132,55 @@ system. The above mentioned proxy is actually one such plugin. If you were in need of a more involved integration than just direct access to the FrobsCo API, or if you needed to hold state, you may want to make such a plugin. -Example: +For example, assuming you have created a new backend plugin called +`frobs-aggregator`, you can add a new route like this: -```ts -// Inside your component -const backendUrl = config.getString('backend.baseUrl'); -fetch(`${backendUrl}/frobs-aggregator/summary`) - .then(response => response.json()) - .then(payload => setSummary(payload as FrobSummary)); +```tsx title="plugins/frobs-aggregator-backend/src/router.ts" +import Router from 'express-promise-router'; + +export async function createRouter() { + const router = Router(); + router.use(express.json()); + + /* highlight-add-start */ + router.get('/summary', async (req, res) => { + const agg = await Promise.all([ + fetch('https://api.frobsco.com/v1/list'), + fetch('http://flerps.partnercompany.com:8080/flerp-batch'), + database.currentThunk(), + ]).then(async ([frobs, flerps, thunk]) => { + return computeAggregate(await frobs.json(), await flerps.json(), thunk); + }); + res.status(200).json(agg); + }); + /* highlight-add-end */ +} ``` -```ts -// Inside a new frobs-aggregator backend plugin -router.use('/summary', async (req, res) => { - const agg = await Promise.all([ - fetch('https://api.frobsco.com/v1/list'), - fetch('http://flerps.partnercompany.com:8080/flerp-batch'), - database.currentThunk(), - ]).then(async ([frobs, flerps, thunk]) => { - return computeAggregate(await frobs.json(), await flerps.json(), thunk); - }); - res.status(200).json(agg); -}); +Then you can fetch the data from your frontend plugin like this: + +```tsx title="plugins/frobs-aggregator/src/components/FrobsAggregator.tsx" +import { + useApi, + discoveryApiRef, + fetchApiRef, +} from '@backstage/core-plugin-api'; +import useAsync from 'react-use/esm/useAsync'; + +function FrobsAggregator() { + const fetchApi = useApi(fetchApiRef); + const discoveryApi = useApi(discoveryApiRef); + + const { value, loading, error } = useAsync(async () => { + // highlight-next-line + const baseUrl = await discoveryApi.getBaseUrl('frobs-aggregator'); + // highlight-next-line + const response = await fetchApi.fetch(`${baseUrl}/summary`); + return response.json(); + }, [fetchApi, discoveryApi]); + + // ... +} ``` For a more detailed example, see @@ -166,8 +213,3 @@ There is a balance to strike regarding when to make an entirely separate backend for a purpose, and when to make a Backstage backend plugin that adapts something that already exists. General advice is not easy to give, but contact us on Discord if you have any questions, and we may be able to offer guidance. - -## Extending the GraphQL Model - -The extensible GraphQL backend layer is not built yet. This section will be -expanded when that happens. Stay tuned! diff --git a/docs/plugins/composability.md b/docs/plugins/composability.md index a0e0e2d5e6..d6c9abc98f 100644 --- a/docs/plugins/composability.md +++ b/docs/plugins/composability.md @@ -1,7 +1,6 @@ --- id: composability title: Composability System -# prettier-ignore description: Documentation for the Backstage plugin composability APIs. --- diff --git a/docs/plugins/integrating-search-into-plugins.md b/docs/plugins/integrating-search-into-plugins.md index d6f2037529..ec1c4e7a5a 100644 --- a/docs/plugins/integrating-search-into-plugins.md +++ b/docs/plugins/integrating-search-into-plugins.md @@ -248,7 +248,7 @@ You can also check out the documentation on [how to test Backstage plugin module Run `yarn start` in the root folder of your Backstage project and look for logs like these: ```sh -[backend]: YYYY-MM-DDTHH:MM:SS.000Z search info Task worker starting: search_index_faq_snippets, {"version":2,"cadence":"PT10M","initialDelayDuration":"PT3S","timeoutAfterDuration":"PT15M"} task=search_index_faq_snippets +[backend]: YYYY-MM-DDTHH:MM:SS.000Z search info Registered scheduled task: search_index_faq_snippets, {"version":2,"cadence":"PT10M","initialDelayDuration":"PT3S","timeoutAfterDuration":"PT15M"} task=search_index_faq_snippets [backend]: YYYY-MM-DDTHH:MM:SS.000Z search info Collating documents for faq-snippets via FaqSnippetsCollatorFactory documentType=faq-snippets [backend]: YYYY-MM-DDTHH:MM:SS.000Z search info Fetching faq snippets from https://backstage.example.biz/faq-snippets [backend]: YYYY-MM-DDTHH:MM:SS.000Z search info Collating documents for faq-snippets succeeded documentType=faq-snippets diff --git a/docs/plugins/new-backend-system.md b/docs/plugins/new-backend-system.md index 12525b9f95..cf983615b5 100644 --- a/docs/plugins/new-backend-system.md +++ b/docs/plugins/new-backend-system.md @@ -195,7 +195,7 @@ A `ServiceRef` is a named reference to an interface which are later used to reso Services is what provides common utilities that previously resided in the `PluginEnvironment` such as Config, Logging and Database. On startup the backend will make sure that the services are initialized before being passed to the plugin/module that depend on them. -ServiceRefs contain a scope which is used to determine if the serviceFactory creating the service will create a new instance scoped per plugin/module or if it will be shared. `plugin` scoped services will be created once per plugin/module and `root` scoped services will be created once per backend instance. +ServiceRefs contain a scope which is used to determine if the service factory creating the service will create a new instance scoped per plugin/module or if it will be shared. `plugin` scoped services will be created once per plugin/module and `root` scoped services will be created once per backend instance. #### Defining a Service diff --git a/docs/plugins/observability.md b/docs/plugins/observability.md index c294001606..7803d90bd5 100644 --- a/docs/plugins/observability.md +++ b/docs/plugins/observability.md @@ -1,7 +1,6 @@ --- id: observability title: Observability -# prettier-ignore description: Adding Observability to Your Plugin --- diff --git a/docs/plugins/proxying.md b/docs/plugins/proxying.md index b32ed4fe12..5182ee7171 100644 --- a/docs/plugins/proxying.md +++ b/docs/plugins/proxying.md @@ -4,6 +4,8 @@ title: Proxying description: Documentation on Proxying --- +This page describes how to configure and use the built-in HTTP proxy functionality in your Backstage backend. + ## Overview The Backstage backend comes packaged with a basic HTTP proxy, that can aid in diff --git a/docs/publishing.md b/docs/publishing.md index 3d23572ffe..e6c0b6b466 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -53,8 +53,6 @@ Additional steps for the main line release - Mention any security fixes - Create Release Notes PR - Add the release note file as [`/docs/releases/vx.y.0.md`](./releases) - - Add an entry to [`/microsite/sidebars.ts`](https://github.com/backstage/backstage/blob/master/microsite/sidebars.ts) for the release note - - Update the navigation bar item in [`/microsite/docusaurus.config.ts`](https://github.com/backstage/backstage/blob/master/microsite/docusaurus.config.ts) to point to the new release note - Finally copy the content, without the metadata header, into the description of the [`Version Packages` Pull Request](https://github.com/backstage/backstage/pulls?q=is%3Aopen+is%3Apr+in%3Atitle+%22Version+Packages) Once the release has been published edit the newly created release in the [GitHub repository](https://github.com/backstage/backstage/releases) and replace the text content with the release notes. diff --git a/docs/references/glossary.md b/docs/references/glossary.md index 906260e710..ad9e2bbee5 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -1,39 +1,48 @@ --- id: glossary title: Glossary -# prettier-ignore description: List of terms, abbreviations, and phrases used in Backstage, together with their explanations. --- ## Access Token -A [token](#token) that gives access to perform actions on behalf of a user. It will commonly have a short expiry time, and be limited to a set of [scopes](#scope). Part of the [OAuth](#oauth) protocol, see [their docs](https://oauth.net/2/access-tokens/) for more information. +A [token](#token) that represents the authorization to access resources on behalf of the end-user in a way that hides the user's actual identity. It will commonly have a short expiry time, and be limited to a set of [scopes](#scope). Part of the [OAuth](#oauth) protocol, see [their docs](https://oauth.net/2/access-tokens/) for details. ## Administrator -Someone responsible for installing and maintaining a Backstage [app](#app) for an organization. A [user role](#user-role). +Someone responsible for installing, configuring, and maintaining a Backstage [app](#app) for an organization. A [user role](#user-role). -## API (catalog plugin) +## API -An [entity](#entity) representing a schema that two [components](#component) use to communicate. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +A software interface consisting of defined rules, protocols, and tools, that allows two applications or [components](#component-catalog-plugin) to communicate and exchange data or functionality. + +APIs are key abstractions that allow large software ecosystems to be scaled efficiently. Within the Backstage model, APIs are first-class citizens, and are the primary method for discovering existing functionality across the ecosystem. See [Backstage System Model](https://backstage.io/docs/features/software-catalog/system-model/#api). ## App -An installed instance of Backstage. An app can be local, intended for a single development group or individual developer, or organizational, for use by an entire enterprise. +An installed instance of Backstage. An app can be local, intended for a single developer or development group, or organizational, for use by an entire enterprise. -## Authorization Code +## Authentication -A type of [OAuth flow](#oauth) used by confidential and public clients to get an [access token](#access-token). See [the OAuth docs](https://oauth.net/2/grant-types/authorization-code/) for more details. +The process of verifying the identity of a user, system, or entity attempting to access a resource, system, or network. It answers the question: "Are you who you claim to be?" See [this Wikipedia article](https://en.wikipedia.org/wiki/Authentication) for more details. + +## Authorization + +The process of determining which operations an authenticated user or system is allowed to perform within a system, application, or resource. It comes after authentication, and answers the question: "What are you allowed to access or do?" It involves assigning specific privileges, access rights, or roles to the user. See [this Wikipedia article](https://en.wikipedia.org/wiki/Authorization) for more details. + +## Authorization Code Grant + +See [Code Grant](#code-grant). ## Backstage -1. An open source framework for creating and deploying [developer portals](#developer-portal), originally created at Spotify. Backstage is an incubation-stage open source project of the [Cloud Native Computing Foundation](#cloud-native-computing-foundation). +1. An open source framework for creating and deploying [developer portals](#developer-portal), originally created at Spotify. Backstage is an incubation-stage open source project of the [Cloud Native Computing Foundation](#cloud-native-computing-foundation-aka-cncf). 2. [The Backstage Framework](#backstage-framework). ## Backstage Framework -The actual framework that Backstage [plugins](#plugin) sit on. This spans both the frontend and the backend, and includes core functionality such as declarative integration, config reading, database management, and many more. +The actual framework that Backstage [plugins](#plugin) sit on. The framework spans the frontend and backend, and includes core functionality such as declarative integration, config reading, database management, and much more. ## Bundle @@ -43,47 +52,49 @@ The actual framework that Backstage [plugins](#plugin) sit on. This spans both t ## Catalog -1. The core Backstage plugin that handle ingestion and display of your organizations software products. - -2. An organization's portfolio of software products managed in Backstage. +See [Software Catalog](#software-catalog). ## Cloud Native Computing -A set of technologies that "empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach." ([CNCF Cloud Native Definition v1.0](https://github.com/cncf/toc/blob/main/DEFINITION.md)). +A set of technologies that "empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach." ([CNCF Cloud Native Definition v1.1](https://github.com/cncf/toc/blob/main/DEFINITION.md)). -## Cloud Native Computing Foundation +## Cloud Native Computing Foundation (aka CNCF) -A foundation dedicated to the promotion and advancement of [Cloud Native Computing](#Cloud-Native-Computing). The mission of the Cloud Native Computing Foundation (CNCF) is "to make cloud native computing ubiquitous" ([CNCF Charter](https://github.com/cncf/foundation/blob/main/charter.md)). +A foundation dedicated to the promotion and advancement of [Cloud Native Computing](#cloud-native-computing). The mission of the Cloud Native Computing Foundation (CNCF) is "to make cloud native computing ubiquitous" ([CNCF Charter](https://github.com/cncf/foundation/blob/main/charter.md)). CNCF is part of the [Linux Foundation](https://www.linuxfoundation.org/). -## CNCF - -Cloud Native Computing Foundation. - ## Code Grant -[OAuth](#oauth) flow where the client receives an [authorization code](#code) that is passed to the backend to be exchanged for an [access token](#access-token) and possibly a [refresh token](#refresh-token). +In the context of [OAuth 2.0](https://oauth.net/2/), refers to the process where an application receives an [authorization code](#authorization-code-grant) after a user grants it permission to access their resources. This code is then exchanged for an [access token](#access-token) and possibly a [refresh token](#refresh-token), which the application uses to access the user's data on their behalf. It's a secure way for applications to access protected resources without directly handling the user's credentials. See the [OAuth docs](https://oauth.net/2/grant-types/authorization-code/) for details. ## Collator (search plugin) -A transformer that takes streams of [documents](#documents) and outputs searchable texts. They're usually responsible for the data transformation and definition and collection process for specific [documents](#documents). +A specialized component of Backstage that's responsible for ordering or indexing data according to a specific set of rules. In Backstage search, collators are used to define what can be searched. Specifically, they're readable object streams of documents that contain a minimum set of fields (including document title, location, and text), but can contain any other fields as defined by the collator itself. A single collator is responsible for defining and collecting documents of a specific type. + +Backstage includes "default" collators for Catalog and TechDocs that you can use out-of-the-box to start searching across Backstage quickly. More collators are available from the Backstage community. Learn more at [Collators](https://backstage.io/docs/features/search/collators). ## Component (catalog plugin) -A software product that is managed in the Backstage [Software Catalog](#software-catalog). A component can be a service, website, library, data pipeline, or any other piece of software managed as a single project. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +1. A modular, independent, reusable software-based unit that encapsulates specific functionality. It has well-defined interfaces, explicitly specified dependencies, and is designed to be integrated with other components to build larger software systems. + +2. A software product that Backstage manages in the [Software Catalog](#software-catalog). A component can be a service, website, library, data pipeline, or any other software artifact that's managed as a single entity. + +A Backstage component can implement [API](#api)s for other components to consume. In turn, it might consume APIs implemented by other components, or directly depend on components or resources that are attached to it at runtime. + +See the [Backstage System Model](https://backstage.io/docs/features/software-catalog/system-model/#component-catalog-plugin). ## Condition (permission plugin) -A mapping from a given entity to criteria a user must fulfill to perform an action on that entity. Examples include `isOwner`, `hasRole`, etc. +A criterion, evaluated on an entity, that a user must meet to be granted permission to perform an action on that entity within a permission plugin. Examples might include `isOwner` or `hasRole`. ## Conditional Decision (permission plugin) -A type of [decision](#policy-decision-permission-plugin) that allows for per-user evaluation of [conditions](#condition-permission-plugin) against a [resource](#resource-permission-plugin). See [Conditional Decisions](../permissions/concepts.md#conditional-decisions) +A [decision](#policy-decision-permission-plugin) mechanism, common in permission plugins, that evaluates real-time conditions (predicates) on a per-user basis to determine access or actions against a [resource](#resource-permission-plugin). This enables highly granular, context-aware control. See [Conditional Decisions](https://backstage.io/docs/permissions/concepts/#conditional-decisions). ## Contributor -A volunteer who helps to improve an OSS product such as Backstage. This volunteer effort includes coding, testing, technical writing, user support, and other work. A [user role](#user-role). +A volunteer who helps to improve an open source product such as Backstage. This volunteer effort includes coding, testing, technical writing, user support, and other work. A [user role](#user-role). ## Declarative Integration @@ -91,101 +102,139 @@ A new paradigm for Backstage frontend plugins, allowing definition in config fil ## Decorator (search plugin) -A transform stream that allows you to add additional information to [documents](#document-search-plugin). +A transform stream that operates during the indexing process, positioned between a [Collator](#collator-search-plugin) (read stream) and an Indexer (write stream). Document Decorators are used to modify documents by adding, removing, or filtering metadata, or even injecting new documents, as they are being prepared for the search index. + +To illustrate, while the [Software Catalog](#software-catalog) understands software entities, it might not track their usage or quality. A decorator can add this extra metadata, which can then be used to bias search results or enhance the search experience within your Backstage instance. ## Deployment Artifacts -An executable or package file with all of the necessary information required to deploy the application at runtime. Deployment artifacts can be hosted on [package registries](#package-registry). +An executable or [package](#package) file with all of the necessary information required to deploy at runtime. Deployment artifacts can be hosted on [package registries](#package-registry). ## Developer -1. Someone who writes code and develops software. +1. A professional who designs, builds, tests, deploys, and maintains software applications and systems. Developers essentially turn ideas or requirements into functional digital products. -2. A [user role](#user-role) defined as someone who uses a Backstage [app](#app). Might or might not actually be a software developer. +2. A [user role](#user-role) defined as someone who creates, modifies, or uses a Backstage [app](#app). Might or might not actually be a software developer. ## Developer Portal -A centralized system comprising a user interface and database used to facilitate and document all the software projects within an organization. Backstage is both a developer portal and (by virtue of being based on plugins) a framework for creating developer portals. +1. A centralized, self-service interface providing developers with all the necessary resources, tools, documentation, and information to effectively build, integrate, deploy, and manage software products within an organization. + +2. Backstage is a specific example of a developer portal, designed as a centralized system with a user interface and database to streamline development and maintenance of an organization's software projects. It features a robust [Software Catalog](#software-catalog) that centralizes and organizes access to the organization's services, websites, mobile features, libraries, and other software components. Backstage also includes [Software Templates](#software-templates-aka-scaffolder) that simplify the creation of new projects and components. + +Backstage is both a developer portal and a plugin-based framework for creating new custom developer portals. ## Document (search plugin) -An abstract concept representing something that can be found by searching for it. A document can represent a software entity, a TechDocs page, etc. Documents are made up of metadata fields, at a minimum -- a title, text, and location (as in a URL). +1. A piece of information or data that is recorded on some medium for the purpose of retention and conveyance. + +2. An abstract representation of information or data that can be discovered and retrieved. For search purposes, a document might represent a software entity, a TechDocs page, or any other type of data that is indexed. In Backstage, a document is structured with metadata fields that must include at least a title, a body (containing its core text content), and a location (such as a URL pointing to its source). ## Domain -An area that relates systems or entities to a business unit. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +1. A collection of systems that share terminology, domain models, metrics, KPIs, business purpose, or documentation; that is, it forms a bounded context. + +2. Typically the unique, human-readable address that is used to identify websites, email servers, and other resources on the internet, such as `google.com` or `example.store`. More narrowly, it can refer to the Top-Level Domain (TLD), which is the part of a web address after the last dot, such as `.com` or `.org`; the country code, such as `.us` or `.uk`; or the sponsored TLD such as `.gov` or `.edu`. + +3. An area that relates systems or entities to a business unit. See [Domain](https://backstage.io/docs/features/software-catalog/system-model/#domain) in the [System Model](https://backstage.io/docs/features/software-catalog/system-model/). ## Entity -What is cataloged in the Backstage Software Catalog. An entity is identified by a unique combination of [kind](#Kind), [namespace](#Namespace), and name. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +1. Something that exists as a separate and distinct unit. Its existence can be real or abstract, physical or conceptual, persistent or ephemeral. + +2. What is cataloged in the Backstage [Software Catalog](#software-catalog). An entity is identified by a unique combination of [kind](#kind), [namespace](#namespace-catalog-plugin), and name. See [The Life of an Entity](https://backstage.io/docs/features/software-catalog/life-of-an-entity) for related key concepts and how it's handled. ## Evaluator -Someone who assesses whether Backstage is a suitable solution for their organization. The only [user role](#user-role) with a pre-deployment [use case](#use-case). +Someone who assesses whether Backstage is a suitable solution for their organization and needs. The only [user role](#user-role) with a pre-deployment [use case](#use-case). ## ID Token -A [JWT](#jwt) used to prove a user's identity, containing for example the user's email. Part of [OpenID Connect](#openid-connect). +A security token used in authentication processes, primarily defined by the [OpenID Connect (OIDC) standard](#openid-connect-aka-oidc). Its main purpose is to prove that a user has been successfully authenticated by an identity provider. See [JSON Web Token](#json-web-token-aka-jwt). ## Index (search plugin) -An index is a collection of [documents](#documents) of a given type. +A collection of [documents](#document-search-plugin) that a search engine uses to quickly locate relevant information within your developer portal. It's essentially a lookup table that allows you to quickly find documents without having to scan the entire dataset. ## Indexer (search plugin) -A write stream of [documents](#documents). +In Backstage's Search Platform, the term _indexer_ isn't a component or concept that developers typically interact with. Instead, it refers to the overall process or the _write stream_ within the Search backend that takes processed documents and adds them to the chosen search engine's index. + +To understand _indexer_ in Backstage, it's helpful to understand the flow of data into the Search system: + +1. A [Collator](#collator-search-plugin) reads raw data from a specific source and transforms it into a stream of [documents](#document-search-plugin), where each document is formatted in a way the search platform understands (e.g., having title, text, location fields, and potentially other metadata). + +2. As the stream of documents flows from the collator, a [decorator](#decorator-search-plugin) can intercept them. The decorator optionally adds, removes, or modifies fields within the documents to enrich them with context that the original collator might not have (such as adding ownership information from the Catalog to TechDocs documents). + +3. After optional decoration, the stream of finalized search documents is then written to the search engine's index. This is what the term _indexer_ implicitly refers to. It's the functionality that takes these structured documents and inserts them into the chosen search engine (like Lunr, PostgreSQL, or Elasticsearch) so they become searchable. + +The `plugin-search-backend-node` package in Backstage is responsible for orchestrating this entire indexing process. It manages the collators, decorators, the connection to the specific search engine, and the scheduling of when these indexing tasks run. ## Integrator -Someone who develops one or more plugins that enable Backstage to interoperate with another software system. A [user role](#user-role). +1. Someone who develops one or more plugins that enable Backstage to interoperate with another software system. A [user role](#user-role). -## JWT +2. May refer to someone who develops software that integrates with Backstage. -JSON Web Token. +## JSON Web Token (aka JWT) -A popular JSON based token format that is commonly encrypted and/or signed, see [the Wikipedia article](https://en.wikipedia.org/wiki/JSON_Web_Token) for more details. +A popular, compact, and self-contained open standard for securely transmitting information between parties as a JSON object. It is commonly used to verify a user's identity ([authentication](#authentication)) and permissions ([authorization](#authorization)). Each JWT consists of a header, payload, and digital signature separated by dots. JWTs are often encrypted, and are always signed for integrity. + +This standard is a key component of [OpenID Connect](#openid-connect-aka-oidc). For more details, see [this Wikipedia article](https://en.wikipedia.org/wiki/JSON_Web_Token). ## Kind -Classification of an [entity](#Entity) in the Backstage Software Catalog, for example _service_, _database_, and _team_. +Classification of an [entity](#entity) in the Backstage Software Catalog, for example _service_, _database_, or _team_. An element of the [kind|namespace|name triplet](#kind-namespace-name-triplet) that is an important concept for uniqueness. -## Kubernetes (CNCF Project) +## Kind|namespace|name triplet -An open-source system for automating deployment, scaling, and management of containerized applications. +The primary reference for [Software Catalog](#software-catalog) entities. It is human-readable and should be unique across your Backstage instance. ## Kubernetes (Backstage plugin) A core Backstage plugin enabling a service owner-focused view of Kubernetes resources. +## Kubernetes (CNCF Project) + +Kubernetes (K8s) is an open-source platform that automates the deployment, scaling, and management of containerized applications. Originally developed at Google to manage its production workloads, it was later offered to the [Cloud Native Computing Foundation (CNCF)](#cloud-native-computing-foundation-aka-cncf) for open-source support and maintenance. + +According to its [official website](https://kubernetes.io/), Kubernetes automatically handles rollouts, rollbacks, and load balancing. It mounts storage systems, dynamically allocates containers based on resource requirements and other constraints, manages batch execution, restarts crashed containers, and more. For additional information, see the [Kubernetes article](https://en.wikipedia.org/wiki/Kubernetes) on Wikipedia. + ## Local Package -One of the [packages](#package) within a [monorepo](#monorepo). These package may or may not also be published to a [package registry](#package-registry). +One of the [packages](#package) within a [monorepo](#monorepo). A package may or may not also be published to a [package registry](#package-registry). ## Monorepo 1. A single repository for a collection of related software projects, such as all projects belonging to an organization. -2. A project layout that consists of multiple [packages](#package) within a single project, where packages are able to have local dependencies on each other. Often enabled through tooling such as [lerna](https://lerna.js.org/) and [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) +2. A project layout that consists of multiple [packages](#package) within a single project, where packages are able to have local dependencies on each other. Often enabled through tooling such as [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) + +## Name + +To be completed. An element of the [kind|namespace|name triplet](#kind-namespace-name-triplet) that is an important concept for uniqueness. ## Namespace (catalog plugin) -An optional attribute that can be used to organize [entities](#entity). - -## Objective - -A high level goal of a [user role](#User-Role) interacting with Backstage. Some goals of the _administrator_ user role, for example, are to maintain an instance ("app") of Backstage; to add and update functionality via plugins; and to troubleshoot issues. +An optional attribute that can be used to organize [entities](#entity). An element of the [kind|namespace|name triplet](#kind-namespace-name-triplet) that is an important concept for uniqueness. ## OAuth -Refers to: OAuth 2.0, a standard protocol for authorization. See [oauth.net/2/](https://oauth.net/2/). +Refers to [OAuth 2.0](https://oauth.net/2/), an industry-standard authorization framework that allows a website or application (the "client") to access protected resources (like user data or functionality) on a different service (the "resource server") on behalf of a user (the "resource owner"), without sharing the user's login credentials with the client application. + +See [OAuth 2.0 explained](https://connect2id.com/learn/oauth-2) for descriptions of OAuth 2.0 and [OIDC](#openid-connect-aka-oidc) (which is built on top of OAuth 2.0). + +## Objective + +A high-level goal of a [user role](#user-role) interacting with Backstage. For example, some objectives of the [administrator](#administrator) user role are to maintain an instance ([app](#app)) of Backstage, to add and update functionality via plugins, and to troubleshoot issues. ## Offline Access -[OAuth](#oauth) flow that results in both a refresh token and [access token](#access-token), where the refresh token has a long expiration or never expires, and can be used to request more access tokens in the future. This lets the user go "offline" with respect to the token issuer, but still be able to request more tokens at a later time without further direct interaction for the user. +[OAuth 2.0](https://oauth.net/2/) flow that results in both a [refresh token](#refresh-token) and an [access token](#access-token), where the refresh token has a long expiration or never expires, and can be used to request more access tokens in the future. This lets the user go "offline" with respect to the token issuer, but still be able to request more tokens at a later time without further direct interaction for the user. -## OpenID Connect +## OpenID Connect (aka OIDC) -A layer on top of [OAuth](#oauth) which standardises authentication. See [the Wikipedia article](https://en.wikipedia.org/wiki/OpenID_Connect) for more details. +A layer on top of [OAuth 2.0](https://oauth.net/2/) which standardises authentication. See [this Wikipedia article](https://en.wikipedia.org/wiki/OpenID_Connect) for details. ## OSS @@ -193,7 +242,9 @@ Open source software. ## Package -A package in the Node.js ecosystem, often published to a [package registry](#package-registry). +1. A bundled collection of executable files, libraries, configuration files, metadata, and other necessary components that allow a piece of software (or a group of related software) to be easily installed, managed, and used. It's a standardized format for distributing software that simplifies installation by ensuring all dependencies are included or easily resolvable, provides integrity checks, and enables easy upgrades or removal. + +2. A package in the Node.js ecosystem, often published to a [package registry](#package-registry). ## Package Registry @@ -201,15 +252,23 @@ A service that hosts [packages](#package). The most prominent example is [NPM](h ## Package Role -The declared role of a package, see [package roles](../tooling/cli/02-build-system.md#package-roles). +The declared role of a package, see [package roles](https://backstage.io/docs/tooling/cli/build-system#package-roles). -## Permission (core Backstage plugin) +## Permission -A core Backstage plugin and framework that allows restriction of actions to specific users. See [their docs](https://backstage.io/docs/permissions/overview) for more information. +Specific rules or settings that define the level of access and types of actions that a user, group, or system process is allowed to perform on a particular resource. Permissions are a core component of authorization that determine "what you can do" after you've been authenticated. Permissions are properties of objects or resources. Closely related to [Privilege](#privileges) (the terms are often used interchangeably). ## Permission (permission plugin) -A restriction on any action that a user can perform against a specific [resource](#resource-permission-plugin) or set of resources. See [the permission framework docs](../permissions/concepts.md#permission) for more details. +1. A core Backstage plugin and framework that allows actions to be limited to specific users. + +2. A rule that determines whether a user is authorized to access a specific [resource](#resource-permission-plugin) or set of resources if a specified set of conditions exists. + +By default, Backstage endpoints are unprotected; any user can perform any action on any resource. The Permission framework addresses this by enabling integrators to configure rules that specify precisely which users can access which resources and actions. Within this framework, a _permission_ is a uniquely named set of rules (or _conditions_) and the results to return based on their evaluation. + +An example might be a permission rule that returns `false` if an entity is not part of a system, where the entity and system are configured for the rule. (See [Defining custom permission rules](https://backstage.io/docs/permissions/custom-rules) for the example.) + +See the Permissions [Overview](https://backstage.io/docs/permissions/overview) and [Concepts](https://backstage.io/docs/permissions/concepts/) for details. ## Persona (use cases) @@ -217,98 +276,141 @@ Alternative term for a [User Role](#user-role). ## Plugin -A module in Backstage that adds a feature. All functionality outside of [the Backstage framework](#backstage-framework), even the core features, are implemented as plugins. +The fundamental building block that adds specific features, functionalities, and integrations to your developer portal. All functionality outside of [the Backstage framework](#backstage-framework), even core features, are implemented as plugins. This modular architecture is a key differentiator of Backstage, making it highly customizable and extensible. + +A plugin is a self-contained unit of code designed to perform a specific task or integrate with an external system. Instead of a monolithic application, Backstage is assembled from a collection of these independent plugins. + +A single logical plugin often consists of both a frontend (UI) component and a backend (API) component. + +- Frontend plugins are typically written in React and TypeScript to provide the user interface elements such as pages, cards, sidebar items, and dashboards that developers interact with. +- Backend plugin are written in Node.js and TypeScript, and handle data fetching, business logic, integrations with external services (like Git providers, CI/CD systems, and cloud platforms), and expose APIs for the frontend to consume. + +There are different types of plugins (run `yarn new` to see them). The current list includes: + +- `plugin` - A new frontend plugin +- `backend-plugin` - A new backend plugin +- `backend-module` - A new backend module +- `web-library` - A new web-library package +- `plugin-common` - A new isomorphic common plugin package +- `plugin-node` - A new `Node.js` library plugin package +- `plugin-react` - A new web library plugin package + +See [Introduction to Plugins](https://backstage.io/docs/plugins/) for how to create a plugin, suggest a plugin, and integrate a plugin into the Software Catalog. See [Create a Backstage Plugin](https://backstage.io/docs/plugins/create-a-plugin/) for how to create a frontend plugin. + +See [Plugin directory](https://backstage.io/plugins/) for a list of community driven plugins, although there is a community plugins repository that contains many more that might not be in that page. ## Policy (permission plugin) -A construct that takes in a Backstage user and a [permission](#permission-permission-plugin) and returns a [policy decision](#policy-decision-permission-plugin). +The central component of the Backstage permission framework that dictates who can do what, to which resources, and under what conditions. + +Backstage policies are implemented as functions or sets of rules that receive a request (containing information about a user and a desired permission/action on a resource) and return an authorization decision (allow, deny, or a conditional decision). Policies are independent of the [authorization](#authorization) model, such as role-based access control or attribute-based access control. See [Policy](https://backstage.io/docs/permissions/concepts/#policy-permission-plugin). + +Policies are defined in Typescript code in the permissions framework. See [Writing a permission policy](https://backstage.io/docs/permissions/writing-a-policy) for examples. ## Policy Decision (permission plugin) -A specific response to a user's request to perform an action on a list of [resources](#resource-permission-plugin). Can be either `Approve`, `Deny` or [`Conditional`](#conditional-decision-permission-plugin). +A specific response to a user's request to perform an action on a list of [resources](#resource-permission-plugin). Can be either `Approve`, `Deny` or `Conditional`. In Backstage, policies are only responsible for decisions regarding whether requests can be approved; the requestors (typically the backend) are responsible for enforcing those decisions. See [Policy decision versus enforcement](https://backstage.io/docs/permissions/concepts/#policy-decision-versus-enforcement). ## Popup -A separate browser window opened on top of the previous one. +A separate browser window that opens on top of the previous one. + +## Privileges + +The term _privilege_ is not a defined abstraction in the context of the Backstage permission framework's core concepts. Instead, Backstage's authorization model is built around [permissions](#permission), [policies](#policy-permission-plugin), and [conditions](#condition-permission-plugin) to determine what actions a user can take on a resource. If you encounter _privilege_ in a Backstage context, it's likely being used in a more general, colloquial sense of "level of access" or referring to a concept. + +Outside of Backstage contexts, _privilege_ typically refers to specific rules or settings that define what a user or process is allowed to do within the system, often relating to system-wide operations or capabilities. Privilege is closely related to [Permission](#permission); the terms are often used interchangeably. ## Procedure (use cases) -A set of actions that accomplish a goal, usually as part of a [use case](#Use-Case). A procedure can be high-level, containing other procedures, or can be as simple as a single [task](#Task). +A set of actions that accomplish a goal, usually as part of a [use case](#use-case). A procedure can be high-level, containing other procedures, or can be as simple as a single [task](#task-use-cases). ## Query Translators (search plugin) -An abstraction layer between a search engine and the [Backstage Search](#search) backend. Allows for translation into queries against your search engine. +An abstraction layer between a search engine and the [Backstage Search](#search) backend. It is an optional backend component that takes an abstract search query---which includes search terms, filters, and desired document types from a Backstage search client—--and transforms it into a concrete query that's optimized for a specific [Search Engine](#search-engine-backstage-search) used by Backstage. + +This translation layer is crucial because it enables Backstage components to utilize the distinct features of individual search engines (like Elasticsearch or Solr) while maintaining loose coupling from their detailed interfaces. Although Backstage's pre-packaged Search Engines come with simple, built-in translators, you can implement custom Query Translators to significantly enhance and tune search results for your organization's unique context. ## Refresh token -A special token that an [OAuth](#oauth) client can use to get a new [access token](#access-token) when the latter expires. - -https://oauth.net/2/refresh-tokens/ +A special token that an [OAuth](#oauth) client can use to get a new [access token](#access-token) when the latter expires. See [OAuth Refresh Tokens](https://oauth.net/2/refresh-tokens/). ## Resource (catalog plugin) -An [entity](#entity) that represents a piece of physical or virtual infrastructure, for example a database, required by a component. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +An [entity](#entity) that represents a piece of physical or virtual infrastructure, such as a database, that's required by a component. See the [System Model](https://backstage.io/docs/features/software-catalog/system-model). ## Resource (permission plugin) A representation of an object that a user interacts with and that can be permissioned. Not to be confused with [Software Catalog resources](#resource-catalog-plugin). -## Rule (permission plugin) - -A predicate-based control that taps into a [resource](#resource-permission-plugin)'s data. - ## Role -See [User Role](#User-Role). +See [User Role](#user-role). + +## Rule (permission plugin) + +A specific type of dynamic access control associated with a [resource](#resource-permission-plugin) it protects. A simple example might be "the current user can access Resource X if Condition Y is true." The catalog plugin defines a resource for catalog entities and rules to check if an entity has a given annotation. ## Scaffolder -Known as [Software Templates](#software-templates). +Another name for [Software Templates](#software-templates-aka-scaffolder). (The term comes from the use of Software Templates as _scaffolds_ for building new components and projects.) ## Scope -A string that describes a certain type of access that can be granted to a user using OAuth, usually in conjunction with [access tokens](#access-token). +A string that describes a certain type of access that can be granted to a user using [OAuth](#oauth), usually in conjunction with [access tokens](#access-token). + +In [OAuth](#oauth), access control is managed through _scopes_ that define specific permissions granted to the application. An OAuth service can issue Access Tokens that are tied to particular sets of scopes, such as viewing profile information, or reading or writing user data. The format and handling of scopes are unique to each OAuth provider, with available scopes typically detailed in their authentication solution's documentation (see [https://developers.google.com/identity/protocols/oauth2/scopes](https://developers.google.com/identity/protocols/oauth2/scopes) for an example). + +For more information about scopes and OAuth, see [OAuth and OpenID Connect](https://backstage.io/docs/auth/oauth/). ## Search -A Backstage plugin that provides a framework for searching a Backstage [app](#app), including the [Software Catalog](#Software-Catalog) and [TechDocs](#TechDocs). A core feature of Backstage. +A Backstage plugin that provides a framework for searching a Backstage [app](#app), including the [Software Catalog](#software-catalog) and [TechDocs](#techdocs). A core feature of Backstage. ## Search Engine (Backstage search) -Existing search technology that [Backstage Search](#search) can take advantage of through its modular design. Lunr is the default search in Backstage Search. +Existing search technology that [Backstage Search](#search) can take advantage of through its modular design. Lunr is the default search in Backstage Search. Can be one of the search engines that are pre-packaged with Backstage or chosen specifically for your instance. ## Software Catalog -A Backstage plugin that provides a framework to keep track of ownership and metadata for any number and type of software [components](#component). A core feature of Backstage. +1. A centralized system that keeps track of ownership and metadata for all software in your ecosystem (services, websites, libraries, data pipelines, etc.). The catalog is built around metadata YAML files that are stored with the code, and are harvested and visualized in Backstage. -## Software Templates +2. The Backstage plugin that implements the Software Catalog feature. A core feature of Backstage. -A Backstage plugin with which to create [components](#component) in Backstage. A core feature of Backstage. Also known as the scaffolder. +The Software Catalog is a core feature of Backstage. See [Backstage Software Catalog](https://backstage.io/docs/next/features/software-catalog/) for an overview, the life of an entity in the catalog, how to configure the catalog, its architecture and high-level design, how to configure and customize it, and its API. The overview describes how the catalog works, how to add components to it, how to find software in it, and more. -## Software Template +## Software Templates (aka Scaffolder) -A "skeleton" software project created and managed in the Backstage Software Templates tool. +1. A "skeleton" software project created and managed in the Backstage Software Templates tool. + +2. A Backstage plugin for creating [components](#component-catalog-plugin) in Backstage. By default, it has the ability to load skeletons of code, template in some variables, and then publish the template to some locations like GitHub or GitLab. + +Software Templates is a core feature of Backstage. It's also known as the [Scaffolder](#scaffolder) for its utility in building new software components and projects. See [Backstage Software Templates](https://backstage.io/docs/features/software-templates/) for an overview, how to configure it, add your own templates, write a template, test it, and more. The overview describes such information as how to get started, choose a template, verify your inputs, run the template, and see a demo. ## System (catalog plugin) -A system is a collection of [entities](#entity) that cooperate to perform a function. A system generally provides one or a few public APIs and consists of a handful of components, resources and private APIs. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +A collection of [entities](#entity) that cooperate to perform a function. A system generally consists of a handful of components, resources, and private or public APIs. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model). ## Task (use cases) -A low-level step-by-step [Procedure](#Procedure). +A low-level step-by-step [procedure](#procedure-use-cases) to achieve a particular result. ## TechDocs -A documentation solution that manages and generates a technical documentation from Markdown files stored with software component code. A core feature of Backstage. +A documentation solution for generating and managing technical documentation in Markdown files that are stored with software component code. A core feature of Backstage. See [TechDocs Documentation](https://backstage.io/docs/features/techdocs/). ## Token -A string containing information. +A string containing information. The format and content depend on its purpose and how it's used. ## Use Case -A purpose for which a [user role](#User-Role) interacts with Backstage. Related to [Objective](#objective): An objective is _what_ the user wants to do; a use case is _how_ the user does it. +A purpose for which a [user role](#user-role) interacts with Backstage. Related to [Objective](#objective): An objective is _what_ a user wants to accomplish; a use case is _how_ the user does it. + +## User + +Any consumer of Backstage or Backstage products/applications. This includes individuals like employees and contractors, as well as software that interacts with the backend through an API or acts as a proxy for a person by operating the user interface. ## User Role -A class of Backstage user for purposes of analyzing [use cases](#use-case). One of: evaluator; administrator; developer; integrator; and contributor. +A class of Backstage user who has permissions to use Backstage for a particular set of [use cases](#use-case). One of: [evaluator](#evaluator); [administrator](#administrator); [developer](#developer); [integrator](#integrator); and [contributor](#contributor). diff --git a/docs/releases/v1.39.0-changelog.md b/docs/releases/v1.39.0-changelog.md new file mode 100644 index 0000000000..feae6629d4 --- /dev/null +++ b/docs/releases/v1.39.0-changelog.md @@ -0,0 +1,2850 @@ +# Release v1.39.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.39.0](https://backstage.github.io/upgrade-helper/?to=1.39.0) + +## @backstage/plugin-catalog-backend@2.0.0 + +### Major Changes + +- 90ab044: **BREAKING**: Removed all deprecated exports, and removed support for the old backend system. + + It also removes the `CodeOwnersProcessor` from the default set of processors, because it is expensive to run and has vague semantics. You need to update your backend to add it to the `catalogProcessingExtensionPoint` if you wish to continue using it. + + The following removed exports are available from `@backstage/plugin-catalog-node`: + + - `locationSpecToMetadataName` + - `locationSpecToLocationEntity` + - `processingResult` + - `EntitiesSearchFilter` + - `EntityFilter` + - `DeferredEntity` + - `EntityRelationSpec` + - `CatalogProcessor` + - `CatalogProcessorParser` + - `CatalogProcessorCache` + - `CatalogProcessorEmit` + - `CatalogProcessorLocationResult` + - `CatalogProcessorEntityResult` + - `CatalogProcessorRelationResult` + - `CatalogProcessorErrorResult` + - `CatalogProcessorRefreshKeysResult` + - `CatalogProcessorResult` + - `EntityProvider` + - `EntityProviderConnection` + - `EntityProviderMutation` + - `AnalyzeOptions` + - `LocationAnalyzer` + - `ScmLocationAnalyzer` + - `PlaceholderResolver` + - `PlaceholderResolverParams` + - `PlaceholderResolverRead` + - `PlaceholderResolverResolveUrl` + - `parseEntityYaml` + + The following removed exports are available from `@backstage/plugin-catalog-common`: + + - `LocationSpec` + - `AnalyzeLocationRequest` + - `AnalyzeLocationResponse` + - `AnalyzeLocationExistingEntity` + - `AnalyzeLocationGenerateEntity` + - `AnalyzeLocationEntityField` + + The following removed exports are instead implemented in the new backend system by `@backstage/plugin-search-backend-module-catalog`: + + - `defaultCatalogCollatorEntityTransformer` + - `CatalogCollatorEntityTransformer` + - `DefaultCatalogCollator` + + The following exports are removed without a direct replacement: + + - `DefaultCatalogCollatorFactory` + - `DefaultCatalogCollatorFactoryOptions` + - `LocationEntityProcessor` + - `LocationEntityProcessorOptions` + - `CatalogBuilder` + - `CatalogEnvironment` + - `CatalogPermissionRuleInput` + - `CatalogProcessingEngine` + - `createRandomProcessingInterval` + - `ProcessingIntervalFunction` + +### Minor Changes + +- 6c9b88e: **BREAKING ALPHA**: You can no longer import the catalog plugin from the `/alpha` export; please use the regular root default export instead. +- d88b922: Adds the ability to disable the default entity processors using a new boolean app config item `catalog.disableDefaultProcessors`. + +### Patch Changes + +- 0e710fc: This patch addresses an issue identified in Backstage when configured with a MySQL database. If an entity of type location + (e..all.yaml) has more than 70 referenced entities, clicking "Refresh" does not update the referenced entities as expected. This occurs because the TEXT type in MySQL has a limit of 65,535 bytes, which is insufficient to store all the referenced entities, causing the refresh operation to fail. +- 8e0f15f: "Added a note clarifying that `entity-fetch` audit events are not visible by default in the logs and are only displayed when the log severity level is adjusted." +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/catalog-client@1.10.0 + - @backstage/backend-openapi-utils@0.5.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/backend-defaults@0.10.0 + +### Minor Changes + +- d385854: **BREAKING**: The `DefaultSchedulerService` constructor options now requires `RootLifecycleService`, `HttpRouterService`, and `PluginMetadataService` fields. + + The scheduler will register a REST API for listing and triggering tasks. Please see [the scheduler documentation](https://backstage.io/docs/backend-system/core-services/scheduler) for more details about this API. + +### Patch Changes + +- 1e06afd: `GithubUrlReader`'s search detects glob-patterns supported by `minimatch`, instead of just detecting + `*` and `?` characters. + + For example, this allows to search for patterns like `{C,c}atalog-info.yaml`. + +- acea1d4: update documentation + +- 72d019d: Removed various typos + +- c6bc67d: Added Valkey support alongside Redis in backend-defaults cache clients, using the new Keyv Valkey package. Also extended backend-test-utils to support Valkey in tests. + +- 36f77e9: Bug fix: Pass user provided token through to gitlab url resolvers + +- 0e7a640: The `GithubUrlReader` will now use the token from `options` when fetching repo details + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-app-api@1.2.3 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/config-loader@1.10.1 + - @backstage/integration-aws-node@0.1.16 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/backend-dynamic-feature-service@0.7.0 + +### Minor Changes + +- 10f693c: **BREAKING** Removed support for the legacy backend, please migrate to the new backend system + +### Patch Changes + +- 72d019d: Fixed various typos. + `FrontendRemoteResolver`'s misspelled `getAdditionaRemoteInfo` has been deprecated. Use the correct spelling `getAdditionalRemoteInfo` instead. +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.0 + - @backstage/backend-defaults@0.10.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config-loader@1.10.1 + - @backstage/backend-openapi-utils@0.5.3 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.33 + - @backstage/plugin-events-backend@0.5.2 + - @backstage/plugin-events-node@0.4.11 + - @backstage/plugin-search-backend-node@1.3.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/backend-test-utils@1.5.0 + +### Minor Changes + +- b3832d1: Add a functional `mockServices.events()` +- c6bc67d: Added Valkey support alongside Redis in backend-defaults cache clients, using the new Keyv Valkey package. Also extended backend-test-utils to support Valkey in tests. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0 + - @backstage/backend-app-api@1.2.3 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/canon@0.4.0 + +### Minor Changes + +- ea36f74: **Breaking Change** Icons on Button and IconButton now need to be imported and placed like this: <Button iconStart={} /> +- ccb1fc6: We are modifying the way we treat custom render using 'useRender()' under the hood from BaseUI. +- 04a65c6: The icon prop in TextField now accept a ReactNode instead of an icon name. We also updated the icon sizes for each input sizes. + +### Patch Changes + +- c8f32db: Use correct colour token for TextField clear button icon, prevent layout shift whenever it is hidden or shown and properly size focus area around it. Also stop leading icon shrinking when used together with clear button. +- e996368: Fix Canon missing dependencies +- 720033c: For improved a11y, clicking a Select component label now focuses the Select trigger element, and the TextField component's label is now styled to indicate it's interactive. +- 6189bfd: Added new icon and onClear props to the TextField to make it easier to accessorize inputs. +- 9510105: Add new Tabs component to Canon +- 97b25a1: Pin version of @base-ui-components/react. +- 206ffbe: Fixed an issue with Canon's DataTable.Pagination component showing the wrong number for the "to" count. +- 72d019d: Removed various typos +- 4551fb7: Update Menu component in Canon to make the UI more condensed. We are also adding a new Combobox option for nested navigation. +- 185d3a8: Use the Field component from Base UI within the TextField. +- 1ea1db0: Add new truncate prop to Text and Heading components in Canon. + +## @backstage/catalog-client@1.10.0 + +### Minor Changes + +- 1a003ff: Add `getLocations` method to `CatalogApi` and `CatalogClient`. This method calls the [`GET /locations`](https://backstage.io/docs/features/software-catalog/software-catalog-api/#get-locations) endpoint from the catalog backend. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/core-app-api@1.17.0 + +### Minor Changes + +- 1e0230e: Support custom `AuthConnector` for `OAuth2`. + + A user can pass their own `AuthConnector` implementation in `OAuth2` constructor. + In which case the session manager will use that instead of the `DefaultAuthConnector` to interact with the + authentication provider. + + A custom `AuthConnector` may call the authentication provider from the front-end, store and retrieve tokens + in the session storage, for example, and otherwise send custom requests to the authentication provider and + handle its responses. + + Note, that if the custom `AuthConnector` transforms scopes returned from the authentication provider, + the transformation must be the same as `OAuth2CreateOptions#scopeTransform` passed to `OAuth2` constructor. + See creating `DefaultAuthConnector` in `OAuth2#create(...)` for an example. + +### Patch Changes + +- 73f6cc3: Updated `I18nextTranslationApi` to support interpolation of JSX elements. +- cc119b2: Fixed an issue causing `OAuthRequestDialog` to re-render on mount. +- Updated dependencies + - @backstage/core-plugin-api@1.10.7 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/integration@1.17.0 + +### Minor Changes + +- d945206: Added support for federated credentials using managed identities in the Azure DevOps integration. Federated credentials are only available for Azure DevOps organizations that have been configured to use Entra ID for authentication. + + ```diff + integrations: + azure: + - host: dev.azure.com + credentials: + + - clientId: ${APP_REGISTRATION_CLIENT_ID} + + managedIdentityClientId: system-assigned + + tenantId: ${AZURE_TENANT_ID} + ``` + + This also adds support for automatically using the system-assigned managed identity of an Azure resource by specifying `system-assigned` as the client ID of the managed identity. + + ```diff + integrations: + azure: + - host: dev.azure.com + credentials: + - - clientId: ${AZURE_CLIENT_ID} + + - clientId: system-assigned + ``` + +- f134cea: Implement Edit URL feature for Gerrit 3.9+. + + It's possible to disable the edit url by adding the `disableEditUrl: true` config in the Gerrit integration. + +### Patch Changes + +- f3381d3: Added missing `organizations` property to `azure` section in `config.d.ts` file +- acea1d4: update documentation +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend@0.25.0 + +### Minor Changes + +- 57221d9: **BREAKING**: Removed support for the old backend system, and removed all deprecated exports. + + If you were using one of the deprecated imports from this package, you will have to follow the instructions in their respective deprecation notices before upgrading. Most of the general utilities are available from `@backstage/plugin-auth-node`, and the specific auth providers are available from dedicated packages such as for example `@backstage/plugin-auth-backend-module-github-provider`. See [the auth docs](https://backstage.io/docs/auth/) for specific instructions. + +### Patch Changes + +- 0d606ac: Added the configuration flag `auth.omitIdentityTokenOwnershipClaim` that causes issued user tokens to no longer contain the `ent` claim that represents the ownership references of the user. + + The benefit of this new flag is that issued user tokens will be much smaller in + size, but they will no longer be self-contained. This means that any consumers + of the token that require access to the ownership claims now need to call the + `/api/auth/v1/userinfo` endpoint instead. Within the Backstage ecosystem this is + done automatically, as clients will still receive the full set of claims during + authentication, while plugin backends will need to use the `UserInfoService` + which already calls the user info endpoint if necessary. + + When enabling this flag, it is important that any custom sign-in resolvers directly return the result of the sign-in method. For example, the following would not work: + + ```ts + const { token } = await ctx.issueToken({ + claims: { sub: entityRef, ent: [entityRef] }, + }); + return { token }; // WARNING: This will not work with the flag enabled + ``` + + Instead, the sign-in resolver should directly return the result: + + ```ts + return ctx.issueToken({ + claims: { sub: entityRef, ent: [entityRef] }, + }); + ``` + +- 72d019d: Removed various typos + +- ab53e6f: Added support for the new `dangerousEntityRefFallback` option for `signInWithCatalogUser` in `AuthResolverContext`. + +- b128ed9: The `static` key store now issues tokens with the same structure as other key stores. Tokens now include the `typ` field in the header and the `uip` (user identity proof) in the payload. + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-bitbucket-cloud-common@0.3.0 + +### Minor Changes + +- 5850717: Update Bitbucket Cloud schema and models. + + The latest schema was fetched from Bitbucket Cloud and stored locally. + Based on the updated schema, the models got regenerated. + + **BREAKING:** + + Due to the schema changes, the model update includes one breaking change: + + - `Account.username` was removed. + + Additionally, there were a couple of compatible changes including the addition of + `BaseCommit.committer` and others. + +### Patch Changes + +- 57ad208: Add support for `repo:updated` events as `Events.RepoUpdatedEvent`. +- Updated dependencies + - @backstage/integration@1.17.0 + +## @backstage/plugin-catalog@1.30.0 + +### Minor Changes + +- 970cb48: Show the pagination text for the offset-paginated catalog table, and remove the pagination bar from the top of the `CatalogTable` when pagination is enabled. + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 2ddbc50: A new `filter` parameter has been added to `EntityContextMenuItemBlueprint` to make it easier to configure which entities a menu item should appear for. The `filter` parameter is a function which accepts an entity and returns a boolean. +- bf85d37: Fix for missing `routeRef` when using `core-plugin-api` in a dialog context +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-scaffolder-common@1.5.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.0 + +### Minor Changes + +- e4dabc6: add new gitea provider module + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-github@0.9.0 + +### Minor Changes + +- ff335e5: **BREAKING** The `GithubLocationAnalyzer` now requires the `AuthService` and the `CatalogService` when being constructed and the `TokenManger` has been removed. + +### Patch Changes + +- ee9f59f: Added filter to include archived repositories +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-backend@2.0.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.0 + +### Minor Changes + +- 10f693c: **BREAKING** Removed support for the legacy backend, please [migrate to the new backend system](https://github.com/backstage/backstage/tree/v1.38.0/plugins/catalog-backend-module-incremental-ingestion#installation). Also, if you were importing from the `/alpha` export of this package, you should remove the `/alpha` part. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.0 + - @backstage/backend-defaults@0.10.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-catalog-backend-module-msgraph@0.7.0 + +### Minor Changes + +- 20c1ea7: Add new `userGroupMember.path`, `user.path` and, `group.path` option to each query type to allow more complex msgraph queries + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.0 + +### Minor Changes + +- f453d5c: **BREAKING** Removed support for the legacy backend and removed references to `@backstage/backend-common`, please [migrate to the new backend system](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating) + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.8 + +## @backstage/plugin-catalog-import@0.13.0 + +### Minor Changes + +- e2fd549: **BREAKING**: `generateStepper` and `defaultGenerateStepper` now require a translation argument to be passed through for supporting translations. + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 66a1140: Add i18n support for `catalog-import` plugin. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/integration@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-node@1.17.0 + +### Minor Changes + +- a459f17: Added `parseEntityYaml` from `@backstage/plugin-catalog-backend`, to make it more easily usable by custom plugins and modules +- 1a003ff: Add `getLocations` method to `CatalogApi` and `CatalogClient`. This method calls the [`GET /locations`](https://backstage.io/docs/features/software-catalog/software-catalog-api/#get-locations) endpoint from the catalog backend. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/catalog-client@1.10.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-react@1.18.0 + +### Minor Changes + +- d47aaa3: Added EntityOrderFilter to sort entities by different fields/columns. This new filter allows users to specify the order in which entities are displayed in the catalog. + + Example usage: + + ```ts + import { + EntityOrderFilter, + useEntityList, + } from '@backstage/plugin-catalog-react'; + // ... + const { updateFilters } = useEntityList(); + + // ... + updateFilters({ + order: new EntityOrderFilter([ + { + field: 'metadata.name', + order: 'desc', + }, + ]), + }); + ``` + +- 1a003ff: Add `getLocations` method to `CatalogApi` and `CatalogClient`. This method calls the [`GET /locations`](https://backstage.io/docs/features/software-catalog/software-catalog-api/#get-locations) endpoint from the catalog backend. + +### Patch Changes + +- 2ddbc50: A new `filter` parameter has been added to `EntityContextMenuItemBlueprint` to make it easier to configure which entities a menu item should appear for. The `filter` parameter is a function which accepts an entity and returns a boolean. +- 6d7f0d5: Fixed an issue causing entities of kind user and group to be empty when an owner was selected +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/frontend-test-utils@0.3.2 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-events-backend-module-github@0.4.0 + +### Minor Changes + +- ae249fc: **BREAKING**: Removed the `createGithubSignatureValidator` export. + + Added support webhook validation based on `integrations.github.[].apps.[].webhookSecret`. + +### Patch Changes + +- c7ef81c: Correct README installation instructions. +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.0 + +### Minor Changes + +- af853ef: Added a module that is able to transfer messages from Google Pub/Sub subscriptions into the Backstage events system. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-kubernetes-node@0.3.0 + +### Minor Changes + +- 9cdf001: **BREAKING**: The `PinnipedHelper` class now expects a regular `LoggerService` instance from the new backend system, instead of a Winston logger. + +### Patch Changes + +- 216c6b2: Updated dependency `@kubernetes/client-node` to `1.1.2`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/types@1.2.1 + +## @backstage/plugin-permission-backend@0.7.0 + +### Minor Changes + +- 4da2965: Fixed an issue causing the `PermissionClient` to exhaust the request body size limit too quickly when making many requests. +- cf8fd51: **BREAKING** Removed support for the legacy backend system, please [migrate to the new backend system](https://backstage.io/docs/backend-system/building-backends/migrating) + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-permission-common@0.9.0 + +### Minor Changes + +- 4da2965: Fixed an issue causing the `PermissionClient` to exhaust the request body size limit too quickly when making many requests. + +### Patch Changes + +- 37328b1: Fixed an issue causing `PermissionClient` to throw an error when authorizing basic permissions with the `permission.EXPERIMENTAL_enableBatchedRequests` config enabled. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-permission-node@0.10.0 + +### Minor Changes + +- 4da2965: Fixed an issue causing the `PermissionClient` to exhaust the request body size limit too quickly when making many requests. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder@1.31.0 + +### Minor Changes + +- 4235e87: add templating extensions page + +### Patch Changes + +- 92c3658: Full support in EntityPicker (and derivatives) for default EntityPresentationApi +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- d7da01d: Fix EntityPicker field to render description as markdown, matching other form components in the system. +- 36ae651: Fixing a bug where the name for `templatingExtensions` was incorrectly set to `templateExtensions` +- 72d019d: Removed various typos +- a274e0a: Migrate custom fields to new schema factory function; + standardize field descriptions to prefer ui:description and present consistently, + utilizing ScaffolderField component where possible. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/integration@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-scaffolder-react@1.16.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-backend@1.33.0 + +### Minor Changes + +- 587cb05: Added `workspace:template` and `workspace:template:file` actions to complement respective `fetch:*` actions + +### Patch Changes + +- eb39388: Fixed bug in fs:delete that prevented wildcard patterns from matching paths starting with "." +- 36ae651: Fixing a bug where the name for `templatingExtensions` was incorrectly set to `templateExtensions` +- 72d019d: Removed various typos +- ec42f8e: Generating new tokens on each Scaffolder Task Retry +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/plugin-scaffolder-backend-module-github@0.7.1 + - @backstage/backend-defaults@0.10.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.9 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.9 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.10 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.9 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.9 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.9 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.8 + - @backstage/plugin-events-node@0.4.11 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-react@1.16.0 + +### Minor Changes + +- 4235e87: add templating extensions page + +### Patch Changes + +- 36ae651: Fixing a bug where the name for `templatingExtensions` was incorrectly set to `templateExtensions` +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-search-react@1.9.0 + +### Minor Changes + +- 611c941: Allow search filters to provide labels and values separately, and not only values + +### Patch Changes + +- 2c76614: Fix memoization of `filterValue` in `SearchFilter.Autocomplete` to prevent unintended resets +- fa48594: search plugin support i18n +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/app-defaults@1.6.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/backend-app-api@1.2.3 + +### Patch Changes + +- 729a7d6: Added a configuration to permit backend plugin module failures on startup: + + ```yaml + backend: + ... + startup: + plugins: + plugin-x: + modules: + module-y: + onPluginModuleBootFailure: continue + ``` + + This configuration permits `plugin-x` with `module-y` to fail on startup. Omitting the + `onPluginModuleBootFailure` configuration matches the previous behavior, wherein any + individual plugin module failure is forwarded to the plugin and aborts backend startup. + + The default can also be changed, so that continuing on failure is the default + unless otherwise specified: + + ```yaml + backend: + startup: + default: + onPluginModuleBootFailure: continue + plugins: + catalog: + modules: + github: + onPluginModuleBootFailure: abort + ``` + +- 72d019d: Removed various typos + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/backend-openapi-utils@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/backend-plugin-api@1.3.1 + +### Patch Changes + +- acea1d4: update documentation +- 72d019d: Removed various typos +- d385854: Minor doc comment update +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/catalog-model@1.7.4 + +### Patch Changes + +- ed4e625: Added support for icons containing colons +- Updated dependencies + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/cli@0.32.1 + +### Patch Changes + +- 674def9: fix: enable `lazyCompilation` and `refreshOptions` for rspack +- d649df0: Internal code cleanup +- c2cae47: Add missing modules to the Backstage CLI alpha entrypoint. +- 3f45861: Add a warning for React 17 deprecation that triggers when frontend packages and plugins start. +- 9aaec54: Internal refactor of opaque type handling. +- 9285385: Added `info` object to the context of the alpha CLI. +- 6cc9507: Updated dependency `@octokit/request` to `^8.0.0`. +- 5cd3c54: Updated dependency `react-refresh` to `^0.17.0`. +- 72d019d: Removed various typos +- 19a4e7c: Internal refactor to move things closer to home +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/catalog-model@1.7.4 + - @backstage/release-manifests@0.0.13 + - @backstage/config-loader@1.10.1 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.10 + - @backstage/types@1.2.1 + +## @backstage/config-loader@1.10.1 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/core-compat-api@0.4.2 + +### Patch Changes + +- 173db8f: Updates to use the new `plugin` property of `AppNodeSpec`. +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 6eedf46: Updated dependency `@backstage-community/plugin-puppetdb` to `^0.6.0`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-components@0.17.2 + +### Patch Changes + +- e0d1025: `LogViewer` now supports a `textWrap` prop that wraps log lines to the next line for overflowing content instead of using horizontal scroll +- bb84534: Fix the hidden sidebar's sub-menu when the sidebar is scrollable +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/theme@0.6.6 + - @backstage/core-plugin-api@1.10.7 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-plugin-api@1.10.7 + +### Patch Changes + +- 73f6cc3: The `TranslationApi` now supports interpolation of JSX elements by passing them directly as values to the translation function. If any of the provided interpolation values are JSX elements, the translation function will return a JSX element instead of a string. +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.6.2 + +### Patch Changes + +- 8448948: Removed `lerna-debug.log*` pattern from `.gitignore` as Lerna was removed from the package in version `@backstage/create-app@0.5.19`. +- ce2cf32: Bumped create-app version. +- 125d096: Bumped create-app version. +- 1c0cb7b: Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/app-defaults@1.6.2 + - @backstage/integration-react@1.2.7 + +## @backstage/frontend-app-api@0.11.2 + +### Patch Changes + +- 173db8f: Updates to use the new `plugin` property of `AppNodeSpec`. +- 1f04491: Added the ability to ignore unknown extension config by passing `{ flags: { allowUnknownExtensionConfig: true } }` to `createSpecializedApp`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-defaults@0.2.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/frontend-app-api@0.11.2 + - @backstage/plugin-app@0.1.9 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/frontend-dynamic-feature-loader@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/config@1.3.2 + +## @backstage/frontend-plugin-api@0.10.2 + +### Patch Changes + +- 173db8f: The `source` property of `AppNodeSpec` has been renamed to `plugin`. The old property has been deprecated and will be removed in a future release. + +- fb58f20: The `id` option of `createFrontendPlugin` has been renamed to `pluginId` in order to better align with similar APIs in the frontend and backend systems. + + The old `id` option is deprecated and will be removed in a future release. + +- 72d019d: Removed various typos + +- Updated dependencies + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-test-utils@0.3.2 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/test-utils@1.7.8 + - @backstage/frontend-app-api@0.11.2 + - @backstage/plugin-app@0.1.9 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/integration-aws-node@0.1.16 + +### Patch Changes + +- db4630e: Fixed bug in DefaultAwsCredentialsManager where aws.mainAccount.region has no effect on the STS region used for account ID lookup during credential provider lookup when falling back to the main account, and it does not default to us-east-1 +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/integration-react@1.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/config@1.3.2 + +## @backstage/release-manifests@0.0.13 + +### Patch Changes + +- 163f3da: This expands the configurability of `release-manifests` to pave the road for more configuration options in the `cli`. + + Specifically it allows the specification of mirrored, proxied, or air-gapped hosts when upgrading across releases when + working in restricted or heavily governed development environments (common in large enterprises and government + entities). + +## @backstage/repo-tools@0.13.3 + +### Patch Changes + +- b229476: Support passing additional properties to OpenAPI server generator +- 659f2ce: Updated dependency `typedoc` to `^0.28.0`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config-loader@1.10.1 + - @backstage/cli-node@0.2.13 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @techdocs/cli@1.9.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-techdocs-node@1.13.3 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + +## @backstage/test-utils@1.7.8 + +### Patch Changes + +- b573341: Added support for interpolating JSX elements with the `MockTranslationApi`. +- Updated dependencies + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/config@1.3.2 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/types@1.2.1 + +## @backstage/theme@0.6.6 + +### Patch Changes + +- 1b14572: Show arrow when MuiTableSortLabel receives focus + +## @backstage/plugin-api-docs@0.12.7 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-catalog@1.30.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-app@0.1.9 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/types@1.2.1 + +## @backstage/plugin-app-backend@0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config-loader@1.10.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.33 + +## @backstage/plugin-app-node@0.1.33 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config-loader@1.10.1 + +## @backstage/plugin-app-visualizer@0.1.19 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.8 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.3 + +### Patch Changes + +- 5cdfe05: Added missing types package +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.8 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.3 + +### Patch Changes + +- 5cc1f7f: Introduce `dangerouslyAllowSignInWithoutUserInCatalog` auth resolver config. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-auth-node@0.6.3 + +### Patch Changes + +- 332e934: Added the `identity` property to `BackstageSignInResult`. + + The `prepareBackstageIdentityResponse` function will now also forward the `identity` to the response if present in the provided sign-in result. + +- ab53e6f: Added a new `dangerousEntityRefFallback` option to the `signInWithCatalogUser` method in `AuthResolverContext`. The option will cause the provided entity reference to be used as a fallback in case the user is not found in the catalog. It is up to the caller to provide the fallback entity reference. + + Auth providers that include pre-defined sign-in resolvers are encouraged to define a flag named `dangerouslyAllowSignInWithoutUserInCatalog` in their config, which in turn enables use of the `dangerousEntityRefFallback` option. For example: + + ```ts + export const usernameMatchingUserEntityName = createSignInResolverFactory({ + optionsSchema: z + .object({ + dangerouslyAllowSignInWithoutUserInCatalog: z.boolean().optional(), + }) + .optional(), + create(options = {}) { + return async ( + info: SignInInfo>, + ctx, + ) => { + const { username } = info.result.fullProfile; + if (!username) { + throw new Error('User profile does not contain a username'); + } + + return ctx.signInWithCatalogUser( + { entityRef: { name: username } }, + { + dangerousEntityRefFallback: + options?.dangerouslyAllowSignInWithoutUserInCatalog + ? { entityRef: { name: username } } + : undefined, + }, + ); + }; + }, + }); + ``` + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-react@0.1.15 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend-module-aws@0.4.11 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-defaults@0.10.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/integration-aws-node@0.1.16 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-azure@0.3.5 + +### Patch Changes + +- be82d83: visualstudio.com domains are now supported along with dev.azure.com +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.2 + +### Patch Changes + +- d385854: Do not swallow errors; instead allow them to bubble up to the task scheduler for better tracking and logging. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/backend-openapi-utils@0.5.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.4.8 + +### Patch Changes + +- 3bce578: Support Bitbucket Cloud's `repo:updated` events at `BitbucketCloudEntityProvider`. + + To make use of the new event type, you have to configure your webhook or add a new ones + that delivers this event type to Backstage similar to `repo:push` before. + + Only `repo:updated` events that modify a repository's URL (e.g., due to a name change) + will cause changes (removing the "old", adding the "new" repository). + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.4.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/config@1.3.2 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.10 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/plugin-catalog-backend-module-github@0.9.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-catalog-backend-module-gitlab@0.6.6 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-defaults@0.10.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-catalog-backend-module-gitlab@0.6.6 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.5 + +### Patch Changes + +- e253d1d: Improves error reporting for missing metadata.name in LDAP catalog provider. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-logs@0.1.10 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-catalog-common@1.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-catalog-graph@0.4.19 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 72d019d: Removed various typos +- 1307f00: Fix rendering of missing relations +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.17 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-unprocessed-entities-common@0.0.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-config-schema@0.1.68 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-devtools@0.1.27 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/core-compat-api@0.4.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/errors@1.2.7 + - @backstage/plugin-devtools-common@0.1.16 + +## @backstage/plugin-devtools-backend@0.5.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/config-loader@1.10.1 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-devtools-common@0.1.16 + +## @backstage/plugin-devtools-common@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-events-backend@0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/backend-openapi-utils@0.5.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-events-backend-module-azure@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-events-backend-module-gerrit@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-events-backend-module-gitlab@0.3.1 + +### Patch Changes + +- a820df1: Adds support for `object_kind` field with priority over `event_name` on Gitlab webhook event types +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-events-backend-test-utils@0.1.44 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-events-node@0.4.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-gateway-backend@1.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-home@0.8.8 + +### Patch Changes + +- f7ca0fe: Added the Catalog presentation API to the HomePageRecentlyVisited and HomePageTopVisited components + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. + +- eddd96c: Added optional title prop to `customHomePageGrid` + +- 16eb4bf: Export ContentModal from `@backstage/plugin-home-react` so people can use this in other scenarios. + Renamed `CatalogReactComponentsNameToClassKey` to `PluginHomeComponentsNameToClassKey` in `overridableComponents.ts` + + Made QuickStartCard `docsLinkTitle` prop more flexible to allow for any React.JSX.Element instead of just a string. + Added QuickStartCard prop `additionalContent` which can eventually replace the prop `video`. + +- 2c1761f: Added a `variant` prop to the `WelcomeTitle` component making it work with the Customizable Home page feature. Adding it like this `` to the list of items under `CustomHomepageGrid` will allow it to render with a size that works well. + +- 195323f: Export root page route from the home plugin to enable adding links/nav to it from outside the plugin + +- 72d019d: Removed various typos + +- d710d74: docs: Update default for `preventCollision` prop + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-home-react@0.1.26 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + +## @backstage/plugin-home-react@0.1.26 + +### Patch Changes + +- 16eb4bf: Export ContentModal from `@backstage/plugin-home-react` so people can use this in other scenarios. + Renamed `CatalogReactComponentsNameToClassKey` to `PluginHomeComponentsNameToClassKey` in `overridableComponents.ts` + + Made QuickStartCard `docsLinkTitle` prop more flexible to allow for any React.JSX.Element instead of just a string. + Added QuickStartCard prop `additionalContent` which can eventually replace the prop `video`. + +- Updated dependencies + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + +## @backstage/plugin-kubernetes@0.12.7 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 216c6b2: Updated dependency `@kubernetes/client-node` to `1.1.2`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/plugin-kubernetes-react@0.5.7 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-kubernetes-backend@0.19.6 + +### Patch Changes + +- f6f692c: Changed logging of cluster details to debug to minimise log clutter. +- 216c6b2: Updated dependency `@kubernetes/client-node` to `1.1.2`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/plugin-kubernetes-node@0.3.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/integration-aws-node@0.1.16 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-kubernetes-cluster@0.0.25 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/plugin-kubernetes-react@0.5.7 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-kubernetes-common@0.9.5 + +### Patch Changes + +- 216c6b2: Updated dependency `@kubernetes/client-node` to `1.1.2`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-kubernetes-react@0.5.7 + +### Patch Changes + +- 599c89e: Add headlamp formatter +- 216c6b2: Updated dependency `@kubernetes/client-node` to `1.1.2`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications@0.5.5 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/core-components@0.17.2 + - @backstage/core-compat-api@0.4.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-signals-react@0.0.13 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + +## @backstage/plugin-notifications-backend@0.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/plugin-notifications-node@0.2.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-signals-node@0.1.20 + +## @backstage/plugin-notifications-backend-module-email@0.3.9 + +### Patch Changes + +- aa3a63a: Enable the ability to configure the endpoint for the SES connection used in the notifications email module. This enables the configuration of alternate endpoints as required, for example for local testing or alternative stacks. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/integration-aws-node@0.1.16 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/plugin-notifications-node@0.2.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + +## @backstage/plugin-notifications-backend-module-slack@0.1.1 + +### Patch Changes + +- 4f10768: Fix slack notification processor to handle a notification with an empty description + +- f6480c7: Fix dataloader caching, and use the proper catalog service ref + +- a1c5bbb: Added email-based Slack User ID lookup if `metadata.annotations.slack.com/bot-notify` is missing from user entity + +- e099d0a: Notifications which mention user entity refs are now replaced with Slack compatible mentions. + + Example: `Welcome <@user:default/billy>!` -> `Welcome <@U123456890>!` + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/plugin-notifications-node@0.2.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + +## @backstage/plugin-notifications-node@0.2.15 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/catalog-client@1.10.0 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-signals-node@0.1.20 + +## @backstage/plugin-org@0.6.39 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. + +- 02e8af1: Enhance user profile card configuration: + + - Added a new optional `maxRelations` numerical configuration that controls over how many user groups are shown directly on the profile card: + - If the setting is omitted, all relations will be shown. + - If `maxRelations` is set to `0`, the list of user groups is not displayed. + - If `maxRelations` is set to a positive number, up to that many groups are displayed. + - If the user belongs to more groups than the specified limit, a clickable link appears that opens a dialog showing all associated user groups. + - A complementary boolean configuration, `hideIcons`, was added to optionally hide the visual icons associated with each group in the displayed list. + - Usage example: + ```yaml + # Example in app-config.yaml + app: + extensions: + - entity-card:org/user-profile: + config: + maxRelations: 5 # (optional) Show up to 5 groups on the card + hideIcons: true # (optional) Hide the group icons + ``` + +- 08ba448: display entity-ref in GroupProfileCard so groups can easily determine their Group ID + +- 18e84c9: Fixed missing spec.profile field on MyGroupsSidebarItem.tsx so the group spec.profile.displayName is shown on the sidebar" + +- 72d019d: Removed various typos + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-org-react@0.1.38 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + +## @backstage/plugin-permission-react@0.4.34 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/config@1.3.2 + +## @backstage/plugin-proxy-backend@0.6.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/types@1.2.1 + - @backstage/plugin-proxy-node@0.1.4 + +## @backstage/plugin-proxy-node@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.10 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.9 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.9 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.9 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.9 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.10 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-defaults@0.10.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.9 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-github@0.7.1 + +### Patch Changes + +- 6579c2c: Use action context logger in Octokit client +- 72d019d: Removed various typos +- b2b654c: Added optional assignees parameter to `publish:github:pull-request` action +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/catalog-model@1.7.4 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.1 + +### Patch Changes + +- d15355c: If the commit action is not `create` log a more appropriate error message to the end user advising that the files they're trying to modify might not exist +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.10 + +### Patch Changes + +- b60253d: Change notification send scaffolder action to use native zod schemas +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/plugin-notifications-node@0.2.15 + - @backstage/plugin-notifications-common@0.0.8 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.9 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/plugin-scaffolder-node-test-utils@0.2.2 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-common@1.5.11 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-node@0.8.2 + +### Patch Changes + +- 16e2e9c: trim leading and trailing slashes from parseRepoUrl query parameters +- 72d019d: Removed various typos +- ec42f8e: Generating new tokens on each Scaffolder Task Retry +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/catalog-model@1.7.4 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-node-test-utils@0.2.2 + +### Patch Changes + +- b27c48d: Include optional `user` in `createMockActionContext` +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/backend-test-utils@1.5.0 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/types@1.2.1 + +## @backstage/plugin-search@1.4.26 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- fa48594: search plugin support i18n +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend@2.0.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/backend-openapi-utils@0.5.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-search-backend-node@1.3.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-catalog@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-search-backend-node@1.3.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.2 + +### Patch Changes + +- 01f772c: Fixed an issue where the `search.elasticsearch.queryOptions` config were not picked up by the `ElasticSearchSearchEngine`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/integration-aws-node@0.1.16 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-explore@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-pg@0.5.44 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-techdocs@0.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-techdocs-node@1.13.3 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-search-backend-node@1.3.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-node@1.3.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-common@1.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-signals@0.0.19 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-signals-react@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/plugin-signals-backend@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + - @backstage/plugin-signals-node@0.1.20 + +## @backstage/plugin-signals-node@0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + +## @backstage/plugin-signals-react@0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-techdocs@1.12.6 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 7d445da: Update keyboard focus on when clicking hash links. This fixes the issue where the "skip to content" link rendered by Material MkDocs isn't focused when used. +- 72d019d: Removed various typos +- 2ffd273: Add hover and focus styling to the "copy to clipboard" button within codeblocks in techdocs. Also added an aria-label to the button for accessibility. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/integration@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.48 + +### Patch Changes + +- Updated dependencies + - @backstage/test-utils@1.7.8 + - @backstage/core-app-api@1.17.0 + - @backstage/plugin-techdocs@1.12.6 + - @backstage/plugin-catalog@1.30.0 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-techdocs-backend@2.0.2 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-defaults@0.10.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-techdocs-node@1.13.3 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-search-backend-module-techdocs@0.4.2 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/integration@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-techdocs-node@1.13.3 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/catalog-model@1.7.4 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/integration-aws-node@0.1.16 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-react@1.2.17 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.7 + - @backstage/config@1.3.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/plugin-user-settings@0.8.22 + +### Patch Changes + +- a7bfdb6: plugin-user-settingsgs support i18n +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 5b04b14: Uppercase language name in language select +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-signals-react@0.0.13 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-node@0.1.20 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.109 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/canon@0.4.0 + - @backstage/cli@0.32.1 + - @backstage/plugin-user-settings@0.8.22 + - @backstage/core-components@0.17.2 + - @backstage/plugin-home@0.8.8 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-scaffolder@1.31.0 + - @backstage/frontend-app-api@0.11.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.17 + - @backstage/plugin-catalog-import@0.13.0 + - @backstage/plugin-catalog-graph@0.4.19 + - @backstage/plugin-notifications@0.5.5 + - @backstage/plugin-kubernetes@0.12.7 + - @backstage/plugin-api-docs@0.12.7 + - @backstage/plugin-devtools@0.1.27 + - @backstage/plugin-techdocs@1.12.6 + - @backstage/plugin-catalog@1.30.0 + - @backstage/plugin-signals@0.0.19 + - @backstage/plugin-search@1.4.26 + - @backstage/plugin-org@0.6.39 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-scaffolder-react@1.16.0 + - @backstage/plugin-kubernetes-cluster@0.0.25 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.24 + - @backstage/app-defaults@1.6.2 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-search-common@1.2.18 + +## example-app-next@0.0.23 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/canon@0.4.0 + - @backstage/cli@0.32.1 + - @backstage/plugin-user-settings@0.8.22 + - @backstage/core-components@0.17.2 + - @backstage/plugin-home@0.8.8 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-scaffolder@1.31.0 + - @backstage/frontend-app-api@0.11.2 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.17 + - @backstage/plugin-app-visualizer@0.1.19 + - @backstage/plugin-catalog-import@0.13.0 + - @backstage/plugin-catalog-graph@0.4.19 + - @backstage/plugin-notifications@0.5.5 + - @backstage/plugin-kubernetes@0.12.7 + - @backstage/plugin-api-docs@0.12.7 + - @backstage/plugin-techdocs@1.12.6 + - @backstage/plugin-catalog@1.30.0 + - @backstage/plugin-signals@0.0.19 + - @backstage/plugin-search@1.4.26 + - @backstage/plugin-app@0.1.9 + - @backstage/plugin-org@0.6.39 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-scaffolder-react@1.16.0 + - @backstage/plugin-kubernetes-cluster@0.0.25 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-defaults@0.2.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.24 + - @backstage/app-defaults@1.6.2 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-search-common@1.2.18 + +## app-next-example-plugin@0.0.23 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + +## example-backend@0.0.38 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.0 + - @backstage/plugin-catalog-backend@2.0.0 + - @backstage/plugin-scaffolder-backend-module-github@0.7.1 + - @backstage/backend-defaults@0.10.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.3 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.2 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-kubernetes-backend@0.19.6 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/plugin-scaffolder-backend@1.33.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-backend@0.7.0 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/plugin-techdocs-backend@2.0.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.10 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.0 + - @backstage/plugin-notifications-backend@0.5.6 + - @backstage/plugin-signals-backend@0.3.4 + - @backstage/plugin-catalog-backend-module-openapi@0.2.10 + - @backstage/plugin-app-backend@0.5.2 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.8 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.8 + - @backstage/plugin-devtools-backend@0.5.5 + - @backstage/plugin-events-backend@0.5.2 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.8 + - @backstage/plugin-proxy-backend@0.6.2 + - @backstage/plugin-search-backend@2.0.2 + - @backstage/plugin-search-backend-module-catalog@0.3.4 + - @backstage/plugin-search-backend-module-explore@0.3.2 + - @backstage/plugin-search-backend-module-techdocs@0.4.2 + - @backstage/plugin-search-backend-node@1.3.11 + +## e2e-test@0.2.28 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.6.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/frontend@0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @internal/scaffolder@0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/plugin-scaffolder-react@1.16.0 + +## techdocs-cli-embedded-app@0.2.108 + +### Patch Changes + +- Updated dependencies + - @backstage/test-utils@1.7.8 + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/cli@0.32.1 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-techdocs@1.12.6 + - @backstage/plugin-catalog@1.30.0 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/core-plugin-api@1.10.7 + - @backstage/app-defaults@1.6.2 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + +## yarn-plugin-backstage@0.0.5 + +### Patch Changes + +- fd70d86: Add both `npm:` and `backstage:` ranges to the lockfile to ensure compatibility with tools that parse the lockfile and ensure dependencies stay locked when building dist workspaces. +- Updated dependencies + - @backstage/release-manifests@0.0.13 + - @backstage/cli-common@0.1.15 + +## @internal/plugin-todo-list@1.0.39 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + +## @internal/plugin-todo-list-backend@1.0.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + +## @internal/plugin-todo-list-common@1.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.0 diff --git a/docs/releases/v1.39.0.md b/docs/releases/v1.39.0.md new file mode 100644 index 0000000000..de6903adb4 --- /dev/null +++ b/docs/releases/v1.39.0.md @@ -0,0 +1,125 @@ +--- +id: v1.39.0 +title: v1.39.0 +description: Backstage Release v1.39.0 +--- + +These are the release notes for the v1.39.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### **BREAKING**: Removals of Old Backend System support + +We are gradually removing support for the old backend system from plugins and modules. In this release, the following backend features no longer support the old backend system: + +- `auth-backend` +- `catalog-backend` +- `permission-backend` +- `catalog-backend-module-incremental-ingestion` +- `catalog-backend-module-unprocessed` + +If you have already migrated to the new backend system, you will not be required to do any code changes, except perhaps removing the /alpha suffix on your imports if you had that. + +If you have not yet migrated, now would be a great time to do so. + +Note that for the `@backstage/plugin-catalog-backend`, this necessitated a major semantic version bump. The others are on version 0.x still and received a minor level bump. If you are using the Backstage yarn plugin, you will get on the new versions automatically. If you do not, you may want to bump your dependency ranges (to e.g. ^2.0.0 for the major bumps) for these to ensure that you keep getting the most recent updates. + +Along with the major bump, most of the previously already deprecated exports were finally removed as well from these packages. There are a bit too many to list here, but as an example, some of the old deprecated exports from the Catalog backend have been available from their new home in `@backstage/plugin-catalog-node` instead. + +An upshot of these changes is that we have nearly entirely eliminated the usage of the old `@backstage/backend-common` package. We hope to get rid of the very final remnants of it as soon as possible. + +### **BREAKING**: `CodeOwnersProcessor` removed from built-in processors + +As part of the major bump of the catalog backend the `CodeOwnersProcessor` has been removed from the set of default processors, because it's quite expensive to run and has vague semantics. You need to update your backend to add it to the `catalogProcessingExtensionPoint` if you wish to continue using it. + +### Deprecating React 17 + +React 17 is now deprecated and the Backstage CLI will warn if you are using it. Please follow the [migration guide](https://backstage.io/docs/tutorials/react18-migration/) to upgrade to React 18. + +### Scheduler Service REST API + +The core scheduler service now comes with its own REST API that you can use to list and trigger tasks. For more information, see the [scheduler service documentation](https://backstage.io/docs/backend-system/core-services/scheduler). + +### Canon 0.4.0 + +Our new design system Canon has reached 0.4.0 in this release. You can read more about the changes in the [canon changelog](https://canon.backstage.io/releases). + +### Omitting ownership claims in issued identity tokens + +The `auth` plugin backend now supports omitting the ownership claims in issued Backstage identity tokens. By setting the `auth.omitIdentityTokenOwnershipClaim` configuration flag the issued tokens will no longer contain the `ent` claim that represents the ownership references of the user. + +The benefit of this new flag is that issued user tokens will be much smaller in size, but they will no longer be self-contained. This means that any consumers of the token that require access to the ownership claims now need to call the `/api/auth/v1/userinfo` endpoint instead. Within the Backstage ecosystem this is done automatically, as clients will still receive the full set of claims during authentication, while plugin backends will need to use the `UserInfoService` which already calls the user info endpoint if necessary. + +When enabling this flag, it is important that any custom sign-in resolvers directly return the result of the sign-in method. For example, the following would not work: + +```ts +const { token } = await ctx.issueToken({ + claims: { sub: entityRef, ent: [entityRef] }, +}); +return { token }; // WARNING: This will not work with the flag enabled +``` + +Instead, the sign-in resolver should return the entire result: + +```ts +return ctx.issueToken({ + claims: { sub: entityRef, ent: [entityRef] }, +}); +``` + +### JSX elements in I18n interpolation + +The internationalization APIs now transparently supports interpolation of JSX elements. If any of the provided replacements are a JSX element, the translation function will also return a JSX element where the parts are joined together in a fragment. This makes it much easier to include things like links in a message while keeping the translations flexible. + +### Built-in sign-in fallback for users not in the catalog + +It is sometimes useful to allow users to [sign-in without existing in the catalog](https://backstage.io/docs/auth/identity-resolver#sign-in-without-users-in-the-catalog), even though care must be taken when allowing this. There is now a new `dangerousEntityRefFallback` option for the `signInWithCatalogUser` method that lets you supply a fallback user identity in case the catalog lookup returns an empty response, which makes it even easier to implement this pattern. + +In addition, many of the available auth provider modules now support a new `dangerouslyAllowSignInWithoutUserInCatalog` configuration option that enables this using a provider-specific fallback. + +Contributed by [@JessicaJHee](https://github.com/JessicaJHee) in [#28967](https://github.com/backstage/backstage/pull/28967) + +### Improved compatibility for Yarn plugin + +The yarn plugin will now add both `npm:` and `backstage:` ranges to lockfile entries, in order to ensure better compatibility with tools that parse the lockfile and ensure dependencies stay locked when building dist workspaces. + +### Federated Credentials for Azure DevOps integration + +If you have configured your Azure DevOps organization to use Entra ID for authentication, you can now use federated credentials using a managed identity. This allows you to authenticate for an app registration without using a client secret. This is mostly useful when you have to authenticate against an Azure DevOps organization in a different Entra ID tenant, and effectively eliminates the need to manage and expose secrets for other tenants. + +Contributed by [@sanderaernouts](https://github.com/sanderaernouts) in [#28437](https://github.com/backstage/backstage/pull/28437) + +### Valkey support for cache service + +The cache service implementation provided by `@backstage/backend-defaults` now also supports Valkey as one of the configurable clients. + +Contributed by [@j1bulbul](https://github.com/j1bulbul) in [#29762](https://github.com/backstage/backstage/pull/29762) + +### Custom AuthConnector implementations + +The frontend `OAuth2` class now lets you provide a custom `AuthConnector` implementation, which can be useful if you need to integrate with auth providers that take a bit more liberty in their OAuth implementation. + +Contributed by [@gusega](https://github.com/gusega) in [#28004](https://github.com/backstage/backstage/pull/28004) + +## Security Fixes + +This release does not contain any security fixes. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.39.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.40.0-changelog.md b/docs/releases/v1.40.0-changelog.md new file mode 100644 index 0000000000..e5b65ab8ed --- /dev/null +++ b/docs/releases/v1.40.0-changelog.md @@ -0,0 +1,2771 @@ +# Release v1.40.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.40.0](https://backstage.github.io/upgrade-helper/?to=1.40.0) + +## @backstage/plugin-scaffolder-backend@2.0.0 + +### Major Changes + +- 33394db: **BREAKING CHANGES** + + Removal of deprecated re-exports from module packages. + + The following functions have been re-exported from the `scaffolder-backend` plugin for quite some time, and now it's time to clean them up. They've been moved as follows: + + - `createPublishAzureAction` should be imported from `@backstage/plugin-scaffolder-backend-module-azure` instead. + + - `createPublishBitbucketCloudAction` should be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` instead. + + - `createPublishBitbucketServerAction` and `createPublishBitbucketServerPullRequestAction` can be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead. + + - `createPublishBitbucketAction` should be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket` instead. + + - `createPublishGerritAction` and `createPublishGerritReviewAction` can be imported from `@backstage/plugin-scaffolder-backend-module-gerrit` instead. + + - `createGithubActionsDispatchAction`, `createGithubDeployKeyAction`, `createGithubEnvironmentAction`, `createGithubIssuesLabelAction`, `CreateGithubPullRequestActionOptions`, `createGithubRepoCreateAction`, `createGithubRepoPushAction`, `createGithubWebhookAction`, and `createPublishGithubAction` can be imported from `@backstage/plugin-scaffolder-backend-module-github` instead. + + - `createPublishGitlabAction` should be imported from `@backstage/plugin-scaffolder-backend-module-gitlab` instead. + + - `ActionContext`. `createTemplateAction`, `executeShellCommand`, `ExecuteShellCommandOptions`, `fetchContents`, `TaskSecrets`, and `TemplateAction` should be imported from `@backstage/plugin-scaffolder-node` instead. + + - `ScaffolderEntitiesProcessor` should be imported from `@backstage/plugin-catalog-backend-module-scaffolder-entity-model` instead. + +- a8fcf04: **BREAKING ALPHA**: The `/alpha` export no longer exports the plugin. Please use `import('@backstage/plugin-scaffolder-backend')` instead as this has been removed. + + **BREAKING CHANGES**: The old `createRouter` function which was used in the old backend system has been removed along with the `RouterOptions` type. + +- 73b94d7: **BREAKING CHANGES** + + The following functions have been re-exported from the `scaffolder-backend` plugin for quite some time, and now it's time to clean them up. They've been moved as follows: + + - `SerializedTask`, `SerializedTaskEvent`, `TaskBroker`, `TaskBrokerDispatchOptions`, `TaskBrokerDispatchResult`, `TaskCompletionState`, `TaskContext`, `TaskEventType`, `TaskStatus`, `TemplateFilter`, and `TemplateGlobal` should be imported from `@backstage/plugin-scaffolder-node` instead. + + - The deprecated `copyWithoutRender` option has been removed from `fetch:template` action. You should rename the option to `copyWithoutTemplating` instead. + +- 5863b04: **BREAKING CHANGES** + + - The `createBuiltinActions` method has been removed, as this should no longer be needed with the new backend system route, and was only useful when passing the default list of actions again in the old backend system. You should be able to rely on the default behaviour of the new backend system which is to merge the actions. + + - The `createCatalogRegisterAction` and `createFetchCatalogEntityAction` actions no longer require an `AuthService`, and now accepts a `CatalogService` instead of `CatalogClient`. + + Unless you're providing your own override action to the default, this should be a non-breaking change. + + You can migrate using the following if you're getting typescript errors: + + ```ts + import { catalogServiceRef } from '@backstage/plugin-catalog-node'; + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; + + export const myModule = createBackendModule({ + pluginId: 'scaffolder', + moduleId: 'test', + register({ registerInit }) { + registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + catalog: catalogServiceRef, + }, + async init({ scaffolder, catalog }) { + scaffolder.addActions( + createCatalogRegisterAction({ + catalog, + }), + createFetchCatalogEntityAction({ + catalog, + integrations, + }), + ); + }, + }); + }, + }); + ``` + +### Minor Changes + +- 73b94d7: **DEPRECATIONS** + + The following types and implementations have been deprecated, either because they're no longer relevant, or because upcoming changes to the `scaffolder-backend` after `2.0.0` will influence the changes to these API surfaces. + + - `CreateWorkerOptions` + - `DatabaseTaskStore` + - `DatabaseTaskStoreOptions` + - `TaskManager` + - `TaskStoreCreateTaskOptions` + - `TaskStoreCreateTaskResult` + - `TaskStoreEmitOptions` + - `TaskStoreListEventsOptions` + - `TaskStoreRecoverTaskOptions` + - `TaskStoreShutDownTaskOptions` + + There is no current path off deprecation, these types are going to be removed and rethought with a better way to define workers in the new backend system. + +### Patch Changes + +- 89a941d: Migrating to latest action format + +- 023629e: Enable usage of secrets within 'each' step of software templates. For example, you can now structure your `each` step like this: + + each: + [ + { name: "Service1", token: "${{ secrets.token1 }}" }, + { name: "Service2", token: "${{ secrets.token2 }}" }, + ] + +- e92e481: Add tests for Scaffolder + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.10 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10 + - @backstage/plugin-scaffolder-backend-module-github@0.8.0 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.10 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/backend-defaults@0.11.0 + +### Minor Changes + +- 3ccb7fc: Enhanced error handling in the auditor service factory to pass errors as objects. Aligned WinstonRootAuditorService with the default service factory's error handling. + +### Patch Changes + +- 1220cf8: Added new rate limit middleware to allow rate limiting requests to the backend + + If you are using the `configure` callback of the root HTTP router service and do NOT call `applyDefaults()` inside it, please see [the relevant changes](https://github.com/backstage/backstage/pull/28708/files#diff-86ad1b6a694dd250823aee39d410428dd837c9d9a04ca8c33bd1081fbe3f22af) that were made, to see if you want to apply them as well to your custom configuration. + Rate limiting can be turned on by adding the following configuration to `app-config.yaml`: + + ```yaml + backend: + rateLimit: + window: 6s + incomingRequestLimit: 100 + ``` + + Plugin specific rate limiting can be configured by adding the following configuration to `app-config.yaml`: + + ```yaml + backend: + rateLimit: + global: false # This will disable the global rate limiting + plugin: + catalog: + window: 6s + incomingRequestLimit: 100 + ``` + +- c999c25: Added some default implementations for the experimental `ActionsService` and `ActionsRegistryService` under `/alpha` that allow registration of actions for a particular plugin. + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-app-api@1.2.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/backend-plugin-api@1.4.0 + +### Minor Changes + +- 664c07a: Added `actionsRegistry` and `actions` experimental services to `/alpha` to allow registration of distributed actions from plugins, and the ability to invoke these actions. You can use these services by including them like the following: + + ```ts + import { + actionsRegistryServiceRef, + actionsServiceRef, + } from '@backstage/backend-plugin-api/alpha'; + + createBackendPlugin({ + pluginId: 'test-plugin', + register({ registerInit }) { + registerInit({ + deps: { + actions: actionsServiceRef, + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actions, actionsRegistry }) { + actionsRegistry.register({ + ..., + }); + + await actions.invoke(...); + }, + }); + }, + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/backend-test-utils@1.6.0 + +### Minor Changes + +- 6dfb7be: Added `mockServices.permissions()` that can return actual results. +- c999c25: Added an `actionsRegistryServiceMock` and `actionsServiceMock` to `/alpha` export for the experimental services. + + This allows you to write tests for your actions by doing something similar to the following: + + ```ts + import { actionsRegistryServiceMock } from '@backstage/backend-test-utils/alpha'; + + const mockActionsRegistry = actionsRegistryServiceMock(); + const mockCatalog = catalogServiceMock({ + entities: [ + ... + ], + }); + + createGetCatalogEntityAction({ + catalog: mockCatalog, + actionsRegistry: mockActionsRegistry, + }); + + await expect( + mockActionsRegistry.invoke({ + id: 'test:get-catalog-entity', + input: { name: 'test' }, + }), + ).resolves.toEqual(...) + ``` + +### Patch Changes + +- 12c1fd4: Make the `user` credentials mock behave more like production +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-app-api@1.2.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/canon@0.5.0 + +### Minor Changes + +- 621fac9: We are updating the default size of the Button component in Canon to be small instead of medium. +- a842554: We set the default size for IconButton in Canon to be small instead of medium. +- 35fd51d: Move TextField component to use react Aria under the hood. Introducing a new FieldLabel component to help build custom fields. +- 78204a2: **Breaking** We are adding a new as prop on the Heading and Text component to make it easier to change the component tag. We are removing the render prop in favour of the as prop. +- c49e335: TextField in Canon now has multiple label sizes as well as the capacity to hide label and description but still make them available for screen readers. +- 24b45ef: Fixes spacing props on layout components and aligned on naming for the Grid component. You should now call the Grid root component using <Grid.Root /> instead of just . + +### Patch Changes + +- 44df879: Add min-width: 0; by default on every Flex components in Canon to help support truncated texts inside flex elements. +- ee6ffe6: Fix styling for the title4 prop on the Heading component in Canon. +- f2f814a: Added a render prop to the Button component in Canon to use it as a link. +- 98f02a6: Add new Switch component in Canon. +- c94f8e0: The filter input in menu comboboxes should now always use the full width of the menu it's in. +- 269316d: Remove leftover console.log from Container component. + +## @backstage/cli@0.33.0 + +### Minor Changes + +- eef0e83: Internal update to promote the modular CLI entrypoint to stable. + +### Patch Changes + +- d07fe35: Added user feedback when opening config docs in browser. The command now clearly indicates what it's doing and provides fallback instructions if the browser fails to open. +- ce70439: The `BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE` flag has been removed. Existing users are encouraged to switch to `EXPERIMENTAL_RSPACK` instead. +- 1d8f00b: Switched to using the `ModuleFederationPlugin` from `@module-federation/enhanced/rspack` for Rspack, rather than the built-in one. +- 2b9633f: The experimental `FORCE_REACT_DEVELOPMENT` flag has been removed. +- d8c4a54: Only use the caching Jest module loader for frontend packages in order to avoid breaking real ESM module imports. +- d6d63c7: Updating the scaffolder action boilerplate to use new `zod` schema +- e36e855: Added `backstage.pluginId` field in `package.json` to all default plugin package templates for the `new` command. +- 1bab255: Internal refactor to combine alpha `build` and `start` modules. +- 713e957: fix: merge eslint reports when using json format +- 8a0164c: Fix an issue where some commands were not usable because of missing dist files +- Updated dependencies + - @backstage/eslint-plugin@0.1.11 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/create-app@0.7.0 + +### Minor Changes + +- 30474c4: Add .cache directory to shipped gitignore. + +### Patch Changes + +- d57a6f7: Bumped create-app version. +- f628f44: Bumped create-app version. +- 9c9faf2: Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/repo-tools@0.14.0 + +### Minor Changes + +- bf9a173: Add support for caching the per-package output from the `package-docs` command. + +### Patch Changes + +- 4bff5d0: Fixed a bug where linting would fail with the generated clients when defining top-level `enum` schema values. +- 2d20024: Fix an issue where errors were not printed to console when running `backstage-repo-tools schema openapi generate` without the `--watch` flag. +- e643ee4: Add missing highlight language for the `package-docs` command. +- c83cd8b: Fixed some circular or otherwise unclear imports +- a372bf1: Updated dependency `@electric-sql/pglite` to `^0.3.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog@1.31.0 + +### Minor Changes + +- 406acb6: Add support to customize the about card icon links via `EntityIconLinkBlueprint` and provide a default catalog view catalog source, launch scaffolder template and read techdocs docs icon links extensions. + + **BREAKING ALPHA** + + The `Scaffolder` launch template and `TechDocs` read documentation icons have been extracted from the default `Catalog` about card links and are now provided respectively by the `Scaffolder` and `TechDocs` plugins in the new frontend system. It means that they will not be available unless you install the `TechDocs` and `Scaffolder` plugins. Also If you are using translation for these icon link titles other than the default, you should now translate them using the scaffolder translation reference or the TechDocs translation reference (the translation keys are still the same, `aboutCard.viewTechdocs` and `aboutCard.launchTemplate`). + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-search-react@1.9.1 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-catalog-backend@2.1.0 + +### Minor Changes + +- 2e7adf0: Implement the action `get-catalog-entity` with the `ActionsRegistry` + +### Patch Changes + +- 2cac8b0: You can now specify an optional value when applying the `HAS_LABEL` permission rule, similar to the `HAS_ANNOTATION` permission rule. +- c83cd8b: Fixed some circular or otherwise unclear imports +- 4654a78: Update `refresh_state_references.id` to be a big int +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.0 + +### Minor Changes + +- 8a150bf: **BREAKING**: `BitbucketCloudEntityProvider` now accepts a `CatalogService` instead of a `CatalogApi`. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.0 + +### Minor Changes + +- eb8b3aa: Add validateLocationsExist option to avoid generating locations for catalog-info.yaml files that do not exist in the source repository. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-github@0.10.0 + +### Minor Changes + +- 7c0dfb0: GitHub organization now matches in a case-insensitive manner when processing events. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.0 + +### Minor Changes + +- 42bb3b8: **BREAKING CHANGE**: User and Group discovery will default to ingesting all users in sub groups that belong to the specified root group in config. Disable by setting `restrictUsersToGroup: true` in app-config under your module settings. + +### Patch Changes + +- 57a0bad: Implement retry for GitLab API calls to handle rate limiting +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-react@1.19.0 + +### Minor Changes + +- 406acb6: Introduces a new `EntityIconLinkBlueprint` that customizes the `About` card icon links on the `Catalog` entity page. + + The blueprint currently accepts a `useProps` hook as `param` and this function returns the following props that will be passed to the icon link component: + + | Name | Description | Type | Default Value | + | ---------- | --------------------------------------------------- | ------------- | ------------- | + | `icon` | The icon to display. | `JSX.Element` | N/A | + | `label` | The label for the element. | `string` | N/A | + | `title` | The title for the element. | `string` | N/A | + | `disabled` | Whether the element is disabled. | `boolean` | `false` | + | `href` | The URL to navigate to when the element is clicked. | `string` | N/A | + | `onClick` | A function to call when the element is clicked. | `() => void` | N/A | + + Here is an usage example: + + ```tsx + import { EntityIconLinkBlueprint } from '@backstage/plugin-catalog-react/alpha'; + //... + + EntityIconLinkBlueprint.make({ + name: 'my-icon-link', + params: { + useProps() { + const { t } = useTranslationRef(myIconLinkTranslationRef); + return { + label: t('myIconLink.label'), + icon: , + href: '/my-plugin', + }; + }, + }, + }); + ``` + + Additionally, the `app-config.yaml` file allows you to override some of the default icon link parameters, including `label` and `title` values. Here's how to set them: + + ```yaml + app: + extensions: + - entity-icon-link:my-plugin/my-icon-link: + config: + label: 'My Custom Icon Link label' + ``` + + Finally, you can disable all links if you want to hide the About card header completely (useful, for example, when links are displayed on separate cards). The header is hidden when no icon links extensions are enabled. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/frontend-test-utils@0.3.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-events-backend-module-kafka@0.1.0 + +### Minor Changes + +- b034b9d: Adds a new module `kafka` for plugin-events-backend + + The module introduces the `KafkaConsumerClient` which creates a Kafka client used to establish consumer connections. It also provides the `KafkaConsumingEventPublisher`, a consumer that subscribes to configured Kafka topics and publishes received messages to the Event Service. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-mcp-actions-backend@0.1.0 + +### Minor Changes + +- 4ed0fb6: Initial implementation of an `mcp-actions` backend + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder@1.32.0 + +### Minor Changes + +- 6c972fe: Added information about the `entityRef` and `taskId` to the analytics events whenever is possible. +- 3c59ece: **New Frontend System Only:** + The `Scaffolder` plugin is now responsible for providing an entity icon link extension to launch templates from the catalog entity page. + +### Patch Changes + +- d781b33: render details for composite property schemas +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- b00c160: Remove React import form notification and scaffolder plugin +- 95a1d72: Added appropriate message when global templating function metadata is absent. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.0 + +### Minor Changes + +- 5863b04: **BREAKING CHANGES** + + The `createGithubEnvironmentAction` action no longer requires an `AuthService`, and now accepts a `CatalogService` instead of `CatalogClient`. + + Unless you're providing your own override action to the default, this should be a non-breaking change. + + You can migrate using the following if you're getting typescript errors: + + ```ts + import { catalogServiceRef } from '@backstage/plugin-catalog-node'; + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; + + export const myModule = createBackendModule({ + pluginId: 'scaffolder', + moduleId: 'test', + register({ registerInit }) { + registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + catalog: catalogServiceRef, + }, + async init({ scaffolder, catalog }) { + scaffolder.addActions( + createGithubEnvironmentAction({ + catalog, + }), + ); + }, + }); + }, + }); + ``` + +### Patch Changes + +- 575c76b: Migrate to using new actions +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-node@0.9.0 + +### Minor Changes + +- 5863b04: **BREAKING CHANGES** + + The legacy methods to define `createTemplateActions` have been replaced with the new native `zod` approaches for defining input and output schemas. + + You can migrate actions that look like the following with the below examples: + + ```ts + // really old legacy json schema + createTemplateAction<{ repoUrl: string }, { repoOutput: string }>({ + id: 'test', + schema: { + input: { + type: 'object' + required: ['repoUrl'] + properties: { + repoUrl: { + type: 'string', + description: 'repository url description' + } + } + } + } + }); + + // old zod method + createTemplateAction({ + id: 'test' + schema: { + input: { + repoUrl: z.string({ description: 'repository url description' }) + } + } + }) + + // new method: + createTemplateAction({ + id: 'test', + schema: { + input: { + repoUrl: z => z.string({ description: 'repository url description' }) + } + } + }) + + // or for more complex zod types like unions + createTemplateAction({ + id: 'test', + schema: { + input: z => z.object({ + repoUrl: z.string({ description: 'repository url description' }) + }) + } + }) + ``` + + This breaking change also means that `logStream` has been removed entirely from `ActionsContext`, and that the `logger` is now just a `LoggerService` implementation instead. There is no replacement for the `logStream`, if you wish to still keep using a `logStream` we recommend that you create your own stream that writes to `ctx.logger` instead. + +### Patch Changes + +- e89d7b6: Use `LoggerService` instead of `Logger`. This is a non-breaking change, as the `LoggerService` is a subset of the `Logger` interface. +- 9c8ff0c: Update pull request creation filter to include .gitignore files in the created pull request +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.0 + +### Minor Changes + +- 3cea7ee: **BREAKING CHANGES** + + Because of the removal of the `logStream` property to the `ActionsContext` this has been removed from the `createMockActionContext` method. + + You can remove this as it's no longer supported in the scaffolder actions. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-test-utils@1.6.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-react@1.17.0 + +### Minor Changes + +- 6c972fe: Added information about the `entityRef` and `taskId` to the analytics events whenever is possible. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-techdocs@1.13.0 + +### Minor Changes + +- 3c59ece: **New Frontend System Only:** + The `TechDocs` plugin is now responsible for providing an entity icon link extension to read documentation from the catalog entity page. +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-search-react@1.9.1 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/theme@0.6.6 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-techdocs-react@1.3.0 + +### Minor Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/app-defaults@1.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/backend-app-api@1.2.4 + +### Patch Changes + +- bb9a501: Fixed a bug where occasionally the initialization order of multiple modules consuming a single extension point could happen in the wrong order. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/backend-dynamic-feature-service@0.7.1 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/backend-openapi-utils@0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/catalog-client@1.10.1 + +### Patch Changes + +- 22fad0d: Fixed `CatalogClient` error responses for `refreshEntity` and `addLocation`. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/core-app-api@1.17.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-compat-api@0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-components@0.17.3 + +### Patch Changes + +- 6232160: table actions header support i18n +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-plugin-api@1.10.8 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- 0169b23: Internal tweak to avoid circular dependencies +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/dev-utils@1.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + +## @backstage/eslint-plugin@0.1.11 + +### Patch Changes + +- 098ef95: Fix custom rules package scanning performance. +- 063b2d3: Added new eslint rule to restrict mixed plugin imports. + + New rule `@backstage/no-mixed-plugin-imports` disallows mixed imports between plugins that are mixing + the backstage architecture. This rule forces that: + + - No imports from frontend plugins to backend plugins or other frontend plugins. + - No imports from backend plugins to frontend plugins or other backend plugins. + - No imports from common plugins to frontend or backend plugins. + + The current recommended configuration is giving a warning for mixed imports. This is to be changed in + the future to an error so please adjust your workspace accordingly. + +## @backstage/frontend-app-api@0.11.3 + +### Patch Changes + +- 0169b23: Internal tweak to avoid circular dependencies +- c38c9e8: Implemented support for the `plugin.info()` method in specialized apps with a default resolved for `package.json` and `catalog-info.yaml`. The default resolution logic can be overridden via the `pluginInfoResolver` option to `createSpecializedApp`, and plugin-specific overrides can be applied via the new `app.pluginOverrides` key in static configuration. +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-defaults@0.2.3 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.2.3 + +### Patch Changes + +- fa5650c: Forwarded the new `pluginInfoResolver` option for `createApp`. +- Updated dependencies + - @backstage/plugin-app@0.1.10 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-app-api@0.11.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/frontend-dynamic-feature-loader@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/config@1.3.2 + +## @backstage/frontend-plugin-api@0.10.3 + +### Patch Changes + +- 0169b23: Internal tweak to avoid circular dependencies + +- 9e3868f: Added a new optional `info` option to `createFrontendPlugin` that lets you provide a loaders for different sources of metadata information about the plugin. + + There are two available loaders. The first one is `info.packageJson`, which can be used to point to a `package.json` file for the plugin. This is recommended for any plugin that is defined within its own package, especially all plugins that are published to a package registry. Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + packageJson: () => import('../package.json'), + }, + }); + ``` + + The second loader is `info.manifest`, which can be used to point to an opaque plugin manifest. This **MUST ONLY** be used by plugins that are intended for use within a single organization. Plugins that are published to an open package registry should **NOT** use this loader. The loader is useful for adding additional internal metadata associated with the plugin, and it is up to the Backstage app to decide how these manifests are parsed and used. The default manifest parser in an app created with `createApp` from `@backstage/frontend-defaults` is able to parse the default `catalog-info.yaml` format and built-in fields such as `spec.owner`. + + Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + manifest: () => import('../catalog-info.yaml'), + }, + }); + ``` + +- 6f48f71: Added a new `useAppNode` hook, which can be used to get a reference to the `AppNode` from by the closest `ExtensionBoundary`. + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-test-utils@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.10 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-app-api@0.11.3 + - @backstage/config@1.3.2 + - @backstage/test-utils@1.7.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/integration-react@1.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + +## @techdocs/cli@1.9.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4 + +## @backstage/test-utils@1.7.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-api-docs@0.12.8 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/plugin-catalog@1.31.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-app@0.1.10 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/integration-react@1.2.8 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-app-backend@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + +## @backstage/plugin-app-node@0.1.34 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config-loader@1.10.1 + +## @backstage/plugin-app-visualizer@0.1.20 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + +## @backstage/plugin-auth-backend@0.25.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.4 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-backend@0.25.1 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-backend@0.25.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.4 + +### Patch Changes + +- b25977f: Updated dependency `@davidzemon/passport-okta-oauth` to `^0.0.6`. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + +## @backstage/plugin-auth-node@0.6.4 + +### Patch Changes + +- 0169b23: Internal tweak to avoid circular dependencies +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-react@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend-module-aws@0.4.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-catalog-backend-module-azure@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-catalog-backend-module-github@0.10.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.6 + +### Patch Changes + +- 087d51d: Export LDAP vendor types and instances for testing custom transformers + +- f07b0ad: Added the ability to configure disabling one side of the relations tree with LDAP. + + Groups have a `member` attribute and users have a `memberOf` attribute, however these can drift out of sync in some LDAP installations, leaving weird states in the Catalog as we collate these results together and deduplicate them. + + You can chose to optionally disable one side of these relationships, or even both by setting the respective mapping to `null` in your `app-config.yaml` for your groups and/or users: + + ```yaml + catalog: + providers: + ldapOrg: + default: + target: ldaps://ds.example.net + bind: + dn: uid=ldap-reader-user,ou=people,ou=example,dc=example,dc=net + secret: ${LDAP_SECRET} + users: + - dn: ou=people,ou=example,dc=example,dc=net + options: + filter: (uid=*) + map: + # this ensures that outgoing memberships from users is ignored + memberOf: null + groups: + - dn: ou=access,ou=groups,ou=example,dc=example,dc=net + options: + filter: (&(objectClass=some-group-class)(!(groupType=email))) + map: + description: l + set: + metadata.customField: 'hello' + map: + # this ensures that outgoing memberships from groups is ignored + members: null + ``` + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-logs@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-msgraph@0.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.8 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-catalog-graph@0.4.20 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-import@0.13.1 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 5d7c539: Catalog import plugin full support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-node@1.17.1 + +### Patch Changes + +- 0169b23: Internal tweak to avoid circular dependencies +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.18 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-config-schema@0.1.69 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-devtools@0.1.28 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-devtools-backend@0.5.6 + +### Patch Changes + +- 9a99735: Removed the usage of `permissionIntegrationRouter` in favor of using the new `coreServices.permissionsRegistry` +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-events-backend@0.5.3 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-azure@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-gerrit@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-github@0.4.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-gitlab@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + +### Patch Changes + +- f983e99: Add an `EventConsumingGooglePubSubPublisher`, for pushing Backstage events to pubsub +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-test-utils@0.1.45 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-node@0.4.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-gateway-backend@1.0.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-home@0.8.9 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 0ebad54: Fixed the `WelcomeTitle` to properly default to the previous value of `inherit` +- cef60db: Home plugin support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-home-react@0.1.27 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/theme@0.6.6 + +## @backstage/plugin-home-react@0.1.27 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- cef60db: Home plugin support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + +## @backstage/plugin-kubernetes@0.12.8 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 3ea5d1b: chore(deps): Update deprecated xterm to new package under @xterm +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/plugin-kubernetes-react@0.5.8 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-kubernetes-backend@0.19.7 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-kubernetes-node@0.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-kubernetes-cluster@0.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/plugin-kubernetes-react@0.5.8 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-kubernetes-node@0.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-kubernetes-react@0.5.8 + +### Patch Changes + +- 3ea5d1b: chore(deps): Update deprecated xterm to new package under @xterm +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-notifications@0.5.6 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- b00c160: Remove React import form notification and scaffolder plugin +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + +## @backstage/plugin-notifications-backend@0.5.7 + +### Patch Changes + +- 41d4d6e: Notifications are now automatically deleted after 1 year by default. + + There is a new scheduled task that runs every 24 hours to delete notifications older than 1 year. + This can be configured by setting the `notifications.retention` in the `app-config.yaml` file. + + ```yaml + notifications: + retention: 1y + ``` + + If the retention is set to false, notifications will not be automatically deleted. + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. + +- ef9ab82: Notifications API will now return user as null always for broadcast notifications + +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-signals-node@0.1.21 + +## @backstage/plugin-notifications-backend-module-email@0.3.10 + +### Patch Changes + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications-backend-module-slack@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications-common@0.0.9 + +### Patch Changes + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- Updated dependencies + - @backstage/config@1.3.2 + +## @backstage/plugin-notifications-node@0.2.16 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-signals-node@0.1.21 + +## @backstage/plugin-org@0.6.40 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 4fe364f: Org plugin support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-org-react@0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + +## @backstage/plugin-permission-backend@0.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-permission-node@0.10.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-permission-react@0.4.35 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-proxy-backend@0.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + - @backstage/plugin-proxy-node@0.1.5 + +## @backstage/plugin-proxy-node@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.10 + +### Patch Changes + +- e89d7b6: Migrating `azure` actions to using the new `zod` schema format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11 + +### Patch Changes + +- 7f710d2: Migrating `bitbucket` actions to use the new `zod` format +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10 + +### Patch Changes + +- ca9fdc0: Migrate `bitbucket-cloud` to new actions format +- 9c8ff0c: Update pull request creation filter to include .gitignore files in the created pull request +- 280611d: Fix `bitbucketCloudBranchRestrictions` API calls to accept null to prevent 400 errors for some branch restriction kinds defined. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10 + +### Patch Changes + +- d8169fc: Migrate the actions to the new format +- 9c8ff0c: Update pull request creation filter to include .gitignore files in the created pull request +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.10 + +### Patch Changes + +- 4a86bca: Migrate actions to new format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.11 + +### Patch Changes + +- 0b2bbf1: Migrate using new actions format +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10 + +### Patch Changes + +- e24b29b: Migrating to use new format for actions +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.10 + +### Patch Changes + +- ed41017: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2 + +### Patch Changes + +- 063b2d3: Fixed dependency to frontend package from tests +- a296637: Migrate to new action format +- 3d6493a: Support merge request labels in publish:gitlab:merge-request +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.11 + +### Patch Changes + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- 3f56115: Removed `octokit` dependency as it was not being used +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.10 + +### Patch Changes + +- a579693: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.10 + +### Patch Changes + +- 6c6fb4a: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.11 + +### Patch Changes + +- b392a34: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.3.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-search@1.4.27 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-search-react@1.9.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend@2.0.3 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-catalog@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-explore@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-pg@0.5.45 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-techdocs@0.4.3 + +### Patch Changes + +- b47ec38: Exports the default document collator for use in document transformation during search indexing. +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-node@1.13.4 + +## @backstage/plugin-search-backend-node@1.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-react@1.9.1 + +### Patch Changes + +- 869fa46: SearchBar clear button support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-signals@0.0.20 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + +## @backstage/plugin-signals-backend@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-signals-node@0.1.21 + +## @backstage/plugin-signals-node@0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-signals-react@0.0.14 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.49 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-search-react@1.9.1 + - @backstage/integration-react@1.2.8 + - @backstage/core-app-api@1.17.1 + - @backstage/test-utils@1.7.9 + +## @backstage/plugin-techdocs-backend@2.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.3 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-techdocs-node@1.13.4 + +## @backstage/plugin-techdocs-common@0.1.1 + +### Patch Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + +### Patch Changes + +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/integration-react@1.2.8 + - @backstage/integration@1.17.0 + +## @backstage/plugin-techdocs-node@1.13.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-user-settings@0.8.23 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- ab6d3dd: Add some translation to user-setting plugin +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-node@0.1.21 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.110 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0 + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/plugin-scaffolder@1.32.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18 + - @backstage/plugin-catalog-import@0.13.1 + - @backstage/plugin-catalog-graph@0.4.20 + - @backstage/plugin-notifications@0.5.6 + - @backstage/plugin-user-settings@0.8.23 + - @backstage/plugin-kubernetes@0.12.8 + - @backstage/plugin-api-docs@0.12.8 + - @backstage/plugin-devtools@0.1.28 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/plugin-signals@0.0.20 + - @backstage/plugin-search@1.4.27 + - @backstage/plugin-home@0.8.9 + - @backstage/plugin-org@0.6.40 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-search-react@1.9.1 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/plugin-kubernetes-cluster@0.0.26 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search-common@1.2.18 + +## example-app-next@0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0 + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/plugin-scaffolder@1.32.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18 + - @backstage/plugin-app-visualizer@0.1.20 + - @backstage/plugin-catalog-import@0.13.1 + - @backstage/plugin-catalog-graph@0.4.20 + - @backstage/plugin-notifications@0.5.6 + - @backstage/plugin-user-settings@0.8.23 + - @backstage/plugin-kubernetes@0.12.8 + - @backstage/plugin-api-docs@0.12.8 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/plugin-signals@0.0.20 + - @backstage/plugin-search@1.4.27 + - @backstage/plugin-home@0.8.9 + - @backstage/plugin-app@0.1.10 + - @backstage/plugin-org@0.6.40 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-app-api@0.11.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/frontend-defaults@0.2.3 + - @backstage/plugin-search-react@1.9.1 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/plugin-kubernetes-cluster@0.0.26 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search-common@1.2.18 + +## app-next-example-plugin@0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/frontend-plugin-api@0.10.3 + +## example-backend@0.0.39 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-backend@0.5.7 + - @backstage/plugin-scaffolder-backend-module-github@0.8.0 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-backend@2.0.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-devtools-backend@0.5.6 + - @backstage/plugin-mcp-actions-backend@0.1.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-search-backend@2.0.3 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-search-backend-module-techdocs@0.4.3 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-kubernetes-backend@0.19.7 + - @backstage/plugin-search-backend-module-catalog@0.3.5 + - @backstage/plugin-techdocs-backend@2.0.3 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-app-backend@0.5.3 + - @backstage/plugin-auth-backend@0.25.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + - @backstage/plugin-permission-backend@0.7.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-proxy-backend@0.6.3 + - @backstage/plugin-search-backend-module-explore@0.3.3 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-signals-backend@0.3.5 + +## e2e-test@0.2.29 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/frontend@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @internal/scaffolder@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/frontend-plugin-api@0.10.3 + +## techdocs-cli-embedded-app@0.2.109 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/test-utils@1.7.9 + - @backstage/theme@0.6.6 + +## yarn-plugin-backstage@0.0.6 + +### Patch Changes + +- a0f9e4e: added functionality so that adding or updating a backstage dependency to a package would maintain the "backstage:^" placeholder for the version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/release-manifests@0.0.13 + +## @internal/plugin-todo-list@1.0.40 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + +## @internal/plugin-todo-list-backend@1.0.40 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 diff --git a/docs/releases/v1.40.0-next.0-changelog.md b/docs/releases/v1.40.0-next.0-changelog.md new file mode 100644 index 0000000000..10ed249086 --- /dev/null +++ b/docs/releases/v1.40.0-next.0-changelog.md @@ -0,0 +1,1490 @@ +# Release v1.40.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.40.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.40.0-next.0) + +## @backstage/backend-plugin-api@1.4.0-next.0 + +### Minor Changes + +- 664c07a: Added `coreServices.actionsRegistry` and `coreServices.actions` to allow registration of distributed actions from plugins, and the ability to invoke these actions + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## @backstage/backend-test-utils@1.6.0-next.0 + +### Minor Changes + +- c999c25: Added mock implementations for `ActionsService` and `ActionsRegistryService` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/backend-app-api@1.2.4-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/canon@0.5.0-next.0 + +### Minor Changes + +- 24b45ef: Fixes spacing props on layout components and aligned on naming for the Grid component. You should now call the Grid root component using <Grid.Root /> instead of just . + +### Patch Changes + +- 269316d: Remove leftover console.log from Container component. + +## @backstage/create-app@0.7.0-next.0 + +### Minor Changes + +- 30474c4: Add .cache directory to shipped gitignore. + +## @backstage/repo-tools@0.14.0-next.0 + +### Minor Changes + +- bf9a173: Add support for caching the per-package output from the `package-docs` command. + +### Patch Changes + +- 2d20024: Fix an issue where errors were not printed to console when running `backstage-repo-tools schema openapi generate` without the `--watch` flag. +- e643ee4: Add missing highlight language for the `package-docs` command. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + +## @backstage/plugin-catalog@1.31.0-next.0 + +### Minor Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-techdocs@1.13.0-next.0 + +### Minor Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-techdocs-react@1.3.0-next.0 + +### Minor Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + +## @backstage/backend-app-api@1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/backend-defaults@0.10.1-next.0 + +### Patch Changes + +- c999c25: Added some default implementations for the `ActionsService` and `ActionsRegistryService` that allow registration of actions for a particular plugin. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-app-api@1.2.4-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## @backstage/backend-dynamic-feature-service@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/plugin-catalog-backend@2.0.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-events-backend@0.5.3-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + - @backstage/backend-openapi-utils@0.5.4-next.0 + - @backstage/plugin-app-node@0.1.34-next.0 + +## @backstage/backend-openapi-utils@0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/core-compat-api@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/dev-utils@1.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/integration-react@1.2.7 + +## @backstage/frontend-app-api@0.11.3-next.0 + +### Patch Changes + +- c38c9e8: Implemented support for the `plugin.info()` method in specialized apps with a default resolved for `package.json` and `catalog-info.yaml`. The default resolution logic can be overridden via the `pluginInfoResolver` option to `createSpecializedApp`, and plugin-specific overrides can be applied via the new `app.pluginOverrides` key in static configuration. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/frontend-defaults@0.2.3-next.0 + +## @backstage/frontend-defaults@0.2.3-next.0 + +### Patch Changes + +- fa5650c: Forwarded the new `pluginInfoResolver` option for `createApp`. +- Updated dependencies + - @backstage/plugin-app@0.1.10-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/frontend-app-api@0.11.3-next.0 + +## @backstage/frontend-dynamic-feature-loader@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## @backstage/frontend-plugin-api@0.10.3-next.0 + +### Patch Changes + +- 9e3868f: Added a new optional `info` option to `createFrontendPlugin` that lets you provide a loaders for different sources of metadata information about the plugin. + + There are two available loaders. The first one is `info.packageJson`, which can be used to point to a `package.json` file for the plugin. This is recommended for any plugin that is defined within its own package, especially all plugins that are published to a package registry. Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + packageJson: () => import('../package.json'), + }, + }); + ``` + + The second loader is `info.manifest`, which can be used to point to an opaque plugin manifest. This **MUST ONLY** be used by plugins that are intended for use within a single organization. Plugins that are published to an open package registry should **NOT** use this loader. The loader is useful for adding additional internal metadata associated with the plugin, and it is up to the Backstage app to decide how these manifests are parsed and used. The default manifest parser in an app created with `createApp` from `@backstage/frontend-defaults` is able to parse the default `catalog-info.yaml` format and built-in fields such as `spec.owner`. + + Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + manifest: () => import('../catalog-info.yaml'), + }, + }); + ``` + +- 6f48f71: Added a new `useAppNode` hook, which can be used to get a reference to the `AppNode` from by the closest `ExtensionBoundary`. + +## @backstage/frontend-test-utils@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.10-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/frontend-app-api@0.11.3-next.0 + +## @techdocs/cli@1.9.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-techdocs-node@1.13.4-next.0 + +## @backstage/plugin-api-docs@0.12.8-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/plugin-catalog@1.31.0-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/plugin-app@0.1.10-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-app-backend@0.5.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-app-node@0.1.34-next.0 + +## @backstage/plugin-app-node@0.1.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/config-loader@1.10.1 + +## @backstage/plugin-app-visualizer@0.1.20-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## @backstage/plugin-auth-backend@0.25.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-backend@0.25.1-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-backend@0.25.1-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-auth-node@0.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-catalog-backend@2.0.1-next.0 + +### Patch Changes + +- 4654a78: Update `refresh_state_references.id` to be a big int +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + - @backstage/backend-openapi-utils@0.5.4-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.4.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-azure@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/backend-openapi-utils@0.5.4-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-backend-module-github@0.9.1-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.6.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.6.7-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-logs@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + +## @backstage/plugin-catalog-graph@0.4.20-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/plugin-catalog-import@0.13.1-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-catalog-node@1.17.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## @backstage/plugin-catalog-react@1.18.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/frontend-test-utils@0.3.3-next.0 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + +## @backstage/plugin-devtools@0.1.28-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + +## @backstage/plugin-devtools-backend@0.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## @backstage/plugin-events-backend@0.5.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + - @backstage/backend-openapi-utils@0.5.4-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-events-backend-module-azure@0.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-events-backend-module-github@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.45-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-events-node@0.4.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-gateway-backend@1.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-home@0.8.9-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/plugin-kubernetes@0.12.8-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/plugin-kubernetes-backend@0.19.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-kubernetes-node@0.3.1-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## @backstage/plugin-kubernetes-cluster@0.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/plugin-kubernetes-node@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-notifications@0.5.6-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + +## @backstage/plugin-notifications-backend@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.0 + - @backstage/plugin-signals-node@0.1.21-next.0 + +## @backstage/plugin-notifications-backend-module-email@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.0 + +## @backstage/plugin-notifications-backend-module-slack@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.0 + +## @backstage/plugin-notifications-node@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-signals-node@0.1.21-next.0 + +## @backstage/plugin-org@0.6.40-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/plugin-org-react@0.1.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/plugin-permission-backend@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## @backstage/plugin-permission-node@0.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + +## @backstage/plugin-proxy-backend@0.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-proxy-node@0.1.5-next.0 + +## @backstage/plugin-proxy-node@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder@1.31.1-next.0 + +### Patch Changes + +- d781b33: render details for composite property schemas +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-scaffolder-react@1.16.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-scaffolder-backend@1.33.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10-next.0 + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.10-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.10-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.7.2-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10-next.0 + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10-next.0 + +### Patch Changes + +- 9c8ff0c: Update pull request creation filter to include .gitignore files in the created pull request +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10-next.0 + +### Patch Changes + +- 9c8ff0c: Update pull request creation filter to include .gitignore files in the created pull request +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2-next.0 + +### Patch Changes + +- 3d6493a: Support merge request labels in publish:gitlab:merge-request +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.2.3-next.0 + +## @backstage/plugin-scaffolder-node@0.8.3-next.0 + +### Patch Changes + +- 9c8ff0c: Update pull request creation filter to include .gitignore files in the created pull request +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-node-test-utils@0.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/backend-test-utils@1.6.0-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-scaffolder-react@1.16.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/plugin-search@1.4.27-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + +## @backstage/plugin-search-backend@2.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + - @backstage/backend-openapi-utils@0.5.4-next.0 + +## @backstage/plugin-search-backend-module-catalog@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + +## @backstage/plugin-search-backend-module-explore@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + +## @backstage/plugin-search-backend-module-pg@0.5.45-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + +## @backstage/plugin-search-backend-module-techdocs@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-techdocs-node@1.13.4-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + +## @backstage/plugin-search-backend-node@1.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-search-react@1.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## @backstage/plugin-signals@0.0.20-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## @backstage/plugin-signals-backend@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + - @backstage/plugin-signals-node@0.1.21-next.0 + +## @backstage/plugin-signals-node@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.49-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.0-next.0 + - @backstage/plugin-catalog@1.31.0-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-techdocs-backend@2.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-techdocs-node@1.13.4-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.3-next.0 + +## @backstage/plugin-techdocs-common@0.1.1-next.0 + +### Patch Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/integration-react@1.2.7 + +## @backstage/plugin-techdocs-node@1.13.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + +## @backstage/plugin-user-settings@0.8.23-next.0 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + +## @backstage/plugin-user-settings-backend@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-signals-node@0.1.21-next.0 + +## example-app@0.2.110-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.31.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.0 + - @backstage/plugin-catalog-import@0.13.1-next.0 + - @backstage/plugin-catalog-graph@0.4.20-next.0 + - @backstage/plugin-notifications@0.5.6-next.0 + - @backstage/plugin-user-settings@0.8.23-next.0 + - @backstage/plugin-kubernetes@0.12.8-next.0 + - @backstage/plugin-api-docs@0.12.8-next.0 + - @backstage/plugin-devtools@0.1.28-next.0 + - @backstage/plugin-techdocs@1.13.0-next.0 + - @backstage/plugin-catalog@1.31.0-next.0 + - @backstage/plugin-signals@0.0.20-next.0 + - @backstage/plugin-search@1.4.27-next.0 + - @backstage/plugin-home@0.8.9-next.0 + - @backstage/plugin-org@0.6.40-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/frontend-app-api@0.11.3-next.0 + - @backstage/canon@0.5.0-next.0 + - @backstage/plugin-scaffolder-react@1.16.1-next.0 + - @backstage/cli@0.32.1 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.0 + - @backstage/integration-react@1.2.7 + +## example-app-next@0.0.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.31.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.0 + - @backstage/plugin-app-visualizer@0.1.20-next.0 + - @backstage/plugin-catalog-import@0.13.1-next.0 + - @backstage/plugin-catalog-graph@0.4.20-next.0 + - @backstage/plugin-notifications@0.5.6-next.0 + - @backstage/plugin-user-settings@0.8.23-next.0 + - @backstage/plugin-kubernetes@0.12.8-next.0 + - @backstage/plugin-api-docs@0.12.8-next.0 + - @backstage/plugin-techdocs@1.13.0-next.0 + - @backstage/plugin-catalog@1.31.0-next.0 + - @backstage/plugin-signals@0.0.20-next.0 + - @backstage/plugin-search@1.4.27-next.0 + - @backstage/plugin-home@0.8.9-next.0 + - @backstage/plugin-app@0.1.10-next.0 + - @backstage/plugin-org@0.6.40-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/frontend-defaults@0.2.3-next.0 + - @backstage/frontend-app-api@0.11.3-next.0 + - @backstage/canon@0.5.0-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-scaffolder-react@1.16.1-next.0 + - @backstage/cli@0.32.1 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.0 + - @backstage/integration-react@1.2.7 + +## app-next-example-plugin@0.0.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## example-backend@0.0.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-events-backend@0.5.3-next.0 + - @backstage/plugin-search-backend@2.0.3-next.0 + - @backstage/plugin-scaffolder-backend@1.33.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.7.2-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11-next.0 + - @backstage/plugin-techdocs-backend@2.0.3-next.0 + - @backstage/plugin-app-backend@0.5.3-next.0 + - @backstage/plugin-auth-backend@0.25.1-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.0 + - @backstage/plugin-devtools-backend@0.5.6-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1-next.0 + - @backstage/plugin-kubernetes-backend@0.19.7-next.0 + - @backstage/plugin-notifications-backend@0.5.7-next.0 + - @backstage/plugin-permission-backend@0.7.1-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + - @backstage/plugin-proxy-backend@0.6.3-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.5-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.3-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.3-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + - @backstage/plugin-signals-backend@0.3.5-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1-next.0 + +## e2e-test@0.2.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.0-next.0 + +## @internal/frontend@0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## @internal/scaffolder@0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-scaffolder-react@1.16.1-next.0 + +## techdocs-cli-embedded-app@0.2.109-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.0-next.0 + - @backstage/plugin-catalog@1.31.0-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/cli@0.32.1 + - @backstage/integration-react@1.2.7 + +## @internal/plugin-todo-list-backend@1.0.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 diff --git a/docs/releases/v1.40.0-next.1-changelog.md b/docs/releases/v1.40.0-next.1-changelog.md new file mode 100644 index 0000000000..7f1ae68b01 --- /dev/null +++ b/docs/releases/v1.40.0-next.1-changelog.md @@ -0,0 +1,1922 @@ +# Release v1.40.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.40.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.40.0-next.1) + +## @backstage/plugin-scaffolder-backend@2.0.0-next.1 + +### Major Changes + +- 33394db: **BREAKING CHANGES** + + Removal of deprecated re-exports from module packages. + + The following functions have been re-exported from the `scaffolder-backend` plugin for quite some time, and now it's time to clean them up. They've been moved as follows: + + - `createPublishAzureAction` should be imported from `@backstage/plugin-scaffolder-backend-module-azure` instead. + + - `createPublishBitbucketCloudAction` should be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` instead. + + - `createPublishBitbucketServerAction` and `createPublishBitbucketServerPullRequestAction` can be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead. + + - `createPublishBitbucketAction` should be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket` instead. + + - `createPublishGerritAction` and `createPublishGerritReviewAction` can be imported from `@backstage/plugin-scaffolder-backend-module-gerrit` instead. + + - `createGithubActionsDispatchAction`, `createGithubDeployKeyAction`, `createGithubEnvironmentAction`, `createGithubIssuesLabelAction`, `CreateGithubPullRequestActionOptions`, `createGithubRepoCreateAction`, `createGithubRepoPushAction`, `createGithubWebhookAction`, and `createPublishGithubAction` can be imported from `@backstage/plugin-scaffolder-backend-module-github` instead. + + - `createPublishGitlabAction` should be imported from `@backstage/plugin-scaffolder-backend-module-gitlab` instead. + + - `ActionContext`. `createTemplateAction`, `executeShellCommand`, `ExecuteShellCommandOptions`, `fetchContents`, `TaskSecrets`, and `TemplateAction` should be imported from `@backstage/plugin-scaffolder-node` instead. + + - `ScaffolderEntitiesProcessor` should be imported from `@backstage/plugin-catalog-backend-module-scaffolder-entity-model` instead. + +- a8fcf04: **BREAKING ALPHA**: The `/alpha` export no longer exports the plugin. Please use `import('@backstage/plugin-scaffolder-backend')` instead as this has been removed. + + **BREAKING CHANGES**: The old `createRouter` function which was used in the old backend system has been removed along with the `RouterOptions` type. + +- 73b94d7: **BREAKING CHANGES** + + The following functions have been re-exported from the `scaffolder-backend` plugin for quite some time, and now it's time to clean them up. They've been moved as follows: + + - `SerializedTask`, `SerializedTaskEvent`, `TaskBroker`, `TaskBrokerDispatchOptions`, `TaskBrokerDispatchResult`, `TaskCompletionState`, `TaskContext`, `TaskEventType`, `TaskStatus`, `TemplateFilter`, and `TemplateGlobal` should be imported from `@backstage/plugin-scaffolder-node` instead. + + - The deprecated `copyWithoutRender` option has been removed from `fetch:template` action. You should rename the option to `copyWithoutTemplating` instead. + +### Minor Changes + +- 73b94d7: **DEPRECATIONS** + + The following types and implementations have been deprecated, either because they're no longer relevant, or because upcoming changes to the `scaffolder-backend` after `2.0.0` will influence the changes to these API surfaces. + + - `CreateWorkerOptions` + - `DatabaseTaskStore` + - `DatabaseTaskStoreOptions` + - `TaskManager` + - `TaskStoreCreateTaskOptions` + - `TaskStoreCreateTaskResult` + - `TaskStoreEmitOptions` + - `TaskStoreListEventsOptions` + - `TaskStoreRecoverTaskOptions` + - `TaskStoreShutDownTaskOptions` + + There is no current path off deprecation, these types are going to be removed and rethought with a better way to define workers in the new backend system. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.10-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10-next.1 + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.10-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11-next.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.7.2-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/canon@0.5.0-next.1 + +### Minor Changes + +- 621fac9: We are updating the default size of the Button component in Canon to be small instead of medium. +- a842554: We set the default size for IconButton in Canon to be small instead of medium. + +## @backstage/backend-app-api@1.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/backend-defaults@0.10.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-app-api@1.2.4-next.1 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/backend-dynamic-feature-service@0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-backend@2.0.1-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34-next.1 + - @backstage/plugin-events-backend@0.5.3-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/backend-openapi-utils@0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/backend-plugin-api@1.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/backend-test-utils@1.6.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-app-api@1.2.4-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/catalog-client@1.10.1-next.0 + +### Patch Changes + +- 22fad0d: Fixed `CatalogClient` error responses for `refreshEntity` and `addLocation`. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/cli@0.32.2-next.0 + +### Patch Changes + +- ce70439: The `BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE` flag has been removed. Existing users are encouraged to switch to `EXPERIMENTAL_RSPACK` instead. +- 1d8f00b: Switched to using the `ModuleFederationPlugin` from `@module-federation/enhanced/rspack` for Rspack, rather than the built-in one. +- 2b9633f: The experimental `FORCE_REACT_DEVELOPMENT` flag has been removed. +- d8c4a54: Only use the caching Jest module loader for frontend packages in order to avoid breaking real ESM module imports. +- 1bab255: Internal refactor to combine alpha `build` and `start` modules. +- 713e957: fix: merge eslint reports when using json format +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.10 + - @backstage/integration@1.17.0 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/core-compat-api@0.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.7.0-next.1 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/app-defaults@1.6.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + +## @backstage/repo-tools@0.14.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + +## @techdocs/cli@1.9.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## @backstage/plugin-api-docs@0.12.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.0-next.1 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-app-backend@0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34-next.1 + +## @backstage/plugin-app-node@0.1.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config-loader@1.10.1 + +## @backstage/plugin-auth-backend@0.25.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-backend@0.25.1-next.1 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-backend@0.25.1-next.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + +## @backstage/plugin-auth-node@0.6.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog@1.31.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder-common@1.5.11 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## @backstage/plugin-catalog-backend@2.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-catalog-backend-module-azure@0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-github@0.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-backend@2.0.1-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.9.1-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.6.7-next.1 + +### Patch Changes + +- 57a0bad: Implement retry for GitLab API calls to handle rate limiting +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.6.7-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.1-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-logs@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.8 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-catalog-graph@0.4.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-import@0.13.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration@1.17.0 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-node@1.17.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/plugin-catalog-react@1.18.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/frontend-test-utils@0.3.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## @backstage/plugin-devtools@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-devtools-backend@0.5.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/plugin-events-backend@0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-backend-module-azure@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-backend-module-gerrit@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-backend-module-github@0.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-backend-module-gitlab@0.3.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-backend-test-utils@0.1.45-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-events-node@0.4.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-gateway-backend@1.0.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-home@0.8.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/theme@0.6.6 + - @backstage/plugin-home-react@0.1.26 + +## @backstage/plugin-kubernetes@0.12.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-kubernetes-react@0.5.7 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-kubernetes-backend@0.19.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-kubernetes-node@0.3.1-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/plugin-kubernetes-cluster@0.0.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-kubernetes-react@0.5.7 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-kubernetes-node@0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-notifications@0.5.6-next.1 + +### Patch Changes + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.13 + +## @backstage/plugin-notifications-backend@0.5.7-next.1 + +### Patch Changes + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-notifications-node@0.2.16-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-signals-node@0.1.21-next.1 + +## @backstage/plugin-notifications-backend-module-email@0.3.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-notifications-node@0.2.16-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications-backend-module-slack@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-notifications-node@0.2.16-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications-common@0.0.9-next.0 + +### Patch Changes + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- Updated dependencies + - @backstage/config@1.3.2 + +## @backstage/plugin-notifications-node@0.2.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-signals-node@0.1.21-next.1 + +## @backstage/plugin-org@0.6.40-next.1 + +### Patch Changes + +- 4fe364f: Org plugin support i18n +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-org-react@0.1.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + +## @backstage/plugin-permission-backend@0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/plugin-permission-node@0.10.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-proxy-backend@0.6.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/types@1.2.1 + - @backstage/plugin-proxy-node@0.1.5-next.1 + +## @backstage/plugin-proxy-node@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-scaffolder@1.31.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/plugin-scaffolder-react@1.16.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration@1.17.0 + - @backstage/integration-react@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.10-next.1 + +### Patch Changes + +- e89d7b6: Migrating `azure` actions to using the new `zod` schema format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11-next.1 + +### Patch Changes + +- 7f710d2: Migrating `bitbucket` actions to use the new `zod` format +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10-next.1 + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10-next.1 + +### Patch Changes + +- ca9fdc0: Migrate `bitbucket-cloud` to new actions format +- 280611d: Fix `bitbucketCloudBranchRestrictions` API calls to accept null to prevent 400 errors for some branch restriction kinds defined. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10-next.1 + +### Patch Changes + +- d8169fc: Migrate the actions to the new format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.10-next.1 + +### Patch Changes + +- 4a86bca: Migrate actions to new format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.11-next.1 + +### Patch Changes + +- 0b2bbf1: Migrate using new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10-next.1 + +### Patch Changes + +- e24b29b: Migrating to use new format for actions +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.10-next.1 + +### Patch Changes + +- ed41017: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.7.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.11-next.1 + +### Patch Changes + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.2.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-node@0.8.3-next.1 + +### Patch Changes + +- e89d7b6: Use `LoggerService` instead of `Logger`. This is a non-breaking change, as the `LoggerService` is a subset of the `Logger` interface. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-node-test-utils@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/backend-test-utils@1.6.0-next.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-react@1.16.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-search@1.4.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.0 + +## @backstage/plugin-search-backend@2.0.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-catalog@0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-explore@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-pg@0.5.45-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-techdocs@0.4.3-next.1 + +### Patch Changes + +- b47ec38: Exports the default document collator for use in document transformation during search indexing. +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## @backstage/plugin-search-backend-node@1.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-signals-backend@0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-signals-node@0.1.21-next.1 + +## @backstage/plugin-signals-node@0.1.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-techdocs@1.13.0-next.1 + +### Patch Changes + +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration@1.17.0 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.49-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.0-next.1 + - @backstage/plugin-catalog@1.31.0-next.1 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration-react@1.2.7 + - @backstage/test-utils@1.7.8 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## @backstage/plugin-techdocs-backend@2.0.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.3-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.1 + +### Patch Changes + +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration@1.17.0 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## @backstage/plugin-techdocs-node@1.13.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + +## @backstage/plugin-user-settings@0.8.23-next.1 + +### Patch Changes + +- ab6d3dd: Add some translation to user-setting plugin +- Updated dependencies + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.13 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-node@0.1.21-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.110-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0-next.1 + - @backstage/cli@0.32.2-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.1 + - @backstage/plugin-techdocs@1.13.0-next.1 + - @backstage/plugin-org@0.6.40-next.1 + - @backstage/plugin-user-settings@0.8.23-next.1 + - @backstage/plugin-notifications@0.5.6-next.1 + - @backstage/plugin-catalog@1.31.0-next.1 + - @backstage/plugin-catalog-graph@0.4.20-next.1 + - @backstage/plugin-catalog-import@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/plugin-home@0.8.9-next.1 + - @backstage/plugin-scaffolder@1.31.1-next.1 + - @backstage/plugin-scaffolder-react@1.16.1-next.1 + - @backstage/app-defaults@1.6.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-api-docs@0.12.8-next.1 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.1 + - @backstage/plugin-devtools@0.1.28-next.1 + - @backstage/plugin-kubernetes@0.12.8-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.1 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-search@1.4.27-next.1 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-signals@0.0.20-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## example-app-next@0.0.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0-next.1 + - @backstage/cli@0.32.2-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.1 + - @backstage/plugin-techdocs@1.13.0-next.1 + - @backstage/plugin-org@0.6.40-next.1 + - @backstage/plugin-user-settings@0.8.23-next.1 + - @backstage/plugin-notifications@0.5.6-next.1 + - @backstage/plugin-catalog@1.31.0-next.1 + - @backstage/plugin-catalog-graph@0.4.20-next.1 + - @backstage/plugin-catalog-import@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/plugin-home@0.8.9-next.1 + - @backstage/plugin-scaffolder@1.31.1-next.1 + - @backstage/plugin-scaffolder-react@1.16.1-next.1 + - @backstage/app-defaults@1.6.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.0 + - @backstage/frontend-defaults@0.2.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-api-docs@0.12.8-next.1 + - @backstage/plugin-app@0.1.10-next.0 + - @backstage/plugin-app-visualizer@0.1.20-next.0 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.1 + - @backstage/plugin-kubernetes@0.12.8-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.1 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-search@1.4.27-next.1 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-signals@0.0.20-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## example-backend@0.0.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11-next.1 + - @backstage/plugin-notifications-backend@0.5.7-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.3-next.1 + - @backstage/plugin-scaffolder-backend@2.0.0-next.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-backend@2.0.1-next.1 + - @backstage/plugin-kubernetes-backend@0.19.7-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.7.2-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.5-next.1 + - @backstage/plugin-techdocs-backend@2.0.3-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-app-backend@0.5.3-next.1 + - @backstage/plugin-auth-backend@0.25.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1-next.1 + - @backstage/plugin-devtools-backend@0.5.6-next.1 + - @backstage/plugin-events-backend@0.5.3-next.1 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1-next.1 + - @backstage/plugin-permission-backend@0.7.1-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-proxy-backend@0.6.3-next.1 + - @backstage/plugin-search-backend@2.0.3-next.1 + - @backstage/plugin-search-backend-module-explore@0.3.3-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-signals-backend@0.3.5-next.1 + +## e2e-test@0.2.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.0-next.1 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/scaffolder@0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.16.1-next.1 + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## techdocs-cli-embedded-app@0.2.109-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.32.2-next.0 + - @backstage/plugin-techdocs@1.13.0-next.1 + - @backstage/plugin-catalog@1.31.0-next.1 + - @backstage/app-defaults@1.6.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration-react@1.2.7 + - @backstage/test-utils@1.7.8 + - @backstage/theme@0.6.6 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## @internal/plugin-todo-list-backend@1.0.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/errors@1.2.7 diff --git a/docs/releases/v1.40.0-next.2-changelog.md b/docs/releases/v1.40.0-next.2-changelog.md new file mode 100644 index 0000000000..ed14cbf003 --- /dev/null +++ b/docs/releases/v1.40.0-next.2-changelog.md @@ -0,0 +1,1539 @@ +# Release v1.40.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.40.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.40.0-next.2) + +## @backstage/plugin-scaffolder-backend@2.0.0-next.2 + +### Major Changes + +- 5863b04: **BREAKING CHANGES** + + - The `createBuiltinActions` method has been removed, as this should no longer be needed with the new backend system route, and was only useful when passing the default list of actions again in the old backend system. You should be able to rely on the default behaviour of the new backend system which is to merge the actions. + + - The `createCatalogRegisterAction` and `createFetchCatalogEntityAction` actions no longer require an `AuthService`, and now accepts a `CatalogService` instead of `CatalogClient`. + + Unless you're providing your own override action to the default, this should be a non-breaking change. + + You can migrate using the following if you're getting typescript errors: + + ```ts + import { catalogServiceRef } from '@backstage/plugin-catalog-node'; + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; + + export const myModule = createBackendModule({ + pluginId: 'scaffolder', + moduleId: 'test', + register({ registerInit }) { + registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + catalog: catalogServiceRef, + }, + async init({ scaffolder, catalog }) { + scaffolder.addActions( + createCatalogRegisterAction({ + catalog, + }), + createFetchCatalogEntityAction({ + catalog, + integrations, + }), + ); + }, + }); + }, + }); + ``` + +### Patch Changes + +- 89a941d: Migrating to latest action format + +- 023629e: Enable usage of secrets within 'each' step of software templates. For example, you can now structure your `each` step like this: + + each: + [ + { name: "Service1", token: "${{ secrets.token1 }}" }, + { name: "Service2", token: "${{ secrets.token2 }}" }, + ] + +- e92e481: Add tests for Scaffolder + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2-next.2 + - @backstage/plugin-scaffolder-backend-module-github@0.8.0-next.2 + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.10-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10-next.2 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10-next.2 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.10-next.2 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/backend-defaults@0.11.0-next.2 + +### Minor Changes + +- 3ccb7fc: Enhanced error handling in the auditor service factory to pass errors as objects. Aligned WinstonRootAuditorService with the default service factory's error handling. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@1.2.4-next.2 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/cli@0.33.0-next.1 + +### Minor Changes + +- eef0e83: Internal update to promote the modular CLI entrypoint to stable. + +### Patch Changes + +- d07fe35: Added user feedback when opening config docs in browser. The command now clearly indicates what it's doing and provides fallback instructions if the browser fails to open. +- d6d63c7: Updating the scaffolder action boilerplate to use new `zod` schema +- e36e855: Added `backstage.pluginId` field in `package.json` to all default plugin package templates for the `new` command. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.10 + - @backstage/integration@1.17.0 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog@1.31.0-next.2 + +### Minor Changes + +- 406acb6: Add support to customize the about card icon links via `EntityIconLinkBlueprint` and provide a default catalog view catalog source, launch scaffolder template and read techdocs docs icon links extensions. + + **BREAKING ALPHA** + + The `Scaffolder` launch template and `TechDocs` read documentation icons have been extracted from the default `Catalog` about card links and are now provided respectively by the `Scaffolder` and `TechDocs` plugins in the new frontend system. It means that they will not be available unless you install the `TechDocs` and `Scaffolder` plugins. Also If you are using translation for these icon link titles other than the default, you should now translate them using the scaffolder translation reference or the TechDocs translation reference (the translation keys are still the same, `aboutCard.viewTechdocs` and `aboutCard.launchTemplate`). + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder-common@1.5.11 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.0-next.2 + +### Minor Changes + +- 8a150bf: **BREAKING**: `BitbucketCloudEntityProvider` now accepts a `CatalogService` instead of a `CatalogApi`. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.0-next.2 + +### Minor Changes + +- 42bb3b8: **BREAKING CHANGE**: User and Group discovery will default to ingesting all users in sub groups that belong to the specified root group in config. Disable by setting `restrictUsersToGroup: true` in app-config under your module settings. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-react@1.19.0-next.2 + +### Minor Changes + +- 406acb6: Introduces a new `EntityIconLinkBlueprint` that customizes the `About` card icon links on the `Catalog` entity page. + + The blueprint currently accepts a `useProps` hook as `param` and this function returns the following props that will be passed to the icon link component: + + | Name | Description | Type | Default Value | + | ---------- | --------------------------------------------------- | ------------- | ------------- | + | `icon` | The icon to display. | `JSX.Element` | N/A | + | `label` | The label for the element. | `string` | N/A | + | `title` | The title for the element. | `string` | N/A | + | `disabled` | Whether the element is disabled. | `boolean` | `false` | + | `href` | The URL to navigate to when the element is clicked. | `string` | N/A | + | `onClick` | A function to call when the element is clicked. | `() => void` | N/A | + + Here is an usage example: + + ```tsx + import { EntityIconLinkBlueprint } from '@backstage/plugin-catalog-react/alpha'; + //... + + EntityIconLinkBlueprint.make({ + name: 'my-icon-link', + params: { + useProps() { + const { t } = useTranslationRef(myIconLinkTranslationRef); + return { + label: t('myIconLink.label'), + icon: , + href: '/my-plugin', + }; + }, + }, + }); + ``` + + Additionally, the `app-config.yaml` file allows you to override some of the default icon link parameters, including `label` and `title` values. Here's how to set them: + + ```yaml + app: + extensions: + - entity-icon-link:my-plugin/my-icon-link: + config: + label: 'My Custom Icon Link label' + ``` + + Finally, you can disable all links if you want to hide the About card header completely (useful, for example, when links are displayed on separate cards). The header is hidden when no icon links extensions are enabled. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-test-utils@0.3.3-next.1 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-scaffolder@1.32.0-next.2 + +### Minor Changes + +- 3c59ece: **New Frontend System Only:** + The `Scaffolder` plugin is now responsible for providing an entity icon link extension to launch templates from the catalog entity page. + +### Patch Changes + +- b00c160: Remove React import form notification and scaffolder plugin +- 95a1d72: Added appropriate message when global templating function metadata is absent. +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.0-next.2 + +### Minor Changes + +- 5863b04: **BREAKING CHANGES** + + The `createGithubEnvironmentAction` action no longer requires an `AuthService`, and now accepts a `CatalogService` instead of `CatalogClient`. + + Unless you're providing your own override action to the default, this should be a non-breaking change. + + You can migrate using the following if you're getting typescript errors: + + ```ts + import { catalogServiceRef } from '@backstage/plugin-catalog-node'; + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; + + export const myModule = createBackendModule({ + pluginId: 'scaffolder', + moduleId: 'test', + register({ registerInit }) { + registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + catalog: catalogServiceRef, + }, + async init({ scaffolder, catalog }) { + scaffolder.addActions( + createGithubEnvironmentAction({ + catalog, + }), + ); + }, + }); + }, + }); + ``` + +### Patch Changes + +- 575c76b: Migrate to using new actions +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + +## @backstage/plugin-scaffolder-node@0.9.0-next.2 + +### Minor Changes + +- 5863b04: **BREAKING CHANGES** + + The legacy methods to define `createTemplateActions` have been replaced with the new native `zod` approaches for defining input and output schemas. + + You can migrate actions that look like the following with the below examples: + + ```ts + // really old legacy json schema + createTemplateAction<{ repoUrl: string }, { repoOutput: string }>({ + id: 'test', + schema: { + input: { + type: 'object' + required: ['repoUrl'] + properties: { + repoUrl: { + type: 'string', + description: 'repository url description' + } + } + } + } + }); + + // old zod method + createTemplateAction({ + id: 'test' + schema: { + input: { + repoUrl: z.string({ description: 'repository url description' }) + } + } + }) + + // new method: + createTemplateAction({ + id: 'test', + schema: { + input: { + repoUrl: z => z.string({ description: 'repository url description' }) + } + } + }) + + // or for more complex zod types like unions + createTemplateAction({ + id: 'test', + schema: { + input: z => z.object({ + repoUrl: z.string({ description: 'repository url description' }) + }) + } + }) + ``` + + This breaking change also means that `logStream` has been removed entirely from `ActionsContext`, and that the `logger` is now just a `LoggerService` implementation instead. There is no replacement for the `logStream`, if you wish to still keep using a `logStream` we recommend that you create your own stream that writes to `ctx.logger` instead. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.0-next.2 + +### Minor Changes + +- 3cea7ee: **BREAKING CHANGES** + + Because of the removal of the `logStream` property to the `ActionsContext` this has been removed from the `createMockActionContext` method. + + You can remove this as it's no longer supported in the scaffolder actions. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-test-utils@1.6.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-techdocs@1.13.0-next.2 + +### Minor Changes + +- 3c59ece: **New Frontend System Only:** + The `TechDocs` plugin is now responsible for providing an entity icon link extension to read documentation from the catalog entity page. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/theme@0.6.6 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + +## @backstage/app-defaults@1.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/backend-app-api@1.2.4-next.2 + +### Patch Changes + +- bb9a501: Fixed a bug where occasionally the initialization order of multiple modules consuming a single extension point could happen in the wrong order. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/backend-dynamic-feature-service@0.7.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/plugin-catalog-backend@2.0.1-next.2 + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34-next.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-events-backend@0.5.3-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/backend-test-utils@1.6.0-next.2 + +### Patch Changes + +- 12c1fd4: Make the `user` credentials mock behave more like production +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/backend-app-api@1.2.4-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/canon@0.5.0-next.2 + +### Patch Changes + +- 44df879: Add min-width: 0; by default on every Flex components in Canon to help support truncated texts inside flex elements. +- ee6ffe6: Fix styling for the title4 prop on the Heading component in Canon. +- f2f814a: Added a render prop to the Button component in Canon to use it as a link. + +## @backstage/core-compat-api@0.4.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/core-plugin-api@1.10.7 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-components@0.17.3-next.0 + +### Patch Changes + +- 6232160: table actions header support i18n +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.7.0-next.2 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/theme@0.6.6 + +## @backstage/frontend-app-api@0.11.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-defaults@0.2.3-next.1 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/plugin-app@0.1.10-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/frontend-app-api@0.11.3-next.1 + +## @backstage/frontend-dynamic-feature-loader@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/config@1.3.2 + +## @backstage/frontend-plugin-api@0.10.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-test-utils@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/plugin-app@0.1.10-next.1 + - @backstage/config@1.3.2 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/test-utils@1.7.8 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/repo-tools@0.14.0-next.2 + +### Patch Changes + +- 4bff5d0: Fixed a bug where linting would fail with the generated clients when defining top-level `enum` schema values. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + +## @techdocs/cli@1.9.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## @backstage/plugin-api-docs@0.12.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-app@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/core-plugin-api@1.10.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-app-visualizer@0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/core-plugin-api@1.10.7 + +## @backstage/plugin-auth-react@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend@2.0.1-next.2 + +### Patch Changes + +- 2cac8b0: You can now specify an optional value when applying the `HAS_LABEL` permission rule, similar to the `HAS_ANNOTATION` permission rule. +- Updated dependencies + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-catalog-backend-module-github@0.9.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.1-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-backend-module-github@0.9.1-next.2 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/plugin-catalog-backend@2.0.1-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-catalog-backend-module-logs@0.1.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.1-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/plugin-catalog-graph@0.4.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-import@0.13.1-next.2 + +### Patch Changes + +- 5d7c539: Catalog import plugin full support i18n +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + +## @backstage/plugin-config-schema@0.1.69-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-devtools@0.1.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-devtools-backend@0.5.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## @backstage/plugin-home@0.8.9-next.2 + +### Patch Changes + +- 0ebad54: Fixed the `WelcomeTitle` to properly default to the previous value of `inherit` +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/plugin-home-react@0.1.27-next.0 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/theme@0.6.6 + +## @backstage/plugin-home-react@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + +## @backstage/plugin-kubernetes@0.12.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/plugin-kubernetes-react@0.5.8-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-kubernetes-cluster@0.0.26-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-kubernetes-react@0.5.8-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-permission-react@0.4.34 + +## @backstage/plugin-kubernetes-react@0.5.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-notifications@0.5.6-next.2 + +### Patch Changes + +- b00c160: Remove React import form notification and scaffolder plugin +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-signals-react@0.0.13 + +## @backstage/plugin-notifications-backend@0.5.7-next.2 + +### Patch Changes + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.1 + - @backstage/plugin-signals-node@0.1.21-next.1 + +## @backstage/plugin-notifications-backend-module-email@0.3.10-next.2 + +### Patch Changes + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.1 + +## @backstage/plugin-org@0.6.40-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-org-react@0.1.39-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.7 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10-next.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2-next.2 + +### Patch Changes + +- a296637: Migrate to new action format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.11-next.2 + +### Patch Changes + +- 3f56115: Removed `octokit` dependency as it was not being used +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.10-next.2 + +### Patch Changes + +- a579693: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.10-next.2 + +### Patch Changes + +- 6c6fb4a: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.11-next.2 + +### Patch Changes + +- b392a34: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.3.0-next.2 + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-react@1.16.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-search@1.4.27-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend@2.0.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-react@1.9.1-next.1 + +### Patch Changes + +- 869fa46: SearchBar clear button support i18n +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/core-plugin-api@1.10.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-signals@0.0.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/core-plugin-api@1.10.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.13 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.49-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/test-utils@1.7.8 + +## @backstage/plugin-techdocs-backend@2.0.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.3-next.1 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-techdocs-react@1.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + +## @backstage/plugin-user-settings@0.8.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.13 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-signals-node@0.1.21-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.110-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/cli@0.33.0-next.1 + - @backstage/canon@0.5.0-next.2 + - @backstage/plugin-notifications@0.5.6-next.2 + - @backstage/plugin-scaffolder@1.32.0-next.2 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-catalog-import@0.13.1-next.2 + - @backstage/plugin-home@0.8.9-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-api-docs@0.12.8-next.2 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-catalog-graph@0.4.20-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.2 + - @backstage/plugin-devtools@0.1.28-next.2 + - @backstage/plugin-kubernetes@0.12.8-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.2 + - @backstage/plugin-org@0.6.40-next.2 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + - @backstage/plugin-search@1.4.27-next.2 + - @backstage/plugin-signals@0.0.20-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/plugin-user-settings@0.8.23-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-search-common@1.2.18 + +## example-app-next@0.0.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/cli@0.33.0-next.1 + - @backstage/canon@0.5.0-next.2 + - @backstage/plugin-notifications@0.5.6-next.2 + - @backstage/plugin-scaffolder@1.32.0-next.2 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-catalog-import@0.13.1-next.2 + - @backstage/plugin-home@0.8.9-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-api-docs@0.12.8-next.2 + - @backstage/plugin-app@0.1.10-next.1 + - @backstage/plugin-app-visualizer@0.1.20-next.1 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-catalog-graph@0.4.20-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.2 + - @backstage/plugin-kubernetes@0.12.8-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.2 + - @backstage/plugin-org@0.6.40-next.2 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + - @backstage/plugin-search@1.4.27-next.2 + - @backstage/plugin-signals@0.0.20-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/plugin-user-settings@0.8.23-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/frontend-defaults@0.2.3-next.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-search-common@1.2.18 + +## app-next-example-plugin@0.0.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + +## example-backend@0.0.39-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.8.0-next.2 + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/plugin-scaffolder-backend@2.0.0-next.2 + - @backstage/plugin-notifications-backend@0.5.7-next.2 + - @backstage/plugin-catalog-backend@2.0.1-next.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-app-backend@0.5.3-next.1 + - @backstage/plugin-auth-backend@0.25.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9-next.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1-next.1 + - @backstage/plugin-devtools-backend@0.5.6-next.2 + - @backstage/plugin-events-backend@0.5.3-next.1 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1-next.1 + - @backstage/plugin-kubernetes-backend@0.19.7-next.1 + - @backstage/plugin-permission-backend@0.7.1-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-proxy-backend@0.6.3-next.1 + - @backstage/plugin-search-backend@2.0.3-next.2 + - @backstage/plugin-search-backend-module-catalog@0.3.5-next.1 + - @backstage/plugin-search-backend-module-explore@0.3.3-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.3-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-signals-backend@0.3.5-next.1 + - @backstage/plugin-techdocs-backend@2.0.3-next.2 + +## e2e-test@0.2.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.0-next.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/frontend@0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @internal/scaffolder@0.0.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + +## techdocs-cli-embedded-app@0.2.109-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/cli@0.33.0-next.1 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/test-utils@1.7.8 + - @backstage/theme@0.6.6 + +## @internal/plugin-todo-list@1.0.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 diff --git a/docs/releases/v1.40.0-next.3-changelog.md b/docs/releases/v1.40.0-next.3-changelog.md new file mode 100644 index 0000000000..6dfc2aa342 --- /dev/null +++ b/docs/releases/v1.40.0-next.3-changelog.md @@ -0,0 +1,166 @@ +# Release v1.40.0-next.3 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.40.0-next.3](https://backstage.github.io/upgrade-helper/?to=1.40.0-next.3) + +## @backstage/plugin-events-backend-module-kafka@0.1.0-next.0 + +### Minor Changes + +- b034b9d: Adds a new module `kafka` for plugin-events-backend + + The module introduces the `KafkaConsumerClient` which creates a Kafka client used to establish consumer connections. It also provides the `KafkaConsumingEventPublisher`, a consumer that subscribes to configured Kafka topics and publishes received messages to the Event Service. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## @backstage/cli@0.33.0-next.2 + +### Patch Changes + +- 8a0164c: Fix an issue where some commands were not usable because of missing dist files +- Updated dependencies + - @backstage/eslint-plugin@0.1.11-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/create-app@0.7.0-next.3 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/eslint-plugin@0.1.11-next.0 + +### Patch Changes + +- 098ef95: Fix custom rules package scanning performance. + +## example-app@0.2.110-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.33.0-next.2 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/canon@0.5.0-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-api-docs@0.12.8-next.2 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-graph@0.4.20-next.2 + - @backstage/plugin-catalog-import@0.13.1-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.2 + - @backstage/plugin-devtools@0.1.28-next.2 + - @backstage/plugin-home@0.8.9-next.2 + - @backstage/plugin-kubernetes@0.12.8-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.2 + - @backstage/plugin-notifications@0.5.6-next.2 + - @backstage/plugin-org@0.6.40-next.2 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder@1.32.0-next.2 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + - @backstage/plugin-search@1.4.27-next.2 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/plugin-signals@0.0.20-next.1 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/plugin-user-settings@0.8.23-next.2 + +## example-app-next@0.0.24-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.33.0-next.2 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/canon@0.5.0-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/frontend-defaults@0.2.3-next.1 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-api-docs@0.12.8-next.2 + - @backstage/plugin-app@0.1.10-next.1 + - @backstage/plugin-app-visualizer@0.1.20-next.1 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-graph@0.4.20-next.2 + - @backstage/plugin-catalog-import@0.13.1-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.2 + - @backstage/plugin-home@0.8.9-next.2 + - @backstage/plugin-kubernetes@0.12.8-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.2 + - @backstage/plugin-notifications@0.5.6-next.2 + - @backstage/plugin-org@0.6.40-next.2 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder@1.32.0-next.2 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + - @backstage/plugin-search@1.4.27-next.2 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/plugin-signals@0.0.20-next.1 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/plugin-user-settings@0.8.23-next.2 + +## e2e-test@0.2.29-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.0-next.3 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## techdocs-cli-embedded-app@0.2.109-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.33.0-next.2 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration-react@1.2.7 + - @backstage/test-utils@1.7.8 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 diff --git a/docs/releases/v1.40.0.md b/docs/releases/v1.40.0.md new file mode 100644 index 0000000000..befaddfd66 --- /dev/null +++ b/docs/releases/v1.40.0.md @@ -0,0 +1,200 @@ +--- +id: v1.40.0 +title: v1.40.0 +description: Backstage Release v1.40.0 +--- + +These are the release notes for the v1.40.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### Scaffolder 2.0 Breaking Changes + +The deprecated legacy action formats have been removed and replaced with the new native `zod` formats. + +This also cleaned up some deprecated `logStream` and `WinstonLogger` usages in the old patterns. + +```ts +// really old legacy json schema +createTemplateAction<{ repoUrl: string }, { repoOutput: string }>({ + id: 'test', + schema: { + input: { + type: 'object' + required: ['repoUrl'] + properties: { + repoUrl: { + type: 'string', + description: 'repository url description' + } + } + } + } +}); + +// old zod method +createTemplateAction({ + id: 'test' + schema: { + input: { + repoUrl: z.string({ description: 'repository url description' }) + } + } +}) + +// new method: +createTemplateAction({ + id: 'test', + schema: { + input: { + repoUrl: z => z.string({ description: 'repository url description' }) + } + } +}) + +``` + +:::note + +As the new `zod` format is more strict if there are any additional properties in your Software Template YAML where you define your action it will trigger an `InputError`. Here is an exact example for reference: + +> "InputError: Invalid input passed to action publish:github, instance is not allowed to have the additional property "allowedHosts" + +To fix these you will simply need to remove the extra property details in your Software Template YAML where you define your action. + +::: + +The `scaffolder-backend` plugin has been converted to being New Backend System only, which means a lot of the public API has been cleaned up. + +The `createRouter` and `createBuiltinActions` have been removed as they were only used in the legacy backend system. + +A lot of deprecated types which were re-exported in the `-backend` package from `-common` and `-node` have been removed, and can be fixed by importing them from the correct package. + +The deprecated `copyWithoutRender` option has been removed from `fetch:template` and should be renamed to `copyWithoutTemplating`. + +The re-exported action creators from the provider packages such as `createPublishAzureAction` and `createPublishGithubAction` should now be imported from the provider modules themselves. + +As always you can head over the latest changelogs for [`@backstage/plugin-scaffolder-backend`](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/CHANGELOG.md) and [`@backstage/plugin-scaffolder-node`](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-node/CHANGELOG.md) +for more detailed information. + +There’s also a number of new deprecation for types which are currently exported from `plugin-scaffolder-node`. We’re going to be looking at re-working the Scaffolder architecture in the future, so we’re going to be removing these types in a future version to iterate on the new API surfaces. Stay tuned for more updates! + +### Actions Registry + +We’ve added two new `alpha` services which can be used to define distributed Actions across Backstage. Plugins can use the `ActionsRegistry` to define actions that are automatically installed with their associated plugin. + +On top of this Actions Registry is a new `mcp-actions` backend plugin, which will surface these actions as tools as an MCP server. This can be used to expose plugin Actions with your favourite AI tools, such as Cursor, Claude or ChatGPT. + +You can find out more information about the `ActionsRegistry` and MCP integration in [this RFC](https://github.com/backstage/backstage/issues/30218). + +We’re actively working on this area, therefore it’s currently highly experimental and could be subject to breaking changes in future releases. However we’d really appreciate some feedback if you want to try and create some Actions for your plugins and surface them in an MCP server! + +In the next release we’ll be looking to integrate these Actions with the Scaffolder allowing you to call these actions from a template. + +### TechDocs deep linking + +Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into other TechDocs in conjunction with `backstage.io/techdocs-entity`. + +Contributed by [@csuich2](https://github.com/csuich2) in [#29760](https://github.com/backstage/backstage/pull/29760) + +### Catalog modules Breaking Changes + +- `BitbucketCloudEntityProvider` now accepts a `CatalogService` instead of `CatalogApi` +- User and Group discovery for GitLab will default to ingesting all users in sub groups that belong to the specified root group in config. Disable by setting `restrictUsersToGroup: true` in app-config under your module settings. + +### New Module drop: `@backstage/plugin-events-backend-module-kafka` + +The module introduces the `KafkaConsumerClient` which creates a Kafka client used to establish consumer connections. It also provides the `KafkaConsumingEventPublisher`, a consumer that subscribes to configured Kafka topics and publishes received messages to the Backstage events service where Backstage plugins can access them. + +Contributed by [@Jonas-Beck](https://github.com/Jonas-Beck) in [#29315](https://github.com/backstage/backstage/pull/29315) + +### New lint rule added + +A new lint rule `@backstage/no-mixed-plugin-imports` was added to the defaults. This enforces rules that were always true but until now were implicit: that you should not import across frontend and backend package boundaries, isomorphic packages should not import non-isomorphic, etc. + +This rule is initially only set at a warning level, to give you some time to react. You may see warnings appear in your build output that were not there before - do pay attention to them, because they may expose some issues that you had not yet noticed. + +We intend to make this rule be at an error level in a future release. + +The rule has an option `excludedTargetPackages` that lets you opt out of enforcement in specific packages. You can put something like this in your root `.eslintrc.js`: + +```js +module.exports = { + root: true, + plugins: ['@spotify', 'react', 'testing-library', '@backstage'], + rules: { + '@backstage/no-mixed-plugin-imports': [ + 'error', // if you want to opt in to strict checks early + { + excludedTargetPackages: [ + '@internal/plugin-foo', + // ... +``` + +Contributed by [@drodil](https://github.com/drodil) in [#30227](https://github.com/backstage/backstage/pull/30227) + +### CLI: movement toward `rspack` + +The `BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE` flag has been removed entirely. If you were using this flag, we encourage you to switch to `EXPERIMENTAL_RSPACK` instead. In the near future, we hope to make `rspack` the default out of the box. + +While making these changes, the experimental `FORCE_REACT_DEVELOPMENT` flag was removed as well. + +### Backend rate limiting + +The backend system now has builtin support for rate limiting of incoming requests, both for your entire backends and on a per-plugin basis. It can use different backing stores for its state, and in-memory and redis is currently implemented out of the box. + +You can read more about this opt-in feature in [the documentation](https://backstage.io/docs/backend-system/core-services/http-router) for the HTTP router service. + +Contributed by [@drodil](https://github.com/drodil) in [#28708](https://github.com/backstage/backstage/pull/28708) + +### New Frontend System plugin info + +Plugins in the new frontend system can now expose rich, extensible metadata about themselves. This data is accessible at runtime inside your app. This is for example useful for adding contact and support information, and much more - and you can even overlay your own data on top of what is provided by open-source plugins. + +You can read more about this in the [frontend app](https://backstage.io/docs/frontend-system/architecture/app) and [plugin](https://backstage.io/docs/frontend-system/architecture/plugins) architecture documentation. + +### Notifications retention + +Notifications that are stored by the notifications backend plugin now have a default retention of one year before being deleted. This helps keep the storage size in check over time. You can override this using the `notifications.retention` duration setting in your app-config. + +Contributed by [@drodil](https://github.com/drodil) in [#30206](https://github.com/backstage/backstage/pull/30206) + +### Lots of i18n work + +A bunch of work was done to enable i18n (translations) in several plugins! This affected at least the following: + +- core components +- the org plugin +- the catalog import plugin +- the home plugin +- the search plugin +- the user settings plugin + +Contributed by [@mario-mui](https://github.com/mario-mui) + +### Canon steams ahead + +While it’s still early days, we still want to call out that the canon design system work steams ahead with various controls added and improvements made. Hang tight! + +## Security Fixes + +This release does not contain any security fixes. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.40.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.41.0-changelog.md b/docs/releases/v1.41.0-changelog.md new file mode 100644 index 0000000000..d8c5d866f2 --- /dev/null +++ b/docs/releases/v1.41.0-changelog.md @@ -0,0 +1,2258 @@ +# Release v1.41.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.41.0](https://backstage.github.io/upgrade-helper/?to=1.41.0) + +## @backstage/plugin-catalog-backend@3.0.0 + +### Major Changes + +- 5127ebe: **BREAKING**: The default `catalog.stitchingStrategy` has been switched to `{ mode: 'deferred' }`. + +- d675d96: **BREAKING**: The relations compatibility mode is no longer enabled by default, and the `disableRelationsCompatiblity` flag has been removed. To re-enable relations compatibility, the new `enableRelationsCompatibility` flag can be used instead. + +- 2339363: **BREAKING:** The experimental `catalog.useUrlReadersSearch` configuration flag (introduced in v1.36) has been removed. + + The `UrlReaderProcessor` now always uses the `search` method of `UrlReaders`. Built-in `UrlReaderService` implementations have been updated accordingly. + If you use custom `UrlReaderService` implementations, you need to adapt their `search` method to correctly handle both specific URLs and potential + search patterns (see changes on built-in readers [in the original PR](https://github.com/backstage/backstage/pull/28379/files#diff-68b0452f173ee54bdd40f7b5e047a9cb8bb59200425622c212c217b76dac1d1b)). + + Previous behavior was to call the `search` method only if the parsed Git URL's filename contained a wildcard and use `readUrl` otherwise. Each `UrlReaderService` must implement this logic in the `search` method instead. + + This allows each `UrlReaderService` implementation to check whether it's a search URL (that contains a wildcard pattern) or not using logic that is specific to each provider. + +- 687bfc8: **BREAKING**: The default `catalog.orphanStrategy` has been switched to `'delete'`. + +- 5de7a9d: **BREAKING**: The default `catalog.orphanProviderStrategy` has been switched to `'delete'`. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/integration@1.17.1 + - @backstage/backend-openapi-utils@0.5.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/backend-test-utils@1.7.0 + +### Minor Changes + +- ead925a: Add a standard `toString` on credentials objects + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/backend-defaults@0.11.1 + - @backstage/backend-app-api@1.2.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/canon@0.6.0 + +### Minor Changes + +- 1d64db6: **Breaking changes** We are updating our Link component to use React Aria under the hood. To match their API we are updating the `to` prop to `href` to match both internal and external routing. We are also updating our variant naming to include all our new font sizes. + +- 83fd7f4: **Breaking change** We are moving the Select component to use React Aria under the hood. We updated most props and events according to their underlying API. + +- cae63df: **Breaking changes** The Tabs components has been updates to use React Aria under the hood and to work with react-router-dom directly. + +- 4c6d891: **BREAKING CHANGES** + + We’re updating our Button component to provide better support for button links. + + - We’re introducing a new `ButtonLink` component, which replaces the previous render prop pattern. + - To maintain naming consistency across components, `IconButton` is being renamed to `ButtonIcon`. + - Additionally, the render prop will be removed from all button-related components. + + These changes aim to simplify usage and improve clarity in our component API. + +- 2e30459: We are moving our Tooltip component to use React Aria under the hood. In doing so, the structure of the component and its prop are changing to follow the new underlying structure. + +- 8fd6fcb: We are renaming @backstage/canon into @backstage/ui. As part of this move we are renaming all class names and CSS variables to follow the new name. "--canon" prefix is becoming "--bui" and all component class names starting with ".canon" will now start with ".bui" + +### Patch Changes + +- 140f652: We are consolidating all css files into a single styles.css in Canon. +- 76255b8: Add new Card component to Canon. +- 8154fb9: Add new SearchField component in Canon +- b0a6c8e: Add new Header component to Canon. +- 6910892: Add new `RadioGroup` + `Radio` component to Canon +- 9c17305: Fix scrolling width and height on ScrollArea component in Canon. +- 390ea20: Export Card and Skeleton components. +- be76576: Improve Button, ButtonIcon and ButtonLink styling in Canon. +- 17beb9b: Update return types for Heading & Text components for React 19. +- a8a8514: We are transforming how we structure our class names and data attributes definitions for all components. They are now all set in the same place. +- 667b951: Added placeholder prop to TextField component. +- eac4a4c: Add new tertiary variant to Button, ButtonIcon and ButtonLink in Canon. +- e71333a: adding export for ButtonLink so it's importable +- 8f2e82d: Add new Skeleton component in Canon +- Updated dependencies + - @backstage/ui@0.6.0 + +## @backstage/core-app-api@1.18.0 + +### Minor Changes + +- 5ddc0fe: if session exists and refresh fails, then create a new session if not instant popup + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/repo-tools@0.15.0 + +### Minor Changes + +- 1e7082e: Clear output directory before running `package-docs` and skip all internal packages. + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/ui@0.6.0 + +### Minor Changes + +- e92bb9b: Canon has been renamed to Backstage UI. This means that `@backstage/canon` has been deprecated and replaced by `@backstage/ui`. + +## @backstage/plugin-scaffolder@1.33.0 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +### Patch Changes + +- 289e4a1: Filter MultiEntityPicker options based on rendered option value +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-scaffolder-react@1.18.0 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-scaffolder-common@1.6.0 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-scaffolder-backend@2.1.0 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +### Patch Changes + +- 424610a: Scaffolder audit Log now includes taskId and createdBy +- dbde180: An internal refactor which adds additional types to experimental checkpoints +- fc70b43: Replaced deprecated uses of `@backstage/backend-common` with the equivalents in `@backstage/backend-defaults` and `@backstage/backend-plugin-api`. +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1 + - @backstage/plugin-scaffolder-common@1.6.0 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-bitbucket-cloud-common@0.3.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.11 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.11 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3 + +## @backstage/plugin-scaffolder-common@1.6.0 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + +## @backstage/plugin-scaffolder-node@0.10.0 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +### Patch Changes + +- dbde180: An internal refactor which adds additional types to experimental checkpoints +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + - @backstage/integration@1.17.1 + - @backstage/plugin-scaffolder-common@1.6.0 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-react@1.18.0 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +### Patch Changes + +- 94c11a5: Scroll to the top of the page when navigating between steps in template forms. +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/plugin-scaffolder-common@1.6.0 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/app-defaults@1.6.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-app-api@1.18.0 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/backend-app-api@1.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/backend-defaults@0.11.1 + +### Patch Changes + +- ead925a: Add a standard `toString` on credentials objects +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/config-loader@1.10.2 + - @backstage/config@1.3.3 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/integration@1.17.1 + - @backstage/backend-app-api@1.2.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/backend-dynamic-feature-service@0.7.2 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- 3d61c36: Fix wrong imports which lead to module initialization failures when enabling dynamic plugins. +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0 + - @backstage/config-loader@1.10.2 + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/backend-openapi-utils@0.5.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-app-node@0.1.35 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-events-backend@0.5.4 + - @backstage/plugin-events-node@0.4.13 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/backend-openapi-utils@0.5.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/backend-plugin-api@1.4.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/catalog-client@1.10.2 + +### Patch Changes + +- 6fb4143: allow arrays in the InMemoryCatalogClient to filter entities +- Updated dependencies + - @backstage/catalog-model@1.7.5 + +## @backstage/catalog-model@1.7.5 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup + +## @backstage/cli@0.33.1 + +### Patch Changes + +- 50f0ce6: Fixes a module not found error when running `backstage-cli info`. +- Updated dependencies + - @backstage/config-loader@1.10.2 + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/integration@1.17.1 + +## @backstage/config@1.3.3 + +### Patch Changes + +- ff23618: Loosen the requirements for a key to be considered valid config. +- 3507fcd: Just some more circular dep cleanup + +## @backstage/config-loader@1.10.2 + +### Patch Changes + +- ff23618: Loosen the requirements for a key to be considered valid config. +- Updated dependencies + - @backstage/config@1.3.3 + +## @backstage/core-compat-api@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/core-components@0.17.4 + +### Patch Changes + +- f6ffea6: Add optional message field for auth providers. This is intended to be a user friendly message that displays in the OAuth request dialog. A default message will be displayed if one is not provided. +- aa3b054: Added `signIn` and `signOut` analytic events to the `@backstage/core-components` of sign in and sign out. +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + +## @backstage/core-plugin-api@1.10.9 + +### Patch Changes + +- f6ffea6: Add optional message field for auth providers. This is intended to be a user friendly message that displays in the OAuth request dialog. A default message will be displayed if one is not provided. +- Updated dependencies + - @backstage/config@1.3.3 + +## @backstage/create-app@0.7.1 + +### Patch Changes + +- 952cefe: Bumped create-app version. + +- 2339363: **BREAKING:** The experimental `catalog.useUrlReadersSearch` configuration flag (introduced in v1.36) has been removed. + + The `UrlReaderProcessor` now always uses the `search` method of `UrlReaders`. Built-in `UrlReaderService` implementations have been updated accordingly. + If you use custom `UrlReaderService` implementations, you need to adapt their `search` method to correctly handle both specific URLs and potential + search patterns (see changes on built-in readers [in the original PR](https://github.com/backstage/backstage/pull/28379/files#diff-68b0452f173ee54bdd40f7b5e047a9cb8bb59200425622c212c217b76dac1d1b)). + + Previous behavior was to call the `search` method only if the parsed Git URL's filename contained a wildcard and use `readUrl` otherwise. Each `UrlReaderService` must implement this logic in the `search` method instead. + + This allows each `UrlReaderService` implementation to check whether it's a search URL (that contains a wildcard pattern) or not using logic that is specific to each provider. + +- c4a0830: Removed deprecated 'allowedHosts' field from GitHub Publish action input in default template files to fix validation errors with strict Zod validation. + +## @backstage/dev-utils@1.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-app-api@1.18.0 + - @backstage/integration-react@1.2.9 + - @backstage/app-defaults@1.6.4 + +## @backstage/frontend-app-api@0.11.4 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/core-app-api@1.18.0 + - @backstage/frontend-defaults@0.2.4 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/frontend-defaults@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/frontend-app-api@0.11.4 + - @backstage/plugin-app@0.1.11 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/frontend-dynamic-feature-loader@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/frontend-plugin-api@0.10.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/frontend-test-utils@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/frontend-app-api@0.11.4 + - @backstage/plugin-app@0.1.11 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/test-utils@1.7.10 + +## @backstage/integration@1.17.1 + +### Patch Changes + +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/config@1.3.3 + +## @backstage/integration-aws-node@0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + +## @backstage/integration-react@1.2.9 + +### Patch Changes + +- 998fd15: Separated gitlab `write_repository` and `api` scope to pass checks in `RefreshingAuthSessionManager` +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration@1.17.1 + +## @techdocs/cli@1.9.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-techdocs-node@1.13.5 + +## @backstage/test-utils@1.7.10 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-app-api@1.18.0 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/theme@0.6.7 + +### Patch Changes + +- 373486e: Add a different background colour to focused `MenuItem`s to fix a bug in MUI 4 (which is fixed in MUI 5) +- b68d269: Update uncomfortably bright color in recently visited and top visited home page cards + +## @backstage/plugin-api-docs@0.12.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-catalog@1.31.1 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-app@0.1.11 + +### Patch Changes + +- 09f5e36: Remove trailing slashes in the `AppRoutes` extension to ensure any nested routing behaves correctly. +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/integration-react@1.2.9 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-app-backend@0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2 + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-app-node@0.1.35 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-app-node@0.1.35 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-app-visualizer@0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-auth-backend@0.25.2 + +### Patch Changes + +- e88cb70: Small internal refactor to move out the `userInfo` database from the `tokenIssuer`. Also removes `exp` from being stored in `UserInfo` and it's now replaced with `created_at` and `updated_at` in the database instead. +- 207778c: Internal refactor of OIDC endpoints and `UserInfoDatabase` +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-auth-backend@0.25.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.5 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-auth-node@0.6.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-auth-react@0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-bitbucket-cloud-common@0.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1 + +## @backstage/plugin-catalog@1.31.1 + +### Patch Changes + +- 6991dab: Turn on `pagination` by default in new frontend system, and also make configurable +- 3ab9b96: Updated card extensions for the new frontend system to use the new entity predicates, and to not show the about card on User and Group pages. +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-scaffolder-common@1.6.0 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.2 + - @backstage/plugin-techdocs-react@1.3.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.13 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-kubernetes-common@0.9.6 + +## @backstage/plugin-catalog-backend-module-azure@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-openapi-utils@0.5.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.10 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-kubernetes-common@0.9.6 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-catalog-backend-module-github@0.10.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0 + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-backend-module-github@0.10.1 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-backend-module-gitlab@0.7.1 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.2 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- e2dd095: Fixed bug in `IncrementalIngestionEngine` by adding `burstLength` check when a burst completes +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0 + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.7 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-catalog-backend-module-logs@0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-catalog-backend-module-msgraph@0.7.2 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.12 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-scaffolder-common@1.6.0 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.9 + +## @backstage/plugin-catalog-common@1.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-catalog-graph@0.4.21 + +### Patch Changes + +- fe1a2f4: Catalog graph plugin support i18n +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-catalog-import@0.13.3 + +### Patch Changes + +- 406b8b8: Fixed bug with error message since ResponseError is now thrown from CatalogClient +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-node@1.17.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-react@1.19.1 + +### Patch Changes + +- a07feb7: Fixed a but in the new alpha entity predicates where the `$in` operator mistakenly case sensitive. +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/frontend-test-utils@0.3.4 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.19 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-catalog-unprocessed-entities-common@0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-config-schema@0.1.70 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-devtools@0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-devtools-common@0.1.17 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-devtools-backend@0.5.7 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2 + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/backend-defaults@0.11.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-devtools-common@0.1.17 + +## @backstage/plugin-devtools-common@0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-events-backend@0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-openapi-utils@0.5.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.13 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-module-azure@0.2.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-module-gerrit@0.2.22 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-module-github@0.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-module-gitlab@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-module-kafka@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-backend-test-utils@0.1.46 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-events-node@0.4.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-gateway-backend@1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-home@0.8.10 + +### Patch Changes + +- d52d67f: Added a New Frontend System App Root Element for the `` component +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-app-api@1.18.0 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-home-react@0.1.28 + +## @backstage/plugin-home-react@0.1.28 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-kubernetes@0.12.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-kubernetes-common@0.9.6 + - @backstage/plugin-kubernetes-react@0.5.9 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-kubernetes-backend@0.19.8 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-kubernetes-node@0.3.2 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-kubernetes-common@0.9.6 + +## @backstage/plugin-kubernetes-cluster@0.0.27 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-kubernetes-common@0.9.6 + - @backstage/plugin-kubernetes-react@0.5.9 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-kubernetes-common@0.9.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + +## @backstage/plugin-kubernetes-node@0.3.2 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-kubernetes-common@0.9.6 + +## @backstage/plugin-kubernetes-react@0.5.9 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-kubernetes-common@0.9.6 + +## @backstage/plugin-mcp-actions-backend@0.1.1 + +### Patch Changes + +- 6bc0799: Fixed the example in the README for generating a static token by adding a subject field +- Updated dependencies + - @backstage/backend-defaults@0.11.1 + - @backstage/catalog-client@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-notifications@0.5.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-notifications-backend@0.5.8 + +### Patch Changes + +- 4401dfb: Allow defining default notification settings via configuration +- 9a5a73f: Fix `addTopic` migration when `user_settings` present +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-events-node@0.4.13 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-notifications-node@0.2.17 + - @backstage/plugin-signals-node@0.1.22 + +## @backstage/plugin-notifications-backend-module-email@0.3.11 + +### Patch Changes + +- f92c9fc: Add optional config for `ses` mail options with `sourceArn`, `fromArn`, `configurationSetName` +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-notifications-node@0.2.17 + +## @backstage/plugin-notifications-backend-module-slack@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-notifications-node@0.2.17 + +## @backstage/plugin-notifications-common@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + +## @backstage/plugin-notifications-node@0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-signals-node@0.1.22 + +## @backstage/plugin-org@0.6.41 + +### Patch Changes + +- 3ab9b96: Updated card extensions for the new frontend system to use the new entity predicates, and switch the card type to `info` for the user and group profile cards. +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-org-react@0.1.40 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-permission-backend@0.7.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-permission-common@0.9.1 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3 + +## @backstage/plugin-permission-node@0.10.2 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + +## @backstage/plugin-permission-react@0.4.36 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-proxy-backend@0.6.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-proxy-node@0.1.6 + +## @backstage/plugin-proxy-node@0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.11 + +### Patch Changes + +- 642282d: Added support for new link format for on-prem Confluence +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.13 + +### Patch Changes + +- cf9ba6f: Fixing the typescript issue with using `z.unknown()` +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.1 + +### Patch Changes + +- f36bcf9: Added support for file deletion to `publish:github:pull-request` action. + + Example usage: + + ```diff + - action: publish:github:pull-request + id: clean-up-pr + input: + description: This is the description + + filesToDelete: + + - outdated/changelog.md + + - sample-file.txt + owner: owner + repo: repo + title: Title Goes Here + + ``` + +- 38db3eb: Fix typo in `InputError` + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-node@1.17.2 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-notifications-node@0.2.17 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.11 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.11 + +### Patch Changes + +- 648b3d7: Add optional input to sentry:project:create to set the new Sentry project's platform +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.3.1 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.1 + +### Patch Changes + +- dbde180: An internal refactor which adds additional types to experimental checkpoints +- Updated dependencies + - @backstage/backend-test-utils@1.7.0 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/backend-plugin-api@1.4.1 + +## @backstage/plugin-search@1.4.28 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.2 + +## @backstage/plugin-search-backend@2.0.4 + +### Patch Changes + +- 69fb975: Error messages should not contain backend SQL query strings in the API response, this change will ensure that messages are logged and empty response is returned to the user +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/backend-defaults@0.11.1 + - @backstage/backend-openapi-utils@0.5.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-catalog@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.4 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-explore@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-pg@0.5.46 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.11 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-techdocs@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/plugin-techdocs-node@1.13.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-node@1.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-common@1.2.19 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-search-react@1.9.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-signals@0.0.21 + +### Patch Changes + +- d52d67f: Added a New Frontend System App Root Element for the `` component +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-signals-backend@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-events-node@0.4.13 + - @backstage/plugin-signals-node@0.1.22 + +## @backstage/plugin-signals-node@0.1.22 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-events-node@0.4.13 + +## @backstage/plugin-signals-react@0.0.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-techdocs@1.13.2 + +### Patch Changes + +- 1debf7f: Fixed an issue causing TechDocs to not properly handle initial redirect. +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration@1.17.1 + - @backstage/theme@0.6.7 + - @backstage/integration-react@1.2.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-auth-react@0.1.17 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.2 + - @backstage/plugin-techdocs-react@1.3.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.51 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2 + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/plugin-catalog@1.31.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/core-app-api@1.18.0 + - @backstage/integration-react@1.2.9 + - @backstage/test-utils@1.7.10 + - @backstage/plugin-search-react@1.9.2 + - @backstage/plugin-techdocs-react@1.3.1 + +## @backstage/plugin-techdocs-backend@2.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/catalog-client@1.10.2 + - @backstage/integration@1.17.1 + - @backstage/plugin-techdocs-node@1.13.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-search-backend-module-techdocs@0.4.4 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-techdocs-react@1.3.1 + +## @backstage/plugin-techdocs-node@1.13.5 + +### Patch Changes + +- 029526c: Updated the error message thrown by parseReferenceAnnotation to reflect the annotation value passed as an argument rather than in correctly assuming location. +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/integration@1.17.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-techdocs-react@1.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-user-settings@0.8.24 + +### Patch Changes + +- aa3b054: Added `signIn` and `signOut` analytic events to the `@backstage/core-components` of sign in and sign out. +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-app-api@1.18.0 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-user-settings-backend@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-signals-node@0.1.22 + +## example-app@0.2.111 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.8.10 + - @backstage/plugin-techdocs@1.13.2 + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/plugin-catalog-graph@0.4.21 + - @backstage/config@1.3.3 + - @backstage/frontend-app-api@0.11.4 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-scaffolder@1.33.0 + - @backstage/ui@0.6.0 + - @backstage/cli@0.33.1 + - @backstage/plugin-scaffolder-react@1.18.0 + - @backstage/plugin-catalog@1.31.1 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-org@0.6.41 + - @backstage/theme@0.6.7 + - @backstage/plugin-catalog-import@0.13.3 + - @backstage/core-app-api@1.18.0 + - @backstage/plugin-user-settings@0.8.24 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-signals@0.0.21 + - @backstage/app-defaults@1.6.4 + - @backstage/plugin-api-docs@0.12.9 + - @backstage/plugin-auth-react@0.1.17 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19 + - @backstage/plugin-devtools@0.1.29 + - @backstage/plugin-kubernetes@0.12.9 + - @backstage/plugin-kubernetes-cluster@0.0.27 + - @backstage/plugin-notifications@0.5.7 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search@1.4.28 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26 + - @backstage/plugin-techdocs-react@1.3.1 + +## example-app-next@0.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.8.10 + - @backstage/plugin-techdocs@1.13.2 + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/plugin-catalog-graph@0.4.21 + - @backstage/config@1.3.3 + - @backstage/frontend-app-api@0.11.4 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-scaffolder@1.33.0 + - @backstage/ui@0.6.0 + - @backstage/cli@0.33.1 + - @backstage/plugin-scaffolder-react@1.18.0 + - @backstage/plugin-catalog@1.31.1 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-org@0.6.41 + - @backstage/theme@0.6.7 + - @backstage/plugin-catalog-import@0.13.3 + - @backstage/core-app-api@1.18.0 + - @backstage/plugin-user-settings@0.8.24 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-app@0.1.11 + - @backstage/plugin-signals@0.0.21 + - @backstage/app-defaults@1.6.4 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-defaults@0.2.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-api-docs@0.12.9 + - @backstage/plugin-app-visualizer@0.1.21 + - @backstage/plugin-auth-react@0.1.17 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19 + - @backstage/plugin-kubernetes@0.12.9 + - @backstage/plugin-kubernetes-cluster@0.0.27 + - @backstage/plugin-notifications@0.5.7 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search@1.4.28 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26 + - @backstage/plugin-techdocs-react@1.3.1 + +## app-next-example-plugin@0.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/frontend-plugin-api@0.10.4 + +## example-backend@0.0.40 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0 + - @backstage/plugin-scaffolder-backend@2.1.0 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-notifications-backend@0.5.8 + - @backstage/plugin-mcp-actions-backend@0.1.1 + - @backstage/plugin-auth-backend@0.25.2 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1 + - @backstage/plugin-search-backend@2.0.4 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-app-backend@0.5.4 + - @backstage/plugin-auth-backend-module-github-provider@0.3.5 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.10 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.4 + - @backstage/plugin-catalog-backend-module-openapi@0.2.12 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.2 + - @backstage/plugin-devtools-backend@0.5.7 + - @backstage/plugin-events-backend@0.5.4 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.2 + - @backstage/plugin-kubernetes-backend@0.19.8 + - @backstage/plugin-permission-backend@0.7.2 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.10 + - @backstage/plugin-proxy-backend@0.6.4 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12 + - @backstage/plugin-search-backend-module-catalog@0.3.6 + - @backstage/plugin-search-backend-module-explore@0.3.4 + - @backstage/plugin-search-backend-module-techdocs@0.4.4 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-signals-backend@0.3.6 + - @backstage/plugin-techdocs-backend@2.0.4 + +## e2e-test@0.2.30 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.1 + +## @internal/frontend@0.0.11 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.4 + +## @internal/scaffolder@0.0.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.18.0 + - @backstage/frontend-plugin-api@0.10.4 + +## techdocs-cli-embedded-app@0.2.110 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2 + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/cli@0.33.1 + - @backstage/plugin-catalog@1.31.1 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-app-api@1.18.0 + - @backstage/integration-react@1.2.9 + - @backstage/app-defaults@1.6.4 + - @backstage/test-utils@1.7.10 + - @backstage/plugin-techdocs-react@1.3.1 + +## yarn-plugin-backstage@0.0.7 + +### Patch Changes + +- d6084b8: Fixed a bug that would prevent the yarn plugin from installing new dependencies with the `backstage:^` protocol. + +## @internal/plugin-todo-list@1.0.41 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + +## @internal/plugin-todo-list-backend@1.0.41 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + +## @internal/plugin-todo-list-common@1.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1 diff --git a/docs/releases/v1.41.0-next.0-changelog.md b/docs/releases/v1.41.0-next.0-changelog.md new file mode 100644 index 0000000000..9988f3005b --- /dev/null +++ b/docs/releases/v1.41.0-next.0-changelog.md @@ -0,0 +1,1497 @@ +# Release v1.41.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.41.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.41.0-next.0) + +## @backstage/plugin-catalog-backend@3.0.0-next.0 + +### Major Changes + +- 2339363: **BREAKING:** The experimental `catalog.useUrlReadersSearch` configuration flag (introduced in v1.36) has been removed. + + The `UrlReaderProcessor` now always uses the `search` method of `UrlReaders`. Built-in `UrlReaderService` implementations have been updated accordingly. + If you use custom `UrlReaderService` implementations, you need to adapt their `search` method to correctly handle both specific URLs and potential + search patterns (see changes on built-in readers [in the original PR](https://github.com/backstage/backstage/pull/28379/files#diff-68b0452f173ee54bdd40f7b5e047a9cb8bb59200425622c212c217b76dac1d1b)). + + Previous behavior was to call the `search` method only if the parsed Git URL's filename contained a wildcard and use `readUrl` otherwise. Each `UrlReaderService` must implement this logic in the `search` method instead. + + This allows each `UrlReaderService` implementation to check whether it's a search URL (that contains a wildcard pattern) or not using logic that is specific to each provider. + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/backend-test-utils@1.7.0-next.0 + +### Minor Changes + +- ead925a: Add a standard `toString` on credentials objects + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/backend-app-api@1.2.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/canon@0.6.0-next.0 + +### Minor Changes + +- 4c6d891: **BREAKING CHANGES** + + We’re updating our Button component to provide better support for button links. + + - We’re introducing a new `ButtonLink` component, which replaces the previous render prop pattern. + - To maintain naming consistency across components, `IconButton` is being renamed to `ButtonIcon`. + - Additionally, the render prop will be removed from all button-related components. + + These changes aim to simplify usage and improve clarity in our component API. + +### Patch Changes + +- 140f652: We are consolidating all css files into a single styles.css in Canon. +- 8154fb9: Add new SearchField component in Canon +- 6910892: Add new `RadioGroup` + `Radio` component to Canon +- a8a8514: We are transforming how we structure our class names and data attributes definitions for all components. They are now all set in the same place. +- 667b951: Added placeholder prop to TextField component. +- e71333a: adding export for ButtonLink so it's importable + +## @backstage/repo-tools@0.15.0-next.0 + +### Minor Changes + +- 1e7082e: Clear output directory before running `package-docs` and skip all internal packages. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @backstage/app-defaults@1.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/backend-defaults@0.11.1-next.0 + +### Patch Changes + +- ead925a: Add a standard `toString` on credentials objects +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-app-api@1.2.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## @backstage/backend-dynamic-feature-service@0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/cli@0.33.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.11 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/core-compat-api@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-components@0.17.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.7.1-next.0 + +### Patch Changes + +- 2339363: **BREAKING:** The experimental `catalog.useUrlReadersSearch` configuration flag (introduced in v1.36) has been removed. + + The `UrlReaderProcessor` now always uses the `search` method of `UrlReaders`. Built-in `UrlReaderService` implementations have been updated accordingly. + If you use custom `UrlReaderService` implementations, you need to adapt their `search` method to correctly handle both specific URLs and potential + search patterns (see changes on built-in readers [in the original PR](https://github.com/backstage/backstage/pull/28379/files#diff-68b0452f173ee54bdd40f7b5e047a9cb8bb59200425622c212c217b76dac1d1b)). + + Previous behavior was to call the `search` method only if the parsed Git URL's filename contained a wildcard and use `readUrl` otherwise. Each `UrlReaderService` must implement this logic in the `search` method instead. + + This allows each `UrlReaderService` implementation to check whether it's a search URL (that contains a wildcard pattern) or not using logic that is specific to each provider. + +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + +## @backstage/frontend-app-api@0.11.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-defaults@0.2.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.11-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/frontend-dynamic-feature-loader@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/frontend-plugin-api@0.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-test-utils@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.11-next.0 + - @backstage/test-utils@1.7.10-next.0 + - @backstage/config@1.3.2 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/integration@1.17.1-next.0 + +### Patch Changes + +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/integration-react@1.2.9-next.0 + +### Patch Changes + +- 998fd15: Separated gitlab `write_repository` and `api` scope to pass checks in `RefreshingAuthSessionManager` +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.8 + +## @techdocs/cli@1.9.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-techdocs-node@1.13.5-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## @backstage/test-utils@1.7.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/theme@0.6.7-next.0 + +### Patch Changes + +- b68d269: Update uncomfortably bright color in recently visited and top visited home page cards + +## @backstage/plugin-api-docs@0.12.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-app@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-app-visualizer@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/plugin-auth-react@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + +## @backstage/plugin-bitbucket-cloud-common@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + +## @backstage/plugin-catalog@1.31.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.2.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-catalog-backend-module-azure@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-bitbucket-cloud-common@0.3.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-github@0.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.10.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/config@1.3.2 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-catalog-backend-module-logs@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/catalog-model@1.7.4 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-graph@0.4.21-next.0 + +### Patch Changes + +- fe1a2f4: Catalog graph plugin support i18n +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-import@0.13.2-next.0 + +### Patch Changes + +- 406b8b8: Fixed bug with error message since ResponseError is now thrown from CatalogClient +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-react@1.19.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.2.9-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/frontend-test-utils@0.3.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/plugin-config-schema@0.1.70-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-devtools@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-devtools-backend@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config-loader@1.10.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-events-backend-module-github@0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + +## @backstage/plugin-home@0.8.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-home-react@0.1.28-next.0 + +## @backstage/plugin-home-react@0.1.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/plugin-kubernetes@0.12.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-kubernetes-react@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-kubernetes-react@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-kubernetes-react@0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-mcp-actions-backend@0.1.1-next.0 + +### Patch Changes + +- 6bc0799: Fixed the example in the README for generating a static token by adding a subject field +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/catalog-client@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-signals-react@0.0.14 + +## @backstage/plugin-notifications-backend@0.5.8-next.0 + +### Patch Changes + +- 9a5a73f: Fix `addTopic` migration when `user_settings` present +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-signals-node@0.1.21 + +## @backstage/plugin-org@0.6.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-org-react@0.1.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.8 + +## @backstage/plugin-scaffolder@1.32.1-next.0 + +### Patch Changes + +- 289e4a1: Filter MultiEntityPicker options based on rendered option value +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-backend@2.0.1-next.0 + +### Patch Changes + +- dbde180: An internal refactor which adds additional types to experimental checkpoints +- fc70b43: Replaced deprecated uses of `@backstage/backend-common` with the equivalents in `@backstage/backend-defaults` and `@backstage/backend-plugin-api`. +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.11-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.1-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.13-next.0 + +### Patch Changes + +- cf9ba6f: Fixing the typescript issue with using `z.unknown()` +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.0 + +### Patch Changes + +- f36bcf9: Added support for file deletion to `publish:github:pull-request` action. + + Example usage: + + ```diff + - action: publish:github:pull-request + id: clean-up-pr + input: + description: This is the description + + filesToDelete: + + - outdated/changelog.md + + - sample-file.txt + owner: owner + repo: repo + title: Title Goes Here + + ``` + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/plugin-notifications-common@0.0.9 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.3.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-node@0.9.1-next.0 + +### Patch Changes + +- dbde180: An internal refactor which adds additional types to experimental checkpoints +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.1-next.0 + +### Patch Changes + +- dbde180: An internal refactor which adds additional types to experimental checkpoints +- Updated dependencies + - @backstage/backend-test-utils@1.7.0-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-react@1.17.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-search@1.4.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend@2.0.4-next.0 + +### Patch Changes + +- 69fb975: Error messages should not contain backend SQL query strings in the API response, this change will ensure that messages are logged and empty response is returned to the user +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-techdocs@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-techdocs-node@1.13.5-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-react@1.9.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-signals@0.0.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + +## @backstage/plugin-techdocs@1.13.2-next.0 + +### Patch Changes + +- 1debf7f: Fixed an issue causing TechDocs to not properly handle initial redirect. +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.51-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/test-utils@1.7.10-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + +## @backstage/plugin-techdocs-backend@2.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.4-next.0 + - @backstage/plugin-techdocs-node@1.13.5-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/plugin-techdocs-node@1.13.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-react@1.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-user-settings@0.8.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-node@0.1.21 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.111-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/plugin-catalog-graph@0.4.21-next.0 + - @backstage/canon@0.6.0-next.0 + - @backstage/plugin-scaffolder@1.32.1-next.0 + - @backstage/plugin-catalog-import@0.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-home@0.8.10-next.0 + - @backstage/plugin-notifications@0.5.7-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-signals@0.0.21-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/plugin-user-settings@0.8.24-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/plugin-api-docs@0.12.9-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + - @backstage/plugin-devtools@0.1.29-next.0 + - @backstage/plugin-kubernetes@0.12.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + - @backstage/plugin-org@0.6.41-next.0 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search@1.4.28-next.0 + - @backstage/plugin-search-common@1.2.18 + +## example-app-next@0.0.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/plugin-catalog-graph@0.4.21-next.0 + - @backstage/canon@0.6.0-next.0 + - @backstage/plugin-scaffolder@1.32.1-next.0 + - @backstage/plugin-catalog-import@0.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + - @backstage/plugin-app@0.1.11-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-home@0.8.10-next.0 + - @backstage/plugin-notifications@0.5.7-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-signals@0.0.21-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/plugin-user-settings@0.8.24-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/frontend-defaults@0.2.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-api-docs@0.12.9-next.0 + - @backstage/plugin-app-visualizer@0.1.21-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + - @backstage/plugin-kubernetes@0.12.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + - @backstage/plugin-org@0.6.41-next.0 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search@1.4.28-next.0 + - @backstage/plugin-search-common@1.2.18 + +## app-next-example-plugin@0.0.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## example-backend@0.0.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-backend@2.0.1-next.0 + - @backstage/plugin-notifications-backend@0.5.8-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.0 + - @backstage/plugin-search-backend@2.0.4-next.0 + - @backstage/plugin-app-backend@0.5.3 + - @backstage/plugin-auth-backend@0.25.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-devtools-backend@0.5.7-next.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + - @backstage/plugin-kubernetes-backend@0.19.7 + - @backstage/plugin-permission-backend@0.7.1 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-proxy-backend@0.6.3 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-signals-backend@0.3.5 + - @backstage/plugin-techdocs-backend@2.0.4-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + - @backstage/plugin-catalog-backend-module-openapi@0.2.12-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + - @backstage/plugin-search-backend-module-catalog@0.3.5 + - @backstage/plugin-search-backend-module-explore@0.3.3 + - @backstage/plugin-search-backend-module-techdocs@0.4.4-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + - @backstage/plugin-permission-common@0.9.0 + +## e2e-test@0.2.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.1-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/frontend@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @internal/scaffolder@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## techdocs-cli-embedded-app@0.2.110-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/test-utils@1.7.10-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + +## @internal/plugin-todo-list@1.0.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 diff --git a/docs/releases/v1.41.0-next.1-changelog.md b/docs/releases/v1.41.0-next.1-changelog.md new file mode 100644 index 0000000000..7efa9025d7 --- /dev/null +++ b/docs/releases/v1.41.0-next.1-changelog.md @@ -0,0 +1,2000 @@ +# Release v1.41.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.41.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.41.0-next.1) + +## @backstage/app-defaults@1.6.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-permission-react@0.4.36-next.0 + +## @backstage/backend-app-api@1.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + +## @backstage/backend-defaults@0.11.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/integration-aws-node@0.1.17-next.0 + - @backstage/backend-app-api@1.2.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/backend-dynamic-feature-service@0.7.2-next.1 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- 3d61c36: Fix wrong imports which lead to module initialization failures when enabling dynamic plugins. +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/plugin-app-node@0.1.35-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-catalog-backend@3.0.0-next.1 + - @backstage/plugin-events-backend@0.5.4-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/backend-openapi-utils@0.5.5-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/backend-openapi-utils@0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + +## @backstage/backend-plugin-api@1.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/backend-test-utils@1.7.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/backend-app-api@1.2.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/catalog-client@1.10.2-next.0 + +### Patch Changes + +- 6fb4143: allow arrays in the InMemoryCatalogClient to filter entities +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + +## @backstage/catalog-model@1.7.5-next.0 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup + +## @backstage/cli@0.33.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/integration@1.17.1-next.1 + +## @backstage/config@1.3.3-next.0 + +### Patch Changes + +- ff23618: Loosen the requirements for a key to be considered valid config. +- 3507fcd: Just some more circular dep cleanup + +## @backstage/config-loader@1.10.2-next.0 + +### Patch Changes + +- ff23618: Loosen the requirements for a key to be considered valid config. +- Updated dependencies + - @backstage/config@1.3.3-next.0 + +## @backstage/core-app-api@1.17.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/core-compat-api@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/core-components@0.17.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/core-plugin-api@1.10.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + +## @backstage/create-app@0.7.1-next.1 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/dev-utils@1.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/app-defaults@1.6.4-next.1 + +## @backstage/frontend-app-api@0.11.4-next.1 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-defaults@0.2.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/frontend-defaults@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/frontend-app-api@0.11.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-app@0.1.11-next.1 + +## @backstage/frontend-dynamic-feature-loader@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/frontend-plugin-api@0.10.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/frontend-test-utils@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/frontend-app-api@0.11.4-next.1 + - @backstage/test-utils@1.7.10-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-app@0.1.11-next.1 + +## @backstage/integration@1.17.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + +## @backstage/integration-aws-node@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + +## @backstage/integration-react@1.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/repo-tools@0.15.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + +## @techdocs/cli@1.9.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/plugin-techdocs-node@1.13.5-next.1 + +## @backstage/test-utils@1.7.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-permission-react@0.4.36-next.0 + +## @backstage/plugin-api-docs@0.12.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-catalog@1.31.1-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-app@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-app-backend@0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-app-node@0.1.35-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-app-node@0.1.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + +## @backstage/plugin-app-visualizer@0.1.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-auth-backend@0.25.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-backend@0.25.2-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-backend@0.25.2-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-auth-node@0.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + +## @backstage/plugin-auth-react@0.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/plugin-catalog@1.31.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-scaffolder-common@1.5.12-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-catalog-backend@3.0.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/backend-openapi-utils@0.5.5-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.4.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/integration@1.17.1-next.1 + - @backstage/integration-aws-node@0.1.17-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-kubernetes-common@0.9.6-next.0 + +## @backstage/plugin-catalog-backend-module-azure@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/backend-openapi-utils@0.5.5-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-kubernetes-common@0.9.6-next.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.10.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-backend@3.0.0-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-backend-module-github@0.10.1-next.1 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.7.1-next.1 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.2-next.1 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- e2dd095: Fixed bug in `IncrementalIngestionEngine` by adding `burstLength` check when a burst completes +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-backend@3.0.0-next.1 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.7-next.0 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-catalog-backend-module-logs@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-backend@3.0.0-next.1 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.7.2-next.0 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.12-next.0 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-scaffolder-common@1.5.12-next.0 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.9-next.0 + +## @backstage/plugin-catalog-common@1.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + +## @backstage/plugin-catalog-graph@0.4.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-catalog-import@0.13.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-catalog-node@1.17.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + +## @backstage/plugin-catalog-react@1.19.1-next.1 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-test-utils@0.3.4-next.1 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-catalog-unprocessed-entities-common@0.0.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + +## @backstage/plugin-config-schema@0.1.70-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/plugin-devtools@0.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-devtools-common@0.1.17-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-devtools-backend@0.5.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-devtools-common@0.1.17-next.0 + +## @backstage/plugin-devtools-common@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + +## @backstage/plugin-events-backend@0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/backend-openapi-utils@0.5.5-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-module-azure@0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-module-github@0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-module-kafka@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.46-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-events-node@0.4.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + +## @backstage/plugin-gateway-backend@1.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + +## @backstage/plugin-home@0.8.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-home-react@0.1.28-next.1 + +## @backstage/plugin-home-react@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-kubernetes@0.12.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-kubernetes-common@0.9.6-next.0 + - @backstage/plugin-kubernetes-react@0.5.9-next.1 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-kubernetes-backend@0.19.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-kubernetes-node@0.3.2-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration-aws-node@0.1.17-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-kubernetes-common@0.9.6-next.0 + +## @backstage/plugin-kubernetes-cluster@0.0.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-kubernetes-common@0.9.6-next.0 + - @backstage/plugin-kubernetes-react@0.5.9-next.1 + +## @backstage/plugin-kubernetes-common@0.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/catalog-model@1.7.5-next.0 + +## @backstage/plugin-kubernetes-node@0.3.2-next.0 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-kubernetes-common@0.9.6-next.0 + +## @backstage/plugin-kubernetes-react@0.5.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-kubernetes-common@0.9.6-next.0 + +## @backstage/plugin-mcp-actions-backend@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-notifications@0.5.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-notifications-common@0.0.10-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-signals-react@0.0.15-next.0 + +## @backstage/plugin-notifications-backend@0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-notifications-common@0.0.10-next.0 + - @backstage/plugin-signals-node@0.1.22-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-notifications-node@0.2.17-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-notifications-backend-module-email@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration-aws-node@0.1.17-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-notifications-common@0.0.10-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-notifications-node@0.2.17-next.0 + +## @backstage/plugin-notifications-backend-module-slack@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-notifications-common@0.0.10-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-notifications-node@0.2.17-next.0 + +## @backstage/plugin-notifications-common@0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + +## @backstage/plugin-notifications-node@0.2.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-notifications-common@0.0.10-next.0 + - @backstage/plugin-signals-node@0.1.22-next.0 + +## @backstage/plugin-org@0.6.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-org-react@0.1.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/plugin-permission-backend@0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-permission-common@0.9.1-next.0 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3-next.0 + +## @backstage/plugin-permission-node@0.10.2-next.0 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## @backstage/plugin-permission-react@0.4.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/plugin-proxy-backend@0.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-proxy-node@0.1.6-next.0 + +## @backstage/plugin-proxy-node@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + +## @backstage/plugin-scaffolder@1.32.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-scaffolder-common@1.5.12-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.1 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-scaffolder-backend@2.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.11-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.11-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3-next.1 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-scaffolder-common@1.5.12-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.1 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-notifications-common@0.0.10-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + - @backstage/plugin-notifications-node@0.2.17-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.3.1-next.1 + +## @backstage/plugin-scaffolder-common@1.5.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/catalog-model@1.7.5-next.0 + +## @backstage/plugin-scaffolder-node@0.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-scaffolder-common@1.5.12-next.0 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/backend-test-utils@1.7.0-next.1 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + +## @backstage/plugin-scaffolder-react@1.17.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-scaffolder-common@1.5.12-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-search@1.4.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-search-backend@2.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/backend-openapi-utils@0.5.5-next.0 + +## @backstage/plugin-search-backend-module-catalog@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.4-next.0 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration-aws-node@0.1.17-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + +## @backstage/plugin-search-backend-module-explore@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + +## @backstage/plugin-search-backend-module-pg@0.5.46-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + +## @backstage/plugin-search-backend-module-techdocs@0.4.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-techdocs-node@1.13.5-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + +## @backstage/plugin-search-backend-node@1.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + +## @backstage/plugin-search-common@1.2.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + +## @backstage/plugin-search-react@1.9.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-signals@0.0.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-signals-react@0.0.15-next.0 + +## @backstage/plugin-signals-backend@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-signals-node@0.1.22-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-signals-node@0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## @backstage/plugin-signals-react@0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/plugin-techdocs@1.13.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-auth-react@0.1.17-next.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.51-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/test-utils@1.7.10-next.1 + - @backstage/plugin-techdocs@1.13.2-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-catalog@1.31.1-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + +## @backstage/plugin-techdocs-backend@2.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/integration@1.17.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.4-next.1 + - @backstage/plugin-techdocs-node@1.13.5-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-techdocs-node@1.13.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/integration-aws-node@0.1.17-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + +## @backstage/plugin-techdocs-react@1.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## @backstage/plugin-user-settings@0.8.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-signals-react@0.0.15-next.0 + +## @backstage/plugin-user-settings-backend@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-signals-node@0.1.22-next.0 + +## example-app@0.2.111-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/frontend-app-api@0.11.4-next.1 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/cli@0.33.1-next.1 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-catalog-import@0.13.3-next.1 + - @backstage/plugin-home@0.8.10-next.1 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-techdocs@1.13.2-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-catalog@1.31.1-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-org@0.6.41-next.1 + - @backstage/plugin-scaffolder@1.32.1-next.1 + - @backstage/plugin-scaffolder-react@1.17.1-next.1 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/plugin-api-docs@0.12.9-next.1 + - @backstage/plugin-catalog-graph@0.4.21-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.1 + - @backstage/plugin-kubernetes@0.12.9-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.1 + - @backstage/plugin-user-settings@0.8.24-next.1 + - @backstage/app-defaults@1.6.4-next.1 + - @backstage/plugin-notifications@0.5.7-next.1 + - @backstage/plugin-search@1.4.28-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/plugin-signals@0.0.21-next.1 + - @backstage/plugin-auth-react@0.1.17-next.1 + - @backstage/plugin-devtools@0.1.29-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.1 + +## example-app-next@0.0.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/frontend-app-api@0.11.4-next.1 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/cli@0.33.1-next.1 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-defaults@0.2.4-next.1 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-catalog-import@0.13.3-next.1 + - @backstage/plugin-home@0.8.10-next.1 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-techdocs@1.13.2-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-catalog@1.31.1-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-org@0.6.41-next.1 + - @backstage/plugin-scaffolder@1.32.1-next.1 + - @backstage/plugin-scaffolder-react@1.17.1-next.1 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/plugin-api-docs@0.12.9-next.1 + - @backstage/plugin-catalog-graph@0.4.21-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.1 + - @backstage/plugin-kubernetes@0.12.9-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.1 + - @backstage/plugin-user-settings@0.8.24-next.1 + - @backstage/app-defaults@1.6.4-next.1 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/plugin-notifications@0.5.7-next.1 + - @backstage/plugin-search@1.4.28-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/plugin-signals@0.0.21-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-app@0.1.11-next.1 + - @backstage/plugin-app-visualizer@0.1.21-next.1 + - @backstage/plugin-auth-react@0.1.17-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.1 + +## example-backend@0.0.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/plugin-app-backend@0.5.4-next.0 + - @backstage/plugin-devtools-backend@0.5.7-next.1 + - @backstage/plugin-proxy-backend@0.6.4-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-backend@0.25.2-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.10-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-catalog-backend@3.0.0-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.4-next.0 + - @backstage/plugin-events-backend@0.5.4-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.2-next.0 + - @backstage/plugin-kubernetes-backend@0.19.8-next.0 + - @backstage/plugin-notifications-backend@0.5.8-next.1 + - @backstage/plugin-permission-backend@0.7.2-next.0 + - @backstage/plugin-scaffolder-backend@2.0.1-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.1 + - @backstage/plugin-search-backend@2.0.4-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.6-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.4-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.4-next.1 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-signals-backend@0.3.6-next.0 + - @backstage/plugin-techdocs-backend@2.0.4-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.2-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.10-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.12-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.5-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.1 + +## techdocs-cli-embedded-app@0.2.110-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/cli@0.33.1-next.1 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/test-utils@1.7.10-next.1 + - @backstage/plugin-techdocs@1.13.2-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-catalog@1.31.1-next.1 + - @backstage/app-defaults@1.6.4-next.1 + +## yarn-plugin-backstage@0.0.7-next.0 + +### Patch Changes + +- d6084b8: Fixed a bug that would prevent the yarn plugin from installing new dependencies with the `backstage:^` protocol. + +## @internal/plugin-todo-list@1.0.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @internal/plugin-todo-list-backend@1.0.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + +## @internal/plugin-todo-list-common@1.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 diff --git a/docs/releases/v1.41.0-next.2-changelog.md b/docs/releases/v1.41.0-next.2-changelog.md new file mode 100644 index 0000000000..b788ac0a35 --- /dev/null +++ b/docs/releases/v1.41.0-next.2-changelog.md @@ -0,0 +1,488 @@ +# Release v1.41.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.41.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.41.0-next.2) + +## @backstage/canon@0.6.0-next.1 + +### Minor Changes + +- 2e30459: We are moving our Tooltip component to use React Aria under the hood. In doing so, the structure of the component and its prop are changing to follow the new underlying structure. + +### Patch Changes + +- 76255b8: Add new Card component to Canon. +- b0a6c8e: Add new Header component to Canon. +- be76576: Improve Button, ButtonIcon and ButtonLink styling in Canon. +- 17beb9b: Update return types for Heading & Text components for React 19. +- eac4a4c: Add new tertiary variant to Button, ButtonIcon and ButtonLink in Canon. +- 8f2e82d: Add new Skeleton component in Canon + +## @backstage/core-app-api@1.18.0-next.1 + +### Minor Changes + +- 5ddc0fe: if session exists and refresh fails, then create a new session if not instant popup + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/plugin-scaffolder@1.33.0-next.2 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.18.0-next.2 + - @backstage/core-components@0.17.4-next.2 + - @backstage/plugin-scaffolder-common@1.6.0-next.1 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + +## @backstage/plugin-scaffolder-backend@2.1.0-next.2 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.6.0-next.1 + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.11-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.2 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11-next.2 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.11-next.2 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.2 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3-next.2 + +## @backstage/plugin-scaffolder-common@1.6.0-next.1 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +## @backstage/plugin-scaffolder-node@0.10.0-next.2 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.6.0-next.1 + +## @backstage/plugin-scaffolder-react@1.18.0-next.2 + +### Minor Changes + +- c1ce316: BREAKING `/alpha`: Converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + + BREAKING `/alpha`: Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + + BREAKING `/alpha`: Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +### Patch Changes + +- 94c11a5: Scroll to the top of the page when navigating between steps in template forms. +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/plugin-scaffolder-common@1.6.0-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + +## @backstage/app-defaults@1.6.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/backend-dynamic-feature-service@0.7.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/cli@0.33.1-next.2 + +### Patch Changes + +- 50f0ce6: Fixes a module not found error when running `backstage-cli info`. + +## @backstage/core-components@0.17.4-next.2 + +### Patch Changes + +- aa3b054: Added `signIn` and `signOut` analytic events to the `@backstage/core-components` of sign in and sign out. +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/create-app@0.7.1-next.2 + +### Patch Changes + +- c4a0830: Removed deprecated 'allowedHosts' field from GitHub Publish action input in default template files to fix validation errors with strict Zod validation. + +## @backstage/dev-utils@1.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/app-defaults@1.6.4-next.2 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + +## @backstage/frontend-app-api@0.11.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/test-utils@1.7.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/theme@0.6.7-next.1 + +### Patch Changes + +- 373486e: Add a different background colour to focused `MenuItem`s to fix a bug in MUI 4 (which is fixed in MUI 5) + +## @backstage/plugin-auth-backend@0.25.2-next.1 + +### Patch Changes + +- e88cb70: Small internal refactor to move out the `userInfo` database from the `tokenIssuer`. Also removes `exp` from being stored in `UserInfo` and it's now replaced with `created_at` and `updated_at` in the database instead. +- 207778c: Internal refactor of OIDC endpoints and `UserInfoDatabase` + +## @backstage/plugin-catalog@1.31.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.2 + - @backstage/plugin-scaffolder-common@1.6.0-next.1 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.6.0-next.1 + +## @backstage/plugin-home@0.8.10-next.2 + +### Patch Changes + +- d52d67f: Added a New Frontend System App Root Element for the `` component +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + +## @backstage/plugin-notifications-backend-module-email@0.3.11-next.1 + +### Patch Changes + +- f92c9fc: Add optional config for `ses` mail options with `sourceArn`, `fromArn`, `configurationSetName` + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.11-next.2 + +### Patch Changes + +- 642282d: Added support for new link format for on-prem Confluence +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + - @backstage/plugin-scaffolder-node-test-utils@0.3.1-next.2 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## @backstage/plugin-signals@0.0.21-next.2 + +### Patch Changes + +- d52d67f: Added a New Frontend System App Root Element for the `` component +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.51-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/test-utils@1.7.10-next.2 + - @backstage/plugin-catalog@1.31.1-next.2 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/plugin-techdocs@1.13.2-next.1 + +## @backstage/plugin-techdocs-node@1.13.5-next.2 + +### Patch Changes + +- 029526c: Updated the error message thrown by parseReferenceAnnotation to reflect the annotation value passed as an argument rather than in correctly assuming location. + +## @backstage/plugin-user-settings@0.8.24-next.2 + +### Patch Changes + +- aa3b054: Added `signIn` and `signOut` analytic events to the `@backstage/core-components` of sign in and sign out. +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + +## example-app@0.2.111-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.8.10-next.2 + - @backstage/canon@0.6.0-next.1 + - @backstage/cli@0.33.1-next.2 + - @backstage/plugin-scaffolder-react@1.18.0-next.2 + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/plugin-user-settings@0.8.24-next.2 + - @backstage/plugin-scaffolder@1.33.0-next.2 + - @backstage/plugin-signals@0.0.21-next.2 + - @backstage/app-defaults@1.6.4-next.2 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-app-api@0.11.4-next.2 + - @backstage/plugin-api-docs@0.12.9-next.1 + - @backstage/plugin-catalog@1.31.1-next.2 + - @backstage/plugin-catalog-graph@0.4.21-next.1 + - @backstage/plugin-catalog-import@0.13.3-next.1 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/plugin-notifications@0.5.7-next.1 + - @backstage/plugin-org@0.6.41-next.1 + - @backstage/plugin-search@1.4.28-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/plugin-techdocs@1.13.2-next.1 + +## example-app-next@0.0.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.8.10-next.2 + - @backstage/canon@0.6.0-next.1 + - @backstage/cli@0.33.1-next.2 + - @backstage/plugin-scaffolder-react@1.18.0-next.2 + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/plugin-user-settings@0.8.24-next.2 + - @backstage/plugin-scaffolder@1.33.0-next.2 + - @backstage/plugin-signals@0.0.21-next.2 + - @backstage/app-defaults@1.6.4-next.2 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-app-api@0.11.4-next.2 + - @backstage/plugin-api-docs@0.12.9-next.1 + - @backstage/plugin-catalog@1.31.1-next.2 + - @backstage/plugin-catalog-graph@0.4.21-next.1 + - @backstage/plugin-catalog-import@0.13.3-next.1 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/plugin-notifications@0.5.7-next.1 + - @backstage/plugin-org@0.6.41-next.1 + - @backstage/plugin-search@1.4.28-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/plugin-techdocs@1.13.2-next.1 + +## example-backend@0.0.40-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.2-next.1 + - @backstage/plugin-scaffolder-backend@2.1.0-next.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.2 + +## @internal/scaffolder@0.0.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.18.0-next.2 + +## techdocs-cli-embedded-app@0.2.110-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.33.1-next.2 + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/app-defaults@1.6.4-next.2 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/test-utils@1.7.10-next.2 + - @backstage/plugin-catalog@1.31.1-next.2 + - @backstage/plugin-techdocs@1.13.2-next.1 diff --git a/docs/releases/v1.41.0.md b/docs/releases/v1.41.0.md new file mode 100644 index 0000000000..2e16e9ffba --- /dev/null +++ b/docs/releases/v1.41.0.md @@ -0,0 +1,102 @@ +--- +id: v1.41.0 +title: v1.41.0 +description: Backstage Release v1.41.0 +--- + +These are the release notes for the v1.41.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### **BREAKING**: Catalog Backend 3.0 - New Defaults + +This major release of the catalog plugin backend switches the default value of a number of different flags that affect the behavior of the catalog. +https://github.com/backstage/backstage/pull/30546 + +#### `catalog.orphanStrategy` is now `delete` by default + +This switches the default orphan strategy to eagerly delete entities that are no longer referenced within the catalog. + +This flag has been suggested many times as a way to clean up entities that have been moved or deleted, and we’re feeling that it’s a good time to turn this on by default. + +You can opt back into the previous behavior by supplying `orphanStrategy: keep` in config. + +#### `catalog.orphanProviderStrategy` is now `delete` by default + +This switches the default provider installation strategy to no longer keep around entities from providers that are no longer present. + +If you have had providers installed in the past that ingested entities into the catalog that you want to keep, the recommendation is to add the provider back to the catalog. If you don’t want the provider to run, you can schedule it with a very large interval. + +#### `catalog.disableRelationsCompatibility` enabled by default + +Relations compatibility is now disabled by default. It can be re-enabled with the new `enableRelationsCompatibility` flag, but be aware that this significantly reduces overall performance of the catalog. + +Relations compatibility ensures that catalog responses contain both `targetRef` and `target` within the relations objects, while if it is disabled, only `targetRef` will be present. The `target` has not been needed within the Backstage ecosystem for a long time, as the move to `targetRef` was rolled out many years ago. Therefore, only bespoke external consumers of the catalog should be affected by this change. + +#### `catalog.stitchingStrategy` is now `{ mode: 'deferred' }` by default + +Stitching is the final phase of ingesting entities into the catalog. It collects all information related to an individual entity, generates the full output version of the entity, and writes it to the tables that power the read API. + +This switches the stitching to happen async in a background task, rather than in the main catalog processing loop. This makes stitching a lot more performant in large catalogs. + +#### `catalog.useUrlReadersSearch` always enabled + +The `catalog.useUrlReadersSearch` flag that was added in 1.36 has been removed and is now always enabled. This means that the `UrlReaderProcessor` in the catalog will always use the `search` method when reading locations, rather than `read`. This allows each individual URL reader to decide whether location refers to a single file, or if it’s a wildcard that needs searching. + +This breaking change only affects those that have installed custom URL readers for use by the catalog. If these readers already implement a search method that is able to read from exact locations, you’re all set, otherwise you will want to update it roughly as follows: + +```ts +search(url, options) { + if (!isWildcard(url)) { + return this.readUrl(url, options) + } + // existing search logic, or throw if wildcards aren’t supported +} +``` + +Contributed by [@tcardonne](https://github.com/tcardonne) in [#29788](https://github.com/backstage/backstage/pull/29788) + +### BREAKING: Scaffolder Permissions Changes + +Some of the `alpha` permissions rules in the scaffolder have had some potentially breaking changes. + +Retrying a task now requires both `scaffolder.task.read` and `scaffolder.task.create` permissions, replacing the previous requirement of `scaffolder.task.read` and `scaffolder.task.cancel`. + +Added a new scaffolder rule `isTaskOwner` for `scaffolder.task.read` and `scaffolder.task.cancel` to allow for conditional permission policies such as restricting access to tasks and task events based on task creators. + +And we’ve converted `scaffolder.task.read` and `scaffolder.task.cancel` into Resource Permissions. + +Contributed by [@04kash](https://github.com/04kash) in [#29202](https://github.com/backstage/backstage/pull/29202) + +### Renaming Canon to Backstage UI + +We have decided to rename Canon, the new design system for Backstage, to Backstage UI. For more context on this change, see [this comment](https://github.com/backstage/backstage/issues/27726#issuecomment-3019711177) on the design system RFC. As part of this change, `@backstage/canon` is being renamed to `@backstage/ui`, and `canon.backstage.io` is being switched to `ui.backstage.io`. + +### Auto `backstage:^` version with Backstage Yarn Plugin + +Fixed a bug that would prevent `yarn` from installing new Backstage dependencies with the `backstage:^` protocol. 🎉 + +Contributed by [@eipc16](https://github.com/eipc16) in [#30390](https://github.com/backstage/backstage/pull/30390) + +## Security Fixes + +This release does not contain any security fixes. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.41.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.42.0-changelog.md b/docs/releases/v1.42.0-changelog.md new file mode 100644 index 0000000000..031fb2676f --- /dev/null +++ b/docs/releases/v1.42.0-changelog.md @@ -0,0 +1,2272 @@ +# Release v1.42.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.42.0](https://backstage.github.io/upgrade-helper/?to=1.42.0) + +## @backstage/backend-defaults@0.12.0 + +### Minor Changes + +- 133519b: feat: new cache manager `Infinispan Data Grid` + +### Patch Changes + +- caee2eb: Fixed WinstonLogger throwing when redactions were null or undefined +- ed74af5: Fixed bug in PackageDiscoveryService where packages with "exports" field caused ERR_PACKAGE_PATH_NOT_EXPORTED error during backend startup. +- 3a7dad9: Updated `better-sqlite3` to v12 +- Updated dependencies + - @backstage/cli-node@0.2.14 + - @backstage/backend-app-api@1.2.6 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/backend-openapi-utils@0.6.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- 3760352: Update `express-openapi-validator` to 5.5.8 to fix security vulnerability in transitive dependency `multer` +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/backend-test-utils@1.8.0 + +### Minor Changes + +- dffaf70: Switched out `mockServices.scheduler` to use a mocked implementation instead of the default scheduler implementation. This implementation runs any scheduled tasks immediately on startup, as long as they don't have an initial delay or a manual trigger. After the initial run, the tasks are never run again unless manually triggered. + +### Patch Changes + +- 279e1f7: Updated the type definition of `mockErrorHandler` to ensure that it is used correctly. + + ```ts + // This is wrong and will now result in a type error + app.use(mockErrorHandler); + + // This is the correct usage + app.use(mockErrorHandler()); + ``` + +- 3a7dad9: Updated `better-sqlite3` to v12 + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/backend-app-api@1.2.6 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/catalog-client@1.11.0 + +### Minor Changes + +- 6b608e7: Added the analyze-location endpoint to the CatalogClient + +## @backstage/cli@0.34.0 + +### Minor Changes + +- 38b4243: Added plugin and module templates for the new frontend system. These templates are not included by default, but can be included by adding `@backstage/cli/templates/new-frontend-plugin` and `@backstage/cli/templates/new-frontend-plugin-module` as [custom templates](https://backstage.io/docs/tooling/cli/templates#installing-custom-templates). + +- 923ceb2: **BREAKING**: The new app build based on [Rspack](https://rspack.dev/) is now the default, and the `EXPERIMENTAL_RSPACK` flag has been removed. To revert to the old behavior, set the `LEGACY_WEBPACK_BUILD` environment flag and install the following optional dependencies: + + ```json + { + "dependencies": { + "@module-federation/enhanced": "^0.9.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", + "esbuild-loader": "^4.0.0", + "eslint-webpack-plugin": "^4.2.0", + "fork-ts-checker-webpack-plugin": "^9.0.0", + "mini-css-extract-plugin": "^2.4.2", + "terser-webpack-plugin": "^5.1.3", + "webpack": "^5.96.0", + "webpack-dev-server": "^5.0.0" + } + } + ``` + + If you do encounter a blocking issue that forces you to use the old WebPack build, please [open an issue](https://github.com/backstage/backstage/issues) explaining the problem. The WebPack build will be removed in a future release. + +- eda80c7: **BREAKING**: Removed support for `.icon.svg` imports, which have been deprecated since the 1.19 release. + +### Patch Changes + +- 2b8082a: Internal refactor of error handling +- 8b1bf6e: Deprecated new frontend system config setting `app.experimental.packages` to just `app.packages`. The old config will continue working for the time being, but may be removed in a future release. +- ead626f: The Node.js transform in `@backstage/cli/config/nodeTransformHooks.mjs` now supports the built-in type stripping in Node.js, which is enabled by default from v22.18.0. +- a6af768: Allow js files to be processed by the nodeTransform loader +- Updated dependencies + - @backstage/cli-node@0.2.14 + +## @backstage/core-compat-api@0.5.0 + +### Minor Changes + +- 62c3628: Rename `createLegacyApp` to `createLegacyAppRoot` as it better refers to the purpose of the function. +- e4ddf22: **BREAKING**: The `defaultPath` override of `convertLegacyPageExtension` has been renamed to `path`, in order to align with the same update that was made to the `PageBlueprint`. + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- fda1bbc: The `compatWrapper` has been switched to use the new `SwappableComponentsApi` instead of the old `ComponentsApi` in its bridging to the old frontend system. +- 5d31d66: Updated the usage of the `RouterBlueprint` and `AppRootWrapperBlueprint` to use the lowercase `component` parameter +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-catalog-react@1.20.0 + +## @backstage/frontend-app-api@0.12.0 + +### Minor Changes + +- 8e21c4d: Use an app plugin for built-in extension app node specs. +- df7bd3b: **BREAKING**: Removed the deprecated `FrontendFeature` type, import it from `@backstage/frontend-plugin-api` instead. +- 8e21c4d: The `AppNodeSpec.plugin` property is now required. +- 5e12252: **BREAKING**: Restructured some of option fields of `createApp` and `createSpecializedApp`. + + - For `createApp`, all option fields _except_ `features` and `bindRoutes` have been moved into a new `advanced` object field. + - For `createSpecializedApp`, all option fields _except_ `features`, `config`, and `bindRoutes` have been moved into a new `advanced` object field. + + This helps highlight that some options are meant to rarely be needed or used, and simplifies the usage of those options that are almost always required. + + As an example, if you used to supply a custom config loader, you would update your code as follows: + + ```diff + createApp({ + features: [...], + - configLoader: new MyCustomLoader(), + + advanced: { + + configLoader: new MyCustomLoader(), + + }, + }) + ``` + +### Patch Changes + +- d9e00e3: Add support for a new `aliasFor` option for `createRouteRef`. This allows for the creation of a new route ref that acts as an alias for an existing route ref that is installed in the app. This is particularly useful when creating modules that override existing plugin pages, without referring to the existing plugin. For example: + + ```tsx + export default createFrontendModule({ + pluginId: 'catalog', + extensions: [ + PageBlueprint.make({ + params: { + defaultPath: '/catalog', + routeRef: createRouteRef({ aliasFor: 'catalog.catalogIndex' }), + loader: () => + import('./CustomCatalogIndexPage').then(m => ( + + )), + }, + }), + ], + }); + ``` + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. + +- ef54427: Internal cleanup of routing system data. + +- 391f0ca: External route references are no longer required to be exported via a plugin instance to function. The default target will still be resolved even if the external route reference is not included in `externalRoutes` of a plugin, but users of the plugin will not be able to configure the target of the route. This is particularly useful when building modules or overrides for existing plugins, allowing you add external routes both within and out from the plugin. + +- f3f9d57: Renaming the `getNodesByRoutePath` parameter from `sourcePath` to `routePath` + +- 8b1bf6e: Deprecated new frontend system config setting `app.experimental.packages` to just `app.packages`. The old config will continue working for the time being, but may be removed in a future release. + +- fda1bbc: Added a default implementation of the `SwappableComponentsApi` and removing the legacy `ComponentsApi` implementation + +- 1c2cc37: Improved runtime error message clarity when extension factories don't return an iterable object. + +- 3d2499f: Moved `createSpecializedApp` options to a new `CreateSpecializedAppOptions` type. + +- Updated dependencies + - @backstage/frontend-defaults@0.3.0 + - @backstage/frontend-plugin-api@0.11.0 + +## @backstage/frontend-defaults@0.3.0 + +### Minor Changes + +- 76832a9: **BREAKING**: Removed the deprecated `CreateAppFeatureLoader` and support for it in other APIs. Switch existing usage to use the newer `createFrontendFeatureLoader` from `@backstage/frontend-plugin-api` instead. +- 5e12252: **BREAKING**: Restructured some of option fields of `createApp` and `createSpecializedApp`. + + - For `createApp`, all option fields _except_ `features` and `bindRoutes` have been moved into a new `advanced` object field. + - For `createSpecializedApp`, all option fields _except_ `features`, `config`, and `bindRoutes` have been moved into a new `advanced` object field. + + This helps highlight that some options are meant to rarely be needed or used, and simplifies the usage of those options that are almost always required. + + As an example, if you used to supply a custom config loader, you would update your code as follows: + + ```diff + createApp({ + features: [...], + - configLoader: new MyCustomLoader(), + + advanced: { + + configLoader: new MyCustomLoader(), + + }, + }) + ``` + +### Patch Changes + +- 22de964: Deprecated `createPublicSignInApp`, which has been replaced by the new `appModulePublicSignIn` from `@backstage/plugin-app/alpha` instead. +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- 8b1bf6e: Deprecated new frontend system config setting `app.experimental.packages` to just `app.packages`. The old config will continue working for the time being, but may be removed in a future release. +- 7adc846: Added support for passing through `allowUnknownExtensionConfig` as a flag +- e5a0a99: **BREAKING**: The `loadingComponent` option has been renamed to `loadingElement`, which is now found under `advanced.loadingElement`. The default loading element has also been switched to `` from `@backstage/core-components`. This is of course an improvement over the previous `"Loading..."` text, but also helps prevent flicker when the app loading is fast. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/frontend-app-api@0.12.0 + - @backstage/plugin-app@0.2.0 + +## @backstage/frontend-plugin-api@0.11.0 + +### Minor Changes + +- c5f88b5: **BREAKING**: Remove deprecated `source` property from the `AppNodeSpec` type, use `AppNodeSpec.plugin` instead. +- e4ddf22: **BREAKING**: The `defaultPath` param of `PageBlueprint` has been renamed to `path`. This change does not affect the compatibility of extensions created with older versions of this blueprint. +- fda1bbc: **BREAKING**: The component system has been overhauled to use `SwappableComponent` instead of `ComponentRef`. Several APIs have been removed and replaced: + + - Removed: `createComponentRef`, `createComponentExtension`, `ComponentRef`, `ComponentsApi`, `componentsApiRef`, `useComponentRef`, `coreComponentRefs` + - Added: `createSwappableComponent`, `SwappableComponentBlueprint`, `SwappableComponentRef`, `SwappableComponentsApi`, `swappableComponentsApiRef` + + **BREAKING**: The default `componentRefs` and exported `Core*Props` have been removed and have replacement `SwappableComponents` and revised type names instead. + + - The `errorBoundaryFallback` component and `CoreErrorBoundaryFallbackProps` type have been replaced with `ErrorDisplay` swappable component and `CoreErrorDisplayProps` respectively. + - The `progress` component and `CoreProgressProps` type have been replaced with `Progress` swappable component and `ProgressProps` respectively. + - The `notFoundErrorPage` component and `CoreNotFoundErrorPageProps` type have been replaced with `NotFoundErrorPage` swappable component and `NotFoundErrorPageProps` respectively. + + **Migration for creating swappable components:** + + ```tsx + // OLD: Using createComponentRef and createComponentExtension + import { + createComponentRef, + createComponentExtension, + } from '@backstage/frontend-plugin-api'; + + const myComponentRef = createComponentRef<{ title: string }>({ + id: 'my-plugin.my-component', + }); + + const myComponentExtension = createComponentExtension({ + ref: myComponentRef, + loader: { + lazy: () => import('./MyComponent').then(m => m.MyComponent), + }, + }); + + // NEW: Using createSwappableComponent and SwappableComponentBlueprint + import { + createSwappableComponent, + SwappableComponentBlueprint, + } from '@backstage/frontend-plugin-api'; + + const MySwappableComponent = createSwappableComponent({ + id: 'my-plugin.my-component', + loader: () => import('./MyComponent').then(m => m.MyComponent), + }); + + const myComponentExtension = SwappableComponentBlueprint.make({ + name: 'my-component', + params: { + component: MySwappableComponent, + loader: () => import('./MyComponent').then(m => m.MyComponent), + }, + }); + ``` + + **Migration for using components:** + + ```tsx + // OLD: Using ComponentsApi and useComponentRef + import { + useComponentRef, + componentsApiRef, + useApi, + coreComponentRefs, + } from '@backstage/frontend-plugin-api'; + + const MyComponent = useComponentRef(myComponentRef); + const ProgressComponent = useComponentRef(coreComponentRefs.progress); + ``` + +// NEW: Direct component usage +import { Progress } from '@backstage/frontend-plugin-api'; + +// Use directly as React Component + + + +```` + +**Migration for core component references:** + +```tsx +// OLD: Core component refs +import { coreComponentRefs } from '@backstage/frontend-plugin-api'; + +coreComponentRefs.progress +coreComponentRefs.notFoundErrorPage +coreComponentRefs.errorBoundaryFallback + +// NEW: Direct swappable component imports +import { Progress, NotFoundErrorPage, ErrorDisplay } from '@backstage/frontend-plugin-api'; + +// Use directly as React components + + + +```` + +- 6a75e00: **BREAKING**: Removed the deprecated `createFrontendPlugin` variant where the plugin ID is passed via an `id` option. To update existing code, switch to using the `pluginId` option instead. + +- 12b6db7: **BREAKING**: Added a new `OverridableFrontendPlugin` type that is used as the return value of `createFrontendPlugin`. This type includes the `withOverrides` and `.getExtension` methods that are helpful when creating plugin overrides, while the base `FrontendPlugin` type no longer includes these methods. This is a breaking change for the `AppTreeApi` and some other places where the `FrontendPlugin` type is still used, but also fixes some cases where the extra plugin methods were causing issues. + +- 37f2989: **BREAKING**: Removed the `routable` property from `ExtensionBoundary`. This property was never needed in practice and is instead inferred from whether or not the extension outputs a route reference. It can be safely removed. + +- 1e6410b: **BREAKING**: The `ResolveInputValueOverrides` type is no longer exported. + +- 29786f6: **BREAKING**: The `NavLogoBlueprint` has been removed and replaced by `NavContentBlueprint`, which instead replaces the entire navbar. The default navbar has also been switched to a more minimal implementation. + + To use `NavContentBlueprint` to install new logos, you can use it as follows: + + ```tsx + NavContentBlueprint.make({ + params: { + component: ({ items }) => { + return compatWrapper( + + + + {/* Other sidebar content */} + + + {items.map((item, index) => ( + + ))} + + + {/* Other sidebar content */} + , + ); + }, + }, + }); + ``` + +- 3243fa6: **BREAKING**: Removed the ability to define a default extension `name` in blueprints. This option had no practical purpose as blueprints already use the `kind` to identity the source of the extension. + +- a082429: **BREAKING**: The separate `RouteResolutionApiResolveOptions` type has been removed. + +- 5d31d66: **BREAKING**: In an attempt to align some of the API's around providing components to `Blueprints`, we've renamed the parameters for both the `RouterBlueprint` and `AppRootWrapperBlueprint` from `Component` to `component`. + + ```tsx + // old + RouterBlueprint.make({ + params: { + Component: ({ children }) =>
    {children}
    , + }, + }); + + // new + RouterBlueprint.make({ + params: { + component: ({ children }) =>
    {children}
    , + }, + }); + ``` + + ```tsx + // old + AppRootWrapperBlueprint.make({ + params: { + Component: ({ children }) =>
    {children}
    , + }, + }); + + // new + AppRootWrapperBlueprint.make({ + params: { + component: ({ children }) =>
    {children}
    , + }, + }); + ``` + + As part of this change, the type for `component` has also changed from `ComponentType>` to `(props: { children: ReactNode }) => JSX.Element | null` which is not breaking, just a little more reflective of the actual expected component. + +- 45ead4a: **BREAKING**: The `AnyRoutes` and `AnyExternalRoutes` types have been removed and their usage has been inlined instead. + + Existing usage can be replaced according to their previous definitions: + + ```ts + type AnyRoutes = { [name in string]: RouteRef | SubRouteRef }; + type AnyExternalRoutes = { [name in string]: ExternalRouteRef }; + ``` + +- 805c298: **BREAKING**: The `ApiBlueprint` has been updated to use the new advanced type parameters through the new `defineParams` blueprint option. This is an immediate breaking change that requires all existing usages of `ApiBlueprint` to switch to the new callback format. Existing extensions created with the old format are still compatible with the latest version of the plugin API however, meaning that this does not break existing plugins. + + To update existing usages of `ApiBlueprint`, you remove the outer level of the `params` object and replace `createApiFactory(...)` with `defineParams => defineParams(...)`. + + For example, the following old usage: + + ```ts + ApiBlueprint.make({ + name: 'error', + params: { + factory: createApiFactory({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => { + return ...; + }, + }) + }, + }) + ``` + + is migrated to the following: + + ```ts + ApiBlueprint.make({ + name: 'error', + params: defineParams => + defineParams({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => { + return ...; + }, + }), + }) + ``` + +- 805c298: Added support for advanced parameter types in extension blueprints. The primary purpose of this is to allow extension authors to use type inference in the definition of the blueprint parameters. This often removes the need for extra imports and improves discoverability of blueprint parameters. + + This feature is introduced through the new `defineParams` option of `createExtensionBlueprint`, along with accompanying `createExtensionBlueprintParams` function to help implement the new format. + + The following is an example of how to create an extension blueprint that uses the new option: + + ```ts + const ExampleBlueprint = createExtensionBlueprint({ + kind: 'example', + attachTo: { id: 'example', input: 'example' }, + output: [exampleComponentDataRef, exampleFetcherDataRef], + defineParams(params: { + component(props: ExampleProps): JSX.Element | null; + fetcher(options: FetchOptions): Promise>; + }) { + // The returned params must be wrapped with `createExtensionBlueprintParams` + return createExtensionBlueprintParams(params); + }, + *factory(params) { + // These params are now inferred + yield exampleComponentDataRef(params.component); + yield exampleFetcherDataRef(params.fetcher); + }, + }); + ``` + + Usage of the above example looks as follows: + + ```ts + const example = ExampleBlueprint.make({ + params: defineParams => defineParams({ + component: ..., + fetcher: ..., + }), + }); + ``` + + This `defineParams => defineParams()` is also known as the "callback syntax" and is required if a blueprint is created with the new `defineParams` option. The callback syntax can also optionally be used for other blueprints too, which means that it is not a breaking change to remove the `defineParams` option, as long as the external parameter types remain compatible. + +- 121899a: **BREAKING**: The `element` param for `AppRootElementBlueprint` no longer accepts a component. If you are currently passing a component such as `element: () => ` or `element: MyComponent`, simply switch to `element: `. + +- a321f3b: **BREAKING**: The `CommonAnalyticsContext` has been removed, and inlined into `AnalyticsContextValue` instead. + +### Patch Changes + +- d9e00e3: Add support for a new `aliasFor` option for `createRouteRef`. This allows for the creation of a new route ref that acts as an alias for an existing route ref that is installed in the app. This is particularly useful when creating modules that override existing plugin pages, without referring to the existing plugin. For example: + + ```tsx + export default createFrontendModule({ + pluginId: 'catalog', + extensions: [ + PageBlueprint.make({ + params: { + defaultPath: '/catalog', + routeRef: createRouteRef({ aliasFor: 'catalog.catalogIndex' }), + loader: () => + import('./CustomCatalogIndexPage').then(m => ( + + )), + }, + }), + ], + }); + ``` + +- 93b5e38: Plugins should now use the new `AnalyticsImplementationBlueprint` to define and provide concrete analytics implementations. For example: + + ```ts + import { AnalyticsImplementationBlueprint } from '@backstage/frontend-plugin-api'; + + const AcmeAnalytics = AnalyticsImplementationBlueprint.make({ + name: 'acme-analytics', + params: define => + define({ + deps: { config: configApiRef }, + factory: ({ config }) => AcmeAnalyticsImpl.fromConfig(config), + }), + }); + ``` + +- 948de17: Tweaked the return types from `createExtension` and `createExtensionBlueprint` to avoid the forwarding of `ConfigurableExtensionDataRef` into exported types. + +- 147482b: Updated the recommended naming of the blueprint param callback from `define` to `defineParams`, making the syntax `defineParams => defineParams(...)`. + +- 3c3c882: Added added defaults for all type parameters of `ExtensionDataRef` and deprecated `AnyExtensionDataRef`, as it is now redundant. + +- 9831f4e: Adjusted the dialog API types to have more sensible defaults + +- 1c2cc37: Improved runtime error message clarity when extension factories don't return an iterable object. + +- 24558f0: Added inline documentation for `createExtension`, `createExtensionBlueprint`, `createFrontendPlugin`, and `createFrontendModule`. + +- Updated dependencies + - @backstage/core-components@0.17.5 + +## @backstage/ui@0.7.0 + +### Minor Changes + +- 0615e54: We are moving our DataTable component to React Aria. We removed our DataTable to only use Table as a single and opinionated option for tables. This new structure is made possible by using React Aria under the hood. +- b245c9d: Backstage UI - HeaderPage - We are updating the breadcrumb to be more visible and accessible. +- 800f593: **Breaking change** We are updating the Menu component to use React Aria under the hood. The structure and all props are changing to follow React Aria's guidance. +- b0e47f3: **Breaking** We are upgrading our `Text` component to support all font sizes making the `Heading` component redundant. The new `Text` component introduces 4 sizes for title and 4 sizes for body text. All of these work in multiple colors and font weights. We improved the `as` prop to include all possible values. The `Link` component has also been updated to match the new `Text` component. + +### Patch Changes + +- de89a3d: Fixes some styles on the Select component in BUI. +- a251b3e: Export CardHeader, CardBody and CardFooter from Card component index +- f761306: Add new TagGroup component to Backstage UI. +- 75fead9: Fixes a couple of small bugs in BUI including setting H1 and H2 correctly on the Header and HeaderPage. +- e7ff178: Update styling of Tooltip element +- 230b410: **Breaking change** Move breadcrumb to fit in the `HeaderPage` instead of the `Header` in Backstage UI. +- 2f9a084: We are motion away from `motion` to use `gsap` instead to make Backstage UI backward compatible with React 17. +- d4e603e: Updated Menu component in Backstage UI to use useId() from React Aria instead of React to support React 17. +- 8bdc491: Remove stylesheet import from Select component. +- 404b426: Add `startCollapsed` prop on the `SearchField` component in BUI. +- e0e886f: Adds onTabSelectionChange to ui header component. + +## @backstage/plugin-app@0.2.0 + +### Minor Changes + +- fda1bbc: **BREAKING**: The `componentsApi` implementation has been removed from the plugin and replaced with the new `SwappableComponentsApi` instead. + + If you were overriding the `componentsApi` implementation, you can now use the new `SwappableComponentsApi` instead. + + ```ts + // old + appPlugin.getExtension('api:app/components').override(...) + + // new + appPlugin.getExtension('api:app/swappable-components').override(...) + ``` + +- 29786f6: Updated the `app/nav` extension to use the new `NavContentBlueprint`, and removed support for extensions created with the now removed `NavLogoBlueprint`. + +- 121899a: **BREAKING**: The `app-root-element` extension now only accepts `JSX.Element` in its `element` param, meaning overrides need to be updated. + +### Patch Changes + +- 91cbdf4: Log a warning when `SwappableComponent` extensions are installed outside of using the `app` plugin + +- fda1bbc: Default implementations of core components are now provided by this package. + + A backwards compatible `componentsApi` implementation is also provided from this package which uses the `SwappableComponentsApi` as the implementation. This backwards compatible wrapper will be removed in the future. + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. + +- a08f95f: Added a new module for implementing public sign-in apps, exported as `appModulePublicSignIn` via the `/alpha` sub-path export. This replaces the `createPublicSignInApp` export from `@backstage/frontend-defaults`, which is now deprecated. + +- 5d31d66: Updated the usage of the `RouterBlueprint` and `AppRootWrapperBlueprint` to use the lowercase `component` parameter + +- 93b5e38: The default implementation of the Analytics API now collects and instantiates analytics implementations exposed via `AnalyticsImplementationBlueprint` extensions. If no such extensions are discovered, the API continues to do nothing with analytics events fired within Backstage. If multiple such extensions are discovered, every discovered implementation automatically receives analytics events. + +- 9831f4e: Adjusted the dialog API types to have more sensible defaults + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/theme@0.6.8 + +## @backstage/plugin-catalog-node@1.18.0 + +### Minor Changes + +- 3f4da39: Added the analyze-location endpoint to the CatalogService + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-react@1.20.0 + +### Minor Changes + +- 3f4da39: Added the `analyzeLocation` method to `catalogApiMock` +- e4ddf22: **BREAKING ALPHA**: The `defaultPath`, `defaultTitle`, and `defaultGroup` params of `PageBlueprint` has been renamed to `path`, `title`, and `group`. The `convertLegacyEntityContentExtension` utility has also received the same change. This change does not affect the compatibility of extensions created with older versions of this blueprint. + +### Patch Changes + +- 77eebdc: Support `filter` parameter on the `EntityHeaderBlueprint` +- a3a878d: Adding `type` as an override to the `convertLegacyEntityCardExtension` +- defc243: hide pagination `queryparams` if pagination mode is set to none +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/frontend-test-utils@0.3.5 + - @backstage/core-compat-api@0.5.0 + - @backstage/catalog-client@1.11.0 + +## @backstage/plugin-kubernetes-backend@0.20.0 + +### Minor Changes + +- 759568d: **BREAKING CHANGE**: Removed support for the legacy backend system. This means that the deprecated `createRouter` and `KubernetesBuilder` and related types have been removed. Please refer to the [relevant documentation](https://backstage.io/docs/features/kubernetes/installation/#adding-kubernetes-backend-plugin) to configure the Kubernetes plugin. + + **BREAKING CHANGE**: The deprecated types `AuthenticationStrategy`, `AuthMetadata`, `ClusterDetails`, `CustomResource`, `CustomResourcesByEntity`, `FetchResponseWrapper`, `KubernetesBuilder`, `KubernetesBuilderReturn`, `KubernetesClustersSupplier`, `KubernetesCredential`, `KubernetesEnvironment`, `KubernetesFetcher`, `KubernetesObjectsProvider`, `KubernetesObjectTypes`, `KubernetesServiceLocator`,`ObjectFetchParams`, `ObjectToFetch`,`RouterOptions` and `ServiceLocatorRequestContext` should all now be imported from `@backstage/plugin-kubernetes-node`. + +### Patch Changes + +- 00ebaeb: Remove usage of the deprecated `loggerToWinstonLogger` from `@backstage/backend-common`. +- 79e342e: Added support for providing a factory to the extension points +- 5f424c6: Added support for Google Service account credentials config to use in GoogleServiceAccountStrategy +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-kubernetes-node@0.3.3 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-notifications-common@0.1.0 + +### Minor Changes + +- 9152ba8: Add an optional generic object `metadata` field to `NotificationPayload`. Metadata can be used to store additional unstructured data for the notification and are available to use by processors. + +## @backstage/plugin-scaffolder@1.34.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI +- b1c0696: Add resizable panels width for the editor and preview panels in the template editor and template form playground layouts. Users can now resize these panels by dragging the divider between the two areas. + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- b0dc9b8: differentiate between entirely and partially composite schemas in schema rendering +- c4b7c50: Export `FormField` type from `/alpha` in `-react` package, and internal refactor. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-scaffolder-react@1.19.0 + - @backstage/plugin-scaffolder-common@1.7.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/catalog-client@1.11.0 + +## @backstage/plugin-scaffolder-backend@2.2.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI +- 2032660: Fixed fs:readdir action example +- 11dc90f: Implement max length for scaffolder auditor audit logging with default of 256 +- 812485c: Add step info to scaffolder action context to access the step id and name. + +### Patch Changes + +- caee2eb: Fixed WinstonLogger throwing when redactions were null or undefined +- 4ae87f5: add `getResources` method to `permissionIntegrationRouter` for frontend task permission checks +- b817c1d: Stop logging of `SPLAT` twice in logs +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0 + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-scaffolder-common@1.7.0 + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.4 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11 + - @backstage/plugin-events-node@0.4.14 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.12 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.13 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.12 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.12 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.12 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.12 + +## @backstage/plugin-scaffolder-common@1.7.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI + +## @backstage/plugin-scaffolder-node@0.11.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- 812485c: Add step info to scaffolder action context to access the step id and name. +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.7.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-react@1.19.0 + +### Minor Changes + +- 4f99e10: **DEPRECATION**: The following types have been deprecated from this package and moved into `@backstage/plugin-scaffolder-common` and should be imported from there instead. + + `Action`, `ListActionsResponse`, `LogEvent`, `ScaffolderApi`, `ScaffolderDryRunOptions`, `ScaffolderDryRunResponse`, `ScaffolderGetIntegrationsListOptions`, `ScaffolderGetIntegrationsListResponse`, + `ScaffolderOutputLink`, `ScaffolderOutputText`, `ScaffolderScaffoldOptions`, `ScaffolderScaffoldResponse`, `ScaffolderStreamLogsOptions`, `ScaffolderTask`, `ScaffolderTaskOutput`, `ScaffolderTaskStatus`, + `ScaffolderUsageExample`, `TemplateFilter`, `TemplateGlobalFunction`, `TemplateGlobalValue`, `TemplateParameterSchema`. + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- c4b7c50: Export `FormField` type from `/alpha` in `-react` package, and internal refactor. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-scaffolder-common@1.7.0 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/catalog-client@1.11.0 + +## @backstage/plugin-techdocs@1.14.0 + +### Minor Changes + +- cb0541f: Adds `additionalAllowedURIProtocols` to sanitizer config + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- f231c2b: Fixes CSS to adjust based on whether or not the global Backstage sidebar is on the page. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-techdocs-react@1.3.2 + +## @backstage/app-defaults@1.6.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/theme@0.6.8 + +## @backstage/backend-app-api@1.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/backend-dynamic-feature-service@0.7.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0 + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/plugin-catalog-backend@3.0.1 + - @backstage/cli-node@0.2.14 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-events-backend@0.5.5 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-app-node@0.1.36 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/backend-plugin-api@1.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-permission-node@0.10.3 + +## @backstage/cli-node@0.2.14 + +### Patch Changes + +- d9a7835: Add `get` and `keys` methods to `Lockfile` class + +## @backstage/core-components@0.17.5 + +### Patch Changes + +- 1de1186: Added missing space for alert display component +- 77467bb: Updated dependency `linkifyjs` to `4.3.2`. +- 5563605: Added `FavoriteToggleProps`. +- Updated dependencies + - @backstage/theme@0.6.8 + +## @backstage/create-app@0.7.2 + +### Patch Changes + +- d7a3d04: Created a flag for scaffolding apps using the new frontend system. +- 4704160: Bumped create-app version. +- 1e8a013: Bumped create-app version. +- e33fce1: Added Notifications and Signals to be installed by default +- 8b1bf6e: Updated the `app.packages` config setting now that it no longer is experimental +- 2a156e0: Updated the `better-sqlite` dependency from `v9.0.0` to `v13.0.0`. You can apply this change to your instance by applying the following change to your `packages/backend/package.json` and running `yarn install`. + + ```diff + "dependencies": { + "app": "link:../app", + - "better-sqlite3": "^9.0.0", + + "better-sqlite3": "^12.0.0", + "node-gyp": "^10.0.0", + "pg": "^8.11.3" + } + ``` + +## @backstage/dev-utils@1.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/app-defaults@1.6.5 + +## @backstage/frontend-dynamic-feature-loader@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + +## @backstage/frontend-test-utils@0.3.5 + +### Patch Changes + +- df7bd3b: Updated import of the `FrontendFeature` type. +- 5d31d66: Updated the usage of the `RouterBlueprint` and `AppRootWrapperBlueprint` to use the lowercase `component` parameter +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/frontend-app-api@0.12.0 + - @backstage/plugin-app@0.2.0 + - @backstage/test-utils@1.7.11 + +## @backstage/repo-tools@0.15.1 + +### Patch Changes + +- 33060b5: Removed build-in ignore of the `packages/canon` package for knip reports. +- 225d7c2: Added `stringEnums` to `mustache` templates +- Updated dependencies + - @backstage/cli-node@0.2.14 + - @backstage/backend-plugin-api@1.4.2 + +## @techdocs/cli@1.9.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-techdocs-node@1.13.6 + +## @backstage/test-utils@1.7.11 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.8 + +## @backstage/theme@0.6.8 + +### Patch Changes + +- b731527: We are introducing two new data attributes on the `body` to support Backstage UI (BUI) new theming system. + +## @backstage/plugin-api-docs@0.12.10 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- 633327c: Improved styling for dark mode +- 8b1bf6e: Updated README instructions for the new frontend system +- Updated dependencies + - @backstage/plugin-catalog@1.31.2 + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-catalog-react@1.20.0 + +## @backstage/plugin-app-backend@0.5.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-app-node@0.1.36 + +## @backstage/plugin-app-node@0.1.36 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-app-visualizer@0.1.22 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + +## @backstage/plugin-auth-backend@0.25.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.3 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.3 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.6 + +### Patch Changes + +- 94476d2: Updated dependency `@davidzemon/passport-okta-oauth` to `^0.0.7`. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-node@0.6.6 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-auth-react@0.1.18 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + +## @backstage/plugin-catalog@1.31.2 + +### Patch Changes + +- c0ea01b: Fix card scrolling behaviour +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- f4622e8: Adding a more sensible default order to the default filters +- 77eebdc: Support multiple headers in new frontend system, and don't render a header until the entity has finished loading +- b158801: Fixed bug in EntityLayout that caused wiping existing query parameters when opening the InspectEntityDialog. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-scaffolder-common@1.7.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-techdocs-react@1.3.2 + +## @backstage/plugin-catalog-backend@3.0.1 + +### Patch Changes + +- 1752be6: Attempt to circumvent event listener memory leak in compression middleware + +- 9658703: Sort built-in relation fields for more stable entity hash in the processing engine + +- 9dd213c: Make the processing hash calculation not care about the order of the processors. + + This change does not affect the behavior of the catalog, but it will make the processing + hash calculation more robust against changes in the order of processors. This should lead to + more stable processing hashes, which in turn should lead to fewer unnecessary reprocessing + of entities. + + After deploying this fix, you may see a period of increased processing and stitching, but + this should stabilize over time as the processing hashes become more consistent. + +- fa6fa60: Fixed getLocationByEntity to use `original_value` instead of `value` when querying search table + +- 3a7dad9: Updated `better-sqlite3` to v12 + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0 + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-catalog-backend-module-aws@0.4.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-azure@0.3.8 + +### Patch Changes + +- b3aa80e: `host` should be optional in `config` schema +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.11 + +### Patch Changes + +- cb36a86: Added support for Google Service account credentials config used in GkeEntityProvider. + Added support for additional metadata `authProvider` and `owner` to be set for the GKE cluster entities. +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-github@0.10.2 + +### Patch Changes + +- d421b16: This change introduces single user versions of the user group resolution code in the multi org provider that will not page through all membership when updating a single user. +- f6c64d1: Fix GitHub catalog entity provider branch matching on event processing. +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.1 + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-catalog-backend-module-github@0.10.2 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.2 + +### Patch Changes + +- 8dfe76f: Added support for multiple group patterns instead of a single one to increase flexibility when filtering groups from GitLab. +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.12 + +### Patch Changes + +- d8cb60e: feat: Add gitlabOrgEntityProviderTransformsExtensionPoint for overriding user and group transformers +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.2 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-catalog-backend@3.0.1 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-logs@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.1 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-catalog-backend-module-msgraph@0.7.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.7.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-catalog-graph@0.4.22 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- 8b1bf6e: Updated README instructions for the new frontend system +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/catalog-client@1.11.0 + +## @backstage/plugin-catalog-import@0.13.4 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/catalog-client@1.11.0 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.20 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + +## @backstage/plugin-config-schema@0.1.71 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + +## @backstage/plugin-devtools@0.1.30 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + +## @backstage/plugin-devtools-backend@0.5.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-events-backend@0.5.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-module-azure@0.2.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-module-gerrit@0.2.23 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-module-github@0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-module-gitlab@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-module-kafka@0.1.2 + +### Patch Changes + +- 0d38009: Remove luxon dependency and minor internal improvements +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-backend-test-utils@0.1.47 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-events-node@0.4.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-gateway-backend@1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-home@0.8.11 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f16d380: Add the missing Visits API to the alpha plugin, fixing a crash due to the API not being installed. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- 121899a: **BREAKING ALPHA**: The `app-root-element` extension now only accepts `JSX.Element` in its `element` param, meaning overrides need to be updated. +- 166dfd7: Fixed bug in CustomHomepageGrid where `clearAll` did not respect the `deletable` flag on widgets +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-home-react@0.1.29 + +## @backstage/plugin-home-react@0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + +## @backstage/plugin-kubernetes@0.12.10 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- 3025cf5: Removed the kubernetes content padding to avoid double padding on k8s entity page +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/plugin-kubernetes-react@0.5.10 + +## @backstage/plugin-kubernetes-cluster@0.0.28 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/plugin-kubernetes-react@0.5.10 + +## @backstage/plugin-kubernetes-node@0.3.3 + +### Patch Changes + +- 79e342e: Added support for providing a factory to the extension points +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-kubernetes-react@0.5.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + +## @backstage/plugin-mcp-actions-backend@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-notifications@0.5.8 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. + +- 5a70981: Fix duplicate notification origins with multiple channels + +- 8a24e0f: Improve customization of the notification snackbar. + + Users can now customize the notification snackbar by providing custom components and icons + for different severity levels. Additionally, the location of the snackbar notifications + can be modified, the density of the snackbar can be changed, and the number of snacks can + be limited. + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/theme@0.6.8 + - @backstage/plugin-notifications-common@0.1.0 + +## @backstage/plugin-notifications-backend@0.5.9 + +### Patch Changes + +- 9152ba8: Add an optional generic object `metadata` field to `NotificationPayload`. Metadata can be used to store additional unstructured data for the notification and are available to use by processors. +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-notifications-node@0.2.18 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + - @backstage/plugin-signals-node@0.1.23 + +## @backstage/plugin-notifications-backend-module-email@0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/plugin-notifications-node@0.2.18 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-notifications-backend-module-slack@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/plugin-notifications-node@0.2.18 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-notifications-node@0.2.18 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-signals-node@0.1.23 + +## @backstage/plugin-org@0.6.42 + +### Patch Changes + +- 43cbb10: Added OwnershipCard, ComponentsGrid and UserProfileCard components to the `overridableComponents`. +- 8b1bf6e: Updated README instructions for the new frontend system +- 4ee19ed: Added support for scrolling to OwnershipCard component +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-catalog-react@1.20.0 + +## @backstage/plugin-org-react@0.1.41 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/catalog-client@1.11.0 + +## @backstage/plugin-permission-backend@0.7.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-permission-node@0.10.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-proxy-backend@0.6.5 + +### Patch Changes + +- 0810cd8: correct rewrite rule to avoid extra subpath in proxy path +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-proxy-node@0.1.7 + +## @backstage/plugin-proxy-node@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.12 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.12 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.2 + +### Patch Changes + +- a22cce0: Fixed bug in the `customProperties` type which was preventing it being used to set a list of values against a key (e.g. for multi-select fields) +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.4 + +### Patch Changes + +- 5bb870b: Show additional information about the cause in error messages from GitLab +- df2bfab: The `description` property in `publish:gitlab:merge-request` has been made optional again to comply with the GitLab API. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/plugin-notifications-node@0.2.18 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/plugin-scaffolder-node-test-utils@0.3.2 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.2 + +### Patch Changes + +- 812485c: Add step info to scaffolder action context to access the step id and name. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/backend-test-utils@1.8.0 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-search@1.4.29 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-catalog-react@1.20.0 + +## @backstage/plugin-search-backend@2.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0 + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-search-backend-module-catalog@0.3.7 + +### Patch Changes + +- d9bda0f: Allow filter to be an array in config schema +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-search-backend-module-explore@0.3.5 + +### Patch Changes + +- 3b8fac1: Updated dependency `@backstage-community/plugin-explore-common` to `^0.5.0`. +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-search-backend-module-pg@0.5.47 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-search-backend-module-techdocs@0.4.5 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-techdocs-node@1.13.6 + +## @backstage/plugin-search-backend-node@1.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-search-react@1.9.3 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/theme@0.6.8 + +## @backstage/plugin-signals@0.0.22 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- 121899a: **BREAKING ALPHA**: The `app-root-element` extension now only accepts `JSX.Element` in its `element` param, meaning overrides need to be updated. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/theme@0.6.8 + +## @backstage/plugin-signals-backend@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + - @backstage/plugin-signals-node@0.1.23 + +## @backstage/plugin-signals-node@0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.52 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-techdocs@1.14.0 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/test-utils@1.7.11 + - @backstage/plugin-techdocs-react@1.3.2 + +## @backstage/plugin-techdocs-backend@2.0.5 + +### Patch Changes + +- 484e500: Updated CachedEntityLoader to use BackstageCredentials instead of raw tokens for cache key generation. It now uses principal-based identification (user entity ref for users, subject for services) instead of token-based keys, providing more consistent caching behavior. +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-search-backend-module-techdocs@0.4.5 + - @backstage/plugin-techdocs-node@1.13.6 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.27 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-techdocs-react@1.3.2 + +## @backstage/plugin-techdocs-node@1.13.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## @backstage/plugin-techdocs-react@1.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + +## @backstage/plugin-user-settings@0.8.25 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + +## @backstage/plugin-user-settings-backend@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-signals-node@0.1.23 + +## example-app@0.2.112 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2 + - @backstage/plugin-org@0.6.42 + - @backstage/core-components@0.17.5 + - @backstage/plugin-scaffolder-react@1.19.0 + - @backstage/plugin-scaffolder@1.34.0 + - @backstage/frontend-app-api@0.12.0 + - @backstage/ui@0.7.0 + - @backstage/cli@0.34.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20 + - @backstage/plugin-catalog-import@0.13.4 + - @backstage/plugin-catalog-graph@0.4.22 + - @backstage/plugin-notifications@0.5.8 + - @backstage/plugin-user-settings@0.8.25 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-kubernetes@0.12.10 + - @backstage/plugin-api-docs@0.12.10 + - @backstage/plugin-devtools@0.1.30 + - @backstage/plugin-techdocs@1.14.0 + - @backstage/plugin-search@1.4.29 + - @backstage/plugin-home@0.8.11 + - @backstage/plugin-signals@0.0.22 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/app-defaults@1.6.5 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-kubernetes-cluster@0.0.28 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27 + - @backstage/plugin-techdocs-react@1.3.2 + +## example-app-next@0.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2 + - @backstage/plugin-org@0.6.42 + - @backstage/core-components@0.17.5 + - @backstage/frontend-defaults@0.3.0 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-scaffolder-react@1.19.0 + - @backstage/plugin-scaffolder@1.34.0 + - @backstage/frontend-app-api@0.12.0 + - @backstage/plugin-app@0.2.0 + - @backstage/ui@0.7.0 + - @backstage/cli@0.34.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-app-visualizer@0.1.22 + - @backstage/plugin-catalog-import@0.13.4 + - @backstage/plugin-catalog-graph@0.4.22 + - @backstage/plugin-notifications@0.5.8 + - @backstage/plugin-user-settings@0.8.25 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-kubernetes@0.12.10 + - @backstage/plugin-api-docs@0.12.10 + - @backstage/plugin-techdocs@1.14.0 + - @backstage/plugin-search@1.4.29 + - @backstage/plugin-home@0.8.11 + - @backstage/plugin-signals@0.0.22 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/app-defaults@1.6.5 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-kubernetes-cluster@0.0.28 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27 + - @backstage/plugin-techdocs-react@1.3.2 + +## app-next-example-plugin@0.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + +## example-backend@0.0.41 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-backend@0.20.0 + - @backstage/plugin-scaffolder-backend@2.2.0 + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-catalog-backend@3.0.1 + - @backstage/plugin-proxy-backend@0.6.5 + - @backstage/plugin-search-backend-module-explore@0.3.5 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2 + - @backstage/plugin-techdocs-backend@2.0.5 + - @backstage/plugin-search-backend-module-catalog@0.3.7 + - @backstage/plugin-notifications-backend@0.5.9 + - @backstage/plugin-app-backend@0.5.5 + - @backstage/plugin-auth-backend@0.25.3 + - @backstage/plugin-auth-backend-module-github-provider@0.3.6 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-devtools-backend@0.5.8 + - @backstage/plugin-events-backend@0.5.5 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.3 + - @backstage/plugin-mcp-actions-backend@0.1.2 + - @backstage/plugin-permission-backend@0.7.3 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/plugin-search-backend@2.0.5 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/plugin-signals-backend@0.3.7 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.13 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.11 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.5 + - @backstage/plugin-catalog-backend-module-openapi@0.2.13 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.3 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.11 + - @backstage/plugin-search-backend-module-techdocs@0.4.5 + +## e2e-test@0.2.31 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.2 + +## @internal/frontend@0.0.12 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + +## @internal/scaffolder@0.0.12 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-scaffolder-react@1.19.0 + +## techdocs-cli-embedded-app@0.2.111 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2 + - @backstage/core-components@0.17.5 + - @backstage/cli@0.34.0 + - @backstage/plugin-techdocs@1.14.0 + - @backstage/theme@0.6.8 + - @backstage/app-defaults@1.6.5 + - @backstage/test-utils@1.7.11 + - @backstage/plugin-techdocs-react@1.3.2 + +## @internal/plugin-todo-list@1.0.42 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + +## @internal/plugin-todo-list-backend@1.0.42 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 diff --git a/docs/releases/v1.42.0-next.0-changelog.md b/docs/releases/v1.42.0-next.0-changelog.md new file mode 100644 index 0000000000..9a3dd201ee --- /dev/null +++ b/docs/releases/v1.42.0-next.0-changelog.md @@ -0,0 +1,353 @@ +# Release v1.42.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.42.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.42.0-next.0) + +## @backstage/ui@0.7.0-next.0 + +### Minor Changes + +- b0e47f3: **Breaking** We are upgrading our `Text` component to support all font sizes making the `Heading` component redundant. The new `Text` component introduces 4 sizes for title and 4 sizes for body text. All of these work in multiple colors and font weights. We improved the `as` prop to include all possible values. The `Link` component has also been updated to match the new `Text` component. + +### Patch Changes + +- e7ff178: Update styling of Tooltip element +- e0e886f: Adds onTabSelectionChange to ui header component. + +## @backstage/canon@0.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.0-next.0 + +## @backstage/core-compat-api@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/create-app@0.7.2-next.0 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/dev-utils@1.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/integration-react@1.2.9 + +## @backstage/frontend-app-api@0.11.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-defaults@0.2.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/frontend-defaults@0.2.5-next.0 + +### Patch Changes + +- 7adc846: Added support for passing through `allowUnknownExtensionConfig` as a flag +- Updated dependencies + - @backstage/frontend-app-api@0.11.5-next.0 + - @backstage/plugin-app@0.1.11 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/frontend-test-utils@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.11.5-next.0 + - @backstage/plugin-app@0.1.11 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-api-docs@0.12.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/plugin-catalog@1.31.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-catalog@1.31.2-next.0 + +### Patch Changes + +- f4622e8: Adding a more sensible default order to the default filters +- 77eebdc: Support multiple headers in new frontend system, and don't render a header until the entity has finished loading +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/integration-react@1.2.9 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-search-react@1.9.2 + +## @backstage/plugin-catalog-backend-module-azure@0.3.8-next.0 + +### Patch Changes + +- b3aa80e: `host` should be optional in `config` schema + +## @backstage/plugin-catalog-graph@0.4.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-catalog-import@0.13.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/integration-react@1.2.9 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-catalog-react@1.19.2-next.0 + +### Patch Changes + +- 77eebdc: Support `filter` parameter on the `EntityHeaderBlueprint` +- a3a878d: Adding `type` as an override to the `convertLegacyEntityCardExtension` +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/integration-react@1.2.9 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/frontend-test-utils@0.3.5-next.0 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-devtools@0.1.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-home@0.8.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-kubernetes@0.12.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-kubernetes-cluster@0.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + +## @backstage/plugin-notifications@0.5.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-org@0.6.42-next.0 + +### Patch Changes + +- 43cbb10: Added OwnershipCard, ComponentsGrid and UserProfileCard components to the `overridableComponents`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-org-react@0.1.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + +## @backstage/plugin-scaffolder@1.33.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/plugin-scaffolder-react@1.18.1-next.0 + - @backstage/integration-react@1.2.9 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-scaffolder-react@1.18.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-search@1.4.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-search-react@1.9.2 + +## @backstage/plugin-signals@0.0.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## @backstage/plugin-techdocs@1.13.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/integration-react@1.2.9 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-search-react@1.9.2 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.52-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/plugin-catalog@1.31.2-next.0 + - @backstage/plugin-techdocs@1.13.3-next.0 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-search-react@1.9.2 + +## @backstage/plugin-user-settings@0.8.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## example-app@0.2.112-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-org@0.6.42-next.0 + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/ui@0.7.0-next.0 + - @backstage/plugin-catalog@1.31.2-next.0 + - @backstage/plugin-api-docs@0.12.10-next.0 + - @backstage/plugin-catalog-graph@0.4.22-next.0 + - @backstage/plugin-catalog-import@0.13.4-next.0 + - @backstage/plugin-home@0.8.11-next.0 + - @backstage/plugin-kubernetes@0.12.10-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.0 + - @backstage/plugin-scaffolder@1.33.1-next.0 + - @backstage/plugin-scaffolder-react@1.18.1-next.0 + - @backstage/plugin-search@1.4.29-next.0 + - @backstage/plugin-techdocs@1.13.3-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26 + - @backstage/plugin-user-settings@0.8.25-next.0 + - @backstage/frontend-app-api@0.11.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.0 + - @backstage/plugin-devtools@0.1.30-next.0 + - @backstage/plugin-notifications@0.5.8-next.0 + - @backstage/plugin-signals@0.0.22-next.0 + - @backstage/cli@0.33.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-search-react@1.9.2 + +## example-app-next@0.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-org@0.6.42-next.0 + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/ui@0.7.0-next.0 + - @backstage/plugin-catalog@1.31.2-next.0 + - @backstage/frontend-defaults@0.2.5-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/plugin-api-docs@0.12.10-next.0 + - @backstage/plugin-catalog-graph@0.4.22-next.0 + - @backstage/plugin-catalog-import@0.13.4-next.0 + - @backstage/plugin-home@0.8.11-next.0 + - @backstage/plugin-kubernetes@0.12.10-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.0 + - @backstage/plugin-scaffolder@1.33.1-next.0 + - @backstage/plugin-scaffolder-react@1.18.1-next.0 + - @backstage/plugin-search@1.4.29-next.0 + - @backstage/plugin-techdocs@1.13.3-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26 + - @backstage/plugin-user-settings@0.8.25-next.0 + - @backstage/frontend-app-api@0.11.5-next.0 + - @backstage/plugin-app-visualizer@0.1.21 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.0 + - @backstage/plugin-notifications@0.5.8-next.0 + - @backstage/plugin-signals@0.0.22-next.0 + - @backstage/cli@0.33.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-app@0.1.11 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-search-react@1.9.2 + +## e2e-test@0.2.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.2-next.0 + +## @internal/scaffolder@0.0.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.18.1-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## techdocs-cli-embedded-app@0.2.111-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.0 + - @backstage/plugin-techdocs@1.13.3-next.0 + - @backstage/cli@0.33.1 + - @backstage/integration-react@1.2.9 diff --git a/docs/releases/v1.42.0-next.1-changelog.md b/docs/releases/v1.42.0-next.1-changelog.md new file mode 100644 index 0000000000..1634530895 --- /dev/null +++ b/docs/releases/v1.42.0-next.1-changelog.md @@ -0,0 +1,2285 @@ +# Release v1.42.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.42.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.42.0-next.1) + +## @backstage/backend-openapi-utils@0.6.0-next.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/catalog-client@1.11.0-next.0 + +### Minor Changes + +- 6b608e7: Added the analyze-location endpoint to the CatalogClient + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/errors@1.2.7 + +## @backstage/frontend-plugin-api@0.11.0-next.0 + +### Minor Changes + +- 29786f6: **BREAKING**: The `NavLogoBlueprint` has been removed and replaced by `NavContentBlueprint`, which instead replaces the entire navbar. The default navbar has also been switched to a more minimal implementation. + + To use `NavContentBlueprint` to install new logos, you can use it as follows: + + ```tsx + NavContentBlueprint.make({ + params: { + component: ({ items }) => { + return compatWrapper( + + + + {/* Other sidebar content */} + + + {items.map((item, index) => ( + + ))} + + + {/* Other sidebar content */} + , + ); + }, + }, + }); + ``` + +- 805c298: **BREAKING**: The `ApiBlueprint` has been updated to use the new advanced type parameters through the new `defineParams` blueprint option. This is an immediate breaking change that requires all existing usages of `ApiBlueprint` to switch to the new callback format. Existing extensions created with the old format are still compatible with the latest version of the plugin API however, meaning that this does not break existing plugins. + + To update existing usages of `ApiBlueprint`, you remove the outer level of the `params` object and replace `createApiFactory(...)` with `define => define(...)`. + + For example, the following old usage: + + ```ts + ApiBlueprint.make({ + name: 'error', + params: { + factory: createApiFactory({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => { + return ...; + }, + }) + }, + }) + ``` + + is migrated to the following: + + ```ts + ApiBlueprint.make({ + name: 'error', + params: define => + define({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => { + return ...; + }, + }), + }) + ``` + +- 805c298: Added support for advanced parameter types in extension blueprints. The primary purpose of this is to allow extension authors to use type inference in the definition of the blueprint parameters. This often removes the need for extra imports and improves discoverability of blueprint parameters. + + This feature is introduced through the new `defineParams` option of `createExtensionBlueprint`, along with accompanying `createExtensionBlueprintParams` function to help implement the new format. + + The following is an example of how to create an extension blueprint that uses the new option: + + ```ts + const ExampleBlueprint = createExtensionBlueprint({ + kind: 'example', + attachTo: { id: 'example', input: 'example' }, + output: [exampleComponentDataRef, exampleFetcherDataRef], + defineParams(params: { + component(props: ExampleProps): JSX.Element | null; + fetcher(options: FetchOptions): Promise>; + }) { + // The returned params must be wrapped with `createExtensionBlueprintParams` + return createExtensionBlueprintParams(params); + }, + *factory(params) { + // These params are now inferred + yield exampleComponentDataRef(params.component); + yield exampleFetcherDataRef(params.fetcher); + }, + }); + ``` + + Usage of the above example looks as follows: + + ```ts + const example = ExampleBlueprint.make({ + params: define => define({ + component: ..., + fetcher: ..., + }), + }); + ``` + + This `define => define()` is also known as the "callback syntax" and is required if a blueprint is created with the new `defineParams` option. The callback syntax can also optionally be used for other blueprints too, which means that it is not a breaking change to remove the `defineParams` option, as long as the external parameter types remain compatible. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/plugin-app@0.2.0-next.0 + +### Minor Changes + +- 29786f6: Updated the `app/nav` extension to use the new `NavContentBlueprint`, and removed support for extensions created with the now removed `NavLogoBlueprint`. + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-catalog-node@1.18.0-next.0 + +### Minor Changes + +- 3f4da39: Added the analyze-location endpoint to the CatalogService + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-catalog-react@1.20.0-next.1 + +### Minor Changes + +- 3f4da39: Added the `analyzeLocation` method to `catalogApiMock` + +### Patch Changes + +- defc243: hide pagination `queryparams` if pagination mode is set to none +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/frontend-test-utils@0.3.5-next.1 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-scaffolder@1.34.0-next.1 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- b0dc9b8: differentiate between entirely and partially composite schemas in schema rendering +- c4b7c50: Export `FormField` type from `/alpha` in `-react` package, and internal refactor. +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/plugin-scaffolder-common@1.7.0-next.0 + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-scaffolder-backend@2.2.0-next.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI +- 812485c: Add step info to scaffolder action context to access the step id and name. + +### Patch Changes + +- caee2eb: Fixed WinstonLogger throwing when redactions were null or undefined +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/backend-openapi-utils@0.6.0-next.0 + - @backstage/plugin-scaffolder-common@1.7.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.4-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.12-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.12-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.12-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.12-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.12-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/types@1.2.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.1 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-scaffolder-common@1.7.0-next.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-scaffolder-node@0.11.0-next.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- 812485c: Add step info to scaffolder action context to access the step id and name. +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.7.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-scaffolder-react@1.19.0-next.1 + +### Minor Changes + +- 4f99e10: **DEPRECATION**: The following types have been deprecated from this package and moved into `@backstage/plugin-scaffolder-common` and should be imported from there instead. + + `Action`, `ListActionsResponse`, `LogEvent`, `ScaffolderApi`, `ScaffolderDryRunOptions`, `ScaffolderDryRunResponse`, `ScaffolderGetIntegrationsListOptions`, `ScaffolderGetIntegrationsListResponse`, + `ScaffolderOutputLink`, `ScaffolderOutputText`, `ScaffolderScaffoldOptions`, `ScaffolderScaffoldResponse`, `ScaffolderStreamLogsOptions`, `ScaffolderTask`, `ScaffolderTaskOutput`, `ScaffolderTaskStatus`, + `ScaffolderUsageExample`, `TemplateFilter`, `TemplateGlobalFunction`, `TemplateGlobalValue`, `TemplateParameterSchema`. + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- c4b7c50: Export `FormField` type from `/alpha` in `-react` package, and internal refactor. +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.7.0-next.0 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-techdocs@1.14.0-next.1 + +### Minor Changes + +- cb0541f: Adds `additionalAllowedURIProtocols` to sanitizer config + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/app-defaults@1.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.8-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/backend-app-api@1.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/backend-defaults@0.11.2-next.0 + +### Patch Changes + +- caee2eb: Fixed WinstonLogger throwing when redactions were null or undefined +- 3a7dad9: Updated `better-sqlite3` to v12 +- Updated dependencies + - @backstage/backend-app-api@1.2.6-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.2 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.1 + +## @backstage/backend-dynamic-feature-service@0.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/backend-openapi-utils@0.6.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/plugin-catalog-backend@3.0.1-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-events-backend@0.5.5-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.2 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.36-next.0 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/backend-plugin-api@1.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/backend-test-utils@1.7.1-next.0 + +### Patch Changes + +- 3a7dad9: Updated `better-sqlite3` to v12 +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/backend-app-api@1.2.6-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/cli@0.33.2-next.0 + +### Patch Changes + +- a6af768: Allow js files to be processed by the nodeTransform loader +- Updated dependencies + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.11 + - @backstage/integration@1.17.1 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/core-compat-api@0.4.5-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-components@0.17.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.8-next.0 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.7.2-next.1 + +### Patch Changes + +- d7a3d04: Created a flag for scaffolding apps using the new frontend system. + +- 2a156e0: Updated the `better-sqlite` dependency from `v9.0.0` to `v13.0.0`. You can apply this change to your instance by applying the following change to your `packages/backend/package.json` and running `yarn install`. + + ```diff + "dependencies": { + "app": "link:../app", + - "better-sqlite3": "^9.0.0", + + "better-sqlite3": "^12.0.0", + "node-gyp": "^10.0.0", + "pg": "^8.11.3" + } + ``` + +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/theme@0.6.8-next.0 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + +## @backstage/frontend-app-api@0.11.5-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/frontend-defaults@0.2.5-next.1 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.2.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.11.5-next.1 + - @backstage/plugin-app@0.2.0-next.0 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/frontend-dynamic-feature-loader@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/config@1.3.3 + +## @backstage/frontend-test-utils@0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.11.5-next.1 + - @backstage/plugin-app@0.2.0-next.0 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/test-utils@1.7.11-next.0 + - @backstage/config@1.3.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/repo-tools@0.15.1-next.0 + +### Patch Changes + +- 225d7c2: Added `stringEnums` to `mustache` templates +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @techdocs/cli@1.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-techdocs-node@1.13.6-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + +## @backstage/test-utils@1.7.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.8-next.0 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/theme@0.6.8-next.0 + +### Patch Changes + +- b731527: We are introducing two new data attributes on the `body` to support Backstage UI (BUI) new theming system. + +## @backstage/ui@0.7.0-next.1 + +### Patch Changes + +- de89a3d: Fixes some styles on the Select component in BUI. +- 75fead9: Fixes a couple of small bugs in BUI including setting H1 and H2 correctly on the Header and HeaderPage. +- 2f9a084: We are motion away from `motion` to use `gsap` instead to make Backstage UI backward compatible with React 17. + +## @backstage/plugin-api-docs@0.12.10-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.1 + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-app-backend@0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config-loader@1.10.2 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.36-next.0 + +## @backstage/plugin-app-node@0.1.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config-loader@1.10.2 + +## @backstage/plugin-app-visualizer@0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-auth-backend@0.25.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.3-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.3-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + +## @backstage/plugin-auth-node@0.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-react@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog@1.31.2-next.1 + +### Patch Changes + +- c0ea01b: Fix card scrolling behaviour +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.7.0-next.0 + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-catalog-backend@3.0.1-next.0 + +### Patch Changes + +- 3a7dad9: Updated `better-sqlite3` to v12 +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-kubernetes-common@0.9.6 + +## @backstage/plugin-catalog-backend-module-azure@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/integration@1.17.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/integration@1.17.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/plugin-kubernetes-common@0.9.6 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-github@0.10.2-next.0 + +### Patch Changes + +- d421b16: This change introduces single user versions of the user group resolution code in the multi org provider that will not page through all membership when updating a single user. +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-catalog-backend@3.0.1-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/integration@1.17.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-catalog-backend-module-github@0.10.2-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/integration@1.17.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.7.2-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-catalog-backend@3.0.1-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-logs@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.1-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/integration@1.17.1 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.7.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.9 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-catalog-graph@0.4.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-import@0.13.4-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + +## @backstage/plugin-config-schema@0.1.71-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-devtools@0.1.30-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/plugin-devtools-common@0.1.17 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-devtools-backend@0.5.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config-loader@1.10.2 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-devtools-common@0.1.17 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-events-backend@0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + - @backstage/types@1.2.1 + +## @backstage/plugin-events-backend-module-azure@0.2.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + +## @backstage/plugin-events-backend-module-github@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + - @backstage/integration@1.17.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-events-backend-module-gitlab@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-events-backend-module-kafka@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + - @backstage/types@1.2.1 + +## @backstage/plugin-events-backend-test-utils@0.1.47-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.14-next.0 + +## @backstage/plugin-events-node@0.4.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-gateway-backend@1.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-home@0.8.11-next.1 + +### Patch Changes + +- f16d380: Add the missing Visits API to the alpha plugin, fixing a crash due to the API not being installed. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-home-react@0.1.29-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-home-react@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-kubernetes@0.12.10-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-kubernetes-common@0.9.6 + - @backstage/plugin-kubernetes-react@0.5.10-next.0 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-kubernetes-backend@0.19.9-next.0 + +### Patch Changes + +- 00ebaeb: Remove usage of the deprecated `loggerToWinstonLogger` from `@backstage/backend-common`. +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-kubernetes-node@0.3.3-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.6 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-kubernetes-cluster@0.0.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-kubernetes-common@0.9.6 + - @backstage/plugin-kubernetes-react@0.5.10-next.0 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-kubernetes-node@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.6 + +## @backstage/plugin-kubernetes-react@0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.6 + +## @backstage/plugin-mcp-actions-backend@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications@0.5.8-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-notifications-backend@0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-notifications-node@0.2.18-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-signals-node@0.1.23-next.0 + +## @backstage/plugin-notifications-backend-module-email@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-notifications-node@0.2.18-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.10 + +## @backstage/plugin-notifications-backend-module-slack@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-notifications-node@0.2.18-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.10 + +## @backstage/plugin-notifications-node@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-signals-node@0.1.23-next.0 + +## @backstage/plugin-org@0.6.42-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-org-react@0.1.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-permission-backend@0.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-permission-node@0.10.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-proxy-backend@0.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-proxy-node@0.1.7-next.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-proxy-node@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.12-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.12-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.4-next.0 + +### Patch Changes + +- df2bfab: The `description` property in `publish:gitlab:merge-request` has been made optional again to comply with the GitLab API. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/plugin-notifications-node@0.2.18-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-notifications-common@0.0.10 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.3.2-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.2-next.0 + +### Patch Changes + +- 812485c: Add step info to scaffolder action context to access the step id and name. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/backend-test-utils@1.7.1-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-search@1.4.29-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend@2.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/backend-openapi-utils@0.6.0-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-catalog@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-explore@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-pg@0.5.47-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-techdocs@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-techdocs-node@1.13.6-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-node@1.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-react@1.9.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-signals@0.0.22-next.1 + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-signals-backend@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-node@0.1.23-next.0 + +## @backstage/plugin-signals-node@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + - @backstage/types@1.2.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.52-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.1 + - @backstage/plugin-techdocs@1.14.0-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/test-utils@1.7.11-next.0 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + +## @backstage/plugin-techdocs-backend@2.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.5-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-techdocs-node@1.13.6-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + +## @backstage/plugin-techdocs-node@1.13.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-react@1.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-user-settings@0.8.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.15 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-node@0.1.23-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.112-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/plugin-scaffolder@1.34.0-next.1 + - @backstage/ui@0.7.0-next.1 + - @backstage/plugin-home@0.8.11-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.1 + - @backstage/frontend-app-api@0.11.5-next.1 + - @backstage/plugin-catalog-import@0.13.4-next.1 + - @backstage/plugin-notifications@0.5.8-next.1 + - @backstage/plugin-kubernetes@0.12.10-next.1 + - @backstage/plugin-api-docs@0.12.10-next.1 + - @backstage/plugin-devtools@0.1.30-next.1 + - @backstage/plugin-techdocs@1.14.0-next.1 + - @backstage/plugin-signals@0.0.22-next.1 + - @backstage/plugin-search@1.4.29-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/theme@0.6.8-next.0 + - @backstage/cli@0.33.2-next.0 + - @backstage/plugin-catalog-graph@0.4.22-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.1 + - @backstage/plugin-org@0.6.42-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27-next.0 + - @backstage/plugin-user-settings@0.8.25-next.1 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + +## example-app-next@0.0.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/plugin-scaffolder@1.34.0-next.1 + - @backstage/ui@0.7.0-next.1 + - @backstage/plugin-home@0.8.11-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.1 + - @backstage/frontend-app-api@0.11.5-next.1 + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-import@0.13.4-next.1 + - @backstage/plugin-notifications@0.5.8-next.1 + - @backstage/plugin-kubernetes@0.12.10-next.1 + - @backstage/plugin-api-docs@0.12.10-next.1 + - @backstage/plugin-techdocs@1.14.0-next.1 + - @backstage/plugin-signals@0.0.22-next.1 + - @backstage/plugin-search@1.4.29-next.1 + - @backstage/plugin-app@0.2.0-next.0 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/cli@0.33.2-next.0 + - @backstage/frontend-defaults@0.2.5-next.1 + - @backstage/plugin-catalog-graph@0.4.22-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.1 + - @backstage/plugin-org@0.6.42-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27-next.0 + - @backstage/plugin-user-settings@0.8.25-next.1 + - @backstage/plugin-app-visualizer@0.1.22-next.0 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + +## app-next-example-plugin@0.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + +## example-backend@0.0.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-backend@0.19.9-next.0 + - @backstage/plugin-scaffolder-backend@2.2.0-next.0 + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-catalog-backend@3.0.1-next.0 + - @backstage/plugin-app-backend@0.5.5-next.0 + - @backstage/plugin-auth-backend@0.25.3-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.6-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-devtools-backend@0.5.8-next.0 + - @backstage/plugin-events-backend@0.5.5-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.3-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.2-next.0 + - @backstage/plugin-notifications-backend@0.5.9-next.0 + - @backstage/plugin-permission-backend@0.7.3-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/plugin-proxy-backend@0.6.5-next.0 + - @backstage/plugin-search-backend@2.0.5-next.0 + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/plugin-signals-backend@0.3.7-next.0 + - @backstage/plugin-techdocs-backend@2.0.5-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.5-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.13-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.7-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.5-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.13-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.11-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.11-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-permission-common@0.9.1 + +## @internal/frontend@0.0.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @internal/scaffolder@0.0.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + +## techdocs-cli-embedded-app@0.2.111-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.1 + - @backstage/plugin-techdocs@1.14.0-next.1 + - @backstage/theme@0.6.8-next.0 + - @backstage/cli@0.33.2-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/test-utils@1.7.11-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + +## @internal/plugin-todo-list@1.0.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + +## @internal/plugin-todo-list-backend@1.0.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/errors@1.2.7 diff --git a/docs/releases/v1.42.0-next.2-changelog.md b/docs/releases/v1.42.0-next.2-changelog.md new file mode 100644 index 0000000000..eccc7a8529 --- /dev/null +++ b/docs/releases/v1.42.0-next.2-changelog.md @@ -0,0 +1,723 @@ +# Release v1.42.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.42.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.42.0-next.2) + +## @backstage/cli@0.34.0-next.1 + +### Minor Changes + +- 38b4243: Added plugin and module templates for the new frontend system. These templates are not included by default, but can be included by adding `@backstage/cli/templates/new-frontend-plugin` and `@backstage/cli/templates/new-frontend-plugin-module` as [custom templates](https://backstage.io/docs/tooling/cli/templates#installing-custom-templates). + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.3 + - @backstage/config-loader@1.10.2 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.11 + - @backstage/integration@1.17.1 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/core-compat-api@0.5.0-next.2 + +### Minor Changes + +- e4ddf22: **BREAKING**: The `defaultPath` override of `convertLegacyPageExtension` has been renamed to `path`, in order to align with the same update that was made to the `PageBlueprint`. + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- 5d31d66: Updated the usage of the `RouterBlueprint` and `AppRootWrapperBlueprint` to use the lowercase `component` parameter +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-plugin-api@1.10.9 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-app-api@0.12.0-next.2 + +### Minor Changes + +- df7bd3b: **BREAKING**: Removed the deprecated `FrontendFeature` type, import it from `@backstage/frontend-plugin-api` instead. + +### Patch Changes + +- d9e00e3: Add support for a new `aliasFor` option for `createRouteRef`. This allows for the creation of a new route ref that acts as an alias for an existing route ref that is installed in the app. This is particularly useful when creating modules that override existing plugin pages, without referring to the existing plugin. For example: + + ```tsx + export default createFrontendModule({ + pluginId: 'catalog', + extensions: [ + PageBlueprint.make({ + params: { + defaultPath: '/catalog', + routeRef: createRouteRef({ aliasFor: 'catalog.catalogIndex' }), + loader: () => + import('./CustomCatalogIndexPage').then(m => ( + + )), + }, + }), + ], + }); + ``` + +- 3d2499f: Moved `createSpecializedApp` options to a new `CreateSpecializedAppOptions` type. + +- Updated dependencies + - @backstage/frontend-defaults@0.3.0-next.2 + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.3.0-next.2 + +### Minor Changes + +- 76832a9: **BREAKING**: Removed the deprecated `CreateAppFeatureLoader` and support for it in other APIs. Switch existing usage to use the newer `createFrontendFeatureLoader` from `@backstage/frontend-plugin-api` instead. + +### Patch Changes + +- 22de964: Deprecated `createPublicSignInApp`, which has been replaced by the new `appModulePublicSignIn` from `@backstage/plugin-app/alpha` instead. +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/frontend-app-api@0.12.0-next.2 + - @backstage/plugin-app@0.2.0-next.1 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/frontend-plugin-api@0.11.0-next.1 + +### Minor Changes + +- c5f88b5: **BREAKING**: Remove deprecated `source` property from the `AppNodeSpec` type, use `AppNodeSpec.plugin` instead. + +- e4ddf22: **BREAKING**: The `defaultPath` param of `PageBlueprint` has been renamed to `path`. This change does not affect the compatibility of extensions created with older versions of this blueprint. + +- 37f2989: **BREAKING**: Removed the `routable` property from `ExtensionBoundary`. This property was never needed in practice and is instead inferred from whether or not the extension outputs a route reference. It can be safely removed. + +- 3243fa6: **BREAKING**: Removed the ability to define a default extension `name` in blueprints. This option had no practical purpose as blueprints already use the `kind` to identity the source of the extension. + +- a082429: **BREAKING**: The separate `RouteResolutionApiResolveOptions` type has been removed. + +- 5d31d66: **BREAKING**: In an attempt to align some of the API's around providing components to `Blueprints`, we've renamed the parameters for both the `RouterBlueprint` and `AppRootWrapperBlueprint` from `Component` to `component`. + + ```tsx + // old + RouterBlueprint.make({ + params: { + Component: ({ children }) =>
    {children}
    , + }, + }); + + // new + RouterBlueprint.make({ + params: { + component: ({ children }) =>
    {children}
    , + }, + }); + ``` + + ```tsx + // old + AppRootWrapperBlueprint.make({ + params: { + Component: ({ children }) =>
    {children}
    , + }, + }); + + // new + AppRootWrapperBlueprint.make({ + params: { + component: ({ children }) =>
    {children}
    , + }, + }); + ``` + + As part of this change, the type for `component` has also changed from `ComponentType>` to `(props: { children: ReactNode }) => JSX.Element | null` which is not breaking, just a little more reflective of the actual expected component. + +- 45ead4a: **BREAKING**: The `AnyRoutes` and `AnyExternalRoutes` types have been removed and their usage has been inlined instead. + + Existing usage can be replaced according to their previous definitions: + + ```ts + type AnyRoutes = { [name in string]: RouteRef | SubRouteRef }; + type AnyExternalRoutes = { [name in string]: ExternalRouteRef }; + ``` + +- 121899a: **BREAKING**: The `element` param for `AppRootElementBlueprint` no longer accepts a component. If you are currently passing a component such as `element: () => ` or `element: MyComponent`, simply switch to `element: `. + +- a321f3b: **BREAKING**: The `CommonAnalyticsContext` has been removed, and inlined into `AnalyticsContextValue` instead. + +### Patch Changes + +- d9e00e3: Add support for a new `aliasFor` option for `createRouteRef`. This allows for the creation of a new route ref that acts as an alias for an existing route ref that is installed in the app. This is particularly useful when creating modules that override existing plugin pages, without referring to the existing plugin. For example: + + ```tsx + export default createFrontendModule({ + pluginId: 'catalog', + extensions: [ + PageBlueprint.make({ + params: { + defaultPath: '/catalog', + routeRef: createRouteRef({ aliasFor: 'catalog.catalogIndex' }), + loader: () => + import('./CustomCatalogIndexPage').then(m => ( + + )), + }, + }), + ], + }); + ``` + +- 93b5e38: Plugins should now use the new `AnalyticsImplementationBlueprint` to define and provide concrete analytics implementations. For example: + + ```ts + import { AnalyticsImplementationBlueprint } from '@backstage/frontend-plugin-api'; + + const AcmeAnalytics = AnalyticsImplementationBlueprint.make({ + name: 'acme-analytics', + params: define => + define({ + deps: { config: configApiRef }, + factory: ({ config }) => AcmeAnalyticsImpl.fromConfig(config), + }), + }); + ``` + +- 948de17: Tweaked the return types from `createExtension` and `createExtensionBlueprint` to avoid the forwarding of `ConfigurableExtensionDataRef` into exported types. + +- 147482b: Updated the recommended naming of the blueprint param callback from `define` to `defineParams`, making the syntax `defineParams => defineParams(...)`. + +- 3c3c882: Added added defaults for all type parameters of `ExtensionDataRef` and deprecated `AnyExtensionDataRef`, as it is now redundant. + +- Updated dependencies + - @backstage/core-components@0.17.5-next.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/plugin-app@0.2.0-next.1 + +### Minor Changes + +- 121899a: **BREAKING**: The `app-root-element` extension now only accepts `JSX.Element` in its `element` param, meaning overrides need to be updated. + +### Patch Changes + +- a08f95f: Added a new module for implementing public sign-in apps, exported as `appModulePublicSignIn` via the `/alpha` sub-path export. This replaces the `createPublicSignInApp` export from `@backstage/frontend-defaults`, which is now deprecated. +- 5d31d66: Updated the usage of the `RouterBlueprint` and `AppRootWrapperBlueprint` to use the lowercase `component` parameter +- 93b5e38: The default implementation of the Analytics API now collects and instantiates analytics implementations exposed via `AnalyticsImplementationBlueprint` extensions. If no such extensions are discovered, the API continues to do nothing with analytics events fired within Backstage. If multiple such extensions are discovered, every discovered implementation automatically receives analytics events. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-components@0.17.5-next.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-catalog-react@1.20.0-next.2 + +### Minor Changes + +- e4ddf22: **BREAKING ALPHA**: The `defaultPath`, `defaultTitle`, and `defaultGroup` params of `PageBlueprint` has been renamed to `path`, `title`, and `group`. The `convertLegacyEntityContentExtension` utility has also received the same change. This change does not affect the compatibility of extensions created with older versions of this blueprint. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/frontend-test-utils@0.3.5-next.2 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/core-components@0.17.5-next.1 + +### Patch Changes + +- 5563605: Added `FavoriteToggleProps`. +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8-next.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.7.2-next.2 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/frontend-test-utils@0.3.5-next.2 + +### Patch Changes + +- df7bd3b: Updated import of the `FrontendFeature` type. +- 5d31d66: Updated the usage of the `RouterBlueprint` and `AppRootWrapperBlueprint` to use the lowercase `component` parameter +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/frontend-app-api@0.12.0-next.2 + - @backstage/plugin-app@0.2.0-next.1 + - @backstage/config@1.3.3 + - @backstage/test-utils@1.7.11-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/ui@0.7.0-next.2 + +### Patch Changes + +- d4e603e: Updated Menu component in Backstage UI to use useId() from React Aria instead of React to support React 17. + +## @backstage/plugin-api-docs@0.12.10-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-catalog@1.31.2-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-app-visualizer@0.1.22-next.1 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-components@0.17.5-next.1 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-catalog@1.31.2-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-search-react@1.9.3-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder-common@1.7.0-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + +## @backstage/plugin-catalog-graph@0.4.22-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-import@0.13.4-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + +## @backstage/plugin-devtools@0.1.30-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/plugin-devtools-common@0.1.17 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-home@0.8.11-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- 121899a: **BREAKING ALPHA**: The `app-root-element` extension now only accepts `JSX.Element` in its `element` param, meaning overrides need to be updated. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-home-react@0.1.29-next.0 + +## @backstage/plugin-kubernetes@0.12.10-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-kubernetes-common@0.9.6 + - @backstage/plugin-kubernetes-react@0.5.10-next.0 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-notifications@0.5.8-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-org@0.6.42-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-scaffolder@1.34.0-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder-common@1.7.0-next.0 + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + +## @backstage/plugin-search@1.4.29-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-search-react@1.9.3-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-catalog@0.3.7-next.1 + +### Patch Changes + +- d9bda0f: Allow filter to be an array in config schema +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-react@1.9.3-next.1 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-components@0.17.5-next.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-signals@0.0.22-next.2 + +### Patch Changes + +- 121899a: **BREAKING ALPHA**: The `app-root-element` extension now only accepts `JSX.Element` in its `element` param, meaning overrides need to be updated. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-techdocs@1.14.0-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-search-react@1.9.3-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + +## @backstage/plugin-techdocs-backend@2.0.5-next.1 + +### Patch Changes + +- 484e500: Updated CachedEntityLoader to use BackstageCredentials instead of raw tokens for cache key generation. It now uses principal-based identification (user entity ref for users, subject for services) instead of token-based keys, providing more consistent caching behavior. +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.5-next.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-node@1.13.6-next.0 + +## @backstage/plugin-user-settings@0.8.25-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-model@1.7.5 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.15 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.112-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.12.0-next.2 + - @backstage/cli@0.34.0-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.2 + - @backstage/plugin-catalog-import@0.13.4-next.2 + - @backstage/plugin-catalog-graph@0.4.22-next.2 + - @backstage/plugin-notifications@0.5.8-next.2 + - @backstage/plugin-user-settings@0.8.25-next.2 + - @backstage/plugin-search-react@1.9.3-next.1 + - @backstage/plugin-kubernetes@0.12.10-next.2 + - @backstage/plugin-scaffolder@1.34.0-next.2 + - @backstage/plugin-api-docs@0.12.10-next.2 + - @backstage/plugin-devtools@0.1.30-next.2 + - @backstage/plugin-techdocs@1.14.0-next.2 + - @backstage/plugin-catalog@1.31.2-next.2 + - @backstage/plugin-search@1.4.29-next.2 + - @backstage/plugin-home@0.8.11-next.2 + - @backstage/ui@0.7.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/plugin-signals@0.0.22-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.1 + - @backstage/plugin-org@0.6.42-next.2 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + +## example-app-next@0.0.26-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-defaults@0.3.0-next.2 + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/frontend-app-api@0.12.0-next.2 + - @backstage/cli@0.34.0-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.2 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-app-visualizer@0.1.22-next.1 + - @backstage/plugin-catalog-import@0.13.4-next.2 + - @backstage/plugin-catalog-graph@0.4.22-next.2 + - @backstage/plugin-notifications@0.5.8-next.2 + - @backstage/plugin-user-settings@0.8.25-next.2 + - @backstage/plugin-search-react@1.9.3-next.1 + - @backstage/plugin-kubernetes@0.12.10-next.2 + - @backstage/plugin-scaffolder@1.34.0-next.2 + - @backstage/plugin-api-docs@0.12.10-next.2 + - @backstage/plugin-techdocs@1.14.0-next.2 + - @backstage/plugin-catalog@1.31.2-next.2 + - @backstage/plugin-search@1.4.29-next.2 + - @backstage/plugin-home@0.8.11-next.2 + - @backstage/plugin-app@0.2.0-next.1 + - @backstage/ui@0.7.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/plugin-signals@0.0.22-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.1 + - @backstage/plugin-org@0.6.42-next.2 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + +## techdocs-cli-embedded-app@0.2.111-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.0-next.1 + - @backstage/plugin-techdocs@1.14.0-next.2 + - @backstage/plugin-catalog@1.31.2-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/test-utils@1.7.11-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 diff --git a/docs/releases/v1.42.0-next.3-changelog.md b/docs/releases/v1.42.0-next.3-changelog.md new file mode 100644 index 0000000000..b05ca6021f --- /dev/null +++ b/docs/releases/v1.42.0-next.3-changelog.md @@ -0,0 +1,435 @@ +# Release v1.42.0-next.3 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.42.0-next.3](https://backstage.github.io/upgrade-helper/?to=1.42.0-next.3) + +## @backstage/cli@0.34.0-next.2 + +### Minor Changes + +- 923ceb2: **BREAKING**: The new app build based on [Rspack](https://rspack.dev/) is now the default, and the `EXPERIMENTAL_RSPACK` flag has been removed. To revert to the old behavior, set the `LEGACY_WEBPACK_BUILD` environment flag and install the following optional dependencies: + + ```json + { + "dependencies": { + "@module-federation/enhanced": "^0.9.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.7", + "esbuild-loader": "^4.0.0", + "eslint-webpack-plugin": "^4.2.0", + "fork-ts-checker-webpack-plugin": "^9.0.0", + "mini-css-extract-plugin": "^2.4.2", + "terser-webpack-plugin": "^5.1.3", + "webpack": "^5.96.0", + "webpack-dev-server": "^5.0.0" + } + } + ``` + + If you do encounter a blocking issue that forces you to use the old WebPack build, please [open an issue](https://github.com/backstage/backstage/issues) explaining the problem. The WebPack build will be removed in a future release. + +- eda80c7: **BREAKING**: Removed support for `.icon.svg` imports, which have been deprecated since the 1.19 release. + +### Patch Changes + +- 8b1bf6e: Deprecated new frontend system config setting `app.experimental.packages` to just `app.packages`. The old config will continue working for the time being, but may be removed in a future release. +- ead626f: The Node.js transform in `@backstage/cli/config/nodeTransformHooks.mjs` now supports the built-in type stripping in Node.js, which is enabled by default from v22.18.0. + +## @backstage/frontend-app-api@0.12.0-next.3 + +### Minor Changes + +- 8e21c4d: Use an app plugin for built-in extension app node specs. +- 8e21c4d: The `AppNodeSpec.plugin` property is now required. +- 5e12252: **BREAKING**: Restructured some of option fields of `createApp` and `createSpecializedApp`. + + - For `createApp`, all option fields _except_ `features` and `bindRoutes` have been moved into a new `advanced` object field. + - For `createSpecializedApp`, all option fields _except_ `features`, `config`, and `bindRoutes` have been moved into a new `advanced` object field. + + This helps highlight that some options are meant to rarely be needed or used, and simplifies the usage of those options that are almost always required. + + As an example, if you used to supply a custom config loader, you would update your code as follows: + + ```diff + createApp({ + features: [...], + - configLoader: new MyCustomLoader(), + + advanced: { + + configLoader: new MyCustomLoader(), + + }, + }) + ``` + +### Patch Changes + +- f3f9d57: Renaming the `getNodesByRoutePath` parameter from `sourcePath` to `routePath` +- 8b1bf6e: Deprecated new frontend system config setting `app.experimental.packages` to just `app.packages`. The old config will continue working for the time being, but may be removed in a future release. +- fda1bbc: Added a default implementation of the `SwappableComponentsApi` and removing the legacy `ComponentsApi` implementation +- 1c2cc37: Improved runtime error message clarity when extension factories don't return an iterable object. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.2 + - @backstage/frontend-defaults@0.3.0-next.3 + +## @backstage/frontend-defaults@0.3.0-next.3 + +### Minor Changes + +- 5e12252: **BREAKING**: Restructured some of option fields of `createApp` and `createSpecializedApp`. + + - For `createApp`, all option fields _except_ `features` and `bindRoutes` have been moved into a new `advanced` object field. + - For `createSpecializedApp`, all option fields _except_ `features`, `config`, and `bindRoutes` have been moved into a new `advanced` object field. + + This helps highlight that some options are meant to rarely be needed or used, and simplifies the usage of those options that are almost always required. + + As an example, if you used to supply a custom config loader, you would update your code as follows: + + ```diff + createApp({ + features: [...], + - configLoader: new MyCustomLoader(), + + advanced: { + + configLoader: new MyCustomLoader(), + + }, + }) + ``` + +### Patch Changes + +- 8b1bf6e: Deprecated new frontend system config setting `app.experimental.packages` to just `app.packages`. The old config will continue working for the time being, but may be removed in a future release. +- e5a0a99: **BREAKING**: The `loadingComponent` option has been renamed to `loadingElement`, which is now found under `advanced.loadingElement`. The default loading element has also been switched to `` from `@backstage/core-components`. This is of course an improvement over the previous `"Loading..."` text, but also helps prevent flicker when the app loading is fast. +- Updated dependencies + - @backstage/plugin-app@0.2.0-next.2 + - @backstage/frontend-plugin-api@0.11.0-next.2 + - @backstage/frontend-app-api@0.12.0-next.3 + - @backstage/core-components@0.17.5-next.2 + +## @backstage/frontend-plugin-api@0.11.0-next.2 + +### Minor Changes + +- fda1bbc: **BREAKING**: The component system has been overhauled to use `SwappableComponent` instead of `ComponentRef`. Several APIs have been removed and replaced: + + - Removed: `createComponentRef`, `createComponentExtension`, `ComponentRef`, `ComponentsApi`, `componentsApiRef`, `useComponentRef`, `coreComponentRefs` + - Added: `createSwappableComponent`, `SwappableComponentBlueprint`, `SwappableComponentRef`, `SwappableComponentsApi`, `swappableComponentsApiRef` + + **BREAKING**: The default `componentRefs` and exported `Core*Props` have been removed and have replacement `SwappableComponents` and revised type names instead. + + - The `errorBoundaryFallback` component and `CoreErrorBoundaryFallbackProps` type have been replaced with `ErrorDisplay` swappable component and `CoreErrorDisplayProps` respectively. + - The `progress` component and `CoreProgressProps` type have been replaced with `Progress` swappable component and `ProgressProps` respectively. + - The `notFoundErrorPage` component and `CoreNotFoundErrorPageProps` type have been replaced with `NotFoundErrorPage` swappable component and `NotFoundErrorPageProps` respectively. + + **Migration for creating swappable components:** + + ```tsx + // OLD: Using createComponentRef and createComponentExtension + import { + createComponentRef, + createComponentExtension, + } from '@backstage/frontend-plugin-api'; + + const myComponentRef = createComponentRef<{ title: string }>({ + id: 'my-plugin.my-component', + }); + + const myComponentExtension = createComponentExtension({ + ref: myComponentRef, + loader: { + lazy: () => import('./MyComponent').then(m => m.MyComponent), + }, + }); + + // NEW: Using createSwappableComponent and SwappableComponentBlueprint + import { + createSwappableComponent, + SwappableComponentBlueprint, + } from '@backstage/frontend-plugin-api'; + + const MySwappableComponent = createSwappableComponent({ + id: 'my-plugin.my-component', + loader: () => import('./MyComponent').then(m => m.MyComponent), + }); + + const myComponentExtension = SwappableComponentBlueprint.make({ + name: 'my-component', + params: { + component: MySwappableComponent, + loader: () => import('./MyComponent').then(m => m.MyComponent), + }, + }); + ``` + + **Migration for using components:** + + ```tsx + // OLD: Using ComponentsApi and useComponentRef + import { + useComponentRef, + componentsApiRef, + useApi, + coreComponentRefs, + } from '@backstage/frontend-plugin-api'; + + const MyComponent = useComponentRef(myComponentRef); + const ProgressComponent = useComponentRef(coreComponentRefs.progress); + ``` + +// NEW: Direct component usage +import { Progress } from '@backstage/frontend-plugin-api'; + +// Use directly as React Component + + + +```` + +**Migration for core component references:** + +```tsx +// OLD: Core component refs +import { coreComponentRefs } from '@backstage/frontend-plugin-api'; + +coreComponentRefs.progress +coreComponentRefs.notFoundErrorPage +coreComponentRefs.errorBoundaryFallback + +// NEW: Direct swappable component imports +import { Progress, NotFoundErrorPage, ErrorDisplay } from '@backstage/frontend-plugin-api'; + +// Use directly as React components + + + +```` + +- 6a75e00: **BREAKING**: Removed the deprecated `createFrontendPlugin` variant where the plugin ID is passed via an `id` option. To update existing code, switch to using the `pluginId` option instead. +- 1e6410b: **BREAKING**: The `ResolveInputValueOverrides` type is no longer exported. + +### Patch Changes + +- 9831f4e: Adjusted the dialog API types to have more sensible defaults +- 1c2cc37: Improved runtime error message clarity when extension factories don't return an iterable object. +- 24558f0: Added inline documentation for `createExtension`, `createExtensionBlueprint`, `createFrontendPlugin`, and `createFrontendModule`. +- Updated dependencies + - @backstage/core-components@0.17.5-next.2 + +## @backstage/ui@0.7.0-next.3 + +### Minor Changes + +- 0615e54: We are moving our DataTable component to React Aria. We removed our DataTable to only use Table as a single and opinionated option for tables. This new structure is made possible by using React Aria under the hood. + +### Patch Changes + +- 230b410: **Breaking change** Move breadcrumb to fit in the `HeaderPage` instead of the `Header` in Backstage UI. +- 8bdc491: Remove stylesheet import from Select component. +- 404b426: Add `startCollapsed` prop on the `SearchField` component in BUI. + +## @backstage/plugin-app@0.2.0-next.2 + +### Minor Changes + +- fda1bbc: **BREAKING**: The `componentsApi` implementation has been removed from the plugin and replaced with the new `SwappableComponentsApi` instead. + + If you were overriding the `componentsApi` implementation, you can now use the new `SwappableComponentsApi` instead. + + ```ts + // old + appPlugin.getExtension('api:app/components').override(...) + + // new + appPlugin.getExtension('api:app/swappable-components').override(...) + ``` + +### Patch Changes + +- 91cbdf4: Log a warning when `SwappableComponent` extensions are installed outside of using the `app` plugin + +- fda1bbc: Default implementations of core components are now provided by this package. + + A backwards compatible `componentsApi` implementation is also provided from this package which uses the `SwappableComponentsApi` as the implementation. This backwards compatible wrapper will be removed in the future. + +- 9831f4e: Adjusted the dialog API types to have more sensible defaults + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.2 + - @backstage/core-components@0.17.5-next.2 + +## @backstage/plugin-kubernetes-backend@0.20.0-next.1 + +### Minor Changes + +- 759568d: **BREAKING CHANGE**: Removed support for the legacy backend system. This means that the deprecated `createRouter` and `KubernetesBuilder` and related types have been removed. Please refer to the [relevant documentation](https://backstage.io/docs/features/kubernetes/installation/#adding-kubernetes-backend-plugin) to configure the Kubernetes plugin. + + **BREAKING CHANGE**: The deprecated types `AuthenticationStrategy`, `AuthMetadata`, `ClusterDetails`, `CustomResource`, `CustomResourcesByEntity`, `FetchResponseWrapper`, `KubernetesBuilder`, `KubernetesBuilderReturn`, `KubernetesClustersSupplier`, `KubernetesCredential`, `KubernetesEnvironment`, `KubernetesFetcher`, `KubernetesObjectsProvider`, `KubernetesObjectTypes`, `KubernetesServiceLocator`,`ObjectFetchParams`, `ObjectToFetch`,`RouterOptions` and `ServiceLocatorRequestContext` should all now be imported from `@backstage/plugin-kubernetes-node`. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-node@0.3.3-next.0 + +## @backstage/plugin-scaffolder@1.34.0-next.3 + +### Minor Changes + +- b1c0696: Add resizable panels width for the editor and preview panels in the template editor and template form playground layouts. Users can now resize these panels by dragging the divider between the two areas. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.2 + - @backstage/core-compat-api@0.5.0-next.3 + - @backstage/core-components@0.17.5-next.2 + +## @backstage/plugin-scaffolder-backend@2.2.0-next.1 + +### Minor Changes + +- 2032660: Fixed fs:readdir action example +- 11dc90f: Implement max length for scaffolder auditor audit logging with default of 256 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.4-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2-next.1 + +## @backstage/backend-openapi-utils@0.6.0-next.1 + +### Patch Changes + +- 3760352: Update `express-openapi-validator` to 5.5.8 to fix security vulnerability in transitive dependency `multer` + +## @backstage/core-compat-api@0.5.0-next.3 + +### Patch Changes + +- fda1bbc: The `compatWrapper` has been switched to use the new `SwappableComponentsApi` instead of the old `ComponentsApi` in its bridging to the old frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.2 + +## @backstage/core-components@0.17.5-next.2 + +### Patch Changes + +- 77467bb: Updated dependency `linkifyjs` to `4.3.2`. + +## @backstage/create-app@0.7.2-next.3 + +### Patch Changes + +- 8b1bf6e: Updated the `app.packages` config setting now that it no longer is experimental + +## @backstage/repo-tools@0.15.1-next.1 + +### Patch Changes + +- 33060b5: Removed build-in ignore of the `packages/canon` package for knip reports. + +## @backstage/plugin-api-docs@0.12.10-next.3 + +### Patch Changes + +- 8b1bf6e: Updated README instructions for the new frontend system +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.2 + - @backstage/core-compat-api@0.5.0-next.3 + - @backstage/core-components@0.17.5-next.2 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.6-next.1 + +### Patch Changes + +- 94476d2: Updated dependency `@davidzemon/passport-okta-oauth` to `^0.0.7`. + +## @backstage/plugin-catalog-backend@3.0.1-next.1 + +### Patch Changes + +- 1752be6: Attempt to circumvent event listener memory leak in compression middleware + +- 9dd213c: Make the processing hash calculation not care about the order of the processors. + + This change does not affect the behavior of the catalog, but it will make the processing + hash calculation more robust against changes in the order of processors. This should lead to + more stable processing hashes, which in turn should lead to fewer unnecessary reprocessing + of entities. + + After deploying this fix, you may see a period of increased processing and stitching, but + this should stabilize over time as the processing hashes become more consistent. + +- fa6fa60: Fixed getLocationByEntity to use `original_value` instead of `value` when querying search table + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.10.2-next.1 + +### Patch Changes + +- f6c64d1: Fix GitHub catalog entity provider branch matching on event processing. +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.1-next.1 + +## @backstage/plugin-catalog-graph@0.4.22-next.3 + +### Patch Changes + +- 8b1bf6e: Updated README instructions for the new frontend system +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.2 + - @backstage/core-compat-api@0.5.0-next.3 + - @backstage/core-components@0.17.5-next.2 + +## @backstage/plugin-events-backend-module-kafka@0.1.2-next.1 + +### Patch Changes + +- 0d38009: Remove luxon dependency and minor internal improvements + +## @backstage/plugin-kubernetes@0.12.10-next.3 + +### Patch Changes + +- 3025cf5: Removed the kubernetes content padding to avoid double padding on k8s entity page +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.2 + - @backstage/core-compat-api@0.5.0-next.3 + - @backstage/core-components@0.17.5-next.2 + +## @backstage/plugin-org@0.6.42-next.3 + +### Patch Changes + +- 8b1bf6e: Updated README instructions for the new frontend system +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.2 + - @backstage/core-compat-api@0.5.0-next.3 + - @backstage/core-components@0.17.5-next.2 + +## @backstage/plugin-proxy-backend@0.6.5-next.1 + +### Patch Changes + +- 0810cd8: correct rewrite rule to avoid extra subpath in proxy path + +## @backstage/plugin-scaffolder-backend-module-github@0.8.2-next.1 + +### Patch Changes + +- a22cce0: Fixed bug in the `customProperties` type which was preventing it being used to set a list of values against a key (e.g. for multi-select fields) + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.4-next.1 + +### Patch Changes + +- 5bb870b: Show additional information about the cause in error messages from GitLab + +## example-backend@0.0.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.1-next.1 + - @backstage/plugin-kubernetes-backend@0.20.0-next.1 + - @backstage/plugin-scaffolder-backend@2.2.0-next.1 + - @backstage/plugin-proxy-backend@0.6.5-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2-next.1 diff --git a/docs/releases/v1.42.0.md b/docs/releases/v1.42.0.md new file mode 100644 index 0000000000..4fe52f7a77 --- /dev/null +++ b/docs/releases/v1.42.0.md @@ -0,0 +1,68 @@ +--- +id: v1.42.0 +title: v1.42.0 +description: Backstage Release v1.42.0 +--- + +These are the release notes for the v1.42.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### The new Frontend System is Adoption Ready! 🎉 + +We've been hard at work over the last few months stabilizing the APIs for the New Frontend System, and we're excited to announce that they're ready for prime time! With the release of version 1.42.0, we're officially encouraging all developers to start migrating their apps to the new system, along with all their plugins. + +The New Frontend System is a major leap forward, offering a more powerful, flexible, and overall better development experience. By migrating, you’ll be able to take advantage of declarative integration of plugins and removing a large amount of code that’s used to configure your Backstage App. With plugins also migrating, there’s new extensibility patterns on the horizon that will allow you to customize Backstage even further than before. + +We know that migrating can be a big undertaking, so we've made it as easy as possible. You can choose to migrate gradually, using a hybrid approach that combines the new and old systems, or you can start fresh with a brand new app using the `--next` flag. + +Whatever path you choose, we've got you covered. Check out our comprehensive [migration guide](https://backstage.io/docs/frontend-system/building-apps/migrating) for step-by-step instructions, and don't hesitate to reach out to us on our repository or Discord if you need help. + +### Default bundler switched to Rspack + +The Backstage CLI has been updated to use [Rspack](https://rspack.rs/) as the bundler for frontend apps. It has been available behind the `EXPERIMENTAL_RSPACK` flag since the 1.32 release, but has now been switched to the default. The use of [WebPack](https://webpack.js.org/) can be restored using the `LEGACY_WEBPACK_BUILD` flag, along with installing the necessary dependencies. See the changelog for `@backstage/cli` for more information. + +### Kubernetes Legacy Backend System Removal + +We’ve removed support for the legacy backend system, as well all of the deprecated exports for the last plugin in the main repository. With this cleanup, we say goodbye to the last occurrence of the old `@backstage/backend-common` in the repository! + +There’s extensive documentation in the [changelog](https://github.com/backstage/backstage/blob/master/plugins/kubernetes-backend/CHANGELOG.md#minor-changes) for migrating to the latest version. + +Please reach out if you have any issues! + +### Scaffolder is now powered by OpenAPI + more deprecations! + +The Scaffolder router and client are now generated by the OpenAPI tooling. One of the oldest PR’s that we had in the repository has been merged after a lot of hard work. Thanks to [@solimant](https://github.com/solimant) and [@aramissennyeydd](https://github.com/aramissennyeydd) for their continued support throughout! + +Also with this, there’s been a lot of types moved into `@backstage/plugin-scaffolder-common` which means that their original exports from `-react` have now been deprecated. Please check out the [CHANGELOG](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-react/CHANGELOG.md) for more details on the affected types. + +Contributed by [@solimant](https://github.com/solimant) in [#27771](https://github.com/backstage/backstage/pull/27771) + +### Catalog performance improvements + +The catalog sometimes did more work than necessary because it was not taking into account that in some places, order doesn’t matter. So that got fixed! The upshot is that you may see in your monitoring that it performs less useless stitching after the upgrade. To achieve this it will have to do a short period of _more_ work right after the upgrade before it converges. Just so you are aware. + +Contributed by [@drodil](https://github.com/drodil) in [#30859](https://github.com/backstage/backstage/pull/30859) + +## Security Fixes + +This release also fixes the possibility of the scaffolder logging both redacted and plain text secrets when used as input to the `fetch:template` action. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.42.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.43.0-changelog.md b/docs/releases/v1.43.0-changelog.md new file mode 100644 index 0000000000..6fa500bdd5 --- /dev/null +++ b/docs/releases/v1.43.0-changelog.md @@ -0,0 +1,2119 @@ +# Release v1.43.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.43.0](https://backstage.github.io/upgrade-helper/?to=1.43.0) + +## @backstage/app-defaults@1.7.0 + +### Minor Changes + +- 9956704: Add and configure the OpenShift authentication provider to the default APIs. + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/core-app-api@1.19.0 + +## @backstage/backend-test-utils@1.9.0 + +### Minor Changes + +- 4e2c237: The `mockServices.rootConfig()` instance now has an `update` method that can be used to test configuration subscriptions and updates. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-app-api@1.2.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/catalog-client@1.12.0 + +### Minor Changes + +- 0e9ec44: Introduced new `streamEntities` async generator method for the catalog. + + Catalog API and Catalog Service now includes a `streamEntities` method that allows for streaming entities from the catalog. + This method is designed to handle large datasets efficiently by processing entities in a stream rather than loading them + all into memory at once. This is useful when you need to fetch a large number of entities but do not want to use pagination + or fetch all entities at once. + + Example usage: + + ```ts + const pageStream = catalogClient.streamEntities({ pageSize: 100 }, { token }); + for await (const page of pageStream) { + // Handle page of entities + for (const entity of page) { + console.log(entity); + } + } + ``` + +### Patch Changes + +- 0efcc97: Updated generated schemas + +## @backstage/core-app-api@1.19.0 + +### Minor Changes + +- 3fca906: Add `OpenShiftAuth` helper to create default OAuth flow for OpenShift. + +### Patch Changes + +- 5ae6d9d: feat: support no en languages +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/types@1.2.2 + +## @backstage/core-components@0.18.0 + +### Minor Changes + +- b9a87f4: Add optional `distance` property to `DependencyEdge` to reflect the distance to a root. + +### Patch Changes + +- 1ad3d94: Dependency graph can now be opened in full screen mode +- e409bec: Fixes for rendering initials in the avatar component. +- ae7d426: update about card links style for pretty display with other language +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + +## @backstage/core-plugin-api@1.11.0 + +### Minor Changes + +- 5114627: Make `openshiftAuthApiRef` available in `@backstage/core-plugin-api`. + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.2 + +## @backstage/frontend-app-api@0.13.0 + +### Minor Changes + +- 6516c3d: The `createSpecializedApp` no longer throws when encountering many common errors when starting up the app. It will instead return them through the `errors` property so that they can be handled more gracefully in the app. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/types@1.2.2 + - @backstage/frontend-defaults@0.3.1 + - @backstage/core-app-api@1.19.0 + +## @backstage/frontend-plugin-api@0.12.0 + +### Minor Changes + +- 894d514: Make `openshiftApiRef` available to the new frontend system. + +### Patch Changes + +- 2fb8b04: Improved the types of `createFrontendPlugin` and `createFrontendModule` so that errors due to incompatible options are indicated more clearly. +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + +## @backstage/integration@1.18.0 + +### Minor Changes + +- 03bdc68: Added support for limiting GithubAppCredentialsMux to specific apps + +### Patch Changes + +- 56897d7: Fixes issue with Github credentials provider which fails to match organization name if using allowedInstallationOwners + +## @backstage/plugin-app@0.3.0 + +### Minor Changes + +- 99790db: Add implementation of OpenShift authentication provider. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/integration-react@1.2.10 + +## @backstage/plugin-auth@0.1.0 + +### Minor Changes + +- 54ddfef: Initial publish of the `auth` frontend package + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-components@0.18.0 + +## @backstage/plugin-auth-backend-module-openshift-provider@0.1.0 + +### Minor Changes + +- 5a84253: Add new `auth-backend-module-openshift-provider`. This authentication provider enables Backstage to sign in with OpenShift. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend@3.1.0 + +### Minor Changes + +- 9b40a55: Add support for specifying an entity `spec.type` in `catalog.rules` and `catalog.locations.rules` within the catalog configuration. + + For example, this enables allowing all `Template` entities with the type `website`: + + ```diff + catalog: + rules: + - allow: + - Component + - API + - Resource + - System + - Domain + - Location + + - allow: + + - kind: Template + + spec.type: website + locations: + - type: url + pattern: https://github.com/org/*\/blob/master/*.yaml + ``` + +### Patch Changes + +- 37b4eaf: The 'get-catalog-entity' action now throws a ConflictError instead of generic Error if multiple entities are found, so MCP call doesn't fail with 500. + +- 2bbd24f: Order catalog processors by priority. + + This change enables the ordering of catalog processors by their priority, + allowing for more control over the catalog processing sequence. + The default priority is set to 20, and processors can be assigned a custom + priority to influence their execution order. Lower number indicates higher priority. + The priority can be set by implementing the `getPriority` method in the processor class + or by adding a `catalog.processors..priority` configuration + in the `app-config.yaml` file. The configuration takes precedence over the method. + +- e934a27: Updating `catalog:get-catalog-entity` action to be `readOnly` and non destructive + +- 0efcc97: Updated generated schemas + +- 2204f5b: Prevent deadlock in catalog deferred stitching + +- 58874c4: Add support to disable catalog providers and processors via configuration + +- a4c82ad: Only run provider orphan cleanup if the engine is started in the first place + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-permission-node@0.10.4 + +## @backstage/plugin-catalog-backend-module-github@0.11.0 + +### Minor Changes + +- 03bdc68: Added support for discovery by app + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.0 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.0 + +### Minor Changes + +- 577f0ed: **BREAKING**: Encode query filters for requests made to msgraph. If you currently have manually encoded characters in a filter, this is a breaking change and must be updated to avoid requests being double encoded. + + ```diff + user: + - filter: department in('MARKETING', 'RESEARCH %26 DEVELOPMENT') + + filter: department in('MARKETING', 'RESEARCH & DEVELOPMENT') + ``` + +### Patch Changes + +- 7597781: Ensure that msgraph parent group stays same in case the group has multiple parents +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-graph@0.5.0 + +### Minor Changes + +- ae6b606: Support custom relations by using an API to define known relations and which to show by default + Fixes "simplified" bug (#30121) which caused graphs not to be simplified + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/core-compat-api@0.5.2 + +## @backstage/plugin-catalog-node@1.19.0 + +### Minor Changes + +- 0e9ec44: Introduced new `streamEntities` async generator method for the catalog. + + Catalog API and Catalog Service now includes a `streamEntities` method that allows for streaming entities from the catalog. + This method is designed to handle large datasets efficiently by processing entities in a stream rather than loading them + all into memory at once. This is useful when you need to fetch a large number of entities but do not want to use pagination + or fetch all entities at once. + + Example usage: + + ```ts + const pageStream = catalogClient.streamEntities({ pageSize: 100 }, { token }); + for await (const page of pageStream) { + // Handle page of entities + for (const entity of page) { + console.log(entity); + } + } + ``` + +### Patch Changes + +- 2bbd24f: Order catalog processors by priority. + + This change enables the ordering of catalog processors by their priority, + allowing for more control over the catalog processing sequence. + The default priority is set to 20, and processors can be assigned a custom + priority to influence their execution order. Lower number indicates higher priority. + The priority can be set by implementing the `getPriority` method in the processor class + or by adding a `catalog.processors..priority` configuration + in the `app-config.yaml` file. The configuration takes precedence over the method. + +- Updated dependencies + - @backstage/catalog-client@1.12.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-permission-node@0.10.4 + +## @backstage/plugin-catalog-react@1.21.0 + +### Minor Changes + +- 0e9ec44: Introduced new `streamEntities` async generator method for the catalog. + + Catalog API and Catalog Service now includes a `streamEntities` method that allows for streaming entities from the catalog. + This method is designed to handle large datasets efficiently by processing entities in a stream rather than loading them + all into memory at once. This is useful when you need to fetch a large number of entities but do not want to use pagination + or fetch all entities at once. + + Example usage: + + ```ts + const pageStream = catalogClient.streamEntities({ pageSize: 100 }, { token }); + for await (const page of pageStream) { + // Handle page of entities + for (const entity of page) { + console.log(entity); + } + } + ``` + +### Patch Changes + +- 0174799: Fix a potential race condition in EntityListProvider when selecting filters +- 4316c11: Catalog table columns support i18n +- 79ff318: Removed the deprecation warning when not passing an explicit type to `EntityCardBlueprint`. Omitting the type is now intended, allowing the layout to pick the default type instead, typically `content`. +- ad0f58d: Support `default*` for older packages as this package is in range for breaking `/alpha` changes +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/frontend-test-utils@0.3.6 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/core-compat-api@0.5.2 + - @backstage/integration-react@1.2.10 + +## @backstage/plugin-scaffolder-backend-module-github@0.9.0 + +### Minor Changes + +- f0f06b4: Adding a new scaffolder action `github:issues:create` following the reference of `github:issues:label` with `dryRun` testing possibility + + It can be used like this + + steps: + - id: create-simple-issue + name: Create Simple Issue + action: github:issues:create + input: + repoUrl: ${{ parameters.repoUrl }} + title: "[${{ parameters.projectName }}] Simple Bug Report" + body: | + ## Bug Description + This is a simple bug report created by the scaffolder template. + + ### Steps to Reproduce + 1. Run the application + 2. Navigate to the main page + 3. Click on the problematic button + + ### Expected Behavior + The button should work correctly. + + ### Actual Behavior + The button does not respond to clicks. + output: + links: + - title: Simple Issue + url: ${{ steps['create-simple-issue'].output.issueUrl }} + +### Patch Changes + +- aee107b: Add `auto_init` option to `github:repo:create` action to create repository with an initial commit containing a README.md file + + This initial commit is created by GitHub itself and the commit is signed, so the repository will not be empty after creation. + + ```diff + - action: github:repo:create + id: init-new-repo + input: + repoUrl: 'github.com?repo=repo&owner=owner' + description: This is the description + visibility: private + + autoInit: true + + ``` + +- 6393b78: Add block creations field in github branch protection scaffolder actions + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-techdocs@1.15.0 + +### Minor Changes + +- a0b604c: Adding redirect handling for TechDocs URLs that reference entities that now reference an external entity for TechDocs. Including tests and documentation. + +### Patch Changes + +- 313cec7: Updated dependency `dompurify` to `^3.2.4`. +- 8d18d23: TechDocs page titles have been improved, especially for deeply nested pages. +- 1dfee19: Reverts a change in CSS layout that shifted the content of the Techdocs too far to the left. +- 4ce5831: Support Techdocs redirect with dompurify 3.2.6+ +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-auth-react@0.1.19 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/integration@1.18.0 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + - @backstage/plugin-search-react@1.9.4 + - @backstage/integration-react@1.2.10 + +## @backstage/plugin-techdocs-addons-test-utils@1.1.0 + +### Minor Changes + +- 72543e9: Adding catalogApiRef to test-utils to support catalog API usage by TechDocs reader page. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.15.0 + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-catalog@1.31.3 + - @backstage/core-app-api@1.19.0 + - @backstage/plugin-search-react@1.9.4 + - @backstage/integration-react@1.2.10 + +## @backstage/plugin-techdocs-backend@2.1.0 + +### Minor Changes + +- 063cdc5: Techdocs: support HumanDuration for cache TTL and timeout configuration +- a0b604c: Adding new entity that specifies an external entity in the techdocs-entity annotation and updates to documentation regarding TechDocs redirects. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-search-backend-module-techdocs@0.4.6 + - @backstage/plugin-techdocs-node@1.13.7 + +## @backstage/backend-app-api@1.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/backend-defaults@0.12.1 + +### Patch Changes + +- 33bd4d0: Deduplicate discovered features discovered with discoveryFeatureLoader + +- 4eda590: Fixed cache namespace and key prefix separator configuration to properly use configured values instead of hardcoded plugin ID. The cache manager now correctly combines the configured namespace with plugin IDs using the configured separator for Redis and Valkey. Memcache and memory store continue to use plugin ID as namespace. + +- f244e61: Add `backend.logger` config options to configure the `RootLoggerService`. + + Read more about the new configuration options in the + [Root Logger Service](https://backstage.io/docs/backend-system/core-services/root-logger/) + documentation. + +- Updated dependencies + - @backstage/config-loader@1.10.3 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-node@0.4.15 + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-app-api@1.2.7 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-permission-node@0.10.4 + +## @backstage/backend-dynamic-feature-service@0.7.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/config-loader@1.10.3 + - @backstage/plugin-catalog-backend@3.1.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-backend@0.5.6 + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-app-node@0.1.37 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-scaffolder-node@0.11.1 + - @backstage/plugin-search-backend-node@1.3.15 + +## @backstage/backend-openapi-utils@0.6.1 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/backend-plugin-api@1.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-node@0.10.4 + +## @backstage/cli@0.34.2 + +### Patch Changes + +- e6f45dc: Updated the WebPack configuration to use `contenthash`. This fixes an issue were builds would sometimes generate output files with the same name but different content across builds, leading to breakages when loading the frontend app. + +- fffd434: Disallow import fallback of critical shared dependencies in module federation. + +- 080f252: Fixed the `new-frontend-plugin` template that was incorrectly passing `id` instead of `pluginId` to `createFrontendPlugin` and unnecessarily importing `React`. + +- e0db9b8: Modify the `backstage.json` also for custom patterns if it extends the default pattern. + + Examples: + + - `@backstage/*` (default pattern) + - `@{backstage,backstage-community}/*` + - `@{extra1,backstage,extra2}/*` + +- 275bda8: Fixed an issue that could cause conflicts of detected modules in workspaces with multiple apps. + +- e1adce4: Updated the backend plugin template to use a new pattern for the `TodoListService` that reduces boilerplate. + +- Updated dependencies + - @backstage/config-loader@1.10.3 + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + +## @backstage/config-loader@1.10.3 + +### Patch Changes + +- a73f495: Allow using `BACKSTAGE_ENV` for loading environment specific config files +- Updated dependencies + - @backstage/types@1.2.2 + +## @backstage/core-compat-api@0.5.2 + +### Patch Changes + +- dc01d6f: Fix for `compatWrapper` creating many wrapping `Providers` when they should not +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + +## @backstage/create-app@0.7.4 + +### Patch Changes + +- b2d9fc1: Creates a plugin that redirects from the Home page to the Catalog index page to avoid seeing a not found page error when starting the app. +- 020d484: Bumped create-app version. +- 02dbe8e: Add missing dependency to `@backstage/cli`, `@backstage/core-plugin-api` and `@backstage/integration-react` + +## @backstage/dev-utils@1.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/app-defaults@1.7.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/core-app-api@1.19.0 + - @backstage/integration-react@1.2.10 + +## @backstage/frontend-defaults@0.3.1 + +### Patch Changes + +- 6516c3d: The default app now leverages the new error reporting functionality from `@backstage/frontend-app-api`. If there are critical errors during startup, an error screen that shows a summary of all errors will now be shown, rather than leaving the screen blank. Other errors will be logged as warnings in the console. +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-app@0.3.0 + - @backstage/core-components@0.18.0 + - @backstage/frontend-app-api@0.13.0 + +## @backstage/frontend-dynamic-feature-loader@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + +## @backstage/frontend-test-utils@0.3.6 + +### Patch Changes + +- 6516c3d: Internal update to use and throw app errors. +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-app@0.3.0 + - @backstage/frontend-app-api@0.13.0 + - @backstage/types@1.2.2 + +## @backstage/integration-react@1.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/integration@1.18.0 + +## @backstage/repo-tools@0.15.2 + +### Patch Changes + +- 133ac7a: Fixed knip-reports command failing when workspace path contains spaces and process termination issues by replacing `execFile` with `spawn` and removing `shell` option. +- Updated dependencies + - @backstage/config-loader@1.10.3 + - @backstage/backend-plugin-api@1.4.3 + +## @techdocs/cli@1.9.8 + +### Patch Changes + +- db63208: Fixed an issue where `@techdocs/cli serve` command did not pick up the latest changes to TechDocs. +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-techdocs-node@1.13.7 + +## @backstage/types@1.2.2 + +### Patch Changes + +- a95cebd: Internal refactoring for better type support + +## @backstage/ui@0.7.1 + +### Patch Changes + +- 7307930: Add missing class for flex: baseline +- 89da341: Fix Select component to properly attach aria-label and aria-labelledby props to the rendered element for improved accessibility. +- 0ffa4c7: Removed the need to mock `window.matchMedia` in tests, falling back to default breakpoint values instead. + +## @backstage/plugin-api-docs@0.12.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-catalog@1.31.3 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + +## @backstage/plugin-app-backend@0.5.6 + +### Patch Changes + +- afd368e: Internal update to not expose the old `createRouter`. +- Updated dependencies + - @backstage/config-loader@1.10.3 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-app-node@0.1.37 + +## @backstage/plugin-app-node@0.1.37 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.3 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-app-visualizer@0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + +## @backstage/plugin-auth-backend@0.25.4 + +### Patch Changes + +- 1d47bf3: Implementing Dynamic Client Registration with the OIDC server. You can enable this by setting `auth.experimentalDynamicClientRegistration.enabled` in `app-config.yaml`. This is highly experimental, but feedback welcome. +- 54ddfef: Updating plugin metadata +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.4 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.4 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-node@0.6.7 + +### Patch Changes + +- 54ddfef: Updating plugin metadata +- 3aff9e1: Changes OAuth cookies from domain-scoped to host-only by avoid setting the domain attribute in the default cookie configurer. +- Updated dependencies + - @backstage/catalog-client@1.12.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-auth-react@0.1.19 + +### Patch Changes + +- 54ddfef: Updating plugin metadata +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + +## @backstage/plugin-bitbucket-cloud-common@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + +## @backstage/plugin-catalog@1.31.3 + +### Patch Changes + +- 4316c11: Catalog table columns support i18n +- ce1239e: Auto-focus the first menu item in `EntityContextMenu`, and do not render a divider if an empty array is passed to `UNSTABLE_extraContextMenuItems`. +- 85c5e04: Fix incorrect `defaultTarget` on `createComponentRouteRef`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/core-compat-api@0.5.2 + - @backstage/plugin-search-react@1.9.4 + - @backstage/integration-react@1.2.10 + - @backstage/plugin-scaffolder-common@1.7.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-azure@0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-bitbucket-cloud-common@0.3.2 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/plugin-catalog-backend-module-github@0.11.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.3 + +### Patch Changes + +- ea80e76: When possible, requests a more limited set of results from the Gitlab projects API, which can reduce the amount of network traffic required to sync with Gitlab. +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.3 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-catalog-backend@3.1.0 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-logs@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.14 + +### Patch Changes + +- afd368e: **BREAKING ALPHA**: The module has been moved from the `/alpha` export to the root of the package. +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-common@1.7.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-catalog-import@0.13.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/integration@1.18.0 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + - @backstage/integration-react@1.2.10 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + +## @backstage/plugin-config-schema@0.1.72 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-devtools@0.1.31 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + +## @backstage/plugin-devtools-backend@0.5.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/config-loader@1.10.3 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-permission-node@0.10.4 + +## @backstage/plugin-events-backend@0.5.6 + +### Patch Changes + +- 0efcc97: Updated generated schemas +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.15 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-module-azure@0.2.24 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.24 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-module-gerrit@0.2.24 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-module-github@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-module-gitlab@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-module-kafka@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-events-backend-test-utils@0.1.48 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-events-node@0.4.15 + +### Patch Changes + +- 0efcc97: Updated generated schemas +- Updated dependencies + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-gateway-backend@1.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-home@0.8.12 + +### Patch Changes + +- 929c55a: Fixed race condition in CustomHomepageGrid by waiting for storage to load before rendering custom layout to prevent + rendering of the default content. +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + - @backstage/core-app-api@1.19.0 + - @backstage/plugin-home-react@0.1.30 + +## @backstage/plugin-home-react@0.1.30 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + +## @backstage/plugin-kubernetes@0.12.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + - @backstage/plugin-kubernetes-react@0.5.11 + +## @backstage/plugin-kubernetes-backend@0.20.2 + +### Patch Changes + +- dd7b6d2: Fix a bug where `getDefault` in the `kubernetesFetcherExtensionPoint` had the wrong `this` value +- 80cf8c9: Fix issue with default objects not being loaded properly +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/catalog-client@1.12.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-kubernetes-node@0.3.4 + - @backstage/plugin-permission-node@0.10.4 + +## @backstage/plugin-kubernetes-cluster@0.0.29 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/plugin-kubernetes-react@0.5.11 + +## @backstage/plugin-kubernetes-node@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-kubernetes-react@0.5.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-mcp-actions-backend@0.1.3 + +### Patch Changes + +- 1d47bf3: Proxy `/.well-known/oauth-authorization-server` to `/.well-known/openid-configuration` on `auth-backend` when `auth.experimentalDynamicClientRegistration.enabled` is enabled. +- 7f2a4a0: Updating docs +- d08b0c9: The MCP backend will now convert known Backstage errors into textual responses with `isError: true`. + The error message can be useful for an LLM to understand and maybe give back to the user. + Previously all errors where thrown out to `@modelcontextprotocol/sdk` which causes a generic 500. +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-notifications@0.5.9 + +### Patch Changes + +- 4815b12: Fixed missing app context when rendering the notifications view +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/core-compat-api@0.5.2 + +## @backstage/plugin-notifications-backend@0.5.10 + +### Patch Changes + +- a95cebd: Internal refactoring for better type support + +- 7e7ed57: A new extension point was added that can be used to modify how the users receiving notifications + are resolved. The interface passed to the extension point should only return complete user entity references + based on the notification target references and the excluded entity references. Note that the inputs are lists + of entity references that can be any entity kind, not just user entities. + + Using this extension point will override the default behavior of resolving users with the + `DefaultNotificationRecipientResolver`. + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/plugin-notifications-node@0.2.19 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-signals-node@0.1.24 + +## @backstage/plugin-notifications-backend-module-email@0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/types@1.2.2 + - @backstage/plugin-notifications-node@0.2.19 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-notifications-backend-module-slack@0.1.5 + +### Patch Changes + +- a95cebd: Internal refactoring for better type support +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/types@1.2.2 + - @backstage/plugin-notifications-node@0.2.19 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-notifications-node@0.2.19 + +### Patch Changes + +- 7e7ed57: A new extension point was added that can be used to modify how the users receiving notifications + are resolved. The interface passed to the extension point should only return complete user entity references + based on the notification target references and the excluded entity references. Note that the inputs are lists + of entity references that can be any entity kind, not just user entities. + + Using this extension point will override the default behavior of resolving users with the + `DefaultNotificationRecipientResolver`. + +- Updated dependencies + - @backstage/catalog-client@1.12.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-signals-node@0.1.24 + +## @backstage/plugin-org@0.6.44 + +### Patch Changes + +- 22b69f2: Fixing issue with extra slash in the routing +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + +## @backstage/plugin-org-react@0.1.42 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/core-components@0.18.0 + +## @backstage/plugin-permission-backend@0.7.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-permission-node@0.10.4 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.12 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-permission-node@0.10.4 + +## @backstage/plugin-permission-node@0.10.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-proxy-backend@0.6.6 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-proxy-node@0.1.8 + +## @backstage/plugin-proxy-node@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-scaffolder@1.34.1 + +### Patch Changes + +- 0d415ae: Render a TechDocs link on the Scaffolder Template List page when templates include either `backstage.io/techdocs-ref` or `backstage.io/techdocs-entity` annotations, using the shared `buildTechDocsURL` helper. Also adds tests to verify both annotations and optional `backstage.io/techdocs-entity-path` are respected. +- 7151260: Prevent the MultiEntityPicker from removing options present in form state when new options are selected +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/integration@1.18.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/core-compat-api@0.5.2 + - @backstage/plugin-scaffolder-react@1.19.1 + - @backstage/integration-react@1.2.10 + - @backstage/plugin-scaffolder-common@1.7.1 + +## @backstage/plugin-scaffolder-backend@2.2.1 + +### Patch Changes + +- a57185f: Added support for executing actions from the `ActionsRegistry` in the `scaffolder-backend` +- c3405db: Fixed a regression that prevented uploads greater than 100KB. Uploads up to 10MB are supported again. +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.0 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-node@0.4.15 + - @backstage/integration@1.18.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.5 + - @backstage/types@1.2.2 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-bitbucket-cloud-common@0.3.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.13 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.14 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.13 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.13 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.13 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.13 + - @backstage/plugin-scaffolder-common@1.7.1 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.13 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.13 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-bitbucket-cloud-common@0.3.2 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.5 + +### Patch Changes + +- a84ddea: The log message now indicates that the pipeline trigger token was deleted and not pipeline itself. +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.19 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.13 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.14 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + - @backstage/plugin-scaffolder-node-test-utils@0.3.3 + +## @backstage/plugin-scaffolder-common@1.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-scaffolder-node@0.11.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-common@1.7.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-test-utils@1.9.0 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-scaffolder-node@0.11.1 + +## @backstage/plugin-scaffolder-react@1.19.1 + +### Patch Changes + +- 58fc108: Fix scaffolder task log stream not having a minimum height +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/plugin-scaffolder-common@1.7.1 + +## @backstage/plugin-search@1.4.30 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/core-compat-api@0.5.2 + - @backstage/plugin-search-react@1.9.4 + +## @backstage/plugin-search-backend@2.0.6 + +### Patch Changes + +- 0efcc97: Updated generated schemas +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/types@1.2.2 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-search-backend-node@1.3.15 + +## @backstage/plugin-search-backend-module-catalog@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-search-backend-node@1.3.15 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.6 + +### Patch Changes + +- cde70ca: Added support for batchKeyField in the Elasticsearch indexer to allow consistent document IDs during bulk uploads. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-search-backend-node@1.3.15 + +## @backstage/plugin-search-backend-module-explore@0.3.7 + +### Patch Changes + +- 9a93520: Deprecate and mark explore collator as moved +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-search-backend-node@1.3.15 + +## @backstage/plugin-search-backend-module-pg@0.5.48 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-search-backend-node@1.3.15 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-search-backend-node@1.3.15 + +## @backstage/plugin-search-backend-module-techdocs@0.4.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/plugin-techdocs-node@1.13.7 + +## @backstage/plugin-search-backend-node@1.3.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-search-react@1.9.4 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-signals@0.0.23 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/core-compat-api@0.5.2 + +## @backstage/plugin-signals-backend@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-signals-node@0.1.24 + +## @backstage/plugin-signals-node@0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.28 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/integration@1.18.0 + - @backstage/core-components@0.18.0 + - @backstage/integration-react@1.2.10 + +## @backstage/plugin-techdocs-node@1.13.7 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0 + - @backstage/backend-plugin-api@1.4.3 + +## @backstage/plugin-techdocs-react@1.3.3 + +### Patch Changes + +- a0b604c: Update to documentation regarding TechDocs redirects. +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + +## @backstage/plugin-user-settings@0.8.26 + +### Patch Changes + +- 320a9ac: Add the OpenShift authenticator provider to the default `user-settings` providers page. +- b713b54: Tool-tip text correction for the Theme selection in settings page +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + - @backstage/core-compat-api@0.5.2 + - @backstage/core-app-api@1.19.0 + +## @backstage/plugin-user-settings-backend@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-signals-node@0.1.24 + +## example-app@0.2.113 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.2 + - @backstage/ui@0.7.1 + - @backstage/plugin-techdocs@1.15.0 + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-notifications@0.5.9 + - @backstage/app-defaults@1.7.0 + - @backstage/plugin-catalog-graph@0.5.0 + - @backstage/plugin-org@0.6.44 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/plugin-auth-react@0.1.19 + - @backstage/plugin-home@0.8.12 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-scaffolder@1.34.1 + - @backstage/plugin-user-settings@0.8.26 + - @backstage/plugin-catalog@1.31.3 + - @backstage/core-components@0.18.0 + - @backstage/frontend-app-api@0.13.0 + - @backstage/plugin-scaffolder-react@1.19.1 + - @backstage/core-app-api@1.19.0 + - @backstage/plugin-api-docs@0.12.11 + - @backstage/plugin-catalog-import@0.13.5 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21 + - @backstage/plugin-devtools@0.1.31 + - @backstage/plugin-kubernetes@0.12.11 + - @backstage/plugin-search@1.4.30 + - @backstage/plugin-search-react@1.9.4 + - @backstage/plugin-signals@0.0.23 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28 + - @backstage/integration-react@1.2.10 + - @backstage/plugin-kubernetes-cluster@0.0.29 + +## example-app-next@0.0.27 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.2 + - @backstage/ui@0.7.1 + - @backstage/plugin-techdocs@1.15.0 + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-notifications@0.5.9 + - @backstage/app-defaults@1.7.0 + - @backstage/plugin-catalog-graph@0.5.0 + - @backstage/plugin-org@0.6.44 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-auth-react@0.1.19 + - @backstage/plugin-auth@0.1.0 + - @backstage/plugin-home@0.8.12 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-scaffolder@1.34.1 + - @backstage/plugin-app@0.3.0 + - @backstage/plugin-user-settings@0.8.26 + - @backstage/plugin-catalog@1.31.3 + - @backstage/core-components@0.18.0 + - @backstage/frontend-app-api@0.13.0 + - @backstage/frontend-defaults@0.3.1 + - @backstage/core-compat-api@0.5.2 + - @backstage/plugin-scaffolder-react@1.19.1 + - @backstage/core-app-api@1.19.0 + - @backstage/plugin-api-docs@0.12.11 + - @backstage/plugin-app-visualizer@0.1.23 + - @backstage/plugin-catalog-import@0.13.5 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21 + - @backstage/plugin-kubernetes@0.12.11 + - @backstage/plugin-search@1.4.30 + - @backstage/plugin-search-react@1.9.4 + - @backstage/plugin-signals@0.0.23 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28 + - @backstage/integration-react@1.2.10 + - @backstage/plugin-kubernetes-cluster@0.0.29 + +## app-next-example-plugin@0.0.27 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-components@0.18.0 + +## example-backend@0.0.42 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.0 + - @backstage/plugin-scaffolder-backend@2.2.1 + - @backstage/plugin-catalog-backend@3.1.0 + - @backstage/plugin-mcp-actions-backend@0.1.3 + - @backstage/plugin-auth-backend@0.25.4 + - @backstage/plugin-techdocs-backend@2.1.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-app-backend@0.5.6 + - @backstage/plugin-kubernetes-backend@0.20.2 + - @backstage/plugin-events-backend@0.5.6 + - @backstage/plugin-search-backend@2.0.6 + - @backstage/plugin-search-backend-module-explore@0.3.7 + - @backstage/plugin-notifications-backend@0.5.10 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-auth-backend-module-github-provider@0.3.7 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.12 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.6 + - @backstage/plugin-catalog-backend-module-openapi@0.2.14 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.4 + - @backstage/plugin-devtools-backend@0.5.9 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.4 + - @backstage/plugin-permission-backend@0.7.4 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.12 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-proxy-backend@0.6.6 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.14 + - @backstage/plugin-search-backend-module-catalog@0.3.8 + - @backstage/plugin-search-backend-module-techdocs@0.4.6 + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/plugin-signals-backend@0.3.8 + +## e2e-test@0.2.32 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.4 + +## @internal/frontend@0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/types@1.2.2 + +## @internal/scaffolder@0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-scaffolder-react@1.19.1 + +## techdocs-cli-embedded-app@0.2.112 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.2 + - @backstage/plugin-techdocs@1.15.0 + - @backstage/app-defaults@1.7.0 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-catalog@1.31.3 + - @backstage/core-components@0.18.0 + - @backstage/core-app-api@1.19.0 + - @backstage/integration-react@1.2.10 + +## @internal/plugin-todo-list@1.0.43 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + +## @internal/plugin-todo-list-backend@1.0.43 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 diff --git a/docs/releases/v1.43.0-next.0-changelog.md b/docs/releases/v1.43.0-next.0-changelog.md new file mode 100644 index 0000000000..6ac9a5df04 --- /dev/null +++ b/docs/releases/v1.43.0-next.0-changelog.md @@ -0,0 +1,636 @@ +# Release v1.43.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.43.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.43.0-next.0) + +## @backstage/backend-test-utils@1.9.0-next.0 + +### Minor Changes + +- 4e2c237: The `mockServices.rootConfig()` instance now has an `update` method that can be used to test configuration subscriptions and updates. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@1.2.6 + - @backstage/backend-defaults@0.12.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-events-node@0.4.14 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.0-next.0 + +### Minor Changes + +- 577f0ed: **BREAKING**: Encode query filters for requests made to msgraph. If you currently have manually encoded characters in a filter, this is a breaking change and must be updated to avoid requests being double encoded. + + ```diff + user: + - filter: department in('MARKETING', 'RESEARCH %26 DEVELOPMENT') + + filter: department in('MARKETING', 'RESEARCH & DEVELOPMENT') + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.18.0 + +## @backstage/cli@0.34.1-next.0 + +### Patch Changes + +- 080f252: Fixed the `new-frontend-plugin` template that was incorrectly passing `id` instead of `pluginId` to `createFrontendPlugin` and unnecessarily importing `React`. +- 275bda8: Fixed an issue that could cause conflicts of detected modules in workspaces with multiple apps. +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.14 + - @backstage/config@1.3.3 + - @backstage/config-loader@1.10.2 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.11 + - @backstage/integration@1.17.1 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/core-compat-api@0.5.2-next.0 + +### Patch Changes + +- dc01d6f: Fix for `compatWrapper` creating many wrapping `Providers` when they should not +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.7.4-next.0 + +### Patch Changes + +- b2d9fc1: Creates a plugin that redirects from the Home page to the Catalog index page to avoid seeing a not found page error when starting the app. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/app-defaults@1.6.5 + - @backstage/catalog-model@1.7.5 + - @backstage/core-app-api@1.18.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8 + +## @backstage/plugin-api-docs@0.12.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog@1.31.3-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-catalog@1.31.3-next.0 + +### Patch Changes + +- ce1239e: Auto-focus the first menu item in `EntityContextMenu`, and do not render a divider if an empty array is passed to `UNSTABLE_extraContextMenuItems`. +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder-common@1.7.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.2 + +## @backstage/plugin-catalog-graph@0.4.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-import@0.13.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-react@1.20.2-next.0 + +### Patch Changes + +- ad0f58d: Support `default*` for older packages as this package is in range for breaking `/alpha` changes +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/frontend-test-utils@0.3.5 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + +## @backstage/plugin-devtools@0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-devtools-common@0.1.17 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-home@0.8.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/theme@0.6.8 + - @backstage/plugin-home-react@0.1.29 + +## @backstage/plugin-kubernetes@0.12.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-kubernetes-common@0.9.6 + - @backstage/plugin-kubernetes-react@0.5.10 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-kubernetes-backend@0.20.2-next.0 + +### Patch Changes + +- 80cf8c9: Fix issue with default objects not being loaded properly +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-kubernetes-common@0.9.6 + - @backstage/plugin-kubernetes-node@0.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.3 + +## @backstage/plugin-kubernetes-cluster@0.0.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-kubernetes-common@0.9.6 + - @backstage/plugin-kubernetes-react@0.5.10 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-notifications@0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-org@0.6.44-next.0 + +### Patch Changes + +- 22b69f2: Fixing issue with extra slash in the routing +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-org-react@0.1.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + +## @backstage/plugin-scaffolder@1.34.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder-common@1.7.0 + - @backstage/plugin-scaffolder-react@1.19.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/plugin-scaffolder-node-test-utils@0.3.3-next.0 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-test-utils@1.9.0-next.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-node@0.11.0 + +## @backstage/plugin-scaffolder-react@1.19.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder-common@1.7.0 + +## @backstage/plugin-search@1.4.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.3 + +## @backstage/plugin-search-backend-module-explore@0.3.6-next.0 + +### Patch Changes + +- 9a93520: Deprecate and mark explore collator as moved +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + - @backstage/config@1.3.3 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-signals@0.0.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-techdocs@1.14.2-next.0 + +### Patch Changes + +- 1dfee19: Reverts a change in CSS layout that shifted the content of the Techdocs too far to the left. +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.2 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.53-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.14.2-next.0 + - @backstage/plugin-catalog@1.31.3-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/test-utils@1.7.11 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-techdocs-react@1.3.2 + +## @backstage/plugin-user-settings@0.8.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-app-api@1.18.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.15 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.113-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.1-next.0 + - @backstage/plugin-org@0.6.44-next.0 + - @backstage/plugin-techdocs@1.14.2-next.0 + - @backstage/plugin-catalog@1.31.3-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/app-defaults@1.6.5 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-app-api@0.12.0 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8 + - @backstage/ui@0.7.0 + - @backstage/plugin-api-docs@0.12.11-next.0 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-graph@0.4.23-next.0 + - @backstage/plugin-catalog-import@0.13.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.0 + - @backstage/plugin-devtools@0.1.31-next.0 + - @backstage/plugin-home@0.8.12-next.0 + - @backstage/plugin-kubernetes@0.12.11-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.0 + - @backstage/plugin-notifications@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder@1.34.1-next.0 + - @backstage/plugin-scaffolder-react@1.19.1-next.0 + - @backstage/plugin-search@1.4.30-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-signals@0.0.23-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27 + - @backstage/plugin-techdocs-react@1.3.2 + - @backstage/plugin-user-settings@0.8.26-next.0 + +## example-app-next@0.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.1-next.0 + - @backstage/plugin-org@0.6.44-next.0 + - @backstage/plugin-techdocs@1.14.2-next.0 + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog@1.31.3-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/app-defaults@1.6.5 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-app-api@0.12.0 + - @backstage/frontend-defaults@0.3.0 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8 + - @backstage/ui@0.7.0 + - @backstage/plugin-api-docs@0.12.11-next.0 + - @backstage/plugin-app@0.2.0 + - @backstage/plugin-app-visualizer@0.1.22 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-graph@0.4.23-next.0 + - @backstage/plugin-catalog-import@0.13.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.0 + - @backstage/plugin-home@0.8.12-next.0 + - @backstage/plugin-kubernetes@0.12.11-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.0 + - @backstage/plugin-notifications@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder@1.34.1-next.0 + - @backstage/plugin-scaffolder-react@1.19.1-next.0 + - @backstage/plugin-search@1.4.30-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-signals@0.0.23-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27 + - @backstage/plugin-techdocs-react@1.3.2 + - @backstage/plugin-user-settings@0.8.26-next.0 + +## example-backend@0.0.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-explore@0.3.6-next.0 + - @backstage/plugin-kubernetes-backend@0.20.2-next.0 + - @backstage/backend-defaults@0.12.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-app-backend@0.5.5 + - @backstage/plugin-auth-backend@0.25.3 + - @backstage/plugin-auth-backend-module-github-provider@0.3.6 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.11 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-catalog-backend@3.0.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.5 + - @backstage/plugin-catalog-backend-module-openapi@0.2.13 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.3 + - @backstage/plugin-devtools-backend@0.5.8 + - @backstage/plugin-events-backend@0.5.5 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.3 + - @backstage/plugin-mcp-actions-backend@0.1.2 + - @backstage/plugin-notifications-backend@0.5.9 + - @backstage/plugin-permission-backend@0.7.3 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.11 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/plugin-proxy-backend@0.6.5 + - @backstage/plugin-scaffolder-backend@2.2.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.13 + - @backstage/plugin-search-backend@2.0.5 + - @backstage/plugin-search-backend-module-catalog@0.3.7 + - @backstage/plugin-search-backend-module-techdocs@0.4.5 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/plugin-signals-backend@0.3.7 + - @backstage/plugin-techdocs-backend@2.0.5 + +## e2e-test@0.2.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.4-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/scaffolder@0.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-scaffolder-react@1.19.1-next.0 + +## techdocs-cli-embedded-app@0.2.112-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.1-next.0 + - @backstage/plugin-techdocs@1.14.2-next.0 + - @backstage/plugin-catalog@1.31.3-next.0 + - @backstage/app-defaults@1.6.5 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/test-utils@1.7.11 + - @backstage/theme@0.6.8 + - @backstage/plugin-techdocs-react@1.3.2 diff --git a/docs/releases/v1.43.0-next.1-changelog.md b/docs/releases/v1.43.0-next.1-changelog.md new file mode 100644 index 0000000000..ba58b6e069 --- /dev/null +++ b/docs/releases/v1.43.0-next.1-changelog.md @@ -0,0 +1,1578 @@ +# Release v1.43.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.43.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.43.0-next.1) + +## @backstage/integration@1.18.0-next.0 + +### Minor Changes + +- 03bdc68: Added support for limiting GithubAppCredentialsMux to specific apps + +## @backstage/plugin-catalog-backend-module-github@0.11.0-next.0 + +### Minor Changes + +- 03bdc68: Added support for discovery by app + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.2-next.0 + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-techdocs-backend@2.1.0-next.0 + +### Minor Changes + +- 063cdc5: Techdocs: support HumanDuration for cache TTL and timeout configuration + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-techdocs-node@1.13.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.6-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/app-defaults@1.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.6-next.0 + +## @backstage/backend-app-api@1.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/backend-defaults@0.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/backend-app-api@1.2.7-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/backend-dynamic-feature-service@0.7.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.2-next.0 + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/plugin-events-backend@0.5.6-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + - @backstage/backend-openapi-utils@0.6.1-next.0 + - @backstage/plugin-app-node@0.1.37-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/backend-openapi-utils@0.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/backend-plugin-api@1.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + +## @backstage/backend-test-utils@1.9.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/backend-app-api@1.2.7-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/cli@0.34.2-next.1 + +### Patch Changes + +- e1adce4: Updated the backend plugin template to use a new pattern for the `TodoListService` that reduces boilerplate. +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + +## @backstage/core-compat-api@0.5.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + +## @backstage/core-components@0.17.6-next.0 + +### Patch Changes + +- e409bec: Fixes for rendering initials in the avatar component. + +## @backstage/create-app@0.7.4-next.1 + +### Patch Changes + +- 02dbe8e: Add missing dependency to `@backstage/cli`, `@backstage/core-plugin-api` and `@backstage/integration-react` + +## @backstage/dev-utils@1.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/core-components@0.17.6-next.0 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/app-defaults@1.6.6-next.0 + +## @backstage/frontend-app-api@0.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/frontend-defaults@0.3.1-next.0 + +## @backstage/frontend-defaults@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/frontend-app-api@0.12.1-next.0 + - @backstage/plugin-app@0.2.1-next.0 + +## @backstage/frontend-dynamic-feature-loader@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + +## @backstage/frontend-plugin-api@0.11.1-next.0 + +### Patch Changes + +- 2fb8b04: Improved the types of `createFrontendPlugin` and `createFrontendModule` so that errors due to incompatible options are indicated more clearly. +- Updated dependencies + - @backstage/core-components@0.17.6-next.0 + +## @backstage/frontend-test-utils@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/frontend-app-api@0.12.1-next.0 + - @backstage/plugin-app@0.2.1-next.0 + +## @backstage/integration-react@1.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + +## @backstage/repo-tools@0.15.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @techdocs/cli@1.9.8-next.0 + +### Patch Changes + +- db63208: Fixed an issue where `@techdocs/cli serve` command did not pick up the latest changes to TechDocs. +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-techdocs-node@1.13.7-next.0 + +## @backstage/plugin-api-docs@0.12.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/plugin-catalog@1.31.3-next.1 + +## @backstage/plugin-app@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/integration-react@1.2.10-next.0 + +## @backstage/plugin-app-backend@0.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-app-node@0.1.37-next.0 + +## @backstage/plugin-app-node@0.1.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-app-visualizer@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + +## @backstage/plugin-auth-backend@0.25.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-auth-backend@0.25.4-next.0 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-auth-backend@0.25.4-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-node@0.6.7-next.0 + +### Patch Changes + +- 3aff9e1: Changes OAuth cookies from domain-scoped to host-only by avoid setting the domain attribute in the default cookie configurer. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-auth-react@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.6-next.0 + +## @backstage/plugin-bitbucket-cloud-common@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog@1.31.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/plugin-scaffolder-common@1.7.1-next.0 + +## @backstage/plugin-catalog-backend@3.0.2-next.0 + +### Patch Changes + +- 37b4eaf: The 'get-catalog-entity' action now throws a ConflictError instead of generic Error if multiple entities are found, so MCP call doesn't fail with 500. +- a4c82ad: Only run provider orphan cleanup if the engine is started in the first place +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/backend-openapi-utils@0.6.1-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.4.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-azure@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/backend-openapi-utils@0.6.1-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.2-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.11.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.3-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.2-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-logs@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.2-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.7.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-catalog-graph@0.4.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + +## @backstage/plugin-catalog-import@0.13.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/integration-react@1.2.10-next.0 + +## @backstage/plugin-catalog-node@1.18.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + +## @backstage/plugin-catalog-react@1.20.2-next.1 + +### Patch Changes + +- 0174799: Fix a potential race condition in EntityListProvider when selecting filters +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/frontend-test-utils@0.3.6-next.0 + - @backstage/integration-react@1.2.10-next.0 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + +## @backstage/plugin-config-schema@0.1.72-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.6-next.0 + +## @backstage/plugin-devtools@0.1.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + +## @backstage/plugin-devtools-backend@0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + +## @backstage/plugin-events-backend@0.5.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/backend-openapi-utils@0.6.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-module-azure@0.2.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-module-github@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-module-kafka@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.48-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-events-node@0.4.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-gateway-backend@1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-home@0.8.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/plugin-home-react@0.1.30-next.0 + +## @backstage/plugin-home-react@0.1.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + +## @backstage/plugin-kubernetes@0.12.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/plugin-kubernetes-react@0.5.11-next.0 + +## @backstage/plugin-kubernetes-backend@0.20.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/plugin-kubernetes-node@0.3.4-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-kubernetes-cluster@0.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/core-components@0.17.6-next.0 + - @backstage/plugin-kubernetes-react@0.5.11-next.0 + +## @backstage/plugin-kubernetes-node@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-kubernetes-react@0.5.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.6-next.0 + +## @backstage/plugin-mcp-actions-backend@0.1.3-next.0 + +### Patch Changes + +- d08b0c9: The MCP backend will now convert known Backstage errors into textual responses with `isError: true`. + The error message can be useful for an LLM to understand and maybe give back to the user. + Previously all errors where thrown out to `@modelcontextprotocol/sdk` which causes a generic 500. +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-notifications@0.5.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + +## @backstage/plugin-notifications-backend@0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-signals-node@0.1.24-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + - @backstage/plugin-notifications-node@0.2.19-next.0 + +## @backstage/plugin-notifications-backend-module-email@0.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-notifications-node@0.2.19-next.0 + +## @backstage/plugin-notifications-backend-module-slack@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-notifications-node@0.2.19-next.0 + +## @backstage/plugin-notifications-node@0.2.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-signals-node@0.1.24-next.0 + +## @backstage/plugin-org@0.6.44-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + +## @backstage/plugin-org-react@0.1.42-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/core-components@0.17.6-next.0 + +## @backstage/plugin-permission-backend@0.7.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + +## @backstage/plugin-permission-node@0.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-proxy-backend@0.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-proxy-node@0.1.8-next.0 + +## @backstage/plugin-proxy-node@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder@1.34.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.1-next.1 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/plugin-scaffolder-common@1.7.1-next.0 + +## @backstage/plugin-scaffolder-backend@2.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.5-next.0 + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.2-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.14-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.3-next.0 + - @backstage/plugin-scaffolder-common@1.7.1-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12-next.0 + - @backstage/backend-openapi-utils@0.6.1-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.13-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.2-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.5-next.0 + +### Patch Changes + +- a84ddea: The log message now indicates that the pipeline trigger token was deleted and not pipeline itself. +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-notifications-node@0.2.19-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-scaffolder-node-test-utils@0.3.3-next.1 + +## @backstage/plugin-scaffolder-common@1.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-scaffolder-node@0.11.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-scaffolder-common@1.7.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/backend-test-utils@1.9.0-next.1 + +## @backstage/plugin-scaffolder-react@1.19.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/plugin-scaffolder-common@1.7.1-next.0 + +## @backstage/plugin-search@1.4.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + +## @backstage/plugin-search-backend@2.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + - @backstage/backend-openapi-utils@0.6.1-next.0 + +## @backstage/plugin-search-backend-module-catalog@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + +## @backstage/plugin-search-backend-module-explore@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + +## @backstage/plugin-search-backend-module-pg@0.5.48-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + +## @backstage/plugin-search-backend-module-techdocs@0.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.13.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + +## @backstage/plugin-search-backend-node@1.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-search-react@1.9.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + +## @backstage/plugin-signals@0.0.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + +## @backstage/plugin-signals-backend@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-signals-node@0.1.24-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-signals-node@0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## @backstage/plugin-techdocs@1.14.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/plugin-auth-react@0.1.19-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.53-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/plugin-catalog@1.31.3-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + - @backstage/plugin-techdocs@1.14.2-next.1 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/integration-react@1.2.10-next.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/integration-react@1.2.10-next.0 + +## @backstage/plugin-techdocs-node@1.13.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + +## @backstage/plugin-techdocs-react@1.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + +## @backstage/plugin-user-settings@0.8.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + +## @backstage/plugin-user-settings-backend@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-signals-node@0.1.24-next.0 + +## example-app@0.2.113-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/cli@0.34.2-next.1 + - @backstage/core-components@0.17.6-next.0 + - @backstage/frontend-app-api@0.12.1-next.0 + - @backstage/plugin-api-docs@0.12.11-next.1 + - @backstage/plugin-catalog@1.31.3-next.1 + - @backstage/plugin-catalog-graph@0.4.23-next.1 + - @backstage/plugin-catalog-import@0.13.5-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.1 + - @backstage/plugin-devtools@0.1.31-next.1 + - @backstage/plugin-home@0.8.12-next.1 + - @backstage/plugin-kubernetes@0.12.11-next.1 + - @backstage/plugin-notifications@0.5.9-next.1 + - @backstage/plugin-org@0.6.44-next.1 + - @backstage/plugin-scaffolder@1.34.1-next.1 + - @backstage/plugin-scaffolder-react@1.19.1-next.1 + - @backstage/plugin-search@1.4.30-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + - @backstage/plugin-signals@0.0.23-next.1 + - @backstage/plugin-techdocs@1.14.2-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28-next.0 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/plugin-user-settings@0.8.26-next.1 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/app-defaults@1.6.6-next.0 + - @backstage/plugin-auth-react@0.1.19-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.1 + +## example-app-next@0.0.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/cli@0.34.2-next.1 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/frontend-app-api@0.12.1-next.0 + - @backstage/frontend-defaults@0.3.1-next.0 + - @backstage/plugin-api-docs@0.12.11-next.1 + - @backstage/plugin-app@0.2.1-next.0 + - @backstage/plugin-app-visualizer@0.1.23-next.0 + - @backstage/plugin-catalog@1.31.3-next.1 + - @backstage/plugin-catalog-graph@0.4.23-next.1 + - @backstage/plugin-catalog-import@0.13.5-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.1 + - @backstage/plugin-home@0.8.12-next.1 + - @backstage/plugin-kubernetes@0.12.11-next.1 + - @backstage/plugin-notifications@0.5.9-next.1 + - @backstage/plugin-org@0.6.44-next.1 + - @backstage/plugin-scaffolder@1.34.1-next.1 + - @backstage/plugin-scaffolder-react@1.19.1-next.1 + - @backstage/plugin-search@1.4.30-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + - @backstage/plugin-signals@0.0.23-next.1 + - @backstage/plugin-techdocs@1.14.2-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28-next.0 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/plugin-user-settings@0.8.26-next.1 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/app-defaults@1.6.6-next.0 + - @backstage/plugin-auth-react@0.1.19-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.1 + +## app-next-example-plugin@0.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + +## example-backend@0.0.42-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.2-next.0 + - @backstage/plugin-techdocs-backend@2.1.0-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.3-next.0 + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.14-next.0 + - @backstage/plugin-scaffolder-backend@2.2.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-app-backend@0.5.6-next.0 + - @backstage/plugin-auth-backend@0.25.4-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.7-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.12-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.4-next.0 + - @backstage/plugin-kubernetes-backend@0.20.2-next.1 + - @backstage/plugin-notifications-backend@0.5.10-next.0 + - @backstage/plugin-permission-backend@0.7.4-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.12-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/plugin-signals-backend@0.3.8-next.0 + - @backstage/plugin-devtools-backend@0.5.9-next.0 + - @backstage/plugin-events-backend@0.5.6-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.4-next.0 + - @backstage/plugin-proxy-backend@0.6.6-next.0 + - @backstage/plugin-search-backend@2.0.6-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.14-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.6-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.6-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.8-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.7-next.1 + +## @internal/frontend@0.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + +## @internal/scaffolder@0.0.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/plugin-scaffolder-react@1.19.1-next.1 + +## techdocs-cli-embedded-app@0.2.112-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.2-next.1 + - @backstage/core-components@0.17.6-next.0 + - @backstage/plugin-catalog@1.31.3-next.1 + - @backstage/plugin-techdocs@1.14.2-next.1 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/app-defaults@1.6.6-next.0 + +## @internal/plugin-todo-list@1.0.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.6-next.0 + +## @internal/plugin-todo-list-backend@1.0.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 diff --git a/docs/releases/v1.43.0-next.2-changelog.md b/docs/releases/v1.43.0-next.2-changelog.md new file mode 100644 index 0000000000..ef7ddb1c1f --- /dev/null +++ b/docs/releases/v1.43.0-next.2-changelog.md @@ -0,0 +1,695 @@ +# Release v1.43.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.43.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.43.0-next.2) + +## @backstage/catalog-client@1.12.0-next.0 + +### Minor Changes + +- 0e9ec44: Introduced new `streamEntities` async generator method for the catalog. + + Catalog API and Catalog Service now includes a `streamEntities` method that allows for streaming entities from the catalog. + This method is designed to handle large datasets efficiently by processing entities in a stream rather than loading them + all into memory at once. This is useful when you need to fetch a large number of entities but do not want to use pagination + or fetch all entities at once. + + Example usage: + + ```ts + const pageStream = catalogClient.streamEntities({ pageSize: 100 }, { token }); + for await (const page of pageStream) { + // Handle page of entities + for (const entity of page) { + console.log(entity); + } + } + ``` + +## @backstage/plugin-auth@0.1.0-next.0 + +### Minor Changes + +- 54ddfef: Initial publish of the `auth` frontend package + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.6-next.1 + +## @backstage/plugin-catalog-node@1.19.0-next.1 + +### Minor Changes + +- 0e9ec44: Introduced new `streamEntities` async generator method for the catalog. + + Catalog API and Catalog Service now includes a `streamEntities` method that allows for streaming entities from the catalog. + This method is designed to handle large datasets efficiently by processing entities in a stream rather than loading them + all into memory at once. This is useful when you need to fetch a large number of entities but do not want to use pagination + or fetch all entities at once. + + Example usage: + + ```ts + const pageStream = catalogClient.streamEntities({ pageSize: 100 }, { token }); + for await (const page of pageStream) { + // Handle page of entities + for (const entity of page) { + console.log(entity); + } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + +## @backstage/plugin-catalog-react@1.21.0-next.2 + +### Minor Changes + +- 0e9ec44: Introduced new `streamEntities` async generator method for the catalog. + + Catalog API and Catalog Service now includes a `streamEntities` method that allows for streaming entities from the catalog. + This method is designed to handle large datasets efficiently by processing entities in a stream rather than loading them + all into memory at once. This is useful when you need to fetch a large number of entities but do not want to use pagination + or fetch all entities at once. + + Example usage: + + ```ts + const pageStream = catalogClient.streamEntities({ pageSize: 100 }, { token }); + for await (const page of pageStream) { + // Handle page of entities + for (const entity of page) { + console.log(entity); + } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/core-components@0.17.6-next.1 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/backend-defaults@0.12.1-next.1 + +### Patch Changes + +- 4eda590: Fixed cache namespace and key prefix separator configuration to properly use configured values instead of hardcoded plugin ID. The cache manager now correctly combines the configured namespace with plugin IDs using the configured separator for Redis and Valkey. Memcache and memory store continue to use plugin ID as namespace. +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/integration@1.18.0-next.0 + - @backstage/integration-aws-node@0.1.17 + +## @backstage/backend-dynamic-feature-service@0.7.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + - @backstage/backend-defaults@0.12.1-next.1 + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/plugin-catalog-backend@3.0.2-next.1 + - @backstage/plugin-app-node@0.1.37-next.1 + +## @backstage/cli@0.34.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + - @backstage/integration@1.18.0-next.0 + +## @backstage/config-loader@1.10.3-next.0 + +### Patch Changes + +- a73f495: Allow using `BACKSTAGE_ENV` for loading environment specific config files + +## @backstage/core-compat-api@0.5.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0-next.2 + +## @backstage/core-components@0.17.6-next.1 + +### Patch Changes + +- 1ad3d94: Dependency graph can now be opened in full screen mode +- ae7d426: update about card links style for pretty display with other language + +## @backstage/create-app@0.7.4-next.2 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/dev-utils@1.1.14-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + +## @backstage/repo-tools@0.15.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + +## @backstage/ui@0.7.1-next.0 + +### Patch Changes + +- 7307930: Add missing class for flex: baseline +- 89da341: Fix Select component to properly attach aria-label and aria-labelledby props to the rendered element for improved accessibility. + +## @backstage/plugin-api-docs@0.12.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/plugin-catalog@1.31.3-next.2 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-app-backend@0.5.6-next.1 + +### Patch Changes + +- afd368e: Internal update to not expose the old `createRouter`. +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/plugin-app-node@0.1.37-next.1 + +## @backstage/plugin-app-node@0.1.37-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + +## @backstage/plugin-auth-backend@0.25.4-next.1 + +### Patch Changes + +- 1d47bf3: Implementing Dynamic Client Registration with the OIDC server. You can enable this by setting `auth.experimentalDynamicClientRegistration.enabled` in `app-config.yaml`. This is highly experimental, but feedback welcome. +- 54ddfef: Updating plugin metadata +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-auth-node@0.6.7-next.1 + +### Patch Changes + +- 54ddfef: Updating plugin metadata +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + +## @backstage/plugin-auth-react@0.1.19-next.1 + +### Patch Changes + +- 54ddfef: Updating plugin metadata +- Updated dependencies + - @backstage/core-components@0.17.6-next.1 + +## @backstage/plugin-catalog@1.31.3-next.2 + +### Patch Changes + +- 85c5e04: Fix incorrect `defaultTarget` on `createComponentRouteRef`. +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-catalog-backend@3.0.2-next.1 + +### Patch Changes + +- 2204f5b: Prevent deadlock in catalog deferred stitching +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.4.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.1 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + - @backstage/integration-aws-node@0.1.17 + +## @backstage/plugin-catalog-backend-module-azure@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.11.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.2-next.1 + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/plugin-catalog-backend-module-github@0.11.0-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.1 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/plugin-catalog-backend-module-gitlab@0.7.3-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.1 + - @backstage/plugin-catalog-backend@3.0.2-next.1 + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.14-next.1 + +### Patch Changes + +- afd368e: **BREAKING ALPHA**: The module has been moved from the `/alpha` export to the root of the package. +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-catalog-graph@0.4.23-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-catalog-import@0.13.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-devtools-backend@0.5.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + - @backstage/backend-defaults@0.12.1-next.1 + +## @backstage/plugin-home@0.8.12-next.2 + +### Patch Changes + +- 929c55a: Fixed race condition in CustomHomepageGrid by waiting for storage to load before rendering custom layout to prevent + rendering of the default content. +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-kubernetes@0.12.11-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-kubernetes-backend@0.20.2-next.2 + +### Patch Changes + +- dd7b6d2: Fix a bug where `getDefault` in the `kubernetesFetcherExtensionPoint` had the wrong `this` value +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration-aws-node@0.1.17 + +## @backstage/plugin-kubernetes-cluster@0.0.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + +## @backstage/plugin-mcp-actions-backend@0.1.3-next.1 + +### Patch Changes + +- 1d47bf3: Proxy `/.well-known/oauth-authorization-server` to `/.well-known/openid-configuration` on `auth-backend` when `auth.experimentalDynamicClientRegistration.enabled` is enabled. +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.1 + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-notifications-backend@0.5.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/plugin-notifications-node@0.2.19-next.1 + +## @backstage/plugin-notifications-backend-module-email@0.3.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-notifications-node@0.2.19-next.1 + +## @backstage/plugin-notifications-backend-module-slack@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/plugin-notifications-node@0.2.19-next.1 + +## @backstage/plugin-notifications-node@0.2.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + +## @backstage/plugin-org@0.6.44-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-org-react@0.1.42-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + +## @backstage/plugin-scaffolder@1.34.1-next.2 + +### Patch Changes + +- 0d415ae: Render a TechDocs link on the Scaffolder Template List page when templates include either `backstage.io/techdocs-ref` or `backstage.io/techdocs-entity` annotations, using the shared `buildTechDocsURL` helper. Also adds tests to verify both annotations and optional `backstage.io/techdocs-entity-path` are respected. +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/plugin-scaffolder-react@1.19.1-next.2 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-scaffolder-backend@2.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.1 + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.3-next.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + +## @backstage/plugin-scaffolder-react@1.19.1-next.2 + +### Patch Changes + +- 58fc108: Fix scaffolder task log stream not having a minimum height +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + +## @backstage/plugin-search@1.4.30-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-search-backend-module-catalog@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-search-backend-module-techdocs@0.4.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + +## @backstage/plugin-techdocs@1.14.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-react@0.1.19-next.1 + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-compat-api@0.5.2-next.2 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.53-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/plugin-catalog@1.31.3-next.2 + - @backstage/plugin-techdocs@1.14.2-next.2 + +## @backstage/plugin-techdocs-backend@2.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.1 + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.6-next.1 + +## @backstage/plugin-user-settings@0.8.26-next.2 + +### Patch Changes + +- b713b54: Tool-tip text correction for the Theme selection in settings page +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/core-compat-api@0.5.2-next.2 + +## example-app@0.2.113-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.1-next.0 + - @backstage/plugin-auth-react@0.1.19-next.1 + - @backstage/plugin-home@0.8.12-next.2 + - @backstage/plugin-scaffolder@1.34.1-next.2 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/plugin-user-settings@0.8.26-next.2 + - @backstage/plugin-scaffolder-react@1.19.1-next.2 + - @backstage/plugin-catalog@1.31.3-next.2 + - @backstage/cli@0.34.2-next.2 + - @backstage/plugin-catalog-graph@0.4.23-next.2 + - @backstage/plugin-catalog-import@0.13.5-next.2 + - @backstage/plugin-org@0.6.44-next.2 + - @backstage/plugin-techdocs@1.14.2-next.2 + - @backstage/plugin-api-docs@0.12.11-next.2 + - @backstage/plugin-kubernetes@0.12.11-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.2 + - @backstage/plugin-search@1.4.30-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28-next.0 + +## example-app-next@0.0.27-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.1-next.0 + - @backstage/plugin-auth-react@0.1.19-next.1 + - @backstage/plugin-auth@0.1.0-next.0 + - @backstage/plugin-home@0.8.12-next.2 + - @backstage/plugin-scaffolder@1.34.1-next.2 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/plugin-user-settings@0.8.26-next.2 + - @backstage/plugin-scaffolder-react@1.19.1-next.2 + - @backstage/plugin-catalog@1.31.3-next.2 + - @backstage/cli@0.34.2-next.2 + - @backstage/plugin-catalog-graph@0.4.23-next.2 + - @backstage/plugin-catalog-import@0.13.5-next.2 + - @backstage/plugin-org@0.6.44-next.2 + - @backstage/plugin-techdocs@1.14.2-next.2 + - @backstage/core-compat-api@0.5.2-next.2 + - @backstage/plugin-api-docs@0.12.11-next.2 + - @backstage/plugin-kubernetes@0.12.11-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.2 + - @backstage/plugin-search@1.4.30-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28-next.0 diff --git a/docs/releases/v1.43.0.md b/docs/releases/v1.43.0.md new file mode 100644 index 0000000000..449023d167 --- /dev/null +++ b/docs/releases/v1.43.0.md @@ -0,0 +1,90 @@ +--- +id: v1.43.0 +title: v1.43.0 +description: Backstage Release v1.43.0 +--- + +These are the release notes for the v1.43.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### **BREAKING:** MSgraph catalog module encoding queries + +The catalog MSgraph module now properly encodes filter queries before they are sent to the remote system. This fixes some confusion in how to properly write queries–and thus simplifies operations for users. However, it does mean that if you use the `@backstage/plugin-catalog-backend-module-msgraph` module, you will have to update your `filter` parameters to be just plain text without any manual encoding. Example: + +```diff + user: +- filter: department in('MARKETING', 'R %26 D') ++ filter: department in('MARKETING', 'R & D') +``` + +Contributed by [@stephenglass](https://github.com/stephenglass) in [#30567](https://github.com/backstage/backstage/pull/30567) + +### OpenShift auth + +Backstage now supports OpenShift as an auth provider! This was a long standing PR that we are very excited to have merged into the project. Go [check out the docs](https://backstage.io/docs/auth/openshift/provider) for it! + +Contributed by [@ioboi](https://github.com/ioboi) in [#29470](https://github.com/backstage/backstage/pull/29470) + +### Improved app error display for new frontend system + +If the frontend app encounters one or more critical errors during startup they are now displayed on an error page that summarizes the errors and their source. This is in contrast to before this change, where errors would result in a blank page with the first error logged to the console. + +Some more errors have also been moved to be warnings, which will be logged in the console regardless of whether the app starts up or not. + +### Actions Registry integration with the Scaffolder + +Actions which are registered in the Actions Registry are now also available in Scaffolder templates. You will be able to browse the actions and see the schema like the original Scaffolder Templating Actions, as well as being able to use `action: acme:my-action` inside template steps to call these distributed actions. + +### _Experimental_: Dynamic Client Registration support for MCP Actions Backend + +We’ve shipped experimental support for allowing the `auth-backend` to issue tokens on behalf of users for use in MCP Clients such as Claude and Cursor. This is highly experimental, and tokens are only valid for 1 hour currently. We’re eager to get some feedback on this feature, so if you would like to try it out you can check out the [mcp-actions docs](https://github.com/backstage/backstage/blob/master/plugins/mcp-actions-backend/README.md#experimental-dynamic-client-registration) and leave us some feedback in a [GitHub issue](https://github.com/backstage/backstage/issues/new), or on our [Community Discord](https://discord.gg/backstage-687207715902193673)! + +### Introducing `BACKSTAGE_ENV` + +The Backstage configuration system now pays attention to the `BACKSTAGE_ENV` environment variable, and uses it to locate config files to load without you having to manually specify `--config` flags at startup. This makes it even smoother to leverage e.g. `app-config.production.yaml` files in your production environment. + +Check out [the updated documentation](https://backstage.io/docs/conf/) for more information. + +Contributed by [@drodil](https://github.com/drodil) in [#30722](https://github.com/backstage/backstage/pull/30722) + +### Backend logger configuration + +It is now possible to configure log level, meta, and log level overrides through static configuration. This allows you to raise or lower the log level for individual plugins or services. But it also allows you to match on any log field using either exact matches or regular expressions. Read more about the new configuration options in the [Root Logger Service](https://backstage.io/docs/backend-system/core-services/root-logger/) documentation. + +Contributed by [@tcardonne](https://github.com/tcardonne) in [#30727](https://github.com/backstage/backstage/pull/30727) + +### Toggling and priorities for catalog features + +You are now able to enable/disable individual processors and providers in your catalog, directly through your app config. You can also affect the order in which processors run, by assigning them priorities. + +Contributed by [@drodil](https://github.com/drodil) in [#31034](https://github.com/backstage/backstage/pull/31034) and [#30969](https://github.com/backstage/backstage/pull/30969) + +### Moved the Explore search module + +Just a quick note, that the search collator module for the `explore` plugin was moved to the community repository, where it fits snugly next to the plugin itself. If you are using the yarn plugin, these references should be updated automatically for you. But if you do not, just update your dependencies on `@backstage/plugin-search-backend-module-explore`, to `@backstage-community/plugin-search-backend-module-explore`. + +## Security Fixes + +This release does not contain any security fixes. However, it is worth calling out that OAuth cookies issued by the auth backend have changed from domain-scoped to host-only. + +Contributed by [@JessicaJHee](https://github.com/JessicaJHee) in [#30922](https://github.com/backstage/backstage/pull/30922) + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.43.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.44.0-changelog.md b/docs/releases/v1.44.0-changelog.md new file mode 100644 index 0000000000..c188973af5 --- /dev/null +++ b/docs/releases/v1.44.0-changelog.md @@ -0,0 +1,2259 @@ +# Release v1.44.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.44.0](https://backstage.github.io/upgrade-helper/?to=1.44.0) + +## @backstage/plugin-scaffolder-backend@3.0.0 + +### Major Changes + +- 9b81a90: **BREAKING** - Removing the deprecated types and interfaces, there's no replacement for these types, and hopefully not currently used as they offer no value with the plugin being on the new backend system and no way to consume them. + + Affected types: `CreateWorkerOptions`, `CurrentClaimedTask`, `DatabaseTaskStore`, `DatabaseTaskStoreOptions`, `TaskManager`, `TaskStore`, `TaskStoreCreateTaskOptions`, `TaskStoreCreateTaskResult`, `TaskStoreEmitOptions`, `TaskStoreListEventsOptions`, `TaskStoreRecoverTaskOptions`, `TaskStoreShutDownTaskOptions`, `TaskWorker` and `TemplateActionRegistry`. + +### Patch Changes + +- f222a2e: Fixed distributed actions not being visible in the scaffolder template actions. + + Depending on the plugin startup order, some of the distributed actions were not being registered correctly, + causing them to be invisible in the scaffolder template actions list. + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.14 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.15 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.14 + - @backstage/plugin-scaffolder-backend-module-github@0.9.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.6 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.14 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.14 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/plugin-bitbucket-cloud-common@0.3.3 + - @backstage/backend-openapi-utils@0.6.2 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + - @backstage/plugin-scaffolder-common@1.7.2 + +## @backstage/backend-defaults@0.13.0 + +### Minor Changes + +- 2d3e2b2: implement support for direct url for AzureBlobStorageUrlReader search function + +- 8b91238: Adds support for configuring server-level HTTP options through the + `app-config.yaml` file under the `backend.server` key. Supported options + include `headersTimeout`, `keepAliveTimeout`, `requestTimeout`, `timeout`, + `maxHeadersCount`, and `maxRequestsPerSocket`. + + These are passed directly to the underlying Node.js HTTP server. + If omitted, Node.js defaults are used. + +- 8495b18: Add a new `externalTokenHandlersServiceRef` to allow custom external token validations + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@1.2.8 + - @backstage/integration@1.18.1 + - @backstage/config-loader@1.10.5 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/integration-aws-node@0.1.18 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-permission-node@0.10.5 + +## @backstage/frontend-test-utils@0.4.0 + +### Minor Changes + +- c41dd80: **BREAKING**: Removed the `extensions` option from `renderInTestApp`. If you need to pass extensions to the test app, use the new `renderTestApp` utility instead. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.3.1 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/config@1.3.5 + - @backstage/frontend-app-api@0.13.1 + - @backstage/test-utils@1.7.12 + +## @techdocs/cli@1.10.0 + +### Minor Changes + +- 43afbe5: Techdocs CLI serve supports automatic refresh, relying on `mkdocs` `watch` feature. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/config@1.3.5 + - @backstage/plugin-techdocs-node@1.13.8 + +## @backstage/theme@0.7.0 + +### Minor Changes + +- 865bce8: **BREAKING**: Removed the built-in `CssBaseline` from `UnifiedThemeProvider`. If your Backstage instance looks broken after this update, you likely forgot to add our new Backstage UI global CSS. To do that, please import `@backstage/ui/css/styles.css` in `packages/app/src/index.tsx`: + + ```tsx + import '@backstage/ui/css/styles.css'; + ``` + + This change also removes the `noCssBaseline` prop, which became redundant. + +### Patch Changes + +- d5cbdba: The `UnifiedThemeProvider` now coordinates theme attributes on the document `body` in case multiple theme providers are rendered. + +## @backstage/ui@0.8.0 + +### Minor Changes + +- 9acc1d6: **BREAKING**: Added a new `PasswordField` component. As part of this change, the `password` and `search` types have been removed from `TextField`. +- b0d11b5: **BREAKING** Restructure Backstage UI component styling to use CSS Modules instead of pure CSS. We don't expect this to be an issue in practice but it is important to call out that all styles are now loaded through CSS modules with generated class names. We are still providing fixed class names for all components to allow anyone to style their Backstage instance. +- 0c53517: **BREAKING** The ScrollArea component has been removed from Backstage UI because it did not meet our accessibility standards. +- 7b319c5: **BREAKING** Remove Icon component in Backstage UI. This component was creating issue for tree-shaking. It is recommended to use icons from @remixicon/react until we found a better alternative in Backstage UI. + +### Patch Changes + +- 2591b42: Adding a new Dialog component to Backstage UI. +- 827340f: remove default selection of tab +- 5dc17cc: Fix margin utility classes in Backstage UI. +- 85faee0: Fix scroll jumping when opening menu in Backstage UI. +- 3c921c5: Making href mandatory in tabs that are part of a Header component +- df7d2cf: Update react-aria-components to version 1.13.0 +- 507ee55: Fix table sorting icon position in Backstage UI. +- 8b7c3c9: Add new `virtualized`, `maxWidth` and `maxHeight` props to `Menu`, `MenuListBox`, `MenuAutocomplete` and `MenuAutocompleteListBox` to allow for virtalization of long lists inside menus. +- b940062: Added support for data attributes in ``, ``, ``, and `` components, ensuring they are correctly applied to the rendered elements. +- 206c801: Cleaning up Backstage UI props definitions as well as removing ScrollArea in Card to improve accessibility. +- 5c21e45: Add react router for internal routing for ButtonLinks +- 865bce8: Added a background color default on the body +- af4d9b4: We are restructuring our CSS to have a better layer structure. +- 9a47125: Improved SearchField component flex layout and animations. Fixed SearchField behavior in Header components by switching from width-based transitions to flex-basis transitions for better responsive behavior. Added new Storybook stories to test SearchField integration with Header component. +- 9781815: Remove auto selection of tabs for tabs that all have href defined +- 4adbb03: Avoid overriding onChange when spreading props +- f6dff5b: Using react router for internal links in the Menu component + +## @backstage/plugin-api-docs@0.13.0 + +### Minor Changes + +- b8a381e: Remove explicit dependency on `isomorphic-form-data`. + + This explicit dependency was added to address [an issue](https://github.com/swagger-api/swagger-ui/issues/7436) in the + dependency `swagger-ui-react`. That [issue has since been resolved](https://github.com/swagger-api/swagger-ui/issues/7436#issuecomment-889792304), + and `isomorphic-form-data` no longer needs to be declared. + + Additionally, this changeset updates the `swagger-ui-react` dependency to version `5.19.0` or higher, which includes + [compatibility](https://github.com/swagger-api/swagger-ui?tab=readme-ov-file#compatibility) with the latest versions of + the OpenAPI specification. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-compat-api@0.5.3 + - @backstage/plugin-catalog@1.31.4 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-permission-react@0.4.37 + +## @backstage/plugin-mui-to-bui@0.2.0 + +### Minor Changes + +- d5cbdba: This is the first release of the Material UI to Backstage UI migration helper plugin. It adds a new page at `/mui-to-bui` that converts an existing MUI v5 theme into Backstage UI (BUI) CSS variables, with live preview and copy/download. + +### Patch Changes + +- 28ee81c: Fix invalid conversion for `--bui-bg` variable +- Updated dependencies + - @backstage/ui@0.8.0 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/theme@0.7.0 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-notifications-backend-module-slack@0.2.0 + +### Minor Changes + +- 3d09bb2: Adds username as optional config in order to send Slack notifications with a specific username in the case when using one Slack App for more than just Backstage. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-notifications-common@0.1.1 + - @backstage/plugin-notifications-node@0.2.20 + +## @backstage/plugin-scaffolder-node@0.12.0 + +### Minor Changes + +- 9b81a90: **BREAKING** - Marking optional fields as required in the `TaskBroker`, these can be fixed with a no-op `() => void` if you don't want to implement the functions. + + - `cancel`, `recoverTasks` and `retry` are the required methods on the `TaskBroker` interface. + + **NOTE**: If you're affected by this breaking change, please reach out to us in an issue as we're thinking about completely removing the `TaskBroker` extension point soon and would like to hear your use cases for the upcoming re-architecture of the `scaffolder-backend` plugin. + +### Patch Changes + +- c8aa210: **BREAKING ALPHA**: We've moved the `scaffolderActionsExtensionPoint` from `/alpha` to the main export. + + ```tsx + // before + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; + + // after + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node'; + ``` + +- 6e2bda7: **DEPRECATION**: We're going to be working on refactoring a lot of the internals of the Scaffolder backend plugin, and with that comes a lot of deprecations and removals for public types that are making these things hard. + + If you're using these types, please reach out to us either on Discord or a GitHub issue with your use cases. + + - `SerializedTask`, `SerializedTaskEvent`, `TaskBroker`, `TaskContext`, `TaskBrokerDispatchOptions`, `TaskBrokerDispatchResult`, `TaskCompletionState`, `TaskEventType`, `TaskFilter`, `TaskFilters`, `TaskStatus` are the types that have now been marked as deprecated, and will be removed in a future release. + +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-scaffolder-common@1.7.2 + +## @backstage/app-defaults@1.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/theme@0.7.0 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-permission-react@0.4.37 + +## @backstage/backend-app-api@1.2.8 + +### Patch Changes + +- dd69cf6: Moved up registration of unhandled rejections and errors listeners to be done as early as possible, avoiding flakiness in backend startups and instead always logging these failures rather than sometimes crashing the process. +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/backend-dynamic-feature-service@0.7.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.2 + - @backstage/backend-defaults@0.13.0 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config-loader@1.10.5 + - @backstage/config@1.3.5 + - @backstage/backend-openapi-utils@0.6.2 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-app-node@0.1.38 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-events-backend@0.5.7 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/backend-openapi-utils@0.6.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/backend-plugin-api@1.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + +## @backstage/backend-test-utils@1.9.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/backend-app-api@1.2.8 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/cli@0.34.4 + +### Patch Changes + +- f2cf564: Removed the script transform cache from the default Jest configuration. The script cache provided a moderate performance boost, but it is incompatible with Jest 30. + +- 33faad2: Allow using custom manifest location in the yarn plugin and version bump. + + The Backstage yarn plugin and version bump allows two new environment variables to configure custom manifest location: + + - `BACKSTAGE_VERSIONS_BASE_URL`: The base URL for fetching the Backstage version + manifest. Defaults to `https://versions.backstage.io/v1/releases/VERSION/manifest.json`. + Useful for running the plugin in environment without direct access to the internet, + for example by using a mirror of the versions API or a proxy. + Note that the environment variable is just the host name, and the path is appended by + the plugin. If you are using the yarn plugin, bump version command will also try + to fetch the new version of the yarn plugin from the same base URL (defaults to + `https://versions.backstage.io/v1/releases/RELEASE/yarn-plugin`) + - `BACKSTAGE_MANIFEST_FILE`: Path to a local manifest file. If set, the plugin + will not attempt to fetch the manifest from the network. Useful for running + the plugin in environment without internet access and without mirror of the + versions API. + +- 6ebc1ea: Fixed module federation config by only setting `import: false` on shared libraries for remote. + +- ab96bb7: Added a new `--entrypoint` option to the `package start` command, which allows you to specify a custom entry directory/file for development applications. This is particularly useful when maintaining separate dev apps for different versions of your plugin (e.g., stable and alpha). + + **Example usage:** + + Consider the following plugin dev folder structure: + + dev/ + index.tsx + alpha/ + index.ts + + - The default `yarn package start` command uses the `dev/` folder as the entry point and executes `dev/index.tsx` file; + - Running `yarn package start --entrypoint dev/alpha` will instead use `dev/alpha/` as the entry point and execute `dev/alpha/index.ts` file. + +- 024645e: Remove unused @octokit modules from cli package + + - @octokit/graphql + - @octokit/graphql-schema + - @octokit/oauth-app + +- d14ef24: Added automatic detection and support for the Backstage Yarn plugin when generating new packages with `yarn new`. When the plugin is installed, new packages will automatically use `backstage:^` ranges for `@backstage/*` dependencies. + +- Updated dependencies + - @backstage/eslint-plugin@0.1.12 + - @backstage/integration@1.18.1 + - @backstage/config-loader@1.10.5 + - @backstage/config@1.3.5 + +## @backstage/config@1.3.5 + +### Patch Changes + +- b45b094: Allow colon to be used as config key. + +## @backstage/config-loader@1.10.5 + +### Patch Changes + +- b45b094: Allow colon to be used as config key. +- Updated dependencies + - @backstage/config@1.3.5 + +## @backstage/core-app-api@1.19.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/core-compat-api@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/core-components@0.18.2 + +### Patch Changes + +- d493126: Swap base token for semantic token in ItemCardHeader to ensure readability in light mode. +- 431130c: Added `renderEdge` prop to `` component in `@backstage/core-components` to allow custom rendering of graph edges. +- 6981ae6: Fixed DependencyGraph `svg` size not adapting to the container size +- 95935fb: Fixed dependency graph automatically scrolling forever +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/theme@0.7.0 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/core-plugin-api@1.11.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + +## @backstage/create-app@0.7.5 + +### Patch Changes + +- c73bfa4: Bumped create-app version. +- c2c6054: Bumped create-app version. +- ffb5b44: Bumped create-app version. +- 316d077: Bumped create-app version. +- 7dcedff: Bump `better-sqlite3` to the latest version + +## @backstage/dev-utils@1.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/theme@0.7.0 + - @backstage/app-defaults@1.7.1 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + +## @backstage/eslint-plugin@0.1.12 + +### Patch Changes + +- 5e98e61: Minor doc updates +- a1dae71: Allow frontend plugin to import from another frontend plugin with same plugin id. + + This prevents the ESLint rule from incorrectly flagging these imports in the new frontend system + where plugin override requires cross-plugin imports. + +## @backstage/frontend-app-api@0.13.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/config@1.3.5 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/frontend-defaults@0.3.2 + +## @backstage/frontend-defaults@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/plugin-app@0.3.1 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/config@1.3.5 + - @backstage/frontend-app-api@0.13.1 + +## @backstage/frontend-dynamic-feature-loader@0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/config@1.3.5 + +## @backstage/frontend-plugin-api@0.12.1 + +### Patch Changes + +- 8ed53eb: Added `coreExtensionData.title`, especially useful for creating extensible layout with tabbed pages, but available for use for other cases too. +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/integration@1.18.1 + +### Patch Changes + +- d772b51: remove host from azure blob storage integration type +- 84443f1: Adds config definitions for Azure Blob Storage. +- Updated dependencies + - @backstage/config@1.3.5 + +## @backstage/integration-aws-node@0.1.18 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + +## @backstage/integration-react@1.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/repo-tools@0.15.3 + +### Patch Changes + +- 1359279: Fixed an issue with the OpenAPI generated client and server where import/export statements were duplicated. +- Updated dependencies + - @backstage/config-loader@1.10.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/test-utils@1.7.12 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/theme@0.7.0 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-react@0.4.37 + +## @backstage/plugin-app@0.3.1 + +### Patch Changes + +- ae1dad0: Fixed an issue that caused the `NotFound` page to not render correctly when a Page was mounted at `/`. +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/theme@0.7.0 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-permission-react@0.4.37 + +## @backstage/plugin-app-backend@0.5.7 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.5 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-app-node@0.1.38 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-app-node@0.1.38 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-app-visualizer@0.1.24 + +### Patch Changes + +- 4406144: Ensure that the text rendering has react keys for all elements +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-auth@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/theme@0.7.0 + +## @backstage/plugin-auth-backend@0.25.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-backend@0.25.5 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.8 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.8 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-backend@0.25.5 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-openshift-provider@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + +## @backstage/plugin-auth-node@0.6.8 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-auth-react@0.1.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-bitbucket-cloud-common@0.3.3 + +### Patch Changes + +- 2aded73: Allow for passing a `pagelen` parameter to configure the `pagelength` property of the `BitbucketCloudEntityProvider` `searchCode` pagination to resolve [bug](https://jira.atlassian.com/browse/BCLOUD-23644) pertaining to duplicate results being returned. +- Updated dependencies + - @backstage/integration@1.18.1 + +## @backstage/plugin-catalog@1.31.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/plugin-search-react@1.9.5 + - @backstage/core-compat-api@0.5.3 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-permission-react@0.4.37 + - @backstage/plugin-scaffolder-common@1.7.2 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-catalog-backend@3.1.2 + +### Patch Changes + +- 9890488: Internal refactor to remove remnants of the old backend system + +- 6493c98: Log before provider-orphaning eviction happens + +- 2aaf01a: Fix for duplicate search results in entity-facets API call + +- e489661: Moved catalog processor and provider disabling and priorities under own config objects. + + This is due to issue with some existing providers, such as GitHub, using array syntax for the provider configuration. + + The new config format is not backwards compatible, so users will need to update their config files. The new format + is as follows: + + ```yaml + catalog: + providerOptions: + providerA: + disabled: false + providerB: + disabled: true + processorOptions: + processorA: + disabled: false + priority: 10 + processorB: + disabled: true + ``` + +- 77516c5: Added new `catalog:validate-entity` action to actions registry. + + This action can be used to validate entities against the software catalog. + This is useful for validating `catalog-info.yaml` file changes locally using the + Backstage MCP server. + +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-openapi-utils@0.6.2 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + +## @backstage/plugin-catalog-backend-module-aws@0.4.16 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/integration@1.18.1 + - @backstage/plugin-kubernetes-common@0.9.7 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/integration-aws-node@0.1.18 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-azure@0.3.10 + +### Patch Changes + +- 84443f1: Adds config definitions for Azure Blob Storage. +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.7 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-openapi-utils@0.6.2 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.4 + +### Patch Changes + +- 2aded73: Allow for passing a `pagelen` parameter to configure the `pagelength` property of the `BitbucketCloudEntityProvider` `searchCode` pagination to resolve [bug](https://jira.atlassian.com/browse/BCLOUD-23644) pertaining to duplicate results being returned. +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/plugin-bitbucket-cloud-common@0.3.3 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.4 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.7 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.7 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-github@0.11.1 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.15 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/plugin-catalog-backend-module-github@0.11.1 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.4 + +### Patch Changes + +- 0443119: Fixed an issue in `GitlabDiscoveryEntityProvider` where entity fetching could fail for projects with special characters or that had been renamed or moved. +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.14 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.4 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.2 + - @backstage/backend-defaults@0.13.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.10 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-logs@0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.2 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.1 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.15 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.15 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-scaffolder-common@1.7.2 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.10 + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/plugin-catalog-common@1.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-catalog-graph@0.5.2 + +### Patch Changes + +- 87b5e6e: Add missing API implementation for catalog graph plugin in NFS apps. +- 431130c: Added `renderEdge` prop to `` component in `@backstage/core-components` to allow custom rendering of graph edges. +- 6981ae6: Fixed DependencyGraph `svg` size not adapting to the container size +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-catalog-import@0.13.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/integration@1.18.1 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/config@1.3.5 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-catalog-common@1.1.6 + +## @backstage/plugin-catalog-node@1.19.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + +## @backstage/plugin-catalog-react@1.21.2 + +### Patch Changes + +- 2a3704d: Correct translation key from "type" to "owner" for owner column in entity table to ensure the right translation is loaded. +- ace202e: Update `material-ui-popup-state` to latest available version. +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/frontend-test-utils@0.4.0 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-react@0.4.37 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.22 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-catalog-unprocessed-entities-common@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/plugin-config-schema@0.1.73 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-devtools@0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-devtools-common@0.1.18 + - @backstage/plugin-permission-react@0.4.37 + +## @backstage/plugin-devtools-backend@0.5.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/config-loader@1.10.5 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-devtools-common@0.1.18 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + +## @backstage/plugin-devtools-common@0.1.18 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/plugin-events-backend@0.5.7 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-openapi-utils@0.6.2 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.16 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-module-azure@0.2.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-module-gerrit@0.2.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-module-github@0.4.5 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-module-gitlab@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-module-kafka@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-backend-test-utils@0.1.49 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-events-node@0.4.16 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-gateway-backend@1.0.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-home@0.8.13 + +### Patch Changes + +- e7d59d3: fix(home): correct `clearAll` logic to properly handle `deletable` flag +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/config@1.3.5 + - @backstage/theme@0.7.0 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-home-react@0.1.31 + +## @backstage/plugin-home-react@0.1.31 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-kubernetes@0.12.12 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/plugin-kubernetes-react@0.5.12 + - @backstage/core-components@0.18.2 + - @backstage/plugin-kubernetes-common@0.9.7 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-permission-react@0.4.37 + +## @backstage/plugin-kubernetes-backend@0.20.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.7 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/integration-aws-node@0.1.18 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-kubernetes-node@0.3.5 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + +## @backstage/plugin-kubernetes-cluster@0.0.30 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/plugin-kubernetes-react@0.5.12 + - @backstage/core-components@0.18.2 + - @backstage/plugin-kubernetes-common@0.9.7 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-permission-react@0.4.37 + +## @backstage/plugin-kubernetes-common@0.9.7 + +### Patch Changes + +- bdd7f95: Make SERVICEACCOUNT_CA_PATH public so it can be imported by external modules. +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/plugin-kubernetes-node@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.7 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-kubernetes-react@0.5.12 + +### Patch Changes + +- ac405f2: The configmaps added to be rendered +- f7a4144: Fixes calculation of CPU utilization in the PodTable +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/plugin-kubernetes-common@0.9.7 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-mcp-actions-backend@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-notifications@0.5.10 + +### Patch Changes + +- f5e0963: Removed unused dependencies +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/theme@0.7.0 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-notifications-common@0.1.1 + - @backstage/plugin-signals-react@0.0.16 + +## @backstage/plugin-notifications-backend@0.5.11 + +### Patch Changes + +- f5e0963: Removed unused dependencies +- 3b8e156: Fixed exclude entity reference not working in notification sending +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-notifications-common@0.1.1 + - @backstage/plugin-notifications-node@0.2.20 + - @backstage/plugin-signals-node@0.1.25 + +## @backstage/plugin-notifications-backend-module-email@0.3.14 + +### Patch Changes + +- b8cf31a: chore(deps): bump `nodemailer` from 6.9.16 to 7.0.7 +- f5e0963: Removed unused dependencies +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/integration-aws-node@0.1.18 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-notifications-common@0.1.1 + - @backstage/plugin-notifications-node@0.2.20 + +## @backstage/plugin-notifications-common@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + +## @backstage/plugin-notifications-node@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-notifications-common@0.1.1 + - @backstage/plugin-signals-node@0.1.25 + +## @backstage/plugin-org@0.6.45 + +### Patch Changes + +- 8b7351f: Add `initialRelationAggregation` and `showAggregateMembersToggle` options to `EntityMembersListCard` as well to `EntityOwnershipCard` +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-catalog-common@1.1.6 + +## @backstage/plugin-org-react@0.1.43 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-permission-backend@0.7.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.13 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + +## @backstage/plugin-permission-common@0.9.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + +## @backstage/plugin-permission-node@0.10.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/plugin-permission-react@0.4.37 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/plugin-proxy-backend@0.6.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-proxy-node@0.1.9 + +## @backstage/plugin-proxy-node@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder@1.34.2 + +### Patch Changes + +- e0ffe84: Add missing `templatingExtensions` option to RouterProps.contextMenu to allow global control across scaffolder pages +- d9aed74: Forward `ui:disabled` in `OwnedEntityPicker` to allow disabling it +- 075e064: Added missing form fields for the new frontend system. +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.2 + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/integration@1.18.1 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/core-compat-api@0.5.3 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-permission-react@0.4.37 + - @backstage/plugin-scaffolder-common@1.7.2 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.14 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.15 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.14 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.14 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/plugin-bitbucket-cloud-common@0.3.3 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- f5e0963: Removed unused dependencies +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.14 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.16 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.14 + +### Patch Changes + +- baf1cab: Fix documentation strings to mention GCP instead of Azure +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.14 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.14 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-github@0.9.1 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-node@1.19.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.6 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- f5e0963: Removed unused dependencies +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.15 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-notifications-common@0.1.1 + - @backstage/plugin-notifications-node@0.2.20 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.14 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.14 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- eea5360: Add sentry:fetch:dsn action to retrieve a Sentry project's DSN +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.15 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-scaffolder-node-test-utils@0.3.4 + +## @backstage/plugin-scaffolder-common@1.7.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/backend-test-utils@1.9.1 + +## @backstage/plugin-scaffolder-react@1.19.2 + +### Patch Changes + +- e61f89e: Don't change loading to false until we've actually got some log state +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/theme@0.7.0 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-permission-react@0.4.37 + - @backstage/plugin-scaffolder-common@1.7.2 + +## @backstage/plugin-search@1.4.31 + +### Patch Changes + +- 67a3e1a: Implemented AbortController request cancellation for overlapping search requests. This change ensures that when users type quickly, previous search requests are properly canceled before new ones start. +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/plugin-search-react@1.9.5 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-search-backend@2.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/config@1.3.5 + - @backstage/backend-openapi-utils@0.6.2 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-search-backend-module-catalog@0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.7 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/integration-aws-node@0.1.18 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-search-backend-module-explore@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-search-backend-module-pg@0.5.49 + +### Patch Changes + +- a919ca3: Truncate long docs to fit PG index size limit +- 8d15a51: Added the < character to the query filter regexp +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-search-backend-module-techdocs@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-search-common@1.2.20 + - @backstage/plugin-techdocs-node@1.13.8 + +## @backstage/plugin-search-backend-node@1.3.16 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-search-common@1.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2 + +## @backstage/plugin-search-react@1.9.5 + +### Patch Changes + +- 67a3e1a: Implemented AbortController request cancellation for overlapping search requests. This change ensures that when users type quickly, previous search requests are properly canceled before new ones start. +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/theme@0.7.0 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-signals@0.0.24 + +### Patch Changes + +- 7b41d9d: Remove `app-root-element:signals/signals-display` which was not doing anything useful +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/theme@0.7.0 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-signals-react@0.0.16 + +## @backstage/plugin-signals-backend@0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-signals-node@0.1.25 + +## @backstage/plugin-signals-node@0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-events-node@0.4.16 + +## @backstage/plugin-signals-react@0.0.16 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-techdocs@1.15.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/integration@1.18.1 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/plugin-search-react@1.9.5 + - @backstage/config@1.3.5 + - @backstage/theme@0.7.0 + - @backstage/core-compat-api@0.5.3 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-auth-react@0.1.20 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-techdocs-addons-test-utils@1.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/plugin-search-react@1.9.5 + - @backstage/plugin-catalog@1.31.4 + - @backstage/test-utils@1.7.12 + - @backstage/plugin-techdocs@1.15.1 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + +## @backstage/plugin-techdocs-backend@2.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-search-backend-module-techdocs@0.4.7 + - @backstage/plugin-techdocs-node@1.13.8 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/integration@1.18.1 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + +## @backstage/plugin-techdocs-node@1.13.8 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/integration-aws-node@0.1.18 + - @backstage/plugin-search-common@1.2.20 + +## @backstage/plugin-techdocs-react@1.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/config@1.3.5 + - @backstage/core-plugin-api@1.11.1 + +## @backstage/plugin-user-settings@0.8.27 + +### Patch Changes + +- 52fa068: Added user settings storage API blueprint +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/theme@0.7.0 + - @backstage/core-compat-api@0.5.3 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-signals-react@0.0.16 + +## @backstage/plugin-user-settings-backend@0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-signals-node@0.1.25 + +## example-app@0.2.114 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.8.0 + - @backstage/plugin-mui-to-bui@0.2.0 + - @backstage/plugin-catalog-graph@0.5.2 + - @backstage/plugin-scaffolder-react@1.19.2 + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/plugin-signals@0.0.24 + - @backstage/cli@0.34.4 + - @backstage/plugin-home@0.8.13 + - @backstage/plugin-org@0.6.45 + - @backstage/plugin-scaffolder@1.34.2 + - @backstage/plugin-search-react@1.9.5 + - @backstage/plugin-search@1.4.31 + - @backstage/plugin-notifications@0.5.10 + - @backstage/plugin-api-docs@0.13.0 + - @backstage/config@1.3.5 + - @backstage/plugin-user-settings@0.8.27 + - @backstage/theme@0.7.0 + - @backstage/plugin-kubernetes-cluster@0.0.30 + - @backstage/plugin-kubernetes@0.12.12 + - @backstage/frontend-app-api@0.13.1 + - @backstage/plugin-catalog@1.31.4 + - @backstage/app-defaults@1.7.1 + - @backstage/plugin-techdocs@1.15.1 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-auth-react@0.1.20 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-import@0.13.6 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22 + - @backstage/plugin-devtools@0.1.32 + - @backstage/plugin-permission-react@0.4.37 + - @backstage/plugin-search-common@1.2.20 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29 + +## example-app-next@0.0.28 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.8.0 + - @backstage/plugin-catalog-graph@0.5.2 + - @backstage/plugin-scaffolder-react@1.19.2 + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/plugin-app@0.3.1 + - @backstage/plugin-signals@0.0.24 + - @backstage/cli@0.34.4 + - @backstage/plugin-home@0.8.13 + - @backstage/plugin-org@0.6.45 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/plugin-scaffolder@1.34.2 + - @backstage/plugin-search-react@1.9.5 + - @backstage/plugin-search@1.4.31 + - @backstage/plugin-notifications@0.5.10 + - @backstage/plugin-api-docs@0.13.0 + - @backstage/config@1.3.5 + - @backstage/plugin-user-settings@0.8.27 + - @backstage/plugin-app-visualizer@0.1.24 + - @backstage/theme@0.7.0 + - @backstage/plugin-kubernetes-cluster@0.0.30 + - @backstage/plugin-kubernetes@0.12.12 + - @backstage/core-compat-api@0.5.3 + - @backstage/frontend-app-api@0.13.1 + - @backstage/plugin-catalog@1.31.4 + - @backstage/app-defaults@1.7.1 + - @backstage/plugin-auth@0.1.1 + - @backstage/plugin-techdocs@1.15.1 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/frontend-defaults@0.3.2 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-auth-react@0.1.20 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-import@0.13.6 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22 + - @backstage/plugin-permission-react@0.4.37 + - @backstage/plugin-search-common@1.2.20 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29 + +## app-next-example-plugin@0.0.28 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + +## example-backend@0.0.43 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.2 + - @backstage/backend-defaults@0.13.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.15 + - @backstage/plugin-scaffolder-backend-module-github@0.9.1 + - @backstage/plugin-scaffolder-backend@3.0.0 + - @backstage/plugin-notifications-backend@0.5.11 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-app-backend@0.5.7 + - @backstage/plugin-auth-backend@0.25.5 + - @backstage/plugin-auth-backend-module-github-provider@0.3.8 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.13 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.1 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.7 + - @backstage/plugin-catalog-backend-module-openapi@0.2.15 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.5 + - @backstage/plugin-devtools-backend@0.5.10 + - @backstage/plugin-events-backend@0.5.7 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.5 + - @backstage/plugin-kubernetes-backend@0.20.3 + - @backstage/plugin-mcp-actions-backend@0.1.4 + - @backstage/plugin-permission-backend@0.7.5 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.13 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + - @backstage/plugin-proxy-backend@0.6.7 + - @backstage/plugin-search-backend@2.0.7 + - @backstage/plugin-search-backend-module-catalog@0.3.9 + - @backstage/plugin-search-backend-module-explore@0.3.8 + - @backstage/plugin-search-backend-module-techdocs@0.4.7 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-signals-backend@0.3.9 + - @backstage/plugin-techdocs-backend@2.1.1 + +## e2e-test@0.2.33 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.5 + +## @internal/frontend@0.0.14 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1 + +## @internal/scaffolder@0.0.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.2 + - @backstage/frontend-plugin-api@0.12.1 + +## techdocs-cli-embedded-app@0.2.113 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/cli@0.34.4 + - @backstage/config@1.3.5 + - @backstage/theme@0.7.0 + - @backstage/plugin-catalog@1.31.4 + - @backstage/app-defaults@1.7.1 + - @backstage/test-utils@1.7.12 + - @backstage/plugin-techdocs@1.15.1 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + +## @internal/plugin-todo-list@1.0.44 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/core-plugin-api@1.11.1 + +## @internal/plugin-todo-list-backend@1.0.44 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + +## @internal/plugin-todo-list-common@1.0.27 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2 diff --git a/docs/releases/v1.44.0-next.0-changelog.md b/docs/releases/v1.44.0-next.0-changelog.md new file mode 100644 index 0000000000..601ea2b234 --- /dev/null +++ b/docs/releases/v1.44.0-next.0-changelog.md @@ -0,0 +1,1578 @@ +# Release v1.44.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.44.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.44.0-next.0) + +## @backstage/plugin-scaffolder-backend@3.0.0-next.0 + +### Major Changes + +- 9b81a90: **BREAKING** - Removing the deprecated types and interfaces, there's no replacement for these types, and hopefully not currently used as they offer no value with the plugin being on the new backend system and no way to consume them. + + Affected types: `CreateWorkerOptions`, `CurrentClaimedTask`, `DatabaseTaskStore`, `DatabaseTaskStoreOptions`, `TaskManager`, `TaskStore`, `TaskStoreCreateTaskOptions`, `TaskStoreCreateTaskResult`, `TaskStoreEmitOptions`, `TaskStoreListEventsOptions`, `TaskStoreRecoverTaskOptions`, `TaskStoreShutDownTaskOptions`, `TaskWorker` and `TemplateActionRegistry`. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.14-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.15-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.14-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.9.1-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.6-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.14-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.14-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.3-next.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-scaffolder-common@1.7.2-next.0 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13-next.0 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/backend-defaults@0.13.0-next.0 + +### Minor Changes + +- 2d3e2b2: implement support for direct url for AzureBlobStorageUrlReader search function +- 8b91238: Adds support for configuring server-level HTTP options through the + `app-config.yaml` file under the `backend.server` key. Supported options + include `headersTimeout`, `keepAliveTimeout`, `requestTimeout`, `timeout`, + `maxHeadersCount`, and `maxRequestsPerSocket`. + + These are passed directly to the underlying Node.js HTTP server. + If omitted, Node.js defaults are used. + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-app-api@1.2.7 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/cli-node@0.2.14 + - @backstage/config@1.3.3 + - @backstage/config-loader@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.2 + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-api-docs@0.13.0-next.0 + +### Minor Changes + +- b8a381e: Remove explicit dependency on `isomorphic-form-data`. + + This explicit dependency was added to address [an issue](https://github.com/swagger-api/swagger-ui/issues/7436) in the + dependency `swagger-ui-react`. That [issue has since been resolved](https://github.com/swagger-api/swagger-ui/issues/7436#issuecomment-889792304), + and `isomorphic-form-data` no longer needs to be declared. + + Additionally, this changeset updates the `swagger-ui-react` dependency to version `5.19.0` or higher, which includes + [compatibility](https://github.com/swagger-api/swagger-ui?tab=readme-ov-file#compatibility) with the latest versions of + the OpenAPI specification. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/plugin-catalog@1.31.4-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-scaffolder-node@0.12.0-next.0 + +### Minor Changes + +- 9b81a90: **BREAKING** - Marking optional fields as required in the `TaskBroker`, these can be fixed with a no-op `() => void` if you don't want to implement the functions. + + - `cancel`, `recoverTasks` and `retry` are the required methods on the `TaskBroker` interface. + + **NOTE**: If you're affected by this breaking change, please reach out to us in an issue as we're thinking about completely removing the `TaskBroker` extension point soon and would like to hear your use cases for the upcoming re-architecture of the `scaffolder-backend` plugin. + +### Patch Changes + +- c8aa210: **BREAKING ALPHA**: We've moved the `scaffolderActionsExtensionPoint` from `/alpha` to the main export. + + ```tsx + // before + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; + + // after + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node'; + ``` + +- 6e2bda7: **DEPRECATION**: We're going to be working on refactoring a lot of the internals of the Scaffolder backend plugin, and with that comes a lot of deprecations and removals for public types that are making these things hard. + + If you're using these types, please reach out to us either on Discord or a GitHub issue with your use cases. + + - `SerializedTask`, `SerializedTaskEvent`, `TaskBroker`, `TaskContext`, `TaskBrokerDispatchOptions`, `TaskBrokerDispatchResult`, `TaskCompletionState`, `TaskEventType`, `TaskFilter`, `TaskFilters`, `TaskStatus` are the types that have now been marked as deprecated, and will be removed in a future release. + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-common@1.7.2-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/app-defaults@1.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/theme@0.6.8 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/backend-dynamic-feature-service@0.7.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.1-next.0 + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-backend@0.5.6 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.14 + - @backstage/config@1.3.3 + - @backstage/config-loader@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-app-node@0.1.37 + - @backstage/plugin-events-node@0.4.15 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/backend-test-utils@1.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/backend-app-api@1.2.7 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-events-node@0.4.15 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/cli@0.34.4-next.0 + +### Patch Changes + +- 6ebc1ea: Fixed module federation config by only setting `import: false` on shared libraries for remote. +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.14 + - @backstage/config@1.3.3 + - @backstage/config-loader@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.11 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.2 + +## @backstage/core-compat-api@0.5.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-components@0.18.2-next.0 + +### Patch Changes + +- d493126: Swap base token for semantic token in ItemCardHeader to ensure readability in light mode. +- 6981ae6: Fixed DependencyGraph `svg` size not adapting to the container size +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.7.5-next.0 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/app-defaults@1.7.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/theme@0.6.8 + +## @backstage/frontend-app-api@0.13.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-defaults@0.3.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/plugin-app@0.3.1-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/frontend-app-api@0.13.1-next.0 + +## @backstage/frontend-dynamic-feature-loader@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/config@1.3.3 + +## @backstage/frontend-plugin-api@0.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-test-utils@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/plugin-app@0.3.1-next.0 + - @backstage/config@1.3.3 + - @backstage/frontend-app-api@0.13.1-next.0 + - @backstage/test-utils@1.7.11 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/integration@1.18.1-next.0 + +### Patch Changes + +- d772b51: remove host from azure blob storage integration type +- 84443f1: Adds config definitions for Azure Blob Storage. +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/integration-react@1.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.11.0 + +## @techdocs/cli@1.9.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-techdocs-node@1.13.8-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + +## @backstage/ui@0.7.2-next.0 + +### Patch Changes + +- 827340f: remove default selection of tab +- 9a47125: Improved SearchField component flex layout and animations. Fixed SearchField behavior in Header components by switching from width-based transitions to flex-basis transitions for better responsive behavior. Added new Storybook stories to test SearchField integration with Header component. + +## @backstage/plugin-app@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-app-visualizer@0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/core-plugin-api@1.11.0 + +## @backstage/plugin-auth@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8 + +## @backstage/plugin-auth-react@0.1.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-bitbucket-cloud-common@0.3.3-next.0 + +### Patch Changes + +- 2aded73: Allow for passing a `pagelen` parameter to configure the `pagelength` property of the `BitbucketCloudEntityProvider` `searchCode` pagination to resolve [bug](https://jira.atlassian.com/browse/BCLOUD-23644) pertaining to duplicate results being returned. +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + +## @backstage/plugin-catalog@1.31.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/plugin-scaffolder-common@1.7.2-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-catalog-backend@3.1.1-next.0 + +### Patch Changes + +- 9890488: Internal refactor to remove remnants of the old backend system + +- 2aaf01a: Fix for duplicate search results in entity-facets API call + +- e489661: Moved catalog processor and provider disabling and priorities under own config objects. + + This is due to issue with some existing providers, such as GitHub, using array syntax for the provider configuration. + + The new config format is not backwards compatible, so users will need to update their config files. The new format + is as follows: + + ```yaml + catalog: + providerOptions: + providerA: + disabled: false + providerB: + disabled: true + processorOptions: + processorA: + disabled: false + priority: 10 + processorB: + disabled: true + ``` + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-kubernetes-common@0.9.7-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + +## @backstage/plugin-catalog-backend-module-azure@0.3.10-next.0 + +### Patch Changes + +- 84443f1: Adds config definitions for Azure Blob Storage. +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.4-next.0 + +### Patch Changes + +- 2aded73: Allow for passing a `pagelen` parameter to configure the `pagelength` property of the `BitbucketCloudEntityProvider` `searchCode` pagination to resolve [bug](https://jira.atlassian.com/browse/BCLOUD-23644) pertaining to duplicate results being returned. +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.3-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.7-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-node@1.19.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + +## @backstage/plugin-catalog-backend-module-github@0.11.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.1-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.4-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.1-next.0 + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-events-node@0.4.15 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-catalog-backend-module-logs@0.1.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-common@1.7.2-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + +## @backstage/plugin-catalog-graph@0.5.2-next.0 + +### Patch Changes + +- 87b5e6e: Add missing API implementation for catalog graph plugin in NFS apps. +- 6981ae6: Fixed DependencyGraph `svg` size not adapting to the container size +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-catalog-import@0.13.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-catalog-react@1.21.2-next.0 + +### Patch Changes + +- 2a3704d: Correct translation key from "type" to "owner" for owner column in entity table to ensure the right translation is loaded. +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/frontend-test-utils@0.3.7-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-config-schema@0.1.73-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-devtools@0.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-devtools-common@0.1.17 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-devtools-backend@0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + - @backstage/config-loader@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-devtools-common@0.1.17 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-events-backend-module-github@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/types@1.2.2 + - @backstage/plugin-events-node@0.4.15 + +## @backstage/plugin-home@0.8.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/plugin-home-react@0.1.31-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/theme@0.6.8 + +## @backstage/plugin-home-react@0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/core-plugin-api@1.11.0 + +## @backstage/plugin-kubernetes@0.12.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/plugin-kubernetes-common@0.9.7-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/plugin-kubernetes-react@0.5.12-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-kubernetes-backend@0.20.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.7-next.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-kubernetes-node@0.3.5-next.0 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-kubernetes-cluster@0.0.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/plugin-kubernetes-common@0.9.7-next.0 + - @backstage/plugin-kubernetes-react@0.5.12-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-kubernetes-common@0.9.7-next.0 + +### Patch Changes + +- bdd7f95: Make SERVICEACCOUNT_CA_PATH public so it can be imported by external modules. +- Updated dependencies + - @backstage/catalog-model@1.7.5 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-kubernetes-node@0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.9.7-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/types@1.2.2 + +## @backstage/plugin-kubernetes-react@0.5.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/plugin-kubernetes-common@0.9.7-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-mcp-actions-backend@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-client@1.12.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.0 + +## @backstage/plugin-notifications@0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.2 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-org@0.6.45-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-catalog-common@1.1.5 + +## @backstage/plugin-org-react@0.1.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + +## @backstage/plugin-scaffolder@1.34.2-next.0 + +### Patch Changes + +- e0ffe84: Add missing `templatingExtensions` option to RouterProps.contextMenu to allow global control across scaffolder pages +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/plugin-scaffolder-react@1.19.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/plugin-scaffolder-common@1.7.2-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.14-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.15-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.14-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.14-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.3-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.14-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.16-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.14-next.0 + +### Patch Changes + +- baf1cab: Fix documentation strings to mention GCP instead of Azure +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.14-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.14-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-github@0.9.1-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.6-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.15-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/plugin-notifications-node@0.2.19 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.14-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.14-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.15-next.0 + +### Patch Changes + +- c8aa210: Updating import for the `scaffolderActionsExtensionPoint` to be the main export +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/types@1.2.2 + - @backstage/plugin-scaffolder-node-test-utils@0.3.4-next.0 + +## @backstage/plugin-scaffolder-common@1.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/backend-test-utils@1.9.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/types@1.2.2 + +## @backstage/plugin-scaffolder-react@1.19.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/plugin-scaffolder-common@1.7.2-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-plugin-api@1.11.0 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.36 + +## @backstage/plugin-search@1.4.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend@2.0.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-pg@0.5.49-next.0 + +### Patch Changes + +- a919ca3: Truncate long docs to fit PG index size limit +- 8d15a51: Added the < character to the query filter regexp +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-backend-module-techdocs@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/plugin-techdocs-node@1.13.8-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-search-react@1.9.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.19 + +## @backstage/plugin-signals@0.0.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.2 + - @backstage/plugin-signals-react@0.0.15 + +## @backstage/plugin-techdocs@1.15.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-auth-react@0.1.20-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/plugin-catalog@1.31.4-next.0 + - @backstage/plugin-techdocs@1.15.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/test-utils@1.7.11 + +## @backstage/plugin-techdocs-backend@2.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/plugin-techdocs-node@1.13.8-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.7-next.0 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/core-plugin-api@1.11.0 + +## @backstage/plugin-techdocs-node@1.13.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-react@1.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.11.0 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-user-settings@0.8.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8 + - @backstage/types@1.2.2 + - @backstage/plugin-signals-react@0.0.15 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-signals-node@0.1.24 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.114-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.2-next.0 + - @backstage/plugin-catalog-graph@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/cli@0.34.4-next.0 + - @backstage/plugin-scaffolder@1.34.2-next.0 + - @backstage/plugin-api-docs@0.13.0-next.0 + - @backstage/plugin-catalog@1.31.4-next.0 + - @backstage/plugin-catalog-import@0.13.6-next.0 + - @backstage/plugin-home@0.8.13-next.0 + - @backstage/plugin-kubernetes@0.12.12-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.30-next.0 + - @backstage/plugin-org@0.6.45-next.0 + - @backstage/plugin-scaffolder-react@1.19.2-next.0 + - @backstage/plugin-search@1.4.31-next.0 + - @backstage/plugin-techdocs@1.15.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.0 + - @backstage/plugin-user-settings@0.8.27-next.0 + - @backstage/app-defaults@1.7.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-auth-react@0.1.20-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.0 + - @backstage/plugin-devtools@0.1.32-next.0 + - @backstage/plugin-notifications@0.5.10-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/plugin-signals@0.0.24-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/frontend-app-api@0.13.1-next.0 + - @backstage/theme@0.6.8 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + +## example-app-next@0.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.2-next.0 + - @backstage/plugin-catalog-graph@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/cli@0.34.4-next.0 + - @backstage/plugin-scaffolder@1.34.2-next.0 + - @backstage/plugin-api-docs@0.13.0-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/plugin-catalog@1.31.4-next.0 + - @backstage/plugin-catalog-import@0.13.6-next.0 + - @backstage/plugin-home@0.8.13-next.0 + - @backstage/plugin-kubernetes@0.12.12-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.30-next.0 + - @backstage/plugin-org@0.6.45-next.0 + - @backstage/plugin-scaffolder-react@1.19.2-next.0 + - @backstage/plugin-search@1.4.31-next.0 + - @backstage/plugin-techdocs@1.15.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.0 + - @backstage/plugin-user-settings@0.8.27-next.0 + - @backstage/app-defaults@1.7.1-next.0 + - @backstage/frontend-defaults@0.3.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-app@0.3.1-next.0 + - @backstage/plugin-app-visualizer@0.1.24-next.0 + - @backstage/plugin-auth@0.1.1-next.0 + - @backstage/plugin-auth-react@0.1.20-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.0 + - @backstage/plugin-notifications@0.5.10-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/plugin-signals@0.0.24-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/frontend-app-api@0.13.1-next.0 + - @backstage/theme@0.6.8 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + +## app-next-example-plugin@0.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + +## example-backend@0.0.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.1-next.0 + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.15-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.9.1-next.0 + - @backstage/plugin-scaffolder-backend@3.0.0-next.0 + - @backstage/plugin-app-backend@0.5.6 + - @backstage/plugin-auth-backend@0.25.4 + - @backstage/plugin-auth-backend-module-github-provider@0.3.7 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-devtools-backend@0.5.10-next.0 + - @backstage/plugin-events-backend@0.5.6 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.4 + - @backstage/plugin-kubernetes-backend@0.20.3-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.4-next.0 + - @backstage/plugin-notifications-backend@0.5.10 + - @backstage/plugin-permission-backend@0.7.4 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-proxy-backend@0.6.6 + - @backstage/plugin-search-backend@2.0.7-next.0 + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/plugin-signals-backend@0.3.8 + - @backstage/plugin-techdocs-backend@2.1.1-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.15-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.12 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.6 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.4 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.12 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-backend-module-catalog@0.3.8 + - @backstage/plugin-search-backend-module-explore@0.3.7 + - @backstage/plugin-search-backend-module-techdocs@0.4.7-next.0 + +## e2e-test@0.2.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.5-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/frontend@0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @internal/scaffolder@0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + +## techdocs-cli-embedded-app@0.2.113-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/cli@0.34.4-next.0 + - @backstage/plugin-catalog@1.31.4-next.0 + - @backstage/plugin-techdocs@1.15.1-next.0 + - @backstage/app-defaults@1.7.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/test-utils@1.7.11 + - @backstage/theme@0.6.8 + +## @internal/plugin-todo-list@1.0.44-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-plugin-api@1.11.0 diff --git a/docs/releases/v1.44.0-next.1-changelog.md b/docs/releases/v1.44.0-next.1-changelog.md new file mode 100644 index 0000000000..e9d3f16f97 --- /dev/null +++ b/docs/releases/v1.44.0-next.1-changelog.md @@ -0,0 +1,1925 @@ +# Release v1.44.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.44.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.44.0-next.1) + +## @backstage/app-defaults@1.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + +## @backstage/backend-app-api@1.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + +## @backstage/backend-defaults@0.13.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/integration-aws-node@0.1.18-next.0 + - @backstage/backend-app-api@1.2.8-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/cli-node@0.2.14 + +## @backstage/backend-dynamic-feature-service@0.7.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/plugin-app-node@0.1.38-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-catalog-backend@3.1.1-next.1 + - @backstage/plugin-events-backend@0.5.7-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/backend-openapi-utils@0.6.2-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/cli-node@0.2.14 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/backend-openapi-utils@0.6.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + +## @backstage/backend-plugin-api@1.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + +## @backstage/backend-test-utils@1.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/backend-app-api@1.2.8-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/cli@0.34.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/cli-node@0.2.14 + - @backstage/release-manifests@0.0.13 + +## @backstage/config@1.3.4-next.0 + +### Patch Changes + +- b45b094: Allow colon to be used as config key. + +## @backstage/config-loader@1.10.4-next.0 + +### Patch Changes + +- b45b094: Allow colon to be used as config key. +- Updated dependencies + - @backstage/config@1.3.4-next.0 + +## @backstage/core-app-api@1.19.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/core-plugin-api@1.11.1-next.0 + +## @backstage/core-compat-api@0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## @backstage/core-components@0.18.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/core-plugin-api@1.11.1-next.0 + +## @backstage/core-plugin-api@1.11.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + +## @backstage/create-app@0.7.5-next.1 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/dev-utils@1.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/app-defaults@1.7.1-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + +## @backstage/frontend-app-api@0.13.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-defaults@0.3.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## @backstage/frontend-defaults@0.3.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/frontend-app-api@0.13.1-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-app@0.3.1-next.1 + +## @backstage/frontend-dynamic-feature-loader@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## @backstage/frontend-plugin-api@0.12.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + +## @backstage/frontend-test-utils@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/frontend-app-api@0.13.1-next.1 + - @backstage/test-utils@1.7.12-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-app@0.3.1-next.1 + +## @backstage/integration@1.18.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + +## @backstage/integration-aws-node@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + +## @backstage/integration-react@1.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + +## @backstage/repo-tools@0.15.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/cli-node@0.2.14 + +## @techdocs/cli@1.9.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/plugin-techdocs-node@1.13.8-next.1 + +## @backstage/test-utils@1.7.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + +## @backstage/plugin-api-docs@0.13.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog@1.31.4-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-app@0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## @backstage/plugin-app-backend@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/config@1.3.4-next.0 + - @backstage/plugin-app-node@0.1.38-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-app-node@0.1.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + +## @backstage/plugin-app-visualizer@0.1.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## @backstage/plugin-auth-backend@0.25.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-backend@0.25.5-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-backend@0.25.5-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-openshift-provider@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + +## @backstage/plugin-auth-node@0.6.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-auth-react@0.1.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + +## @backstage/plugin-catalog@1.31.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-scaffolder-common@1.7.2-next.1 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-catalog-backend@3.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/backend-openapi-utils@0.6.2-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-catalog-backend-module-aws@0.4.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/integration@1.18.1-next.1 + - @backstage/integration-aws-node@0.1.18-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/plugin-kubernetes-common@0.9.7-next.1 + +## @backstage/plugin-catalog-backend-module-azure@0.3.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/backend-openapi-utils@0.6.2-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-kubernetes-common@0.9.7-next.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.11.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-backend@3.1.1-next.1 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-backend-module-github@0.11.1-next.1 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.7.4-next.1 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-backend@3.1.1-next.1 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-catalog-backend-module-logs@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-backend@3.1.1-next.1 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-scaffolder-common@1.7.2-next.1 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.10-next.0 + +## @backstage/plugin-catalog-common@1.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-catalog-graph@0.5.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-catalog-import@0.13.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-catalog-node@1.19.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-catalog-react@1.21.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-test-utils@0.3.7-next.1 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## @backstage/plugin-catalog-unprocessed-entities-common@0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2-next.0 + +## @backstage/plugin-config-schema@0.1.73-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + +## @backstage/plugin-devtools@0.1.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-devtools-common@0.1.18-next.0 + +## @backstage/plugin-devtools-backend@0.5.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-devtools-common@0.1.18-next.0 + +## @backstage/plugin-devtools-common@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2-next.0 + +## @backstage/plugin-events-backend@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/backend-openapi-utils@0.6.2-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-module-azure@0.2.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-module-github@0.4.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-module-gitlab@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-module-kafka@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-backend-test-utils@0.1.49-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-events-node@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + +## @backstage/plugin-gateway-backend@1.0.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + +## @backstage/plugin-home@0.8.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-home-react@0.1.31-next.1 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-home-react@0.1.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## @backstage/plugin-kubernetes@0.12.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-kubernetes-react@0.5.12-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-kubernetes-common@0.9.7-next.1 + +## @backstage/plugin-kubernetes-backend@0.20.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration-aws-node@0.1.18-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-kubernetes-node@0.3.5-next.1 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-kubernetes-common@0.9.7-next.1 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-kubernetes-cluster@0.0.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-kubernetes-react@0.5.12-next.1 + - @backstage/plugin-kubernetes-common@0.9.7-next.1 + +## @backstage/plugin-kubernetes-common@0.9.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2-next.0 + +## @backstage/plugin-kubernetes-node@0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-kubernetes-common@0.9.7-next.1 + +## @backstage/plugin-kubernetes-react@0.5.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-kubernetes-common@0.9.7-next.1 + +## @backstage/plugin-mcp-actions-backend@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-notifications@0.5.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-notifications-common@0.1.1-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-signals-react@0.0.16-next.0 + +## @backstage/plugin-notifications-backend@0.5.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-notifications-common@0.1.1-next.0 + - @backstage/plugin-signals-node@0.1.25-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/plugin-notifications-node@0.2.20-next.0 + +## @backstage/plugin-notifications-backend-module-email@0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration-aws-node@0.1.18-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-notifications-common@0.1.1-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-notifications-node@0.2.20-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-notifications-backend-module-slack@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-notifications-common@0.1.1-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-notifications-node@0.2.20-next.0 + +## @backstage/plugin-notifications-common@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + +## @backstage/plugin-notifications-node@0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-notifications-common@0.1.1-next.0 + - @backstage/plugin-signals-node@0.1.25-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-org@0.6.45-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-catalog-common@1.1.6-next.0 + +## @backstage/plugin-org-react@0.1.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-permission-backend@0.7.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + +## @backstage/plugin-permission-common@0.9.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + +## @backstage/plugin-permission-node@0.10.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + +## @backstage/plugin-permission-react@0.4.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + +## @backstage/plugin-proxy-backend@0.6.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-proxy-node@0.1.9-next.0 + +## @backstage/plugin-proxy-node@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + +## @backstage/plugin-scaffolder@1.34.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.1 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-scaffolder-common@1.7.2-next.1 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-scaffolder-backend@3.0.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.14-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.15-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.14-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.14-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.14-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.6-next.1 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + - @backstage/backend-openapi-utils@0.6.2-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13-next.1 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/plugin-scaffolder-common@1.7.2-next.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.14-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14-next.1 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + - @backstage/plugin-catalog-node@1.19.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-notifications-common@0.1.1-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + - @backstage/plugin-notifications-node@0.2.20-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.3.4-next.1 + +## @backstage/plugin-scaffolder-common@1.7.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.1 + - @backstage/plugin-permission-common@0.9.2-next.0 + +## @backstage/plugin-scaffolder-node@0.12.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-scaffolder-common@1.7.2-next.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/backend-test-utils@1.9.1-next.1 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + +## @backstage/plugin-scaffolder-react@1.19.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-scaffolder-common@1.7.2-next.1 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-search@1.4.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-search-backend@2.0.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/backend-openapi-utils@0.6.2-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-search-backend-module-catalog@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration-aws-node@0.1.18-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-search-backend-module-explore@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-search-backend-module-pg@0.5.49-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-search-backend-module-techdocs@0.4.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/plugin-techdocs-node@1.13.8-next.1 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-search-backend-node@1.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-search-common@1.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2-next.0 + +## @backstage/plugin-search-react@1.9.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-signals@0.0.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-signals-react@0.0.16-next.0 + +## @backstage/plugin-signals-backend@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-signals-node@0.1.25-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-signals-node@0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## @backstage/plugin-signals-react@0.0.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.1-next.0 + +## @backstage/plugin-techdocs@1.15.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-auth-react@0.1.20-next.1 + - @backstage/plugin-search-common@1.2.20-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/test-utils@1.7.12-next.0 + - @backstage/plugin-techdocs@1.15.1-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/plugin-catalog@1.31.4-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + +## @backstage/plugin-techdocs-backend@2.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/integration@1.18.1-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.7-next.1 + - @backstage/plugin-techdocs-node@1.13.8-next.1 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/catalog-client@1.12.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.1 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## @backstage/plugin-techdocs-node@1.13.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/integration-aws-node@0.1.18-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## @backstage/plugin-techdocs-react@1.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## @backstage/plugin-user-settings@0.8.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-signals-react@0.0.16-next.0 + +## @backstage/plugin-user-settings-backend@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-signals-node@0.1.25-next.0 + +## example-app@0.2.114-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/cli@0.34.4-next.1 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-app-api@0.13.1-next.1 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-catalog-import@0.13.6-next.1 + - @backstage/plugin-home@0.8.13-next.1 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/plugin-techdocs@1.15.1-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/app-defaults@1.7.1-next.1 + - @backstage/plugin-api-docs@0.13.0-next.1 + - @backstage/plugin-catalog@1.31.4-next.1 + - @backstage/plugin-catalog-graph@0.5.2-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-notifications@0.5.10-next.1 + - @backstage/plugin-org@0.6.45-next.1 + - @backstage/plugin-scaffolder@1.34.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.2-next.1 + - @backstage/plugin-search@1.4.31-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + - @backstage/plugin-signals@0.0.24-next.1 + - @backstage/plugin-user-settings@0.8.27-next.1 + - @backstage/plugin-auth-react@0.1.20-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.1 + - @backstage/plugin-devtools@0.1.32-next.1 + - @backstage/plugin-kubernetes@0.12.12-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.30-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.1 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## example-app-next@0.0.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/cli@0.34.4-next.1 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-app-api@0.13.1-next.1 + - @backstage/frontend-defaults@0.3.2-next.1 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-catalog-import@0.13.6-next.1 + - @backstage/plugin-home@0.8.13-next.1 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/plugin-techdocs@1.15.1-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/app-defaults@1.7.1-next.1 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-api-docs@0.13.0-next.1 + - @backstage/plugin-catalog@1.31.4-next.1 + - @backstage/plugin-catalog-graph@0.5.2-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-notifications@0.5.10-next.1 + - @backstage/plugin-org@0.6.45-next.1 + - @backstage/plugin-scaffolder@1.34.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.2-next.1 + - @backstage/plugin-search@1.4.31-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + - @backstage/plugin-signals@0.0.24-next.1 + - @backstage/plugin-user-settings@0.8.27-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-app@0.3.1-next.1 + - @backstage/plugin-app-visualizer@0.1.24-next.1 + - @backstage/plugin-auth-react@0.1.20-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.1 + - @backstage/plugin-kubernetes@0.12.12-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.30-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.1 + - @backstage/plugin-auth@0.1.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## example-backend@0.0.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/plugin-app-backend@0.5.7-next.0 + - @backstage/plugin-devtools-backend@0.5.10-next.1 + - @backstage/plugin-proxy-backend@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-backend@0.25.5-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.13-next.0 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.1-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-catalog-backend@3.1.1-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.7-next.0 + - @backstage/plugin-events-backend@0.5.7-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.5-next.0 + - @backstage/plugin-kubernetes-backend@0.20.3-next.1 + - @backstage/plugin-notifications-backend@0.5.11-next.0 + - @backstage/plugin-permission-backend@0.7.5-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-scaffolder-backend@3.0.0-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.1-next.1 + - @backstage/plugin-search-backend@2.0.7-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.9-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.8-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.7-next.1 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/plugin-signals-backend@0.3.9-next.0 + - @backstage/plugin-techdocs-backend@2.1.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.8-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.15-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.5-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.4-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.15-next.1 + +## techdocs-cli-embedded-app@0.2.113-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/cli@0.34.4-next.1 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/test-utils@1.7.12-next.0 + - @backstage/plugin-techdocs@1.15.1-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/app-defaults@1.7.1-next.1 + - @backstage/plugin-catalog@1.31.4-next.1 + +## @internal/plugin-todo-list@1.0.44-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + +## @internal/plugin-todo-list-backend@1.0.44-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + +## @internal/plugin-todo-list-common@1.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.2-next.0 diff --git a/docs/releases/v1.44.0-next.2-changelog.md b/docs/releases/v1.44.0-next.2-changelog.md new file mode 100644 index 0000000000..74b467ebba --- /dev/null +++ b/docs/releases/v1.44.0-next.2-changelog.md @@ -0,0 +1,2298 @@ +# Release v1.44.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.44.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.44.0-next.2) + +## @backstage/config@1.3.5-next.0 + +# @backstage/config + +## 1.3.4-next.0 + +### Patch Changes + +- b45b094: Allow colon to be used as config key. + +## 1.3.3 + +### Patch Changes + +- ff23618: Loosen the requirements for a key to be considered valid config. +- 3507fcd: Just some more circular dep cleanup + +## 1.3.3-next.0 + +### Patch Changes + +- ff23618: Loosen the requirements for a key to be considered valid config. +- 3507fcd: Just some more circular dep cleanup + +## 1.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.1 + - @backstage/errors@1.2.7 + +## 1.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.1-next.0 + - @backstage/errors@1.2.7-next.0 + +## 1.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.6 + - @backstage/types@1.2.0 + +## 1.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.6-next.0 + - @backstage/types@1.2.0 + +## 1.3.0 + +### Minor Changes + +- d52d7f9: Make `readDurationFromConfig` support both ISO and ms formats as well, to make it easier to enter time as an end user + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.0 + - @backstage/errors@1.2.5 + +## 1.2.0 + +### Minor Changes + +- 50cf9df: The `ConfigReader` now treats `null` values as present but explicitly undefined, meaning it will not fall back to the next level of configuration. + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.2.0-next.1 + +### Minor Changes + +- 50cf9df: The `ConfigReader` now treats `null` values as present but explicitly undefined, meaning it will not fall back to the next level of configuration. + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## 1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## 1.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## 1.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.3-next.0 + - @backstage/types@1.1.1 + +## 1.1.0 + +### Minor Changes + +- 62f448edb0b5: Added a `readDurationFromConfig` function + +### Patch Changes + +- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. +- 8cec7664e146: Removed `@types/node` dependency +- Updated dependencies + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## 1.1.0-next.2 + +### Patch Changes + +- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. +- Updated dependencies + - @backstage/errors@1.2.2-next.0 + - @backstage/types@1.1.1-next.0 + +## 1.1.0-next.1 + +### Patch Changes + +- 8cec7664e146: Removed `@types/node` dependency +- Updated dependencies + - @backstage/errors@1.2.1 + - @backstage/types@1.1.0 + +## 1.1.0-next.0 + +### Minor Changes + +- 62f448edb0b5: Added a `readDurationFromConfig` function + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.1 + - @backstage/types@1.1.0 + +## 1.0.8 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.1.0 + +## 1.0.7 + +### Patch Changes + +- 482dae5de1c: Updated link to docs. +- Updated dependencies + - @backstage/types@1.0.2 + +## 1.0.7-next.0 + +### Patch Changes + +- 482dae5de1c: Updated link to docs. +- Updated dependencies + - @backstage/types@1.0.2 + +## 1.0.6 + +### Patch Changes + +- ba2d69ee17: Adds the ability to coerce values to their boolean representatives. + Values such as `"true"` `1` `on` and `y` will become `true` when using `getBoolean` and the opposites `false`. + This happens particularly when such parameters are used with environmental substitution as environment variables are always strings. +- Updated dependencies + - @backstage/types@1.0.2 + +## 1.0.6-next.0 + +### Patch Changes + +- ba2d69ee17: Adds the ability to coerce values to their boolean representatives. + Values such as `"true"` `1` `on` and `y` will become `true` when using `getBoolean` and the opposites `false`. + This happens particularly when such parameters are used with environmental substitution as environment variables are always strings. +- Updated dependencies + - @backstage/types@1.0.2 + +## 1.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2 + +## 1.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.1 + +## 1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.2-next.0 + +## 1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.1 + +## 1.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.1-next.0 + +## 1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.0 + +## 1.0.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.0 + +## 1.0.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.0 + +## 1.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.0 + +## 1.0.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + +## 1.0.2-next.0 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. + +## 1.0.1 + +### Patch Changes + +- 6e830352d4: Updated dependency `@types/node` to `^16.0.0`. + +## 1.0.1-next.0 + +### Patch Changes + +- 6e830352d4: Updated dependency `@types/node` to `^16.0.0`. + +## 1.0.0 + +### Major Changes + +- b58c70c223: This package has been promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy). + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.0 + +## 0.1.15 + +### Patch Changes + +- Fix for the previous release with missing type declarations. +- Updated dependencies + - @backstage/types@0.1.3 + +## 0.1.14 + +### Patch Changes + +- c77c5c7eb6: Added `backstage.role` to `package.json` +- Updated dependencies + - @backstage/types@0.1.2 + +## 0.1.13 + +### Patch Changes + +- f685e1398f: Loading of app configurations now reference the `@deprecated` construct from + JSDoc to determine if a property in-use has been deprecated. Users are notified + of deprecated keys in the format: + + ```txt + The configuration key 'catalog.processors.githubOrg' of app-config.yaml is deprecated and may be removed soon. Configure a GitHub integration instead. + ``` + + When the `withDeprecatedKeys` option is set to `true` in the `process` method + of `loadConfigSchema`, the user will be notified that deprecated keys have been + identified in their app configuration. + + The `backend-common` and `plugin-app-backend` packages have been updated to set + `withDeprecatedKeys` to true so that users are notified of deprecated settings + by default. + +## 0.1.13-next.0 + +### Patch Changes + +- f685e1398f: Loading of app configurations now reference the `@deprecated` construct from + JSDoc to determine if a property in-use has been deprecated. Users are notified + of deprecated keys in the format: + + ```txt + The configuration key 'catalog.processors.githubOrg' of app-config.yaml is deprecated and may be removed soon. Configure a GitHub integration instead. + ``` + + When the `withDeprecatedKeys` option is set to `true` in the `process` method + of `loadConfigSchema`, the user will be notified that deprecated keys have been + identified in their app configuration. + + The `backend-common` and `plugin-app-backend` packages have been updated to set + `withDeprecatedKeys` to true so that users are notified of deprecated settings + by default. + +## 0.1.12 + +### Patch Changes + +- f5343e7c1a: The `ConfigReader#get` method now always returns a deep clone of the configuration data. + +## 0.1.11 + +### Patch Changes + +- 10d267a1b7: Minor exports cleanup +- 41c49884d2: Start using the new `@backstage/types` package. Initially, this means using the `Observable` and `Json*` types from there. The types also remain in their old places but deprecated, and will be removed in a future release. +- 925a967f36: Replace usage of test-utils-core with test-utils + +## 0.1.10 + +### Patch Changes + +- febddedcb2: Bump `lodash` to remediate `SNYK-JS-LODASH-590103` security vulnerability + +## 0.1.9 + +### Patch Changes + +- f88b2c7db: Documented `Config` interface and mark types as public. + +## 0.1.8 + +### Patch Changes + +- 47113f1f1: Only warn once per key when trying to read visibility-filtered values + +## 0.1.7 + +### Patch Changes + +- 90f25476a: Extended the `Config` interface to have an optional `subscribe` method that can be used be notified of updates to the configuration. + +## 0.1.6 + +### Patch Changes + +- e9d3983ee: Add warning when trying to access configuration values that have been filtered out by visibility. + +## 0.1.5 + +### Patch Changes + +- d8b81fd28: Bump `json-schema` dependency from `0.2.5` to `0.3.0`. + +## 0.1.4 + +### Patch Changes + +- 0434853a5: Reformulate the json types to break type recursion + +## 0.1.3 + +### Patch Changes + +- a1f5e6545: Adds an optional type to `config.get` & `config.getOptional`. This avoids the need for casting. For example: + + ```ts + const config = useApi(configApiRef); + + const myConfig = config.get('myPlugin.complexConfig'); + // vs + const myConfig config.get('myPlugin.complexConfig') as SomeTypeDefinition; + ``` + +## 0.1.2 + +### Patch Changes + +- e3bd9fc2f: Fix unneeded defensive code +- e3bd9fc2f: Fix useless conditional + +## @backstage/config-loader@1.10.5-next.0 + +# @backstage/config-loader + +## 1.10.4-next.0 + +### Patch Changes + +- b45b094: Allow colon to be used as config key. +- Updated dependencies + - @backstage/config@1.3.4-next.0 + +## 1.10.3 + +### Patch Changes + +- a73f495: Allow using `BACKSTAGE_ENV` for loading environment specific config files +- Updated dependencies + - @backstage/types@1.2.2 + +## 1.10.3-next.0 + +### Patch Changes + +- a73f495: Allow using `BACKSTAGE_ENV` for loading environment specific config files + +## 1.10.2 + +### Patch Changes + +- ff23618: Loosen the requirements for a key to be considered valid config. +- Updated dependencies + - @backstage/config@1.3.3 + +## 1.10.2-next.0 + +### Patch Changes + +- ff23618: Loosen the requirements for a key to be considered valid config. +- Updated dependencies + - @backstage/config@1.3.3-next.0 + +## 1.10.1 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## 1.10.1-next.0 + +### Patch Changes + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## 1.10.0 + +### Minor Changes + +- 2fd73aa: The include transforms applied during config loading will now only apply to the known keys `$file`, `$env`, and `$include`. Any other key that begins with a \`# @backstage/config-loader will now be passed through as is. + +### Patch Changes + +- f422984: Added `@types/minimist` to `devDependencies` +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## 1.10.0-next.0 + +### Minor Changes + +- 2fd73aa: The include transforms applied during config loading will now only apply to the known keys `$file`, `$env`, and `$include`. Any other key that begins with a \`# @backstage/config-loader will now be passed through as is. + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## 1.9.6 + +### Patch Changes + +- f866b86: Internal refactor to use explicit `require` for lazy-loading dependency. +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## 1.9.6-next.0 + +### Patch Changes + +- f866b86: Internal refactor to use explicit `require` for lazy-loading dependency. +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## 1.9.5 + +### Patch Changes + +- 8ecf8cb: Exclude `@backstage/backend-common` from schema collection if `@backstage/backend-defaults` is present +- Updated dependencies + - @backstage/types@1.2.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## 1.9.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.1-next.0 + - @backstage/config@1.3.2-next.0 + - @backstage/errors@1.2.7-next.0 + - @backstage/cli-common@0.1.15 + +## 1.9.5-next.0 + +### Patch Changes + +- 8ecf8cb: Exclude `@backstage/backend-common` from schema collection if `@backstage/backend-defaults` is present +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.1 + - @backstage/errors@1.2.6 + - @backstage/types@1.2.0 + +## 1.9.3 + +### Patch Changes + +- 5c9cc05: Use native fetch instead of node-fetch +- Updated dependencies + - @backstage/errors@1.2.6 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.1 + - @backstage/types@1.2.0 + +## 1.9.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.6-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.1-next.0 + - @backstage/types@1.2.0 + +## 1.9.3-next.0 + +### Patch Changes + +- 5c9cc05: Use native fetch instead of node-fetch +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.0 + - @backstage/errors@1.2.5 + - @backstage/types@1.2.0 + +## 1.9.2 + +### Patch Changes + +- c5e39e7: Internal refactor to use the deferred from the types package +- Updated dependencies + - @backstage/config@1.3.0 + - @backstage/types@1.2.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.5 + +## 1.9.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.15-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.9.1 + +### Patch Changes + +- ef3c507: Updated dependency `typescript-json-schema` to `^0.65.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.9.1-next.0 + +### Patch Changes + +- ef3c507: Updated dependency `typescript-json-schema` to `^0.65.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.9.0 + +### Minor Changes + +- 274428f: Add configuration key to File and Remote `ConfigSource`s that enables configuration of parsing logic. Previously limited to yaml, these `ConfigSource`s now allow for a multitude of parsing options (e.g. JSON). + +### Patch Changes + +- 93095ee: Make sure node-fetch is version 2.7.0 or greater +- 1edd6c2: The `env` option of `ConfigSources.default` now correctly allows undefined members. +- 493feac: Add boolean `allowMissingDefaultConfig` option to `ConfigSources.default` and + `ConfigSources.defaultForTargets`, which results in omission of a ConfigSource + for the default app-config.yaml configuration file if it's not present. +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.9.0-next.2 + +### Patch Changes + +- 93095ee: Make sure node-fetch is version 2.7.0 or greater +- Updated dependencies + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.9.0-next.1 + +### Minor Changes + +- 274428f: Add configuration key to File and Remote `ConfigSource`s that enables configuration of parsing logic. Previously limited to yaml, these `ConfigSource`s now allow for a multitude of parsing options (e.g. JSON). + +### Patch Changes + +- 1edd6c2: The `env` option of `ConfigSources.default` now correctly allows undefined members. +- 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.2-next.0 + +### Patch Changes + +- 493feac: Add boolean `allowMissingDefaultConfig` option to `ConfigSources.default` and + `ConfigSources.defaultForTargets`, which results in omission of a ConfigSource + for the default app-config.yaml configuration file if it's not present. +- 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 + +### 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 + +- Updated dependencies + - @backstage/cli-common@0.1.14-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.8.0 + +### Minor Changes + +- 2ce31b3: The default environment variable substitution function will now trim whitespace characters from the substituted value. This alleviates bugs where whitespace characters are mistakenly included in environment variables. + + If you depend on the old behavior, you can override the default substitution function with your own, for example: + + ```ts + ConfigSources.default({ + substitutionFunc: async name => process.env[name], + }); + ``` + +- 99bab65: Support parameter substitution for environment variables + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.8.0-next.0 + +### Minor Changes + +- 99bab65: Support parameter substitution for environment variables + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## 1.7.0 + +### Minor Changes + +- db8358d: Forward `null` values read from configuration files in configuration data, rather than treating them as an absence of config. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## 1.7.0-next.1 + +### Minor Changes + +- db8358d: Forward `null` values read from configuration files in configuration data, rather than treating them as an absence of config. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.4-next.0 + - @backstage/types@1.1.1 + +## 1.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/types@1.1.1 + +## 1.6.2 + +### Patch Changes + +- 0a9a03c: Make schema processing gracefully handle an empty config. +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- bf3da16: Updated dependency `typescript-json-schema` to `^0.63.0`. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## 1.6.2-next.0 + +### Patch Changes + +- 0a9a03c: Make schema processing gracefully handle an empty config. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## 1.6.1 + +### Patch Changes + +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## 1.6.1-next.0 + +### Patch Changes + +- 7acbb5a: Removed `mock-fs` dev dependency. +- Updated dependencies + - @backstage/config@1.1.1 + - @backstage/cli-common@0.1.13 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## 1.6.0 + +### Minor Changes + +- 24f5a85: Add "path" to `TransformFunc` context + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## 1.6.0-next.0 + +### Minor Changes + +- 24f5a85: Add "path" to `TransformFunc` context + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## 1.5.3 + +### Patch Changes + +- 22ca64f117: Correctly resolve config targets into absolute paths +- 087bab5b42: Updated dependency `typescript-json-schema` to `^0.62.0`. +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## 1.5.2-next.0 + +### Patch Changes + +- 22ca64f117: Correctly resolve config targets into absolute paths +- Updated dependencies + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/types@1.1.1 + +## 1.5.1 + +### Patch Changes + +- 0b55f773a7: Removed some unused dependencies +- 30c553c1d2: Updated dependency `typescript-json-schema` to `^0.61.0`. +- 773ea341d2: The `FileConfigSource` will now retry file reading after a short delay if it reads an empty file. This is to avoid flakiness during watch mode where change events can trigger before the file content has been written. +- a4617c422a: Added `watch` option to configuration loaders that can be used to disable file watching by setting it to `false`. +- Updated dependencies + - @backstage/errors@1.2.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/types@1.1.1 + +## 1.5.1-next.1 + +### Patch Changes + +- 0b55f773a7: Removed some unused dependencies +- 30c553c1d2: Updated dependency `typescript-json-schema` to `^0.61.0`. +- a4617c422a: Added `watch` option to configuration loaders that can be used to disable file watching by setting it to `false`. +- Updated dependencies + - @backstage/errors@1.2.3-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.1-next.0 + - @backstage/types@1.1.1 + +## 1.5.1-next.0 + +### Patch Changes + +- 773ea341d2: The `FileConfigSource` will now retry file reading after a short delay if it reads an empty file. This is to avoid flakiness during watch mode where change events can trigger before the file content has been written. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + +## 1.5.0 + +### Minor Changes + +- 9606ba0939e6: Deep visibility now also applies to values that are not covered by the configuration schema. + + For example, given the following configuration schema: + + ```ts + // plugins/a/config.schema.ts + export interface Config { + /** @deepVisibility frontend */ + a?: unknown; + } + + // plugins/a/config.schema.ts + export interface Config { + a?: { + b?: string; + }; + } + ``` + + All values under `a` are now visible to the frontend, while previously only `a` and `a/b` would've been visible. + +### Patch Changes + +- 8cec7664e146: Removed `@types/node` dependency +- f9657b891b00: Do not unnecessarily notify subscribers when no-op updates to config happen +- Updated dependencies + - @backstage/config@1.1.0 + - @backstage/errors@1.2.2 + - @backstage/types@1.1.1 + - @backstage/cli-common@0.1.12 + +## 1.5.0-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0-next.2 + - @backstage/errors@1.2.2-next.0 + - @backstage/types@1.1.1-next.0 + - @backstage/cli-common@0.1.12 + +## 1.5.0-next.2 + +### Patch Changes + +- 8cec7664e146: Removed `@types/node` dependency +- Updated dependencies + - @backstage/config@1.1.0-next.1 + - @backstage/cli-common@0.1.12 + - @backstage/errors@1.2.1 + - @backstage/types@1.1.0 + +## 1.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0-next.0 + - @backstage/cli-common@0.1.12 + - @backstage/errors@1.2.1 + - @backstage/types@1.1.0 + +## 1.5.0-next.0 + +### Minor Changes + +- 9606ba0939e6: Deep visibility now also applies to values that are not covered by the configuration schema. + + For example, given the following configuration schema: + + ```ts + // plugins/a/config.schema.ts + export interface Config { + /** @deepVisibility frontend */ + a?: unknown; + } + + // plugins/a/config.schema.ts + export interface Config { + a?: { + b?: string; + }; + } + ``` + + All values under `a` are now visible to the frontend, while previously only `a` and `a/b` would've been visible. + +### Patch Changes + +- f9657b891b00: Do not unnecessarily notify subscribers when no-op updates to config happen +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/types@1.1.0 + +## 1.4.0 + +### Minor Changes + +- 2f1859585998: Loading invalid TypeScript configuration schemas will now throw an error rather than silently being ignored. + + In particular this includes defining any additional types other than `Config` in the schema file, or use of unsupported types such as `Record` or `Partial`. + +- cd514545d1d0: Adds a new `deepVisibility` schema keyword that sets child visibility recursively to the defined value, respecting preexisting values or child `deepVisibility`. + + Example usage: + + ```ts + export interface Config { + /** + * Enforces a default of `secret` instead of `backend` for this object. + * @deepVisibility secret + */ + mySecretProperty: { + type: 'object'; + properties: { + secretValue: { + type: 'string'; + }; + + verySecretProperty: { + type: 'string'; + }; + }; + }; + } + ``` + + Example of a schema that would not be allowed: + + ```ts + export interface Config { + /** + * Set the top level property to secret, enforcing a default of `secret` instead of `backend` for this object. + * @deepVisibility secret + */ + mySecretProperty: { + type: 'object'; + properties: { + frontendUrl: { + /** + * We can NOT override the visibility to reveal a property to the front end. + * @visibility frontend + */ + type: 'string'; + }; + + verySecretProperty: { + type: 'string'; + }; + }; + }; + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/types@1.1.0 + +## 1.4.0-next.1 + +### Minor Changes + +- 2f1859585998: Loading invalid TypeScript configuration schemas will now throw an error rather than silently being ignored. + + In particular this includes defining any additional types other than `Config` in the schema file, or use of unsupported types such as `Record` or `Partial`. + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/types@1.1.0 + +## 1.4.0-next.0 + +### Minor Changes + +- cd514545d1d0: Adds a new `deepVisibility` schema keyword that sets child visibility recursively to the defined value, respecting preexisting values or child `deepVisibility`. + + Example usage: + + ```ts + export interface Config { + /** + * Enforces a default of `secret` instead of `backend` for this object. + * @deepVisibility secret + */ + mySecretProperty: { + type: 'object'; + properties: { + secretValue: { + type: 'string'; + }; + + verySecretProperty: { + type: 'string'; + }; + }; + }; + } + ``` + + Example of a schema that would not be allowed: + + ```ts + export interface Config { + /** + * Set the top level property to secret, enforcing a default of `secret` instead of `backend` for this object. + * @deepVisibility secret + */ + mySecretProperty: { + type: 'object'; + properties: { + frontendUrl: { + /** + * We can NOT override the visibility to reveal a property to the front end. + * @visibility frontend + */ + type: 'string'; + }; + + verySecretProperty: { + type: 'string'; + }; + }; + }; + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/types@1.1.0 + +## 1.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/types@1.1.0 + +## 1.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.1-next.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/types@1.1.0 + +## 1.3.1 + +### Patch Changes + +- f25427f665f7: Fix a bug where config items with `/` in the key were incorrectly handled. +- a5c5491ff50c: Use `durationToMilliseconds` from `@backstage/types` instead of our own +- Updated dependencies + - @backstage/types@1.1.0 + - @backstage/errors@1.2.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + +## 1.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.0-next.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + +## 1.3.1-next.0 + +### Patch Changes + +- f25427f665f7: Fix a bug where config items with `/` in the key were incorrectly handled. +- Updated dependencies + - @backstage/config@1.0.7 + - @backstage/cli-common@0.1.12 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 1.3.0 + +### Minor Changes + +- 201206132da: Introduced a new config source system to replace `loadConfig`. There is a new `ConfigSource` interface along with utilities provided by `ConfigSources`, as well as a number of built-in configuration source implementations. The new system is more flexible and makes it easier to create new and reusable sources of configuration, such as loading configuration from secret providers. + + The following is an example of how to load configuration using the default behavior: + + ```ts + const source = ConfigSources.default({ + argv: options?.argv, + remote: options?.remote, + }); + const config = await ConfigSources.toConfig(source); + ``` + + The `ConfigSource` interface looks like this: + + ```ts + export interface ConfigSource { + readConfigData(options?: ReadConfigDataOptions): AsyncConfigSourceIterator; + } + ``` + + It is best implemented using an async iterator: + + ```ts + class MyConfigSource implements ConfigSource { + async *readConfigData() { + yield { + config: [ + { + context: 'example', + data: { backend: { baseUrl: 'http://localhost' } }, + }, + ], + }; + } + } + ``` + +### Patch Changes + +- 7c116bcac7f: Fixed the way that some request errors are thrown +- 473db605a4f: Added a new `noUndeclaredProperties` option to `SchemaLoader` to support enforcing that there are no extra keys when verifying config. +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 1.3.0-next.0 + +### Minor Changes + +- 201206132da: Introduced a new config source system to replace `loadConfig`. There is a new `ConfigSource` interface along with utilities provided by `ConfigSources`, as well as a number of built-in configuration source implementations. The new system is more flexible and makes it easier to create new and reusable sources of configuration, such as loading configuration from secret providers. + + The following is an example of how to load configuration using the default behavior: + + ```ts + const source = ConfigSources.default({ + argv: options?.argv, + remote: options?.remote, + }); + const config = await ConfigSources.toConfig(source); + ``` + + The `ConfigSource` interface looks like this: + + ```ts + export interface ConfigSource { + readConfigData(options?: ReadConfigDataOptions): AsyncConfigSourceIterator; + } + ``` + + It is best implemented using an async iterator: + + ```ts + class MyConfigSource implements ConfigSource { + async *readConfigData() { + yield { + config: [ + { + context: 'example', + data: { backend: { baseUrl: 'http://localhost' } }, + }, + ], + }; + } + } + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 1.2.0 + +### Minor Changes + +- c791fcd96b9: Configuration validation is now more permissive when it comes to config whose values are `string` but whose schemas declare them to be `boolean` or `number`. + + For example, configuration was previously marked invalid when a string `'true'` was set on a property expecting type `boolean` or a string `'146'` was set on a property expecting type `number` (as when providing configuration via variable substitution sourced from environment variables). Now, such configurations will be considered valid and their values will be coerced to the right type at read-time. + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/types@1.0.2 + +## 1.1.9 + +### Patch Changes + +- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. +- 482dae5de1c: Updated link to docs. +- Updated dependencies + - @backstage/errors@1.1.5 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/types@1.0.2 + +## 1.1.9-next.0 + +### Patch Changes + +- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. +- 482dae5de1c: Updated link to docs. +- Updated dependencies + - @backstage/errors@1.1.5-next.0 + - @backstage/cli-common@0.1.12-next.0 + - @backstage/config@1.0.7-next.0 + - @backstage/types@1.0.2 + +## 1.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/cli-common@0.1.11 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## 1.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## 1.1.7 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 40e7e6e1a2: Updated dependency `typescript-json-schema` to `^0.55.0`. +- Updated dependencies + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.5 + +## 1.1.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.11-next.0 + - @backstage/config@1.0.5-next.1 + - @backstage/errors@1.1.4-next.1 + - @backstage/types@1.0.2-next.1 + +## 1.1.7-next.1 + +### Patch Changes + +- 40e7e6e1a2: Updated dependency `typescript-json-schema` to `^0.55.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/cli-common@0.1.10 + - @backstage/errors@1.1.4-next.1 + +## 1.1.7-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/types@1.0.2-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + +## 1.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.1 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4 + - @backstage/errors@1.1.3 + +## 1.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.0.1-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + +## 1.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3 + - @backstage/errors@1.1.2 + - @backstage/types@1.0.0 + +## 1.1.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3-next.2 + - @backstage/errors@1.1.2-next.2 + - @backstage/types@1.0.0 + +## 1.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3-next.1 + - @backstage/errors@1.1.2-next.1 + - @backstage/types@1.0.0 + +## 1.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3-next.0 + - @backstage/errors@1.1.2-next.0 + - @backstage/types@1.0.0 + +## 1.1.4 + +### Patch Changes + +- 5ecca7e44b: No longer log when reloading remote config. +- 7d47def9c4: Removed dependency on `@types/jest`. +- 667d917488: Updated dependency `msw` to `^0.47.0`. +- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. +- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. +- Updated dependencies + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.2 + - @backstage/errors@1.1.1 + +## 1.1.4-next.2 + +### Patch Changes + +- 5ecca7e44b: No longer log when reloading remote config. +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/errors@1.1.1-next.0 + +## 1.1.4-next.1 + +### Patch Changes + +- 667d917488: Updated dependency `msw` to `^0.47.0`. +- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. + +## 1.1.4-next.0 + +### Patch Changes + +- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. + +## 1.1.3 + +### Patch Changes + +- bcada7cd9f: From now on the `$file` placeholder will trim the whitespaces and newline characters from the end of the file it reads. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- a3acec8819: Updated dependency `typescript-json-schema` to `^0.54.0`. +- Updated dependencies + - @backstage/errors@1.1.0 + +## 1.1.3-next.1 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- a3acec8819: Updated dependency `typescript-json-schema` to `^0.54.0`. + +## 1.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.1.0-next.0 + +## 1.1.2 + +### Patch Changes + +- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. + +## 1.1.2-next.0 + +### Patch Changes + +- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. + +## 1.1.1 + +### Patch Changes + +- cfc0f19699: Updated dependency `fs-extra` to `10.1.0`. +- 9e8ef53498: Handle empty config files gracefully +- Updated dependencies + - @backstage/cli-common@0.1.9 + - @backstage/config@1.0.1 + +## 1.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli-common@0.1.9-next.0 + - @backstage/config@1.0.1-next.0 + +## 1.1.1-next.0 + +### Patch Changes + +- cfc0f19699: Updated dependency `fs-extra` to `10.1.0`. +- 9e8ef53498: Handle empty config files gracefully + +## 1.1.0 + +### Minor Changes + +- 19f6c6c32a: Added `ignoreSchemaErrors` to `schema.process`. + +### Patch Changes + +- e0a51384ac: build(deps): bump `ajv` from 7.0.3 to 8.10.0 +- 230ad0826f: Bump to using `@types/node` v16 +- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values. + +## 1.1.0-next.1 + +### Minor Changes + +- 19f6c6c32a: Added `ignoreSchemaErrors` to `schema.process`. + +### Patch Changes + +- 230ad0826f: Bump to using `@types/node` v16 + +## 1.0.1-next.0 + +### Patch Changes + +- e0a51384ac: build(deps): bump `ajv` from 7.0.3 to 8.10.0 +- c47509e1a0: Implemented changes suggested by Deepsource.io including multiple double non-null assertion operators and unexpected awaits for non-promise values. + +## 1.0.0 + +### Major Changes + +- b58c70c223: This package has been promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy). + +### Patch Changes + +- 664821371e: The `typescript-json-schema` dependency that is used during schema collection is now lazy loaded, as it eagerly loads in the TypeScript compiler. +- f910c2a3f8: build(deps): bump `typescript-json-schema` from 0.52.0 to 0.53.0 +- Updated dependencies + - @backstage/config@1.0.0 + - @backstage/errors@1.0.0 + - @backstage/types@1.0.0 + +## 0.9.7 + +### Patch Changes + +- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 + +## 0.9.7-next.0 + +### Patch Changes + +- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 + +## 0.9.6 + +### Patch Changes + +- c3a1300f79: Include any files included in configuration via $include or $file directives when watching for configuration changes. + +## 0.9.5 + +### Patch Changes + +- Fix for the previous release with missing type declarations. +- Updated dependencies + - @backstage/cli-common@0.1.8 + - @backstage/config@0.1.15 + - @backstage/errors@0.2.2 + - @backstage/types@0.1.3 + +## 0.9.4 + +### Patch Changes + +- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 +- c77c5c7eb6: Added `backstage.role` to `package.json` +- Updated dependencies + - @backstage/errors@0.2.1 + - @backstage/cli-common@0.1.7 + - @backstage/config@0.1.14 + - @backstage/types@0.1.2 + +## 0.9.3 + +### Patch Changes + +- f685e1398f: Loading of app configurations now reference the `@deprecated` construct from + JSDoc to determine if a property in-use has been deprecated. Users are notified + of deprecated keys in the format: + + ```txt + The configuration key 'catalog.processors.githubOrg' of app-config.yaml is deprecated and may be removed soon. Configure a GitHub integration instead. + ``` + + When the `withDeprecatedKeys` option is set to `true` in the `process` method + of `loadConfigSchema`, the user will be notified that deprecated keys have been + identified in their app configuration. + + The `backend-common` and `plugin-app-backend` packages have been updated to set + `withDeprecatedKeys` to true so that users are notified of deprecated settings + by default. + +- Updated dependencies + - @backstage/config@0.1.13 + +## 0.9.3-next.0 + +### Patch Changes + +- f685e1398f: Loading of app configurations now reference the `@deprecated` construct from + JSDoc to determine if a property in-use has been deprecated. Users are notified + of deprecated keys in the format: + + ```txt + The configuration key 'catalog.processors.githubOrg' of app-config.yaml is deprecated and may be removed soon. Configure a GitHub integration instead. + ``` + + When the `withDeprecatedKeys` option is set to `true` in the `process` method + of `loadConfigSchema`, the user will be notified that deprecated keys have been + identified in their app configuration. + + The `backend-common` and `plugin-app-backend` packages have been updated to set + `withDeprecatedKeys` to true so that users are notified of deprecated settings + by default. + +- Updated dependencies + - @backstage/config@0.1.13-next.0 + +## 0.9.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@0.1.12 + - @backstage/errors@0.2.0 + +## 0.9.1 + +### Patch Changes + +- 84663d59a3: Bump `typescript-json-schema` from `^0.51.0` to `^0.52.0`. + +## 0.9.0 + +### Minor Changes + +- f6722d2458: Removed deprecated option `env` from `LoadConfigOptions` and associated tests +- 67d6cb3c7e: Removed deprecated option `configPaths` as it has been superseded by `configTargets` + +### Patch Changes + +- 1e7070443d: In case remote.reloadIntervalSeconds is passed, it must be a valid positive value + +## 0.8.1 + +### Patch Changes + +- b055a6addc: Align on usage of `cross-fetch` vs `node-fetch` in frontend vs backend packages, and remove some unnecessary imports of either one of them +- 4bea7b81d3: Uses key visibility as fallback in non-object arrays + +## 0.8.0 + +### Minor Changes + +- 1e99c73c75: Update `loadConfig` to return `LoadConfigResult` instead of an array of `AppConfig`. + + This function is primarily used internally by other config loaders like `loadBackendConfig` which means no changes are required for most users. + + If you use `loadConfig` directly you will need to update your usage from: + + ```diff + - const appConfigs = await loadConfig(options) + + const { appConfigs } = await loadConfig(options) + ``` + +### Patch Changes + +- 8809b6c0dd: Update the json-schema dependency version. +- Updated dependencies + - @backstage/cli-common@0.1.6 + +## 0.7.2 + +### Patch Changes + +- 0611f3b3e2: Reading app config from a remote server +- 26c5659c97: Bump msw to the same version as the rest + +## 0.7.1 + +### Patch Changes + +- 10615525f3: Switch to use the json and observable types from `@backstage/types` +- ea21f7f567: bump `typescript-json-schema` from 0.50.1 to 0.51.0 +- Updated dependencies + - @backstage/config@0.1.11 + - @backstage/cli-common@0.1.5 + - @backstage/errors@0.1.4 + +## 0.7.0 + +### Minor Changes + +- 7e97d0b8c1: Removed the `EnvFunc` public export. Its only usage was to be passed in to `LoadConfigOptions.experimentalEnvFunc`. If you were using this type, add a definition in your own project instead with the signature `(name: string) => Promise`. + +### Patch Changes + +- 223e8de6b4: Configuration schema errors are now filtered using the provided visibility option. This means that schema errors due to missing backend configuration will no longer break frontend builds. +- 7e97d0b8c1: Add public tags and documentation +- 36e67d2f24: Internal updates to apply more strict checks to throw errors. +- Updated dependencies + - @backstage/errors@0.1.3 + +## 0.6.10 + +### Patch Changes + +- 957e4b3351: Updated dependencies +- Updated dependencies + - @backstage/cli-common@0.1.4 + +## 0.6.9 + +### Patch Changes + +- ee7a1a4b64: Add option to collect configuration schemas from explicit package paths in addition to by package name. +- e68bd978e2: Allow collection of configuration schemas from multiple versions of the same package. + +## 0.6.8 + +### Patch Changes + +- d1da88a19: Properly export all used types. +- Updated dependencies + - @backstage/cli-common@0.1.3 + - @backstage/config@0.1.9 + +## 0.6.7 + +### Patch Changes + +- 0ade9d02b: Include `devDependencies` and `optionalDependencies` in the detection of Backstage packages when collecting configuration schema. +- 9b8cec063: Add support for config file watching through a new group of `watch` options to `loadConfig`. +- Updated dependencies + - @backstage/config@0.1.7 + +## 0.6.6 + +### Patch Changes + +- e9d3983ee: Add option to populate the `filteredKeys` property when processing configuration with a schema. +- Updated dependencies + - @backstage/config@0.1.6 + +## 0.6.5 + +### Patch Changes + +- ae84b20cf: Revert the upgrade to `fs-extra@10.0.0` as that seemed to have broken all installs inexplicably. + +## 0.6.4 + +### Patch Changes + +- f00493739: Removed workaround for breaking change in typescript 4.3 and bump `typescript-json-schema` instead. This should again allow the usage of `@items.visibility ` to set the visibility of array items. + +## 0.6.3 + +### Patch Changes + +- 2cf98d279: Resolve the path to app-config.yaml from the current working directory. This will allow use of `yarn link` or running the CLI in other directories and improve the experience for local backstage development. +- 438a512eb: Fixed configuration schema parsing when using TypeScript `4.3`. + +## 0.6.2 + +### Patch Changes + +- 290405276: Updated dependencies + +## 0.6.1 + +### Patch Changes + +- d8b81fd28: Bump `json-schema` dependency from `0.2.5` to `0.3.0`. +- Updated dependencies [d8b81fd28] + - @backstage/config@0.1.5 + +## 0.6.0 + +### Minor Changes + +- 82c66b8cd: Fix bug where `${...}` was not being escaped to `${...}` + + Add support for environment variable substitution in `$include`, `$file` and + `$env` transform values. + + - This change allows for including dynamic paths, such as environment specific + secrets by using the same environment variable substitution (`${..}`) already + supported outside of the various include transforms. + - If you are currently using the syntax `${...}` in your include transform values, + you will need to escape the substitution by using `${...}` instead to maintain + the same behavior. + +## 0.5.1 + +### Patch Changes + +- 062df71db: Bump `config-loader` to `ajv` 7, to enable v7 feature use elsewhere +- e9aab60c7: Each piece of the configuration schema is now validated upfront, in order to produce more informative errors. + +## 0.5.0 + +### Minor Changes + +- ef7957be4: Removed support for the deprecated `$data` placeholder. +- ef7957be4: Enable further processing of configuration files included using the `$include` placeholder. Meaning that for example for example `$env` includes will be processed as usual in included files. + +### Patch Changes + +- ef7957be4: Added support for environment variable substitutions in string configuration values using a `${VAR}` placeholder. All environment variables must be available, or the entire expression will be evaluated to `undefined`. To escape a substitution, use `${...}`, which will end up as `${...}`. + + For example: + + ```yaml + app: + baseUrl: https://${BASE_HOST} + ``` + +## 0.4.1 + +### Patch Changes + +- ad5c56fd9: Deprecate `$data` and replace it with `$include` which allows for any type of json value to be read from external files. In addition, `$include` can be used without a path, which causes the value at the root of the file to be loaded. + + Most usages of `$data` can be directly replaced with `$include`, except if the referenced value is not a string, in which case the value needs to be changed. For example: + + ```yaml + # app-config.yaml + foo: + $data: foo.yaml#myValue # replacing with $include will turn the value into a number + $data: bar.yaml#myValue # replacing with $include is safe + + # foo.yaml + myValue: 0xf00 + + # bar.yaml + myValue: bar + ``` + +## 0.4.0 + +### Minor Changes + +- 4e7091759: Fix typo of "visibility" in config schema reference + + If you have defined a config element named `visiblity`, you + will need to fix the spelling to `visibility`. For more info, + see . + +### Patch Changes + +- b4488ddb0: Added a type alias for PositionError = GeolocationPositionError + +## 0.3.0 + +### Minor Changes + +- 1722cb53c: Added support for loading and validating configuration schemas, as well as declaring config visibility through schemas. + + The new `loadConfigSchema` function exported by `@backstage/config-loader` allows for the collection and merging of configuration schemas from all nearby dependencies of the project. + + A configuration schema is declared using the `https://backstage.io/schema/config-v1` JSON Schema meta schema, which is based on draft07. The only difference to the draft07 schema is the custom `visibility` keyword, which is used to indicate whether the given config value should be visible in the frontend or not. The possible values are `frontend`, `backend`, and `secret`, where `backend` is the default. A visibility of `secret` has the same scope at runtime, but it will be treated with more care in certain contexts, and defining both `frontend` and `secret` for the same value in two different schemas will result in an error during schema merging. + + Packages that wish to contribute configuration schema should declare it in a root `"configSchema"` field in `package.json`. The field can either contain an inlined JSON schema, or a relative path to a schema file. Schema files can be in either `.json` or `.d.ts` format. + + TypeScript configuration schema files should export a single `Config` type, for example: + + ```ts + export interface Config { + app: { + /** + * Frontend root URL + * @visibility frontend + */ + baseUrl: string; + }; + } + ``` + +## 0.2.0 + +### Minor Changes + +- 8c2b76e45: **BREAKING CHANGE** + + The existing loading of additional config files like `app-config.development.yaml` using APP_ENV or NODE_ENV has been removed. + Instead, the CLI and backend process now accept one or more `--config` flags to load config files. + + Without passing any flags, `app-config.yaml` and, if it exists, `app-config.local.yaml` will be loaded. + If passing any `--config ` flags, only those files will be loaded, **NOT** the default `app-config.yaml` one. + + The old behaviour of for example `APP_ENV=development` can be replicated using the following flags: + + ```bash + --config ../../app-config.yaml --config ../../app-config.development.yaml + ``` + +- ce5512bc0: Added support for new shorthand when defining secrets, where `$env: ENV` can be used instead of `$secret: { env: ENV }` etc. + +## @backstage/backend-defaults@0.13.0-next.2 + +### Minor Changes + +- 8495b18: Add a new `externalTokenHandlersServiceRef` to allow custom external token validations + +## @backstage/plugin-mui-to-bui@0.2.0-next.0 + +### Minor Changes + +- d5cbdba: This is the first release of the Material UI to Backstage UI migration helper plugin. It adds a new page at `/mui-to-bui` that converts an existing MUI v5 theme into Backstage UI (BUI) CSS variables, with live preview and copy/download. + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.2-next.1 + - @backstage/theme@0.6.9-next.0 + +## @backstage/plugin-notifications-backend-module-slack@0.2.0-next.1 + +### Minor Changes + +- 3d09bb2: Adds username as optional config in order to send Slack notifications with a specific username in the case when using one Slack App for more than just Backstage. + +## @backstage/app-defaults@1.7.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## @backstage/cli@0.34.4-next.2 + +### Patch Changes + +- ab96bb7: Added a new `--entrypoint` option to the `package start` command, which allows you to specify a custom entry directory/file for development applications. This is particularly useful when maintaining separate dev apps for different versions of your plugin (e.g., stable and alpha). + + **Example usage:** + + Consider the following plugin dev folder structure: + + dev/ + index.tsx + alpha/ + index.ts + + - The default `yarn package start` command uses the `dev/` folder as the entry point and executes `dev/index.tsx` file; + - Running `yarn package start --entrypoint dev/alpha` will instead use `dev/alpha/` as the entry point and execute `dev/alpha/index.ts` file. + +## @backstage/core-components@0.18.2-next.2 + +### Patch Changes + +- 95935fb: Fixed dependency graph automatically scrolling forever +- Updated dependencies + - @backstage/theme@0.6.9-next.0 + +## @backstage/create-app@0.7.5-next.2 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/dev-utils@1.1.15-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/app-defaults@1.7.1-next.2 + +## @backstage/test-utils@1.7.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.9-next.0 + +## @backstage/theme@0.6.9-next.0 + +### Patch Changes + +- d5cbdba: The `UnifiedThemeProvider` now coordinates theme attributes on the document `body` in case multiple theme providers are rendered. + +## @backstage/ui@0.7.2-next.1 + +### Patch Changes + +- a9b88be: Enable tooltips on disabled buttons with automatic wrapper +- 4adbb03: Avoid overriding onChange when spreading props + +## @backstage/plugin-app@0.3.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## @backstage/plugin-auth@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## @backstage/plugin-catalog-backend@3.1.2-next.2 + +### Patch Changes + +- 6493c98: Log before provider-orphaning eviction happens +- 77516c5: Added new `catalog:validate-entity` action to actions registry. + + This action can be used to validate entities against the software catalog. + This is useful for validating `catalog-info.yaml` file changes locally using the + Backstage MCP server. + +## @backstage/plugin-home@0.8.13-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## @backstage/plugin-kubernetes-react@0.5.12-next.2 + +### Patch Changes + +- ac405f2: The configmaps added to be rendered +- f7a4144: Fixes calculation of CPU utilization in the PodTable +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + +## @backstage/plugin-notifications@0.5.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## @backstage/plugin-notifications-backend@0.5.11-next.1 + +### Patch Changes + +- 3b8e156: Fixed exclude entity reference not working in notification sending + +## @backstage/plugin-org@0.6.45-next.2 + +### Patch Changes + +- 8b7351f: Add `initialRelationAggregation` and `showAggregateMembersToggle` options to `EntityMembersListCard` as well to `EntityOwnershipCard` +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + +## @backstage/plugin-scaffolder@1.34.2-next.2 + +### Patch Changes + +- 075e064: Added missing form fields for the new frontend system. +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.2-next.2 + - @backstage/core-components@0.18.2-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + +## @backstage/plugin-scaffolder-react@1.19.2-next.2 + +### Patch Changes + +- e61f89e: Don't change loading to false until we've actually got some log state +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## @backstage/plugin-search-react@1.9.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## @backstage/plugin-signals@0.0.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## @backstage/plugin-techdocs@1.15.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/plugin-search-react@1.9.5-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + +## @backstage/plugin-user-settings@0.8.27-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## example-app@0.2.114-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-mui-to-bui@0.2.0-next.0 + - @backstage/plugin-scaffolder-react@1.19.2-next.2 + - @backstage/plugin-org@0.6.45-next.2 + - @backstage/cli@0.34.4-next.2 + - @backstage/ui@0.7.2-next.1 + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/plugin-scaffolder@1.34.2-next.2 + - @backstage/app-defaults@1.7.1-next.2 + - @backstage/plugin-home@0.8.13-next.2 + - @backstage/plugin-notifications@0.5.10-next.2 + - @backstage/plugin-search-react@1.9.5-next.2 + - @backstage/plugin-signals@0.0.24-next.2 + - @backstage/plugin-techdocs@1.15.1-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/plugin-user-settings@0.8.27-next.2 + +## example-app-next@0.0.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.2-next.2 + - @backstage/plugin-org@0.6.45-next.2 + - @backstage/cli@0.34.4-next.2 + - @backstage/ui@0.7.2-next.1 + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/plugin-scaffolder@1.34.2-next.2 + - @backstage/app-defaults@1.7.1-next.2 + - @backstage/plugin-app@0.3.1-next.2 + - @backstage/plugin-auth@0.1.1-next.1 + - @backstage/plugin-home@0.8.13-next.2 + - @backstage/plugin-notifications@0.5.10-next.2 + - @backstage/plugin-search-react@1.9.5-next.2 + - @backstage/plugin-signals@0.0.24-next.2 + - @backstage/plugin-techdocs@1.15.1-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/plugin-user-settings@0.8.27-next.2 + +## techdocs-cli-embedded-app@0.2.113-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.4-next.2 + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/app-defaults@1.7.1-next.2 + - @backstage/test-utils@1.7.12-next.1 + - @backstage/plugin-techdocs@1.15.1-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 diff --git a/docs/releases/v1.44.0-next.3-changelog.md b/docs/releases/v1.44.0-next.3-changelog.md new file mode 100644 index 0000000000..8a65d6d6a6 --- /dev/null +++ b/docs/releases/v1.44.0-next.3-changelog.md @@ -0,0 +1,219 @@ +# Release v1.44.0-next.3 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.44.0-next.3](https://backstage.github.io/upgrade-helper/?to=1.44.0-next.3) + +## @backstage/backend-app-api@1.2.8-next.1 + +### Patch Changes + +- dd69cf6: Moved up registration of unhandled rejections and errors listeners to be done as early as possible, avoiding flakiness in backend startups and instead always logging these failures rather than sometimes crashing the process. + +## @backstage/cli@0.34.4-next.3 + +### Patch Changes + +- f2cf564: Removed the script transform cache from the default Jest configuration. The script cache provided a moderate performance boost, but it is incompatible with Jest 30. + +- 024645e: Remove unused @octokit modules from cli package + + - @octokit/graphql + - @octokit/graphql-schema + - @octokit/oauth-app + +- d14ef24: Added automatic detection and support for the Backstage Yarn plugin when generating new packages with `yarn new`. When the plugin is installed, new packages will automatically use `backstage:^` ranges for `@backstage/*` dependencies. + +## @backstage/core-components@0.18.2-next.3 + +### Patch Changes + +- 431130c: Added `renderEdge` prop to `` component in `@backstage/core-components` to allow custom rendering of graph edges. + +## @backstage/create-app@0.7.5-next.3 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/frontend-plugin-api@0.12.1-next.2 + +### Patch Changes + +- 8ed53eb: Added `coreExtensionData.title`, especially useful for creating extensible layout with tabbed pages, but available for use for other cases too. +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + +## @backstage/ui@0.7.2-next.2 + +### Patch Changes + +- 3c921c5: Making href mandatory in tabs that are part of a Header component +- 5c21e45: Add react router for internal routing for ButtonLinks +- 9781815: Remove auto selection of tabs for tabs that all have href defined +- f6dff5b: Using react router for internal links in the Menu component + +## @backstage/plugin-app-visualizer@0.1.24-next.2 + +### Patch Changes + +- 4406144: Ensure that the text rendering has react keys for all elements +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + - @backstage/frontend-plugin-api@0.12.1-next.2 + +## @backstage/plugin-catalog-backend-module-aws@0.4.16-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies + +## @backstage/plugin-catalog-backend-module-azure@0.3.10-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.4-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.4-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.7-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies + +## @backstage/plugin-catalog-backend-module-github@0.11.1-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies + +## @backstage/plugin-catalog-backend-module-github-org@0.3.15-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.11.1-next.2 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.4-next.2 + +### Patch Changes + +- 0443119: Fixed an issue in `GitlabDiscoveryEntityProvider` where entity fetching could fail for projects with special characters or that had been renamed or moved. +- 99fcf98: Removed unused dependencies + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.14-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.4-next.2 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.1-next.1 + +### Patch Changes + +- 99fcf98: Removed unused dependencies + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.15-next.1 + +### Patch Changes + +- 99fcf98: Removed unused dependencies + +## @backstage/plugin-catalog-graph@0.5.2-next.2 + +### Patch Changes + +- 431130c: Added `renderEdge` prop to `` component in `@backstage/core-components` to allow custom rendering of graph edges. +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + - @backstage/frontend-plugin-api@0.12.1-next.2 + +## @backstage/plugin-home@0.8.13-next.3 + +### Patch Changes + +- e7d59d3: fix(home): correct `clearAll` logic to properly handle `deletable` flag +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + - @backstage/frontend-plugin-api@0.12.1-next.2 + +## @backstage/plugin-kubernetes@0.12.12-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + - @backstage/frontend-plugin-api@0.12.1-next.2 + +## @backstage/plugin-kubernetes-cluster@0.0.30-next.2 + +### Patch Changes + +- 99fcf98: Removed unused dependencies +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + +## @backstage/plugin-notifications@0.5.10-next.3 + +### Patch Changes + +- f5e0963: Removed unused dependencies +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + - @backstage/frontend-plugin-api@0.12.1-next.2 + +## @backstage/plugin-notifications-backend@0.5.11-next.2 + +### Patch Changes + +- f5e0963: Removed unused dependencies + +## @backstage/plugin-notifications-backend-module-email@0.3.14-next.1 + +### Patch Changes + +- b8cf31a: chore(deps): bump `nodemailer` from 6.9.16 to 7.0.7 +- f5e0963: Removed unused dependencies + +## @backstage/plugin-scaffolder@1.34.2-next.3 + +### Patch Changes + +- d9aed74: Forward `ui:disabled` in `OwnedEntityPicker` to allow disabling it +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + - @backstage/frontend-plugin-api@0.12.1-next.2 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.14-next.2 + +### Patch Changes + +- f5e0963: Removed unused dependencies + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.6-next.2 + +### Patch Changes + +- f5e0963: Removed unused dependencies + +## @backstage/plugin-signals@0.0.24-next.3 + +### Patch Changes + +- 7b41d9d: Remove `app-root-element:signals/signals-display` which was not doing anything useful +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + - @backstage/frontend-plugin-api@0.12.1-next.2 diff --git a/docs/releases/v1.44.0.md b/docs/releases/v1.44.0.md new file mode 100644 index 0000000000..c57708a8ec --- /dev/null +++ b/docs/releases/v1.44.0.md @@ -0,0 +1,141 @@ +--- +id: v1.44.0 +title: v1.44.0 +description: Backstage Release v1.44.0 +--- + +These are the release notes for the v1.44.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for all the hard work in getting this release developed and done. + +## Highlights + +### Scaffolder Backend 3.0 + +**BREAKING**: + +Removal of deprecated types and interfaces: `CreateWorkerOptions`, `CurrentClaimedTask`, `DatabaseTaskStore`, `TaskManager`, etc. + +The `TaskBroker` interface now requires the `cancel`, `recoverTasks`, and `retry` methods to be implemented. If your implementation of `TaskBroker` doesn’t use these methods, you can replace them with a `no-op () => void` function. +Please reach out to us in an issue as we're thinking about completely removing the `TaskBroker` extension point soon and would like to hear your use cases for the upcoming re-architecture of the `scaffolder-backend` plugin. + +The `scaffolderActionsExtensionPoint` has been moved from `/alpha` to the main export. + +```ts +// before +import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; + +// after +import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node'; +``` + +**DEPRECATION**: + +We're going to be working on refactoring a lot of the internals of the Scaffolder backend plugin, and with that come a lot of deprecations and removals for public types that are making these things hard. + +If you're using these types, please reach out to us either on Discord or a GitHub issue with your use cases. + +- `SerializedTask`, `SerializedTaskEvent`, `TaskBroker`, `TaskContext`, `TaskBrokerDispatchOptions`, `TaskBrokerDispatchResult`, `TaskCompletionState`, `TaskEventType`, `TaskFilter`, `TaskFilters`, `TaskStatus` are the types that have now been marked as deprecated, and will be removed in a future release. + +### Design System: Backstage Theme + +**BREAKING** Removed the built-in `CssBaseline` from `UnifiedThemeProvider`. If your Backstage instance looks broken after this update, you likely forgot to add our new Backstage UI global CSS. To do that, please import `@backstage/ui/css/styles.css` in `packages/app/src/index.tsx`: + +```tsx +import '@backstage/ui/css/styles.css'; +``` + +This change also removes the `noCssBaseline` prop, which became redundant. + +### Design System: Backstage UI + +**NEW** + +Adding a new `Dialog` component to Backstage UI. Contributed by [@ssjoblad](https://github.com/@ssjoblad) in [#31371](https://github.com/backstage/backstage/pull/31371) +Added new `virtualized`, `maxWidth` and `maxHeight` props to `Menu`, `MenuListBox`, `MenuAutocomplete` and `MenuAutocompleteListBox` to allow for virtualization of long lists inside menus. + +**BREAKING** + +New `PasswordField` component - removed `password` and `search` types from `TextField`. Contributed by [@birdhb](https://github.com/birdhb) in [#31238](https://github.com/backstage/backstage/pull/31238) +Restructured Backstage UI component styling to use CSS Modules instead of pure CSS. We don't expect this to be an issue in practice but it is important to call out that all styles are now loaded through CSS modules with generated class names. We are still providing fixed class names for all components to allow anyone to style their Backstage instance. +The `ScrollArea` component has been removed from Backstage UI because it did not meet our accessibility standards. +Removed Icon component in Backstage UI. This component was creating issues for tree-shaking. It is recommended to use icons from `@remixicon/react` until we find a better alternative in Backstage UI. + +### **BREAKING**: Extension testing with new `renderTestApp` + +The `extensions` option was removed from `renderInTestApp`, because it led to confusing effects where the old and new frontend worlds were mixed. If you need to pass extensions to the test app, use the new `renderTestApp` utility instead. + +### Backstage CLI: Yarn plugin + +Added automatic detection and support for the Backstage Yarn plugin when generating new packages with `yarn new`. When the plugin is installed, new packages will automatically use `backstage:^` ranges for `@backstage/*` dependencies. + +### Backstage CLI: App entrypoints + +Added a new `--entrypoint` option to the `package start` command, which allows you to specify a custom entry directory/file for development applications. This is particularly useful when maintaining separate dev apps for different versions of your plugin (e.g., stable and alpha). + +For example, consider the following plugin dev folder structure: + +``` +dev/ + index.tsx + alpha/ + index.ts +``` + +- The default `yarn package start` command uses the `dev/` folder as the entry point and executes `dev/index.tsx` file; +- Running `yarn package start --entrypoint dev/alpha` will instead use `dev/alpha/` as the entry point and execute `dev/alpha/index.ts` file. + +### Support for custom external service auth methods + +A new service ref has finally landed: the external token handler. This allows adopters to add custom handlers for authorization tokens that are sent to your backend plugins. So if your organization already has a settled service-to-service auth method in your backend flora, you can now seamlessly make Backstage accept those too. This complements the pre-existing support for static and JWKS-based tokens. + +As usual, it's all documented in [the corresponding service-to-service auth section](https://backstage.io/docs/auth/service-to-service-auth) on the microsite. + +Contributed by [@Sarabadu](https://github.com/Sarabadu) in [#28942](https://github.com/backstage/backstage/pull/28942) + +### New plugin: Themer + +There’s a new Material UI to Backstage UI migration helper plugin. It adds a new page at `/mui-to-bui` that converts an existing MUI v5 theme into Backstage UI (BUI) CSS variables, with live preview and copy/download. There are some more details and screenshots in [the pull request](https://github.com/backstage/backstage/pull/31140). + +### Relaxed linting in the new frontend system + +The built-in lint rules used to forbid frontend plugin packages from importing other frontend plugin packages - those dependencies should normally be moved to a `-react` or `-common` package instead. + +But in the new frontend system, it becomes a common desire to extend and adapt other plugins, which implies importing those plugins in code. So the lint rules have been relaxed to support this specific case, IF the plugin IDs of the two packages are the same. + +This means that you can now make an (internal) frontend plugin package that your app imports, and then that internal package in turn imports the open source plugin you are adapting. So you no longer have to keep your adaptations inside the app itself! + +Contributed by [@drodil](https://github.com/drodil) in [#31373](https://github.com/backstage/backstage/pull/31373) + +### TechDocs CLI serve now supports live reloading + +The TechDocs CLI and its embedded app now leverage `mkdocs` live reload support. Let us know how it works out for you! + +Contributed by [@GabDug](https://github.com/GabDug) in [#30541](https://github.com/backstage/backstage/pull/30541) + +### Easier server options through config + +You can now more easily set low level HTTP server options such as request timeouts for your backend, directly from your app-config without having to adapt your root HTTP router service. Check out [the relevant service docs](https://backstage.io/docs/backend-system/core-services/root-http-router) for more details! + +Contributed by [@BethGriggs](https://github.com/BethGriggs) in [#30483](https://github.com/backstage/backstage/pull/30483) + +## Security Fixes + +This release does not contain any security fixes. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.44.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.45.0-next.0-changelog.md b/docs/releases/v1.45.0-next.0-changelog.md new file mode 100644 index 0000000000..da49684cfb --- /dev/null +++ b/docs/releases/v1.45.0-next.0-changelog.md @@ -0,0 +1,2372 @@ +# Release v1.45.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.45.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.45.0-next.0) + +## @backstage/backend-test-utils@1.10.0-next.0 + +### Minor Changes + +- d57b13b: Added support for Postgres 18 to the available `TestDatabases`. + + Note that the set of _default_ databases to test against for users of the `TestDatabases` class was also updated to include Postgres 14 and 18, instead of 13 and 17. If you need to override this, you can pass in an explicit `ids` argument, for example `ids: ['POSTGRES_17', 'POSTGRES_13', 'SQLITE_3']`. + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-app-api@1.2.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/eslint-plugin@0.2.0-next.0 + +### Minor Changes + +- 926389b: Added `@backstage/no-ui-css-imports-in-non-frontend` rule, which ensures that CSS from `@backstage/ui` is not imported outside of the frontend app. + +## @backstage/app-defaults@1.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/theme@0.7.0 + +## @backstage/backend-app-api@1.2.9-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/backend-defaults@0.13.1-next.0 + +### Patch Changes + +- 9bcfa77: Adjusted the log line wording of task worker starting +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- b2f6a5a: Fix #31348 issue where BitbucketUrlReader ignored provided token and instead always used integration credentials +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-app-api@1.2.9-next.0 + - @backstage/config-loader@1.10.6-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/cli-node@0.2.15-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/integration-aws-node@0.1.19-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/backend-dynamic-feature-service@0.7.6-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-catalog-backend@3.1.3-next.0 + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/plugin-events-backend@0.5.8-next.0 + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config-loader@1.10.6-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/cli-node@0.2.15-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-openapi-utils@0.6.3-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-app-node@0.1.39-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/backend-openapi-utils@0.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/backend-plugin-api@1.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/catalog-client@1.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/errors@1.2.7 + +## @backstage/catalog-model@1.7.6-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/cli@0.34.5-next.0 + +### Patch Changes + +- fc7cbfc: The templates executed with the `yarn new` command now supports templating filenames. +- fc7cbfc: Added a template for the `yarn new` command to create an catalog entity provider. To add this template to an explicit list in the root `package.json`, use `@backstage/cli/templates/catalog-provider-module`. +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/eslint-plugin@0.2.0-next.0 + - @backstage/config-loader@1.10.6-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/cli-node@0.2.15-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.2 + +## @backstage/cli-node@0.2.15-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/config@1.3.6-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/config-loader@1.10.6-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/core-app-api@1.19.2-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-compat-api@0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-components@0.18.3-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.7.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-plugin-api@1.11.2-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.7.6-next.0 + +### Patch Changes + +- fc7cbfc: Added the new `@backstage/cli/templates/catalog-provider-module` template to the explicit template configuration for the `next-app` template. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.17-next.0 + +### Patch Changes + +- b29a856: Fixed styling of the dev app by adding a lazy import of `@backstage/ui/css/styles.css`. +- Updated dependencies + - @backstage/ui@0.8.2-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/app-defaults@1.7.2-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/theme@0.7.0 + +## @backstage/frontend-app-api@0.13.2-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/frontend-defaults@0.3.3-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.13.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-app@0.3.2-next.0 + +## @backstage/frontend-dynamic-feature-loader@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + +## @backstage/frontend-plugin-api@0.12.2-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-test-utils@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.13.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/test-utils@1.7.13-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-app@0.3.2-next.0 + +## @backstage/integration@1.18.2-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/errors@1.2.7 + +## @backstage/integration-aws-node@0.1.19-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/errors@1.2.7 + +## @backstage/integration-react@1.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + +## @backstage/repo-tools@0.15.4-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config-loader@1.10.6-next.0 + - @backstage/cli-node@0.2.15-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @techdocs/cli@1.10.1-next.0 + +### Patch Changes + +- c2a2017: Fix for missing styles due to move to BUI. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-techdocs-node@1.13.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/cli-common@0.1.15 + +## @backstage/test-utils@1.7.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/theme@0.7.0 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/ui@0.8.2-next.0 + +### Patch Changes + +- 26c6a78: Fix default text color in Backstage UI +- dac851f: Fix the default font size in Backstage UI. +- 3c0ea67: Fix CSS layer ordering in Backstage UI to make sure component styles are loaded after tokens and base declarations. +- 4eb455c: Fix font smoothing as default in Backstage UI. +- 00bfb83: Fix default font wight and font family in Backstage UI. + +## @backstage/plugin-api-docs@0.13.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/plugin-catalog@1.31.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + +## @backstage/plugin-app@0.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/theme@0.7.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/plugin-app-backend@0.5.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config-loader@1.10.6-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-app-node@0.1.39-next.0 + +## @backstage/plugin-app-node@0.1.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-app-visualizer@0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + +## @backstage/plugin-auth@0.1.2-next.0 + +### Patch Changes + +- 1609e79: Authentication content screen now uses application title. +- Updated dependencies + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.7.0 + +## @backstage/plugin-auth-backend@0.25.6-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.6-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.9-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.6-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-backend-module-openshift-provider@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-auth-node@0.6.9-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-auth-react@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-bitbucket-cloud-common@0.3.4-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/integration@1.18.2-next.0 + +## @backstage/plugin-catalog@1.31.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-scaffolder-common@1.7.3-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## @backstage/plugin-catalog-backend@3.1.3-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-openapi-utils@0.6.3-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.4.17-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/integration-aws-node@0.1.19-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-kubernetes-common@0.9.8-next.0 + +## @backstage/plugin-catalog-backend-module-azure@0.3.11-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.8-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-openapi-utils@0.6.3-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.4-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-kubernetes-common@0.9.8-next.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.11.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-catalog-backend-module-github@0.11.2-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-catalog-backend-module-gitlab@0.7.5-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-catalog-backend@3.1.3-next.0 + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.11-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-logs@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.3-next.0 + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.2-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-scaffolder-common@1.7.3-next.0 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.6-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.11-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-catalog-common@1.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-catalog-graph@0.5.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-catalog-import@0.13.7-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + +## @backstage/plugin-catalog-node@1.19.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-catalog-react@1.21.3-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/frontend-test-utils@0.4.1-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.23-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-unprocessed-entities-common@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-config-schema@0.1.74-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-devtools@0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-devtools-common@0.1.19-next.0 + +## @backstage/plugin-devtools-backend@0.5.11-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/config-loader@1.10.6-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-devtools-common@0.1.19-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-devtools-common@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-events-backend@0.5.8-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-openapi-utils@0.6.3-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.17-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-events-backend-module-azure@0.2.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-events-backend-module-github@0.4.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-events-backend-module-gitlab@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-events-backend-module-kafka@0.1.5-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-events-backend-test-utils@0.1.50-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + +## @backstage/plugin-events-node@0.4.17-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-gateway-backend@1.0.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-home@0.8.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-home-react@0.1.32-next.0 + +## @backstage/plugin-home-react@0.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + +## @backstage/plugin-kubernetes@0.12.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-react@0.5.13-next.0 + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/plugin-kubernetes-common@0.9.8-next.0 + +## @backstage/plugin-kubernetes-backend@0.20.4-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration-aws-node@0.1.19-next.0 + - @backstage/plugin-kubernetes-node@0.3.6-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-kubernetes-common@0.9.8-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-kubernetes-cluster@0.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-react@0.5.13-next.0 + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/plugin-kubernetes-common@0.9.8-next.0 + +## @backstage/plugin-kubernetes-common@0.9.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-kubernetes-node@0.3.6-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + - @backstage/plugin-kubernetes-common@0.9.8-next.0 + +## @backstage/plugin-kubernetes-react@0.5.13-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-kubernetes-common@0.9.8-next.0 + +## @backstage/plugin-mcp-actions-backend@0.1.5-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-mui-to-bui@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.8.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/theme@0.7.0 + +## @backstage/plugin-notifications@0.5.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.7.0 + - @backstage/plugin-notifications-common@0.1.2-next.0 + - @backstage/plugin-signals-react@0.0.17-next.0 + +## @backstage/plugin-notifications-backend@0.5.12-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.21-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-notifications-common@0.1.2-next.0 + - @backstage/plugin-signals-node@0.1.26-next.0 + +## @backstage/plugin-notifications-backend-module-email@0.3.15-next.0 + +### Patch Changes + +- 22a5362: Updated `AWS SES` client to version 2 to support `nodemailer` version 7. +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.21-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration-aws-node@0.1.19-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-notifications-common@0.1.2-next.0 + +## @backstage/plugin-notifications-backend-module-slack@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.21-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-notifications-common@0.1.2-next.0 + +## @backstage/plugin-notifications-common@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-notifications-node@0.2.21-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/plugin-notifications-common@0.1.2-next.0 + - @backstage/plugin-signals-node@0.1.26-next.0 + +## @backstage/plugin-org@0.6.46-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + +## @backstage/plugin-org-react@0.1.44-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/catalog-client@1.12.1-next.0 + +## @backstage/plugin-permission-backend@0.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-permission-common@0.9.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-permission-node@0.10.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-permission-react@0.4.38-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-proxy-backend@0.6.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + - @backstage/plugin-proxy-node@0.1.10-next.0 + +## @backstage/plugin-proxy-node@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.5-next.0 + +## @backstage/plugin-scaffolder@1.34.3-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-scaffolder-common@1.7.3-next.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## @backstage/plugin-scaffolder-backend@3.0.1-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.4-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-openapi-utils@0.6.3-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.15-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.16-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.15-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.15-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.7-next.0 + - @backstage/plugin-scaffolder-common@1.7.3-next.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-bitbucket-cloud-common@0.3.4-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.15-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.21-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-notifications-common@0.1.2-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.3.5-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-scaffolder-common@1.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-scaffolder-node@0.12.1-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-scaffolder-common@1.7.3-next.0 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.5-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-test-utils@1.10.0-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-scaffolder-react@1.19.3-next.0 + +### Patch Changes + +- 886a8a1: Fixed a bug in the Scaffolder's template parsing in the `useTemplateSchema` hook by removing the title instead of setting it to `undefined` +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/theme@0.7.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-scaffolder-common@1.7.3-next.0 + +## @backstage/plugin-search@1.4.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-search-backend@2.0.8-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-openapi-utils@0.6.3-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-search-backend-module-catalog@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.8-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/integration-aws-node@0.1.19-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-search-backend-module-explore@0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-search-backend-module-pg@0.5.50-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-search-backend-module-techdocs@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/plugin-techdocs-node@1.13.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-search-backend-node@1.3.17-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-search-common@1.2.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## @backstage/plugin-search-react@1.9.6-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/theme@0.7.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.21-next.0 + +## @backstage/plugin-signals@0.0.25-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/theme@0.7.0 + - @backstage/types@1.2.2 + - @backstage/plugin-signals-react@0.0.17-next.0 + +## @backstage/plugin-signals-backend@0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + - @backstage/plugin-signals-node@0.1.26-next.0 + +## @backstage/plugin-signals-node@0.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-signals-react@0.0.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/types@1.2.2 + +## @backstage/plugin-techdocs@1.15.2-next.0 + +### Patch Changes + +- a4d4a70: Fixed an issue where the entire TechDocs page would re-render when navigating between pages within the same entity's documentation. +- Updated dependencies + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-auth-react@0.1.21-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.15.2-next.0 + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/test-utils@1.7.13-next.0 + - @backstage/plugin-catalog@1.31.5-next.0 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## @backstage/plugin-techdocs-backend@2.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-techdocs-node@1.13.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.8-next.0 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## @backstage/plugin-techdocs-node@1.13.9-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/integration-aws-node@0.1.19-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.21-next.0 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-react@1.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-user-settings@0.8.29-next.0 + +### Patch Changes + +- 2b6fda3: Revert `storageApiRef` implementation +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.7.0 + - @backstage/types@1.2.2 + - @backstage/plugin-signals-react@0.0.17-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.8-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-signals-node@0.1.26-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.115-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.5-next.0 + - @backstage/ui@0.8.2-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-techdocs@1.15.2-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-signals@0.0.25-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.23-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/frontend-app-api@0.13.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/app-defaults@1.7.2-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-api-docs@0.13.1-next.0 + - @backstage/plugin-auth-react@0.1.21-next.0 + - @backstage/plugin-catalog@1.31.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-graph@0.5.3-next.0 + - @backstage/plugin-devtools@0.1.33-next.0 + - @backstage/plugin-home@0.8.14-next.0 + - @backstage/plugin-kubernetes@0.12.13-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.31-next.0 + - @backstage/plugin-mui-to-bui@0.2.1-next.0 + - @backstage/plugin-notifications@0.5.11-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-search@1.4.32-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.0 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## example-app-next@0.0.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.5-next.0 + - @backstage/ui@0.8.2-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-techdocs@1.15.2-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + - @backstage/plugin-auth@0.1.2-next.0 + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-signals@0.0.25-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.23-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/frontend-app-api@0.13.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/app-defaults@1.7.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/frontend-defaults@0.3.3-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-api-docs@0.13.1-next.0 + - @backstage/plugin-app@0.3.2-next.0 + - @backstage/plugin-app-visualizer@0.1.25-next.0 + - @backstage/plugin-auth-react@0.1.21-next.0 + - @backstage/plugin-catalog@1.31.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-graph@0.5.3-next.0 + - @backstage/plugin-home@0.8.14-next.0 + - @backstage/plugin-kubernetes@0.12.13-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.31-next.0 + - @backstage/plugin-notifications@0.5.11-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-search@1.4.32-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.0 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## app-next-example-plugin@0.0.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + +## example-backend@0.0.44-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-catalog-backend@3.1.3-next.0 + - @backstage/plugin-notifications-backend@0.5.12-next.0 + - @backstage/plugin-scaffolder-backend@3.0.1-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.7.8-next.0 + - @backstage/plugin-search-backend@2.0.8-next.0 + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/plugin-kubernetes-backend@0.20.4-next.0 + - @backstage/plugin-events-backend@0.5.8-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.8-next.0 + - @backstage/plugin-auth-backend@0.25.6-next.0 + - @backstage/plugin-devtools-backend@0.5.11-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.6-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.5-next.0 + - @backstage/plugin-app-backend@0.5.8-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.9-next.0 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.2-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.6-next.0 + - @backstage/plugin-permission-backend@0.7.6-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/plugin-proxy-backend@0.6.8-next.0 + - @backstage/plugin-signals-backend@0.3.10-next.0 + - @backstage/plugin-techdocs-backend@2.1.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.14-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.16-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.14-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.10-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.9-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.8-next.0 + +## e2e-test@0.2.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.6-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/frontend@0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## @internal/scaffolder@0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + +## techdocs-cli-embedded-app@0.2.114-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.5-next.0 + - @backstage/ui@0.8.2-next.0 + - @backstage/plugin-techdocs@1.15.2-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/app-defaults@1.7.2-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/test-utils@1.7.13-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-catalog@1.31.5-next.0 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## @internal/plugin-todo-list@1.0.45-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + +## @internal/plugin-todo-list-backend@1.0.45-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## @internal/plugin-todo-list-common@1.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.0 diff --git a/docs/releases/v1.45.0-next.1-changelog.md b/docs/releases/v1.45.0-next.1-changelog.md new file mode 100644 index 0000000000..098dd21e02 --- /dev/null +++ b/docs/releases/v1.45.0-next.1-changelog.md @@ -0,0 +1,9366 @@ +# Release v1.45.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.45.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.45.0-next.1) + +## @techdocs/cli@1.10.2-next.0 + +# @techdocs/cli + +## 1.10.1-next.0 + +### Patch Changes + +- c2a2017: Fix for missing styles due to move to BUI. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-techdocs-node@1.13.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/cli-common@0.1.15 + +## 1.10.0 + +### Minor Changes + +- 43afbe5: Techdocs CLI serve supports automatic refresh, relying on `mkdocs` `watch` feature. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/config@1.3.5 + - @backstage/plugin-techdocs-node@1.13.8 + +## 1.9.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/plugin-techdocs-node@1.13.8-next.1 + +## 1.9.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-techdocs-node@1.13.8-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + +## 1.9.8 + +### Patch Changes + +- db63208: Fixed an issue where `@techdocs/cli serve` command did not pick up the latest changes to TechDocs. +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-techdocs-node@1.13.7 + +## 1.9.8-next.0 + +### Patch Changes + +- db63208: Fixed an issue where `@techdocs/cli serve` command did not pick up the latest changes to TechDocs. +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-techdocs-node@1.13.7-next.0 + +## 1.9.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-techdocs-node@1.13.6 + +## 1.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-techdocs-node@1.13.6-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + +## 1.9.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-techdocs-node@1.13.5 + +## 1.9.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/plugin-techdocs-node@1.13.5-next.1 + +## 1.9.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-techdocs-node@1.13.5-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4 + +## 1.9.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## 1.9.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## 1.9.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-techdocs-node@1.13.4-next.0 + +## 1.9.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-techdocs-node@1.13.3 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + +## 1.9.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0-next.3 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.3-next.3 + +## 1.9.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0-next.2 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.3-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + +## 1.9.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0-next.1 + - @backstage/plugin-techdocs-node@1.13.3-next.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.1-next.0 + - @backstage/plugin-techdocs-node@1.13.3-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.0 + - @backstage/plugin-techdocs-node@1.13.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.0-next.2 + - @backstage/plugin-techdocs-node@1.13.2-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.0-next.1 + - @backstage/plugin-techdocs-node@1.13.2-next.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.9.0-next.0 + - @backstage/plugin-techdocs-node@1.13.2-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.2 + - @backstage/plugin-techdocs-node@1.13.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.2-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.1-next.2 + +## 1.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.2-next.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.1-next.1 + +## 1.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.2-next.0 + - @backstage/plugin-techdocs-node@1.13.1-next.0 + +## 1.9.0 + +### Minor Changes + +- 8de3d2d: Allow configurable optional retries for publisher AWS S3 operations. + +### Patch Changes + +- 69f84ac: Internal update to work with dynamic imports. +- Updated dependencies + - @backstage/backend-defaults@0.8.0 + - @backstage/plugin-techdocs-node@1.13.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.0-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.3 + - @backstage/plugin-techdocs-node@1.13.0-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.2 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.0-next.1 + +## 1.9.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.1 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.0-next.0 + +## 1.9.0-next.0 + +### Minor Changes + +- 8de3d2d: Allow configurable optional retries for publisher AWS S3 operations. + +### Patch Changes + +- 69f84ac: Internal update to work with dynamic imports. +- Updated dependencies + - @backstage/backend-defaults@0.8.0-next.0 + - @backstage/plugin-techdocs-node@1.13.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.8.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.7.0 + - @backstage/catalog-model@1.7.3 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.12.16 + +## 1.8.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.7.0-next.1 + - @backstage/catalog-model@1.7.3-next.0 + - @backstage/config@1.3.2-next.0 + - @backstage/plugin-techdocs-node@1.12.16-next.1 + - @backstage/cli-common@0.1.15 + +## 1.8.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.7.0-next.0 + - @backstage/catalog-model@1.7.2 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.1 + - @backstage/plugin-techdocs-node@1.12.16-next.0 + +## 1.8.24 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.6.0 + - @backstage/plugin-techdocs-node@1.12.15 + - @backstage/catalog-model@1.7.2 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.1 + +## 1.8.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.6.0-next.2 + - @backstage/plugin-techdocs-node@1.12.15-next.2 + - @backstage/catalog-model@1.7.2-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.1-next.0 + +## 1.8.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.6.0-next.1 + - @backstage/catalog-model@1.7.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.0 + - @backstage/plugin-techdocs-node@1.12.15-next.1 + +## 1.8.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.6.0-next.0 + - @backstage/plugin-techdocs-node@1.12.15-next.0 + - @backstage/catalog-model@1.7.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.0 + +## 1.8.22 + +### Patch Changes + +- 702f41d: Bumped dev dependencies `@types/node` +- Updated dependencies + - @backstage/config@1.3.0 + - @backstage/backend-defaults@0.5.3 + - @backstage/cli-common@0.1.15 + - @backstage/catalog-model@1.7.1 + - @backstage/plugin-techdocs-node@1.12.13 + +## 1.8.22-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.3-next.3 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.15-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.13-next.3 + +## 1.8.22-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.3-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.15-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.13-next.2 + +## 1.8.22-next.1 + +### Patch Changes + +- 702f41d: Bumped dev dependencies `@types/node` +- Updated dependencies + - @backstage/cli-common@0.1.15-next.0 + - @backstage/backend-defaults@0.5.3-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.13-next.1 + +## 1.8.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.3-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.13-next.0 + +## 1.8.20 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1 + - @backstage/plugin-techdocs-node@1.12.12 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.20-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.2 + - @backstage/plugin-techdocs-node@1.12.12-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.12-next.1 + +## 1.8.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.12-next.0 + +## 1.8.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0 + - @backstage/plugin-techdocs-node@1.12.11 + - @backstage/catalog-model@1.7.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.19-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.2 + - @backstage/plugin-techdocs-node@1.12.11-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.11-next.1 + +## 1.8.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.11-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2 + - @backstage/plugin-techdocs-node@1.12.9 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.3 + - @backstage/plugin-techdocs-node@1.12.9-next.3 + - @backstage/catalog-model@1.6.0-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.2 + - @backstage/plugin-techdocs-node@1.12.9-next.2 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.9-next.1 + - @backstage/backend-defaults@0.4.2-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.4.2-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.9-next.0 + +## 1.8.16 + +### Patch Changes + +- c964a3d: Import discovery from backend-defaults instead of backend-common +- Updated dependencies + - @backstage/backend-defaults@0.4.0 + - @backstage/plugin-techdocs-node@1.12.8 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 1.8.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.8-next.1 + - @backstage/backend-defaults@0.3.4-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + +## 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 + +## 1.8.12 + +### Patch Changes + +- 2110d76: Removed `dockerode` dependency. +- Updated dependencies + - @backstage/backend-common@0.23.0 + - @backstage/plugin-techdocs-node@1.12.5 + - @backstage/cli-common@0.1.14 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## 1.8.12-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.5-next.3 + - @backstage/cli-common@0.1.14-next.0 + - @backstage/backend-common@0.23.0-next.3 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + +## 1.8.12-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.5-next.2 + - @backstage/backend-common@0.23.0-next.2 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.0-next.1 + - @backstage/plugin-techdocs-node@1.12.5-next.1 + +## 1.8.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.22.1-next.0 + - @backstage/plugin-techdocs-node@1.12.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.11 + +### Patch Changes + +- 1a0e009: Fix cookie endpoint mock for `serve` +- Updated dependencies + - @backstage/catalog-model@1.5.0 + - @backstage/backend-common@0.22.0 + - @backstage/plugin-techdocs-node@1.12.4 + +## 1.8.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.22.0-next.1 + - @backstage/plugin-techdocs-node@1.12.4-next.1 + +## 1.8.10-next.0 + +### Patch Changes + +- 1a0e009: Fix cookie endpoint mock for `serve` +- Updated dependencies + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/backend-common@0.21.8-next.0 + - @backstage/plugin-techdocs-node@1.12.4-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.9 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7 + - @backstage/plugin-techdocs-node@1.12.3 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.7-next.1 + - @backstage/plugin-techdocs-node@1.12.3-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.3-next.0 + - @backstage/backend-common@0.21.7-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.8 + +### Patch Changes + +- 8caf2f7: Fix how the cli server mocks the new auth cookie endpoint. +- Updated dependencies + - @backstage/backend-common@0.21.6 + - @backstage/plugin-techdocs-node@1.12.2 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.5 + - @backstage/plugin-techdocs-node@1.12.1 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0 + +## 1.8.6 + +### Patch Changes + +- 1bd4596: Removed the `ts-node` dev dependency. +- Updated dependencies + - @backstage/backend-common@0.21.4 + - @backstage/config@1.2.0 + - @backstage/plugin-techdocs-node@1.12.0 + - @backstage/catalog-model@1.4.5 + - @backstage/cli-common@0.1.13 + +## 1.8.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.12.0-next.2 + - @backstage/backend-common@0.21.4-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.2.0-next.1 + +## 1.8.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/backend-common@0.21.4-next.1 + - @backstage/plugin-techdocs-node@1.11.6-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/cli-common@0.1.13 + +## 1.8.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.3-next.0 + - @backstage/plugin-techdocs-node@1.11.5-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/cli-common@0.1.13 + +## 1.8.2 + +### Patch Changes + +- 6bb6f3e: Updated dependency `fs-extra` to `^11.2.0`. + Updated dependency `@types/fs-extra` to `^11.0.0`. +- d2e3ab9: Updated dependency `dockerode` to `^4.0.0`. +- 6ba64c4: Updated dependency `commander` to `^12.0.0`. +- d8d243c: fix: mkdocs parameter casing +- Updated dependencies + - @backstage/backend-common@0.21.0 + - @backstage/catalog-model@1.4.4 + - @backstage/plugin-techdocs-node@1.11.2 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.2-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0-next.3 + - @backstage/plugin-techdocs-node@1.11.2-next.3 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0-next.2 + - @backstage/plugin-techdocs-node@1.11.2-next.2 + - @backstage/config@1.1.1 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/cli-common@0.1.13 + +## 1.8.2-next.1 + +### Patch Changes + +- d8d243c: fix: mkdocs parameter casing +- Updated dependencies + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/backend-common@0.21.0-next.1 + - @backstage/plugin-techdocs-node@1.11.2-next.1 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.21.0-next.0 + - @backstage/plugin-techdocs-node@1.11.2-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1 + - @backstage/plugin-techdocs-node@1.11.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1-next.2 + - @backstage/plugin-techdocs-node@1.11.1-next.2 + +## 1.8.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1-next.1 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.1-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + +## 1.8.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.1-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.1-next.0 + +## 1.8.0 + +### Minor Changes + +- d15d483: Add command `--runAsDefaultUser` for `@techdocs/cli generate` to bypass running the docker builds as host user for macOS and Linux. +- b2dccad: Support passing additional `mkdocs-server` CLI parameters (`--dirtyreload`, `--strict` and `--clean`) when run in containerized mode. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0 + - @backstage/plugin-techdocs-node@1.11.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.0-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.3 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.0-next.3 + +## 1.8.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.11.0-next.2 + +## 1.8.0-next.1 + +### Minor Changes + +- b2dccad7b3: Support passing additional `mkdocs-server` CLI parameters (`--dirtyreload`, `--strict` and `--clean`) when run in containerized mode. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.11.0-next.1 + - @backstage/backend-common@0.20.0-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.8.0-next.0 + +### Minor Changes + +- d15d483a49: Add command `--runAsDefaultUser` for `@techdocs/cli generate` to bypass running the docker builds as host user for macOS and Linux. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.20.0-next.0 + - @backstage/plugin-techdocs-node@1.11.0-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.7.0 + +### Minor Changes + +- 8600b86820: validate Docker status before running mkdocs server + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.10.0 + - @backstage/backend-common@0.19.9 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.6.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.9-next.2 + - @backstage/plugin-techdocs-node@1.10.0-next.2 + +## 1.6.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.10.0-next.1 + - @backstage/backend-common@0.19.9-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.9-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + - @backstage/plugin-techdocs-node@1.9.1-next.0 + +## 1.6.0 + +### Minor Changes + +- d06b30b050: Add possibility to use a mkdocs config file with a different name than `mkdocs. with the serve command using the `--mkdocs-config-file-name\` argument + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- 2b6e572051: Restructured tests. +- Updated dependencies + - @backstage/backend-common@0.19.8 + - @backstage/plugin-techdocs-node@1.9.0 + - @backstage/catalog-model@1.4.3 + - @backstage/cli-common@0.1.13 + - @backstage/config@1.1.1 + +## 1.6.0-next.2 + +### Minor Changes + +- d06b30b050: Add possibility to use a mkdocs config file with a different name than `mkdocs. with the serve command using the `--mkdocs-config-file-name\` argument + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.8-next.2 + - @backstage/plugin-techdocs-node@1.9.0-next.2 + - @backstage/catalog-model@1.4.3-next.0 + - @backstage/cli-common@0.1.13-next.0 + - @backstage/config@1.1.1-next.0 + +## 1.5.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.7-next.1 + - @backstage/plugin-techdocs-node@1.8.2-next.1 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/cli-common@0.1.13-next.0 + +## 1.5.2-next.0 + +### Patch Changes + +- de42eebaaf: Bumped dev dependencies `@types/node` and `mock-fs`. +- 2b6e572051: Restructured tests. +- Updated dependencies + - @backstage/cli-common@0.1.13-next.0 + - @backstage/backend-common@0.19.7-next.0 + - @backstage/plugin-techdocs-node@1.8.2-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + +## 1.5.0 + +### Minor Changes + +- 10a86bd4ae12: Add optional config and cli option for techdocs to specify default mkdocs plugins. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.5 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/plugin-techdocs-node@1.8.0 + - @backstage/cli-common@0.1.12 + +## 1.5.0-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.4.2-next.2 + - @backstage/config@1.1.0-next.2 + - @backstage/backend-common@0.19.5-next.3 + - @backstage/cli-common@0.1.12 + - @backstage/plugin-techdocs-node@1.8.0-next.3 + +## 1.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0-next.1 + - @backstage/backend-common@0.19.5-next.2 + - @backstage/catalog-model@1.4.2-next.1 + - @backstage/plugin-techdocs-node@1.8.0-next.2 + - @backstage/cli-common@0.1.12 + +## 1.5.0-next.1 + +### Minor Changes + +- 10a86bd4ae12: Add optional config and cli option for techdocs to specify default mkdocs plugins. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.1.0-next.0 + - @backstage/plugin-techdocs-node@1.8.0-next.1 + - @backstage/backend-common@0.19.5-next.1 + - @backstage/catalog-model@1.4.2-next.0 + - @backstage/cli-common@0.1.12 + +## 1.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.4-next.0 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/plugin-techdocs-node@1.7.6-next.0 + +## 1.4.5 + +### Patch Changes + +- 971bdd6a4732: Bumped internal `nodemon` dependency. +- Updated dependencies + - @backstage/backend-common@0.19.2 + - @backstage/plugin-techdocs-node@1.7.4 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + +## 1.4.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.2-next.2 + - @backstage/plugin-techdocs-node@1.7.4-next.2 + +## 1.4.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.2-next.1 + - @backstage/plugin-techdocs-node@1.7.4-next.1 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + +## 1.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.2-next.0 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/plugin-techdocs-node@1.7.4-next.0 + +## 1.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.1 + - @backstage/catalog-model@1.4.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/plugin-techdocs-node@1.7.3 + +## 1.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.1-next.0 + - @backstage/catalog-model@1.4.1-next.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + - @backstage/plugin-techdocs-node@1.7.3-next.0 + +## 1.4.3 + +### Patch Changes + +- 68a21956ef52: Remove reference to deprecated import +- Updated dependencies + - @backstage/backend-common@0.19.0 + - @backstage/plugin-techdocs-node@1.7.2 + - @backstage/catalog-model@1.4.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.8 + +## 1.4.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.0-next.2 + - @backstage/plugin-techdocs-node@1.7.2-next.2 + - @backstage/catalog-model@1.4.0-next.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.19.0-next.1 + - @backstage/plugin-techdocs-node@1.7.2-next.1 + - @backstage/catalog-model@1.4.0-next.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.6-next.0 + - @backstage/config@1.0.7 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/plugin-techdocs-node@1.7.2-next.0 + +## 1.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5 + - @backstage/plugin-techdocs-node@1.7.1 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5-next.1 + - @backstage/plugin-techdocs-node@1.7.1-next.1 + - @backstage/config@1.0.7 + +## 1.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.5-next.0 + - @backstage/plugin-techdocs-node@1.7.1-next.0 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.1 + +### Patch Changes + +- b348420a804: Adding global-agent to enable the ability to publish through a proxy +- Updated dependencies + - @backstage/backend-common@0.18.4 + - @backstage/plugin-techdocs-node@1.7.0 + - @backstage/catalog-model@1.3.0 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.1-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.3.0-next.0 + - @backstage/backend-common@0.18.4-next.2 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/plugin-techdocs-node@1.6.1-next.3 + +## 1.4.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.4-next.2 + - @backstage/catalog-model@1.2.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/plugin-techdocs-node@1.6.1-next.2 + +## 1.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.4-next.1 + - @backstage/catalog-model@1.2.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + - @backstage/plugin-techdocs-node@1.6.1-next.1 + +## 1.4.1-next.0 + +### Patch Changes + +- b348420a804: Adding global-agent to enable the ability to publish through a proxy +- Updated dependencies + - @backstage/backend-common@0.18.4-next.0 + - @backstage/config@1.0.7 + - @backstage/catalog-model@1.2.1 + - @backstage/cli-common@0.1.12 + - @backstage/plugin-techdocs-node@1.6.1-next.0 + +## 1.4.0 + +### Minor Changes + +- 8e465ce52e2: Running `@techdocs/cli generate` with the `--verbose` flag will now print the mkdocs output. +- ea2bbef1b16: Added support for an HTTPS proxy for techdocs AWS S3 requests + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.6.0 + - @backstage/backend-common@0.18.3 + - @backstage/catalog-model@1.2.1 + - @backstage/cli-common@0.1.12 + - @backstage/config@1.0.7 + +## 1.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.6.0-next.2 + - @backstage/backend-common@0.18.3-next.2 + - @backstage/config@1.0.7-next.0 + +## 1.4.0-next.1 + +### Minor Changes + +- 8e465ce52e2: Running `@techdocs/cli generate` with the `--verbose` flag will now print the mkdocs output. +- ea2bbef1b16: Added support for an HTTPS proxy for techdocs AWS S3 requests + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.6.0-next.1 + - @backstage/backend-common@0.18.3-next.1 + - @backstage/cli-common@0.1.12-next.0 + - @backstage/config@1.0.7-next.0 + - @backstage/catalog-model@1.2.1-next.1 + +## 1.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/plugin-techdocs-node@1.5.1-next.0 + +## 1.3.2 + +### Patch Changes + +- dd1e37649f: Deprecated getMkDocsYml in favor of getMkdocsYml (lowercase 'd') + +- dcacf94912: Fix proxying to mkdocs + + The domain localhost may point to both 127.0.0.1 and ::1, ipv4 and ipv6 + and when node tries to lookup localhost it might prefer ipv6 while mkdocs + is only listening on ipv4. This tells node-proxy to target the ipv4 address + instead of relying on localhost hostname lookup. + +- 339d9a5b5c: Added support for using a default `mkdocs.yml` configuration file when none is provided + +- 6e0b6a0d50: Fixed publish command missing awsBucketRootPath option. + Fixed publish command having the gcsBucketRootPath option misconfigured, previously returning a boolean vs a string. + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-techdocs-node@1.5.0 + - @backstage/catalog-model@1.2.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + +## 1.3.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2-next.2 + - @backstage/catalog-model@1.2.0-next.1 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/plugin-techdocs-node@1.4.6-next.2 + +## 1.3.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2-next.1 + - @backstage/catalog-model@1.1.6-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/plugin-techdocs-node@1.4.6-next.1 + +## 1.3.2-next.0 + +### Patch Changes + +- 6e0b6a0d50: Fixed publish command missing awsBucketRootPath option. + Fixed publish command having the gcsBucketRootPath option misconfigured, previously returning a boolean vs a string. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.4.6-next.0 + - @backstage/catalog-model@1.1.6-next.0 + - @backstage/backend-common@0.18.2-next.0 + +## 1.3.0 + +### Minor Changes + +- bc18c902a2: Add `--preview-app-bundle-path` and `--preview-app-port` options to the `serve` command enabling previewing with apps other than the provided one + +### Patch Changes + +- 9f2b786fc9: Provide context for logged errors. +- Updated dependencies + - @backstage/backend-common@0.18.0 + - @backstage/catalog-model@1.1.5 + - @backstage/config@1.0.6 + - @backstage/cli-common@0.1.11 + - @backstage/plugin-techdocs-node@1.4.4 + +## 1.3.0-next.2 + +### Minor Changes + +- bc18c902a2: Add `--preview-app-bundle-path` and `--preview-app-port` options to the `serve` command enabling previewing with apps other than the provided one + +### Patch Changes + +- 9f2b786fc9: Provide context for logged errors. +- Updated dependencies + - @backstage/backend-common@0.18.0-next.1 + - @backstage/plugin-techdocs-node@1.4.4-next.2 + - @backstage/catalog-model@1.1.5-next.1 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6-next.0 + +## 1.2.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.0-next.0 + - @backstage/config@1.0.6-next.0 + - @backstage/catalog-model@1.1.5-next.1 + - @backstage/cli-common@0.1.11 + - @backstage/plugin-techdocs-node@1.4.4-next.1 + +## 1.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.5-next.0 + - @backstage/backend-common@0.17.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.5 + - @backstage/plugin-techdocs-node@1.4.4-next.0 + +## 1.2.4 + +### Patch Changes + +- 8015ff1258: Tweaked wording to use inclusive terminology +- Updated dependencies + - @backstage/backend-common@0.17.0 + - @backstage/plugin-techdocs-node@1.4.3 + - @backstage/cli-common@0.1.11 + - @backstage/catalog-model@1.1.4 + - @backstage/config@1.0.5 + +## 1.2.4-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.17.0-next.3 + - @backstage/plugin-techdocs-node@1.4.3-next.3 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/cli-common@0.1.11-next.0 + - @backstage/config@1.0.5-next.1 + +## 1.2.4-next.2 + +### Patch Changes + +- 8015ff1258: Tweaked wording to use inclusive terminology +- Updated dependencies + - @backstage/backend-common@0.17.0-next.2 + - @backstage/cli-common@0.1.11-next.0 + - @backstage/plugin-techdocs-node@1.4.3-next.2 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/config@1.0.5-next.1 + +## 1.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.17.0-next.1 + - @backstage/plugin-techdocs-node@1.4.3-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/cli-common@0.1.10 + +## 1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.1-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.5-next.0 + - @backstage/plugin-techdocs-node@1.4.3-next.0 + +## 1.2.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0 + - @backstage/plugin-techdocs-node@1.4.2 + - @backstage/catalog-model@1.1.3 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4 + +## 1.2.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.1 + - @backstage/plugin-techdocs-node@1.4.2-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + +## 1.2.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.16.0-next.0 + - @backstage/plugin-techdocs-node@1.4.2-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.4-next.0 + +## 1.2.2 + +### Patch Changes + +- 0b2a30dead: fixing techdocs-cli Docker client creation + + Docker client does not need to be created when --no-docker + option is provided. + + If you had DOCKER_CERT_PATH environment variable defined + the Docker client was looking for certificates + and breaking techdocs-cli generate command even with --no-docker + option. + +- Updated dependencies + - @backstage/catalog-model@1.1.2 + - @backstage/backend-common@0.15.2 + - @backstage/plugin-techdocs-node@1.4.1 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3 + +## 1.2.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.2-next.2 + - @backstage/plugin-techdocs-node@1.4.1-next.2 + - @backstage/catalog-model@1.1.2-next.2 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3-next.2 + +## 1.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.2-next.1 + - @backstage/catalog-model@1.1.2-next.1 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3-next.1 + - @backstage/plugin-techdocs-node@1.4.1-next.1 + +## 1.2.2-next.0 + +### Patch Changes + +- 0b2a30dead: fixing techdocs-cli Docker client creation + + Docker client does not need to be created when --no-docker + option is provided. + + If you had DOCKER_CERT_PATH environment variable defined + the Docker client was looking for certificates + and breaking techdocs-cli generate command even with --no-docker + option. + +- Updated dependencies + - @backstage/catalog-model@1.1.2-next.0 + - @backstage/plugin-techdocs-node@1.4.1-next.0 + - @backstage/backend-common@0.15.2-next.0 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.3-next.0 + +## 1.2.1 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/backend-common@0.15.1 + - @backstage/plugin-techdocs-node@1.4.0 + - @backstage/catalog-model@1.1.1 + - @backstage/cli-common@0.1.10 + - @backstage/config@1.0.2 + +## 1.2.1-next.2 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/cli-common@0.1.10-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/backend-common@0.15.1-next.3 + - @backstage/plugin-techdocs-node@1.4.0-next.2 + +## 1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-node@1.4.0-next.1 + - @backstage/backend-common@0.15.1-next.2 + +## 1.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.1-next.0 + - @backstage/plugin-techdocs-node@1.3.1-next.0 + +## 1.2.0 + +### Minor Changes + +- 855952db53: Added CLI option `--docker-option` to allow passing additional options to the `docker run` command executed my `serve` and `serve:mkdocs`. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-techdocs-node@1.3.0 + +## 1.2.0-next.2 + +### Minor Changes + +- 855952db53: Added CLI option `--docker-option` to allow passing additional options to the `docker run` command executed my `serve` and `serve:mkdocs`. + +## 1.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/plugin-techdocs-node@1.3.0-next.1 + +## 1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-techdocs-node@1.2.1-next.0 + +## 1.1.3 + +### Patch Changes + +- a5d73da942: Fix the flag parsing for `legacyCopyReadmeMdToIndexMd` in `techdocs-cli generate` command, and decouple it's logic from the `techdocs-ref` flag. +- 14ce0d9347: Fixed a bug that prevented docker images from being pulled by default when generating TechDocs. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.2.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + +## 1.1.3-next.1 + +### Patch Changes + +- a5d73da942: Fix the flag parsing for `legacyCopyReadmeMdToIndexMd` in `techdocs-cli generate` command, and decouple it's logic from the `techdocs-ref` flag. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.2.0-next.1 + - @backstage/catalog-model@1.1.0-next.1 + - @backstage/backend-common@0.14.1-next.1 + +## 1.1.3-next.0 + +### Patch Changes + +- 14ce0d9347: Fixed a bug that prevented docker images from being pulled by default when generating TechDocs. +- Updated dependencies + - @backstage/backend-common@0.14.1-next.0 + - @backstage/catalog-model@1.1.0-next.0 + - @backstage/plugin-techdocs-node@1.1.3-next.0 + +## 1.1.2 + +### Patch Changes + +- f96e98f4cd: Updated dependency `cypress` to `^10.0.0`. +- bff65e6958: Updated sidebar-related logic to use `` + `useSidebarPinState()` and/or `` + `useSidebarOpenState()` from `@backstage/core-components`. +- Updated dependencies + - @backstage/backend-common@0.14.0 + - @backstage/plugin-techdocs-node@1.1.2 + - @backstage/catalog-model@1.0.3 + +## 1.1.2-next.2 + +### Patch Changes + +- f96e98f4cd: Updated dependency `cypress` to `^10.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.0-next.2 + - @backstage/plugin-techdocs-node@1.1.2-next.2 + +## 1.1.2-next.1 + +### Patch Changes + +- bff65e6958: Updated sidebar-related logic to use `` + `useSidebarPinState()` and/or `` + `useSidebarOpenState()` from `@backstage/core-components`. +- Updated dependencies + - @backstage/backend-common@0.13.6-next.1 + - @backstage/catalog-model@1.0.3-next.0 + - @backstage/plugin-techdocs-node@1.1.2-next.1 + +## 1.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.13.6-next.0 + - @backstage/plugin-techdocs-node@1.1.2-next.0 + +## 1.1.1 + +### Patch Changes + +- 344ea56acc: Bump `commander` to version 9.1.0 +- 52fddad92d: The TechDocs CLI's embedded app now imports all API refs from the `@backstage/plugin-techdocs-react` package. +- c14e78a367: Update `techdocs-cli serve`'s `proxyEndpoint` to match the base URL of the embedded techdocs app. +- Updated dependencies + - @backstage/backend-common@0.13.3 + - @backstage/cli-common@0.1.9 + - @backstage/config@1.0.1 + - @backstage/plugin-techdocs-node@1.1.1 + - @backstage/catalog-model@1.0.2 + +## 1.1.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.13.3-next.2 + - @backstage/cli-common@0.1.9-next.0 + - @backstage/config@1.0.1-next.0 + - @backstage/catalog-model@1.0.2-next.0 + - @backstage/plugin-techdocs-node@1.1.1-next.1 + +## 1.1.1-next.1 + +### Patch Changes + +- 52fddad92d: The TechDocs CLI's embedded app now imports all API refs from the `@backstage/plugin-techdocs-react` package. +- Updated dependencies + - @backstage/backend-common@0.13.3-next.1 + +## 1.1.1-next.0 + +### Patch Changes + +- 344ea56acc: Bump `commander` to version 9.1.0 +- Updated dependencies + - @backstage/backend-common@0.13.3-next.0 + - @backstage/plugin-techdocs-node@1.1.1-next.0 + +## 1.1.0 + +### Minor Changes + +- 733187987b: Removed an undocumented, broken behavior where `README.md` files would be copied to `index.md` if it did not exist, leading to broken links in the TechDocs UI. + + **WARNING**: If you notice 404s in TechDocs after updating, check to make sure that all markdown files referenced in your `mkdocs.yml`s' `nav` sections exist. The following flag may be passed to the `generate` command to temporarily revert to the broken behavior. + + ```sh + techdocs-cli generate --legacyCopyReadmeMdToIndexMd + ``` + +### Patch Changes + +- 230ad0826f: Bump to using `@types/node` v16 +- eb470ea54c: Adds a new flag to override the entrypoint when using a custom docker image. It could be used to reuse existing images with different entrypoints. +- Updated dependencies + - @backstage/catalog-model@1.0.1 + - @backstage/backend-common@0.13.2 + - @backstage/plugin-techdocs-node@1.1.0 + +## 1.1.0-next.1 + +### Minor Changes + +- bcf1a2496c: BREAKING: The default Techdocs behavior will no longer attempt to copy `docs/README.md` or `README.md` to `docs/index.md` (if not found). To retain this behavior in your instance, you can set the following config in your `app-config.yaml`: + + ```yaml + techdocs: + generator: + mkdocs: + legacyCopyReadmeMdToIndexMd: true + ``` + +### Patch Changes + +- 230ad0826f: Bump to using `@types/node` v16 +- eb470ea54c: Adds a new flag to override the entrypoint when using a custom docker image. It could be used to reuse existing images with different entrypoints. +- Updated dependencies + - @backstage/backend-common@0.13.2-next.2 + - @backstage/plugin-techdocs-node@1.1.0-next.2 + +## 1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.0.1-next.0 + - @backstage/backend-common@0.13.2-next.0 + - @backstage/plugin-techdocs-node@1.0.1-next.0 + +## 1.0.0 + +### Major Changes + +- b58c70c223: This package has been promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy). + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.13.1 + - @backstage/catalog-model@1.0.0 + - @backstage/config@1.0.0 + - @backstage/plugin-techdocs-node@1.0.0 + +## 0.8.17 + +### Patch Changes + +- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 +- 91bf1e6c1a: Use `@backstage/plugin-techdocs-node` package instead of `@backstage/techdocs-common`. +- Updated dependencies + - @backstage/backend-common@0.13.0 + - @backstage/plugin-techdocs-node@0.11.12 + - @backstage/catalog-model@0.13.0 + +## 0.8.17-next.0 + +### Patch Changes + +- e0a69ba49f: build(deps): bump `fs-extra` from 9.1.0 to 10.0.1 +- 91bf1e6c1a: Use `@backstage/plugin-techdocs-node` package instead of `@backstage/techdocs-common`. +- Updated dependencies + - @backstage/backend-common@0.13.0-next.0 + - @backstage/plugin-techdocs-node@0.11.12-next.0 + - @backstage/catalog-model@0.13.0-next.0 + +## 0.8.16 + +### Patch Changes + +- 853efd42bd: Bump `@backstage/techdocs-common` to `0.11.10` to use `spotify/techdocs:v0.3.7` which upgrades `mkdocs-theme` as a dependency of `mkdocs-techdocs-core`. +- Updated dependencies + - @backstage/catalog-model@0.12.0 + - @backstage/backend-common@0.12.0 + - @backstage/techdocs-common@0.11.11 + +## 0.8.15 + +### Patch Changes + +- ed78516480: chore(deps-dev): bump `cypress` from 7.3.0 to 9.5.0 +- 209fd128e6: Updated usage of `github:` location types in docs to use `url:` instead. +- 61ff215e08: - Adds `cypress` and `cypress-plugin-snapshots` as dependencies for integration and visual regression tests. + - Updates README documentation with instructions for how to run tests. + - Clarifies output text for prepack script. +- Updated dependencies + - @backstage/backend-common@0.11.0 + - @backstage/catalog-model@0.11.0 + - @backstage/techdocs-common@0.11.10 + +## 0.8.14 + +### Patch Changes + +- c77c5c7eb6: Added `backstage.role` to `package.json` +- Updated dependencies + - @backstage/backend-common@0.10.8 + - @backstage/catalog-model@0.10.0 + - @backstage/cli-common@0.1.7 + - @backstage/config@0.1.14 + - @backstage/techdocs-common@0.11.8 + +## 0.8.13 + +### Patch Changes + +- b70c186194: Updated the HTTP server to allow for simplification of the development of the CLI itself. +- Updated dependencies + - @backstage/backend-common@0.10.7 + - @backstage/techdocs-common@0.11.7 + +## 0.8.13-next.0 + +### Patch Changes + +- b70c186194: Updated the HTTP server to allow for simplification of the development of the CLI itself. +- Updated dependencies + - @backstage/backend-common@0.10.7-next.0 + - @backstage/techdocs-common@0.11.7-next.0 + +## 0.8.12 + +### Patch Changes + +- 14472509a3: Use a local file dependency for techdocs-cli-embedded-app, to ensure that it's always pulled out of the workspace +- Updated dependencies + - @backstage/backend-common@0.10.6 + - @backstage/techdocs-common@0.11.6 + +## 0.8.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.6-next.0 + - @backstage/techdocs-common@0.11.6-next.0 + +## 0.8.12-next.0 + +### Patch Changes + +- 14472509a3: Use a local file dependency for techdocs-cli-embedded-app, to ensure that it's always pulled out of the workspace + +## 0.8.11 + +### Patch Changes + +- 10086f5873: Bumped `react-dev-utils` from `^12.0.0-next.47` to `^12.0.0-next.60`. +- Updated dependencies + - @backstage/techdocs-common@0.11.5 + - @backstage/backend-common@0.10.5 + +## 0.8.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.10.4-next.0 + - @backstage/config@0.1.13-next.0 + - @backstage/techdocs-common@0.11.4-next.0 + - @backstage/catalog-model@0.9.10-next.0 + +## 0.8.10 + +### Patch Changes + +- 8fbc988bfc: remove internal and inline CSS from index.html +- Updated dependencies + - @backstage/techdocs-common@0.11.2 + - @backstage/backend-common@0.10.1 + +## 0.8.9 + +### Patch Changes + +- 5fdc8df0e8: The `index.html` template was updated to use the new `config` global. +- Updated dependencies + - @backstage/backend-common@0.10.0 + - @backstage/techdocs-common@0.11.1 + +## 0.8.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.9.13 + - @backstage/techdocs-common@0.11.0 + +## 0.8.7 + +### Patch Changes + +- e7230ef814: Bump react-dev-utils to v12 +- Updated dependencies + - @backstage/backend-common@0.9.12 + +## 0.8.6 + +### Patch Changes + +- e21e3c6102: Bumping minimum requirements for `dockerode` and `testcontainers` +- 1578ad341b: Add support for specifying bucketRootPath for AWS and GCS publishers +- f2694e3750: Adds ability to use encrypted S3 buckets by utilizing the SSE option in the AWS SDK +- Updated dependencies + - @backstage/catalog-model@0.9.7 + - @backstage/backend-common@0.9.10 + - @backstage/techdocs-common@0.10.7 + +## 0.8.5 + +### Patch Changes + +- Reunified the [techdocs-cli](https://github.com/backstage/techdocs-cli) monorepo code back into the main [backstage](https://github.com/backstage/backstage) repo + + See [7288](https://github.com/backstage/backstage/issues/7288)). The changes include some internal refactoring that do not affect functionality beyond the local development setup. + +## 0.8.4 + +### Patch Changes + +- 8333394: The [change](https://github.com/backstage/techdocs-cli/commit/b25014cec313d46ce1c9b4f324cc09047a00fc1f) updated the `@backstage/techdocs-common` from version `0.9.0` to `0.10.2` and one of the intermediate versions, the [0.10.0](https://github.com/backstage/backstage/blob/cac4afb95fdbd130a66e53a1b0430a1e62787a7f/packages/techdocs-common/CHANGELOG.md#patch-changes-2), introduced the use of search in context that requires an implementation for the Search API. + + Created a custom techdocs page to disable search in the Reader component, preventing it from using the Search API, as we don't want to provide search in preview mode. + +## 0.8.3 + +### Patch Changes + +- edbb988: Upgrades the techdocs common page to the latest version 0.10.2. + + See [@backstage/techdocs-common changelog](https://github.com/backstage/backstage/blob/cac4afb95fdbd130a66e53a1b0430a1e62787a7f/packages/techdocs-common/CHANGELOG.md#L3). + +- db4ebfc: Add an `etag` flag to the `generate` command that is stored in the `techdocs_metadata.json` file. + +## 0.8.2 + +### Patch Changes + +- 8fc7384: Allow to execute techdocs-cli serve using docker techdocs-container on Windows + +## 0.8.1 + +### Patch Changes + +- 0187424: Separate build and publish release steps + +## 0.8.0 + +### Minor Changes + +- c6f437a: OpenStack Swift configuration changed due to OSS SDK Client change in @backstage/techdocs-common, it was a breaking change. + PR Reference: + +### Patch Changes + +- 05f0409: Merge Jobs for Release Pull Requests and Package Publishes + +## 0.7.0 + +### Minor Changes + +- 9d1f8d8: The `techdocs-cli publish` command will now publish TechDocs content to remote + storage using the lowercase'd entity triplet as the storage path. This is in + line with the beta release of the TechDocs plugin (`v0.11.0`). + + If you have been running `techdocs-cli` prior to this version, you will need to + follow this [migration guide](https://backstage.io/docs/features/techdocs/how-to-guides#how-to-migrate-from-techdocs-alpha-to-beta). + +## 0.6.2 + +### Patch Changes + +- f1bcf1a: Changelog (from v0.6.1 to v0.6.2) + + #### :bug: Bug Fix + + - `techdocs-cli` + - [#105](https://github.com/backstage/techdocs-cli/pull/105) Add azureAccountKey parameter back to the publish command ([@emmaindal](https://github.com/emmaindal)) + + #### :house: Internal + + - `techdocs-cli-embedded-app` + - [#122](https://github.com/backstage/techdocs-cli/pull/122) chore(deps-dev): bump @types/node from 12.20.20 to 16.7.1 in /packages/techdocs-cli-embedded-app ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - [#120](https://github.com/backstage/techdocs-cli/pull/120) chore(deps-dev): bump @types/react-dom from 16.9.14 to 17.0.9 in /packages/techdocs-cli-embedded-app ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - [#119](https://github.com/backstage/techdocs-cli/pull/119) chore(deps-dev): bump @testing-library/user-event from 12.8.3 to 13.2.1 in /packages/techdocs-cli-embedded-app ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - [#118](https://github.com/backstage/techdocs-cli/pull/118) chore(deps-dev): bump @testing-library/react from 10.4.9 to 12.0.0 ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - Other + - [#117](https://github.com/backstage/techdocs-cli/pull/117) chore(deps): bump @backstage/plugin-catalog from 0.6.11 to 0.6.12 ([@dependabot\[bot\]](https://github.com/apps/dependabot)) + - [#124](https://github.com/backstage/techdocs-cli/pull/124) Update release process docs ([@emmaindal](https://github.com/emmaindal)) + - [#116](https://github.com/backstage/techdocs-cli/pull/116) ignore dependabot branches for project board workflow ([@emmaindal](https://github.com/emmaindal)) + - [#106](https://github.com/backstage/techdocs-cli/pull/106) Configure dependabot for all packages ([@emmaindal](https://github.com/emmaindal)) + - [#102](https://github.com/backstage/techdocs-cli/pull/102) readme: add information about running techdocs-common locally ([@vcapretz](https://github.com/vcapretz)) + - [#103](https://github.com/backstage/techdocs-cli/pull/103) Introduce changesets and improve the publish workflow ([@minkimcello](https://github.com/minkimcello)) + - [#101](https://github.com/backstage/techdocs-cli/pull/101) update yarn lockfile to get rid of old version of node-forge ([@emmaindal](https://github.com/emmaindal)) + + #### Committers: 3 + + Thank you for contributing ❤️ + + - `Emma Indal` ([@emmaindal](https://github.com/emmaindal)) + - `Min Kim` ([@minkimcello](https://github.com/minkimcello)) + - `Vitor Capretz` ([@vcapretz](https://github.com/vcapretz)) + +## @backstage/plugin-techdocs@1.15.3-next.0 + +# @backstage/plugin-techdocs + +## 1.15.2-next.0 + +### Patch Changes + +- a4d4a70: Fixed an issue where the entire TechDocs page would re-render when navigating between pages within the same entity's documentation. +- Updated dependencies + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-auth-react@0.1.21-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## 1.15.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/integration@1.18.1 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/plugin-search-react@1.9.5 + - @backstage/config@1.3.5 + - @backstage/theme@0.7.0 + - @backstage/core-compat-api@0.5.3 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-auth-react@0.1.20 + - @backstage/plugin-search-common@1.2.20 + +## 1.15.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/plugin-search-react@1.9.5-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + +## 1.15.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-auth-react@0.1.20-next.1 + - @backstage/plugin-search-common@1.2.20-next.0 + - @backstage/catalog-client@1.12.0 + +## 1.15.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/integration@1.18.1-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-auth-react@0.1.20-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/catalog-client@1.12.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.11.0 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.8 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## 1.15.0 + +### Minor Changes + +- a0b604c: Adding redirect handling for TechDocs URLs that reference entities that now reference an external entity for TechDocs. Including tests and documentation. + +### Patch Changes + +- 313cec7: Updated dependency `dompurify` to `^3.2.4`. +- 8d18d23: TechDocs page titles have been improved, especially for deeply nested pages. +- 1dfee19: Reverts a change in CSS layout that shifted the content of the Techdocs too far to the left. +- 4ce5831: Support Techdocs redirect with dompurify 3.2.6+ +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-auth-react@0.1.19 + - @backstage/core-plugin-api@1.11.0 + - @backstage/catalog-client@1.12.0 + - @backstage/integration@1.18.0 + - @backstage/core-components@0.18.0 + - @backstage/core-compat-api@0.5.2 + - @backstage/plugin-search-react@1.9.4 + - @backstage/integration-react@1.2.10 + +## 1.14.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-react@0.1.19-next.1 + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-compat-api@0.5.2-next.2 + +## 1.14.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/integration@1.18.0-next.0 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/plugin-auth-react@0.1.19-next.0 + +## 1.14.2-next.0 + +### Patch Changes + +- 1dfee19: Reverts a change in CSS layout that shifted the content of the Techdocs too far to the left. +- Updated dependencies + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/catalog-client@1.11.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.2 + +## 1.14.0 + +### Minor Changes + +- cb0541f: Adds `additionalAllowedURIProtocols` to sanitizer config + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- f231c2b: Fixes CSS to adjust based on whether or not the global Backstage sidebar is on the page. +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-techdocs-react@1.3.2 + +## 1.14.0-next.2 + +### Patch Changes + +- e4ddf22: Internal update to align with new blueprint parameter naming in the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-search-react@1.9.3-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + +## 1.14.0-next.1 + +### Minor Changes + +- cb0541f: Adds `additionalAllowedURIProtocols` to sanitizer config + +### Patch Changes + +- f2f133c: Internal update to use the new variant of `ApiBlueprint`. +- Updated dependencies + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-common@0.1.1 + +## 1.13.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/integration-react@1.2.9 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-search-react@1.9.2 + +## 1.13.2 + +### Patch Changes + +- 1debf7f: Fixed an issue causing TechDocs to not properly handle initial redirect. +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration@1.17.1 + - @backstage/theme@0.6.7 + - @backstage/integration-react@1.2.9 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-auth-react@0.1.17 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.2 + - @backstage/plugin-techdocs-react@1.3.1 + +## 1.13.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-auth-react@0.1.17-next.1 + +## 1.13.2-next.0 + +### Patch Changes + +- 1debf7f: Fixed an issue causing TechDocs to not properly handle initial redirect. +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1 + +## 1.13.0 + +### Minor Changes + +- 3c59ece: **New Frontend System Only:** + The `TechDocs` plugin is now responsible for providing an entity icon link extension to read documentation from the catalog entity page. +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-search-react@1.9.1 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/theme@0.6.6 + - @backstage/plugin-search-common@1.2.18 + +## 1.13.0-next.2 + +### Minor Changes + +- 3c59ece: **New Frontend System Only:** + The `TechDocs` plugin is now responsible for providing an entity icon link extension to read documentation from the catalog entity page. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/theme@0.6.6 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + +## 1.13.0-next.1 + +### Patch Changes + +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration@1.17.0 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## 1.13.0-next.0 + +### Minor Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/plugin-techdocs-common@0.1.1-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/integration-react@1.2.7 + +## 1.12.6 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 7d445da: Update keyboard focus on when clicking hash links. This fixes the issue where the "skip to content" link rendered by Material MkDocs isn't focused when used. +- 72d019d: Removed various typos +- 2ffd273: Add hover and focus styling to the "copy to clipboard" button within codeblocks in techdocs. Also added an aria-label to the button for accessibility. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/integration@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/core-plugin-api@1.10.7 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.6-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0-next.3 + - @backstage/plugin-search-react@1.9.0-next.2 + - @backstage/core-compat-api@0.4.2-next.3 + - @backstage/core-components@0.17.2-next.1 + - @backstage/core-plugin-api@1.10.7-next.0 + - @backstage/plugin-catalog-react@1.18.0-next.3 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.2-next.1 + - @backstage/integration-react@1.2.7-next.3 + - @backstage/theme@0.6.6-next.0 + - @backstage/plugin-auth-react@0.1.15-next.1 + - @backstage/plugin-search-common@1.2.18-next.0 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.17-next.1 + +## 1.12.6-next.2 + +### Patch Changes + +- 7d445da: Update keyboard focus on when clicking hash links. This fixes the issue where the "skip to content" link rendered by Material MkDocs isn't focused when used. +- 2ffd273: Add hover and focus styling to the "copy to clipboard" button within codeblocks in techdocs. Also added an aria-label to the button for accessibility. +- Updated dependencies + - @backstage/integration@1.17.0-next.2 + - @backstage/core-plugin-api@1.10.7-next.0 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.2-next.2 + - @backstage/core-components@0.17.2-next.1 + - @backstage/frontend-plugin-api@0.10.2-next.1 + - @backstage/integration-react@1.2.7-next.2 + - @backstage/plugin-auth-react@0.1.15-next.1 + - @backstage/plugin-catalog-react@1.18.0-next.2 + - @backstage/plugin-search-react@1.9.0-next.1 + - @backstage/plugin-techdocs-react@1.2.17-next.1 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6-next.0 + - @backstage/plugin-search-common@1.2.18-next.0 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.6-next.1 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/theme@0.6.6-next.0 + - @backstage/core-components@0.17.2-next.0 + - @backstage/frontend-plugin-api@0.10.2-next.0 + - @backstage/core-compat-api@0.4.2-next.1 + - @backstage/integration@1.16.4-next.1 + - @backstage/plugin-search-react@1.9.0-next.0 + - @backstage/plugin-catalog-react@1.18.0-next.1 + - @backstage/plugin-techdocs-react@1.2.17-next.0 + - @backstage/plugin-auth-react@0.1.15-next.0 + - @backstage/integration-react@1.2.7-next.1 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.6 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.18-next.0 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.16.4-next.0 + - @backstage/core-compat-api@0.4.2-next.0 + - @backstage/plugin-catalog-react@1.18.0-next.0 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/integration-react@1.2.7-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-components@0.17.1 + - @backstage/core-plugin-api@1.10.6 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.1 + - @backstage/theme@0.6.5 + - @backstage/plugin-auth-react@0.1.14 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.8 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.16 + +## 1.12.5 + +### Patch Changes + +- a47fd39: Removes instances of default React imports, a necessary update for the upcoming React 19 migration. + + + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.16 + - @backstage/plugin-catalog-react@1.17.0 + - @backstage/frontend-plugin-api@0.10.1 + - @backstage/integration-react@1.2.6 + - @backstage/core-compat-api@0.4.1 + - @backstage/core-components@0.17.1 + - @backstage/core-plugin-api@1.10.6 + - @backstage/plugin-search-react@1.8.8 + - @backstage/plugin-auth-react@0.1.14 + - @backstage/theme@0.6.5 + - @backstage/integration@1.16.3 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.5-next.2 + +### Patch Changes + +- a47fd39: Removes instances of default React imports, a necessary update for the upcoming React 19 migration. + + + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.1-next.1 + - @backstage/integration-react@1.2.6-next.1 + - @backstage/core-compat-api@0.4.1-next.2 + - @backstage/core-components@0.17.1-next.1 + - @backstage/core-plugin-api@1.10.6-next.0 + - @backstage/plugin-techdocs-react@1.2.16-next.1 + - @backstage/plugin-catalog-react@1.17.0-next.2 + - @backstage/plugin-search-react@1.8.8-next.1 + - @backstage/plugin-auth-react@0.1.14-next.1 + - @backstage/theme@0.6.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.3-next.0 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.16-next.0 + - @backstage/core-components@0.17.1-next.0 + - @backstage/integration-react@1.2.6-next.0 + - @backstage/integration@1.16.3-next.0 + - @backstage/frontend-plugin-api@0.10.1-next.0 + - @backstage/plugin-auth-react@0.1.14-next.0 + - @backstage/plugin-catalog-react@1.16.1-next.1 + - @backstage/plugin-search-react@1.8.8-next.0 + - @backstage/core-compat-api@0.4.1-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.5 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.4 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.16.1-next.0 + - @backstage/core-compat-api@0.4.1-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-components@0.17.0 + - @backstage/core-plugin-api@1.10.5 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.0 + - @backstage/integration@1.16.2 + - @backstage/integration-react@1.2.5 + - @backstage/theme@0.6.4 + - @backstage/plugin-auth-react@0.1.13 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.7 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.15 + +## 1.12.4 + +### Patch Changes + +- fffe3c0: Fixed double scrollbar issue that would appear on the Entity TechDocs view page that would stop the page from full scrolling to the top when navigating to a new page +- 065e6b9: Excludes SVG styling from sanitization +- b5a8208: Added `TechDocsAddonsBlueprint` extension to allow adding of techdocs addons. +- ed1cb3e: Adds the page name of techdocs to the document's title. +- fe4abb8: Updates logic to check for SVG sources when inlining them. +- Updated dependencies + - @backstage/core-components@0.17.0 + - @backstage/core-plugin-api@1.10.5 + - @backstage/integration@1.16.2 + - @backstage/plugin-search-react@1.8.7 + - @backstage/frontend-plugin-api@0.10.0 + - @backstage/plugin-catalog-react@1.16.0 + - @backstage/core-compat-api@0.4.0 + - @backstage/plugin-techdocs-react@1.2.15 + - @backstage/integration-react@1.2.5 + - @backstage/plugin-auth-react@0.1.13 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.4 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.0-next.2 + - @backstage/plugin-catalog-react@1.16.0-next.2 + - @backstage/core-compat-api@0.4.0-next.2 + - @backstage/core-components@0.16.5-next.1 + - @backstage/integration@1.16.2-next.0 + - @backstage/plugin-search-react@1.8.7-next.2 + - @backstage/plugin-techdocs-react@1.2.15-next.2 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.4 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.5-next.0 + - @backstage/theme@0.6.4 + - @backstage/plugin-auth-react@0.1.13-next.1 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.4-next.1 + +### Patch Changes + +- fffe3c0: Fixed double scrollbar issue that would appear on the Entity TechDocs view page that would stop the page from full scrolling to the top when navigating to a new page +- Updated dependencies + - @backstage/core-components@0.16.5-next.0 + - @backstage/plugin-catalog-react@1.16.0-next.1 + - @backstage/core-compat-api@0.3.7-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.4 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.9.6-next.1 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.4 + - @backstage/theme@0.6.4 + - @backstage/plugin-auth-react@0.1.13-next.0 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.7-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.15-next.1 + +## 1.12.4-next.0 + +### Patch Changes + +- 065e6b9: Excludes svg styling from sanitization +- b5a8208: Added `TechDocsAddonsBlueprint` extension to allow adding of techdocs addons. +- ed1cb3e: Adds the page name of techdoc to the document's title. +- fe4abb8: Updates logic to check for SVG sources when inlining svgs. +- Updated dependencies + - @backstage/plugin-search-react@1.8.7-next.0 + - @backstage/plugin-catalog-react@1.16.0-next.0 + - @backstage/plugin-techdocs-react@1.2.15-next.0 + - @backstage/frontend-plugin-api@0.9.6-next.0 + - @backstage/core-compat-api@0.3.7-next.0 + - @backstage/integration-react@1.2.4 + +## 1.12.3 + +### Patch Changes + +- eb3d91a: Use the custom error page if provided for displaying errors instead of the default error page + +- 524f0af: Add missing route ref to the `/alpha` entity content extension. + +- f4be934: Changed the base URL in addLinkClickListener from window.location.origin to app.baseUrl for improved path handling. This fixes an issue where Backstage, when running on a subpath, was unable to handle non-Backstage URLs of the same origin correctly. + +- 1f40e6b: Add optional props to `TechDocCustomHome` to allow for more flexibility: + + ```tsx + import { TechDocsCustomHome } from '@backstage/plugin-techdocs'; + //... + + const options = { emptyRowsWhenPaging: false }; + const linkDestination = (entity: Entity): string | undefined => { + return entity.metadata.annotations?.['external-docs']; + }; + const techDocsTabsConfig = [ + { + label: 'Recommended Documentation', + panels: [ + { + title: 'Golden Path', + description: 'Documentation about standards to follow', + panelType: 'DocsCardGrid', + panelProps: { CustomHeader: () => }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('golden-path') ?? false, + }, + { + title: 'Recommended', + description: 'Useful documentation', + panelType: 'InfoCardGrid', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + ], + }, + { + label: 'Browse All', + panels: [ + { + description: 'Browse all docs', + filterPredicate: filterEntity, + panelType: 'TechDocsIndexPage', + title: 'All', + panelProps: { PageWrapper: React.Fragment, CustomHeader: React.Fragment, options: options }, + }, + ], + }, + ]; + + const AppRoutes = () => { + + ) => ({children})} + /> + } + /> + ; + }; + ``` + + Add new Grid option called `InfoCardGrid` which is a more customizable card option for the Docs grid. + + ```tsx + entity.metadata['external-docs']} + /> + ``` + + Expose existing `CustomDocsPanel` so that it can be used independently if desired. + + ```tsx + const panels: PanelConfig[] = [ + { + description: '', + filterPredicate: entity => {}, + panelType: 'InfoCardGrid', + title: 'Standards', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + }, + { + description: '', + filterPredicate: entity => {}, + panelType: 'DocsCardGrid', + title: 'Contribute', + }, + ]; + { + panels.map((config, index) => ( + + )); + } + ``` + +- 58ec9e7: Removed older versions of React packages as a preparatory step for upgrading to React 19. This commit does not introduce any functional changes, but removes dependencies on previous React versions, allowing for a cleaner upgrade path in subsequent commits. + +- Updated dependencies + - @backstage/plugin-search-react@1.8.6 + - @backstage/core-components@0.16.4 + - @backstage/plugin-catalog-react@1.15.2 + - @backstage/frontend-plugin-api@0.9.5 + - @backstage/integration-react@1.2.4 + - @backstage/core-compat-api@0.3.6 + - @backstage/core-plugin-api@1.10.4 + - @backstage/plugin-techdocs-react@1.2.14 + - @backstage/plugin-auth-react@0.1.12 + - @backstage/theme@0.6.4 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.5-next.3 + - @backstage/core-compat-api@0.3.6-next.3 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-components@0.16.4-next.1 + - @backstage/core-plugin-api@1.10.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.4-next.0 + - @backstage/theme@0.6.4-next.0 + - @backstage/plugin-auth-react@0.1.12-next.1 + - @backstage/plugin-catalog-react@1.15.2-next.3 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.6-next.3 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.14-next.1 + +## 1.12.3-next.2 + +### Patch Changes + +- eb3d91a: Use the custom error page if provided for displaying errors instead of the default error page +- Updated dependencies + - @backstage/core-components@0.16.4-next.1 + - @backstage/plugin-catalog-react@1.15.2-next.2 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.3.6-next.2 + - @backstage/core-plugin-api@1.10.4-next.0 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.9.5-next.2 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.4-next.0 + - @backstage/theme@0.6.4-next.0 + - @backstage/plugin-auth-react@0.1.12-next.1 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.6-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.14-next.1 + +## 1.12.2-next.1 + +### Patch Changes + +- 524f0af: Add missing route ref to the `/alpha` entity content extension. +- 58ec9e7: Removed older versions of React packages as a preparatory step for upgrading to React 19. This commit does not introduce any functional changes, but removes dependencies on previous React versions, allowing for a cleaner upgrade path in subsequent commits. +- Updated dependencies + - @backstage/core-components@0.16.4-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.1 + - @backstage/integration-react@1.2.4-next.0 + - @backstage/core-compat-api@0.3.6-next.1 + - @backstage/core-plugin-api@1.10.4-next.0 + - @backstage/plugin-techdocs-react@1.2.14-next.0 + - @backstage/plugin-catalog-react@1.15.2-next.1 + - @backstage/plugin-search-react@1.8.6-next.1 + - @backstage/plugin-auth-react@0.1.12-next.0 + - @backstage/theme@0.6.4-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.2-next.0 + +### Patch Changes + +- f4be934: Changed the base URL in addLinkClickListener from window.location.origin to app.baseUrl for improved path handling. This fixes an issue where Backstage, when running on a subpath, was unable to handle non-Backstage URLs of the same origin correctly. + +- 1f40e6b: Add optional props to `TechDocCustomHome` to allow for more flexibility: + + ```tsx + import { TechDocsCustomHome } from '@backstage/plugin-techdocs'; + //... + + const options = { emptyRowsWhenPaging: false }; + const linkDestination = (entity: Entity): string | undefined => { + return entity.metadata.annotations?.['external-docs']; + }; + const techDocsTabsConfig = [ + { + label: 'Recommended Documentation', + panels: [ + { + title: 'Golden Path', + description: 'Documentation about standards to follow', + panelType: 'DocsCardGrid', + panelProps: { CustomHeader: () => }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('golden-path') ?? false, + }, + { + title: 'Recommended', + description: 'Useful documentation', + panelType: 'InfoCardGrid', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + filterPredicate: entity => + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + ], + }, + { + label: 'Browse All', + panels: [ + { + description: 'Browse all docs', + filterPredicate: filterEntity, + panelType: 'TechDocsIndexPage', + title: 'All', + panelProps: { PageWrapper: React.Fragment, CustomHeader: React.Fragment, options: options }, + }, + ], + }, + ]; + + const AppRoutes = () => { + + ) => ({children})} + /> + } + /> + ; + }; + ``` + + Add new Grid option called `InfoCardGrid` which is a more customizable card option for the Docs grid. + + ```tsx + entity.metadata['external-docs']} + /> + ``` + + Expose existing `CustomDocsPanel` so that it can be used independently if desired. + + ```tsx + const panels: PanelConfig[] = [ + { + description: '', + filterPredicate: entity => {}, + panelType: 'InfoCardGrid', + title: 'Standards', + panelProps: { + CustomHeader: () => + linkDestination: linkDestination, + }, + }, + { + description: '', + filterPredicate: entity => {}, + panelType: 'DocsCardGrid', + title: 'Contribute', + }, + ]; + { + panels.map((config, index) => ( + + )); + } + ``` + +- Updated dependencies + - @backstage/plugin-search-react@1.8.6-next.0 + - @backstage/frontend-plugin-api@0.9.5-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.3.6-next.0 + - @backstage/core-components@0.16.3 + - @backstage/core-plugin-api@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.16.1 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-auth-react@0.1.11 + - @backstage/plugin-catalog-react@1.15.2-next.0 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.13 + +## 1.12.1 + +### Patch Changes + +- 3710b35: Allow passing down `withSearch` prop to `EntityTechdocsContent` component since it was `true` by default, now user can use the `EntityTechdocsContent` component _without_ showing the search field on top of the content. +- Updated dependencies + - @backstage/plugin-catalog-react@1.15.1 + - @backstage/frontend-plugin-api@0.9.4 + - @backstage/core-plugin-api@1.10.3 + - @backstage/core-components@0.16.3 + - @backstage/integration@1.16.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.3.5 + - @backstage/errors@1.2.7 + - @backstage/integration-react@1.2.3 + - @backstage/theme@0.6.3 + - @backstage/plugin-auth-react@0.1.11 + - @backstage/plugin-search-common@1.2.17 + - @backstage/plugin-search-react@1.8.5 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.13 + +## 1.12.1-next.1 + +### Patch Changes + +- 3710b35: Allow passing down `withSearch` prop to `EntityTechdocsContent` component since it was `true` by default, now user can use the `EntityTechdocsContent` component _without_ showing the search field on top of the content. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.4-next.0 + - @backstage/core-plugin-api@1.10.3-next.0 + - @backstage/core-compat-api@0.3.5-next.0 + - @backstage/plugin-catalog-react@1.15.1-next.1 + - @backstage/plugin-search-react@1.8.5-next.0 + - @backstage/core-components@0.16.3-next.0 + - @backstage/integration-react@1.2.3-next.0 + - @backstage/plugin-auth-react@0.1.11-next.0 + - @backstage/plugin-techdocs-react@1.2.13-next.0 + - @backstage/catalog-model@1.7.3-next.0 + - @backstage/config@1.3.2-next.0 + - @backstage/errors@1.2.7-next.0 + - @backstage/plugin-search-common@1.2.17-next.0 + - @backstage/integration@1.16.1-next.0 + - @backstage/theme@0.6.3 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.15.1-next.0 + - @backstage/integration-react@1.2.2 + - @backstage/core-compat-api@0.3.4 + +## 1.12.0 + +### Minor Changes + +- e153ca6: Add pagination support to TechDocs Index Page and make it the default + +### Patch Changes + +- 7d8777d: Added support for the Search bar in docs residing in the entity page tab, and not only the global "/docs" page. +- Updated dependencies + - @backstage/plugin-catalog-react@1.15.0 + - @backstage/integration@1.16.0 + - @backstage/plugin-search-react@1.8.4 + - @backstage/core-compat-api@0.3.4 + - @backstage/frontend-plugin-api@0.9.3 + - @backstage/theme@0.6.3 + - @backstage/core-components@0.16.2 + - @backstage/errors@1.2.6 + - @backstage/catalog-model@1.7.2 + - @backstage/config@1.3.1 + - @backstage/core-plugin-api@1.10.2 + - @backstage/integration-react@1.2.2 + - @backstage/plugin-auth-react@0.1.10 + - @backstage/plugin-search-common@1.2.16 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.12 + +## 1.11.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.3.4-next.2 + - @backstage/plugin-catalog-react@1.14.3-next.2 + - @backstage/errors@1.2.6-next.0 + - @backstage/catalog-model@1.7.2-next.0 + - @backstage/config@1.3.1-next.0 + - @backstage/core-components@0.16.2-next.2 + - @backstage/core-plugin-api@1.10.2-next.0 + - @backstage/frontend-plugin-api@0.9.3-next.2 + - @backstage/integration@1.16.0-next.1 + - @backstage/integration-react@1.2.2-next.1 + - @backstage/theme@0.6.3-next.0 + - @backstage/plugin-auth-react@0.1.10-next.2 + - @backstage/plugin-search-common@1.2.16-next.0 + - @backstage/plugin-search-react@1.8.4-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.12-next.2 + +## 1.11.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.14.3-next.1 + - @backstage/core-components@0.16.2-next.1 + - @backstage/catalog-model@1.7.1 + - @backstage/config@1.3.0 + - @backstage/core-compat-api@0.3.4-next.1 + - @backstage/core-plugin-api@1.10.1 + - @backstage/errors@1.2.5 + - @backstage/frontend-plugin-api@0.9.3-next.1 + - @backstage/integration@1.16.0-next.0 + - @backstage/integration-react@1.2.2-next.0 + - @backstage/theme@0.6.3-next.0 + - @backstage/plugin-auth-react@0.1.10-next.1 + - @backstage/plugin-search-common@1.2.15 + - @backstage/plugin-search-react@1.8.4-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.12-next.1 + +## 1.11.3-next.0 + +### Patch Changes + +- 7d8777d: Added support for the Search bar in docs residing in the entity page tab, and not only the global "/docs" page. +- Updated dependencies + - @backstage/integration@1.16.0-next.0 + - @backstage/plugin-search-react@1.8.4-next.0 + - @backstage/plugin-catalog-react@1.14.3-next.0 + - @backstage/frontend-plugin-api@0.9.3-next.0 + - @backstage/theme@0.6.3-next.0 + - @backstage/catalog-model@1.7.1 + - @backstage/config@1.3.0 + - @backstage/core-compat-api@0.3.4-next.0 + - @backstage/core-components@0.16.2-next.0 + - @backstage/core-plugin-api@1.10.1 + - @backstage/errors@1.2.5 + - @backstage/integration-react@1.2.2-next.0 + - @backstage/plugin-auth-react@0.1.10-next.0 + - @backstage/plugin-search-common@1.2.15 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.12-next.0 + +## 1.11.1 + +### Patch Changes + +- 37a7810: Fixed an issue where `` would re-render infinitely under certain conditions. +- e937ae7: Fix an issue with index page of documentation site being re-rendered. +- 90246a9: Fix techdocs config schema for custom elements sanitizer +- 605bdc0: Avoid page re-rendering when clicking on anchor links in the same documentation page. +- 4f0cb89: Added DomPurify sanitizer configuration for custom elements implementing RFC . + See for how to enable it in the configuration. +- f246178: Removed `canvas` dev dependency. +- 4a2f73a: Fix an issue that caused the current documentation page to be re-rendered when navigating to + another one. +- Updated dependencies + - @backstage/config@1.3.0 + - @backstage/theme@0.6.1 + - @backstage/plugin-catalog-react@1.14.1 + - @backstage/core-components@0.16.0 + - @backstage/plugin-techdocs-react@1.2.10 + - @backstage/catalog-model@1.7.1 + - @backstage/core-compat-api@0.3.2 + - @backstage/core-plugin-api@1.10.1 + - @backstage/errors@1.2.5 + - @backstage/frontend-plugin-api@0.9.1 + - @backstage/integration@1.15.2 + - @backstage/integration-react@1.2.1 + - @backstage/plugin-auth-react@0.1.8 + - @backstage/plugin-search-common@1.2.15 + - @backstage/plugin-search-react@1.8.2 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.11.1-next.3 + +### Patch Changes + +- e937ae7: Fix an issue with index page of documentation site being re-rendered. +- Updated dependencies + - @backstage/core-components@0.16.0-next.2 + - @backstage/plugin-catalog-react@1.14.1-next.3 + - @backstage/core-compat-api@0.3.2-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.10.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.1-next.2 + - @backstage/integration@1.15.1 + - @backstage/integration-react@1.2.0 + - @backstage/theme@0.6.1-next.0 + - @backstage/plugin-auth-react@0.1.8-next.2 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.2-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.10-next.2 + +## 1.11.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.14.1-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.3.2-next.1 + - @backstage/core-components@0.16.0-next.1 + - @backstage/core-plugin-api@1.10.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.1-next.1 + - @backstage/integration@1.15.1 + - @backstage/integration-react@1.2.0 + - @backstage/theme@0.6.1-next.0 + - @backstage/plugin-auth-react@0.1.8-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.2-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.10-next.1 + +## 1.11.1-next.1 + +### Patch Changes + +- 90246a9: Fix techdocs config schema for custom elements sanitizer +- Updated dependencies + - @backstage/theme@0.6.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.3.2-next.1 + - @backstage/core-components@0.16.0-next.1 + - @backstage/core-plugin-api@1.10.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.1-next.1 + - @backstage/integration@1.15.1 + - @backstage/integration-react@1.2.0 + - @backstage/plugin-auth-react@0.1.8-next.1 + - @backstage/plugin-catalog-react@1.14.1-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.2-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.10-next.1 + +## 1.11.1-next.0 + +### Patch Changes + +- 605bdc0: Avoid page re-rendering when clicking on anchor links in the same documentation page. +- 4f0cb89: Added DomPurify sanitizer configuration for custom elements implementing RFC . + See for how to enable it in the configuration. +- f246178: Removed `canvas` dev dependency. +- 4a2f73a: Fix an issue that caused the current documentation page to be re-rendered when navigating to + another one. +- Updated dependencies + - @backstage/core-components@0.16.0-next.0 + - @backstage/plugin-techdocs-react@1.2.10-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.3.2-next.0 + - @backstage/core-plugin-api@1.10.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.1-next.0 + - @backstage/integration@1.15.1 + - @backstage/integration-react@1.2.0 + - @backstage/theme@0.6.0 + - @backstage/plugin-auth-react@0.1.8-next.0 + - @backstage/plugin-catalog-react@1.14.1-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.2-next.0 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.11.0 + +### Minor Changes + +- e77ff3d: Adds support for custom background colors in code blocks and inline code within TechDocs. + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- a77cb40: Make `emptyState` input optional on `entity-content:techdocs` extension so that + the default empty state extension works correctly. +- e918061: Add support for mkdocs material palette conditional hashes. +- 720a2f9: Updated dependency `git-url-parse` to `^15.0.0`. +- e8b4966: Use more of the available space for the navigation sidebar. +- Updated dependencies + - @backstage/core-components@0.15.1 + - @backstage/frontend-plugin-api@0.9.0 + - @backstage/integration-react@1.2.0 + - @backstage/core-compat-api@0.3.1 + - @backstage/core-plugin-api@1.10.0 + - @backstage/plugin-techdocs-react@1.2.9 + - @backstage/plugin-catalog-react@1.14.0 + - @backstage/plugin-search-react@1.8.1 + - @backstage/plugin-auth-react@0.1.7 + - @backstage/theme@0.6.0 + - @backstage/integration@1.15.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.11.0-next.2 + +### Minor Changes + +- e77ff3d: Adds support for custom background colors in code blocks and inline code within TechDocs. + +### Patch Changes + +- e918061: Add support for mkdocs material palette conditional hashes. +- 720a2f9: Updated dependency `git-url-parse` to `^15.0.0`. +- e8b4966: Use more of the available space for the navigation sidebar. +- Updated dependencies + - @backstage/plugin-catalog-react@1.14.0-next.2 + - @backstage/integration@1.15.1-next.1 + - @backstage/theme@0.6.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.3.1-next.2 + - @backstage/core-components@0.15.1-next.2 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.9.0-next.2 + - @backstage/integration-react@1.2.0-next.2 + - @backstage/plugin-auth-react@0.1.7-next.2 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.1-next.2 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.9-next.2 + +## 1.10.11-next.1 + +### Patch Changes + +- e969dc7: Move `@types/react` to a peer dependency. +- Updated dependencies + - @backstage/core-components@0.15.1-next.1 + - @backstage/frontend-plugin-api@0.9.0-next.1 + - @backstage/integration-react@1.2.0-next.1 + - @backstage/core-compat-api@0.3.1-next.1 + - @backstage/core-plugin-api@1.10.0-next.1 + - @backstage/plugin-techdocs-react@1.2.9-next.1 + - @backstage/plugin-catalog-react@1.14.0-next.1 + - @backstage/plugin-search-react@1.8.1-next.1 + - @backstage/plugin-auth-react@0.1.7-next.1 + - @backstage/theme@0.5.8-next.0 + - @backstage/integration@1.15.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.10-next.0 + +### Patch Changes + +- a77cb40: Make `emptyState` input optional on `entity-content:techdocs` extension so that + the default empty state extension works correctly. +- Updated dependencies + - @backstage/frontend-plugin-api@0.9.0-next.0 + - @backstage/core-compat-api@0.3.1-next.0 + - @backstage/core-components@0.15.1-next.0 + - @backstage/core-plugin-api@1.10.0-next.0 + - @backstage/plugin-catalog-react@1.13.1-next.0 + - @backstage/plugin-search-react@1.8.1-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.15.0 + - @backstage/integration-react@1.1.32-next.0 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.7-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.9-next.0 + +## 1.10.9 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. + +- fe94ad8: Fixes left navigation positioning when using mkdocs blog plugin + +- b0206dc: Added support for setting page status with 'new' and 'deprecated' values, allowing visual indication of page status in TechDocs. To use include the following at the top of your markdown file: + + ```markdown + --- + status: new + --- + ``` + +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. + +- c7cb4c0: Add `empty-state:techdocs/entity-content` extension to allow overriding the empty state for the entity page techdocs tab. + +- 97db53e: Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling + +- Updated dependencies + - @backstage/core-components@0.15.0 + - @backstage/plugin-catalog-react@1.13.0 + - @backstage/frontend-plugin-api@0.8.0 + - @backstage/plugin-techdocs-react@1.2.8 + - @backstage/core-compat-api@0.3.0 + - @backstage/plugin-search-react@1.8.0 + - @backstage/integration-react@1.1.31 + - @backstage/catalog-model@1.7.0 + - @backstage/integration@1.15.0 + - @backstage/core-plugin-api@1.9.4 + - @backstage/theme@0.5.7 + - @backstage/plugin-auth-react@0.1.6 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.9-next.2 + +### Patch Changes + +- c891b69: Add `FavoriteToggle` in `core-components` to standardise favorite marking +- 836127c: Updated dependency `@testing-library/react` to `^16.0.0`. +- 97db53e: Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling +- Updated dependencies + - @backstage/core-components@0.14.11-next.1 + - @backstage/plugin-catalog-react@1.13.0-next.2 + - @backstage/integration-react@1.1.31-next.0 + - @backstage/plugin-search-react@1.8.0-next.2 + - @backstage/integration@1.15.0-next.0 + - @backstage/core-compat-api@0.3.0-next.2 + - @backstage/core-plugin-api@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.2 + - @backstage/theme@0.5.7-next.0 + - @backstage/plugin-auth-react@0.1.6-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.2 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-compat-api@0.3.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.6-next.0 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + +## 1.10.9-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-search-react@1.8.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.10.8 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- c7603e8: Deprecate the old pattern of `create*Extension`, and replace it with the equivalent Blueprint implementation instead +- 27794d1: Allow for more granular control of TechDocsReaderPage styling. Theme overrides can now be provided to TechDocs without affecting the theme in other areas of Backstage. +- 4490d73: Refactor TechDocs' mkdocs-redirects support. +- 8543e72: TechDocs redirect feature now includes a notification to the user before they are redirected. +- 67e76f2: TechDocs now supports the `mkdocs-redirects` plugin. Redirects defined using the `mkdocs-redirect` plugin will be handled automatically in TechDocs. Redirecting to external urls is not supported. In the case that an external redirect url is provided, TechDocs will redirect to the current documentation site home. +- bdc5471: Fixed issue where header styles were incorrectly generated when themes used CSS variables to define font size. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/frontend-plugin-api@0.7.0 + - @backstage/plugin-catalog-react@1.12.3 + - @backstage/plugin-search-react@1.7.14 + - @backstage/core-components@0.14.10 + - @backstage/core-compat-api@0.2.8 + - @backstage/plugin-search-common@1.2.14 + - @backstage/integration@1.14.0 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-auth-react@0.1.5 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-techdocs-react@1.2.7 + +## 1.10.8-next.3 + +### Patch Changes + +- 27794d1: Allow for more granular control of TechDocsReaderPage styling. Theme overrides can now be provided to TechDocs without affecting the theme in other areas of Backstage. +- 8543e72: TechDocs redirect feature now includes a notification to the user before they are redirected. +- Updated dependencies + - @backstage/frontend-plugin-api@0.7.0-next.3 + - @backstage/catalog-model@1.6.0-next.0 + - @backstage/core-compat-api@0.2.8-next.3 + - @backstage/plugin-catalog-react@1.12.3-next.3 + - @backstage/plugin-search-react@1.7.14-next.3 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0-next.0 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-search-common@1.2.14-next.1 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.1 + +## 1.10.8-next.2 + +### Patch Changes + +- 67e76f2: TechDocs now supports the `mkdocs-redirects` plugin. Redirects defined using the `mkdocs-redirect` plugin will be handled automatically in TechDocs. Redirecting to external urls is not supported. In the case that an external redirect url is provided, TechDocs will redirect to the current documentation site home. +- bdc5471: Fixed issue where header styles were incorrectly generated when themes used CSS variables to define font size. +- Updated dependencies + - @backstage/frontend-plugin-api@0.7.0-next.2 + - @backstage/core-compat-api@0.2.8-next.2 + - @backstage/plugin-search-common@1.2.14-next.1 + - @backstage/plugin-search-react@1.7.14-next.2 + - @backstage/plugin-catalog-react@1.12.3-next.2 + - @backstage/integration@1.14.0-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## 1.10.8-next.1 + +### Patch Changes + +- 69bd940: Use annotation constants from new techdocs-common package. +- 6349099: Added config input type to the extensions +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.3-next.1 + - @backstage/plugin-techdocs-common@0.1.0-next.0 + - @backstage/frontend-plugin-api@0.6.8-next.1 + - @backstage/core-compat-api@0.2.8-next.1 + - @backstage/plugin-search-react@1.7.14-next.1 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-search-common@1.2.14-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## 1.10.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.8-next.0 + - @backstage/plugin-catalog-react@1.12.3-next.0 + - @backstage/plugin-search-react@1.7.14-next.0 + - @backstage/core-components@0.14.10-next.0 + - @backstage/integration@1.14.0-next.0 + - @backstage/plugin-auth-react@0.1.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.8-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-search-common@1.2.13 + - @backstage/plugin-techdocs-react@1.2.7-next.0 + +## 1.10.7 + +### Patch Changes + +- 8fc2622: Fixed an issue that was causing techdocs pages unnecessarily re-render on navigate. +- 6fa652c: Improve default sorting of docs table +- 605b691: Allow for searching TechDocs by entity title +- 60caa92: Fix double scrollbar bug in reader +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.6 + - @backstage/core-components@0.14.9 + - @backstage/integration@1.13.0 + - @backstage/plugin-catalog-react@1.12.2 + - @backstage/plugin-search-common@1.2.13 + - @backstage/frontend-plugin-api@0.6.7 + - @backstage/integration-react@1.1.29 + - @backstage/plugin-auth-react@0.1.4 + - @backstage/plugin-search-react@1.7.13 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.7 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + +## 1.10.7-next.2 + +### Patch Changes + +- 6fa652c: Improve default sorting of docs table +- Updated dependencies + - @backstage/core-components@0.14.9-next.1 + - @backstage/frontend-plugin-api@0.6.7-next.1 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/plugin-auth-react@0.1.4-next.1 + - @backstage/plugin-catalog-react@1.12.2-next.2 + - @backstage/plugin-search-react@1.7.13-next.1 + - @backstage/plugin-techdocs-react@1.2.6-next.1 + - @backstage/core-compat-api@0.2.7-next.1 + +## 1.10.7-next.1 + +### Patch Changes + +- 60caa92: Fix double scrollbar bug in reader +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.2-next.1 + - @backstage/core-compat-api@0.2.7-next.0 + - @backstage/core-components@0.14.9-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-search-react@1.7.13-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.7-next.0 + - @backstage/integration@1.13.0-next.0 + - @backstage/integration-react@1.1.29-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.4-next.0 + - @backstage/plugin-search-common@1.2.12 + - @backstage/plugin-techdocs-react@1.2.6-next.0 + +## 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 + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/core-components@0.14.8-next.2 + - @backstage/integration@1.12.0-next.1 + - @backstage/plugin-techdocs-react@1.2.5-next.2 + - @backstage/plugin-catalog-react@1.12.1-next.2 + - @backstage/plugin-search-common@1.2.12-next.0 + - @backstage/plugin-search-react@1.7.12-next.2 + - @backstage/plugin-auth-react@0.1.3-next.2 + - @backstage/integration-react@1.1.28-next.1 + - @backstage/frontend-plugin-api@0.6.6-next.2 + - @backstage/core-compat-api@0.2.6-next.2 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3-next.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6-next.0 + +## 1.10.6-next.1 + +### 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. +- Updated dependencies + - @backstage/core-components@0.14.8-next.1 + - @backstage/core-compat-api@0.2.6-next.1 + - @backstage/core-plugin-api@1.9.3-next.0 + - @backstage/integration@1.12.0-next.0 + - @backstage/frontend-plugin-api@0.6.6-next.1 + - @backstage/integration-react@1.1.28-next.0 + - @backstage/plugin-auth-react@0.1.3-next.1 + - @backstage/plugin-catalog-react@1.12.1-next.1 + - @backstage/plugin-search-react@1.7.12-next.1 + - @backstage/plugin-techdocs-react@1.2.5-next.1 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.6-next.0 + +### 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. +- 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 +- 1256d88: Fix weird opening behaviour of the component. +- Updated dependencies + - @backstage/theme@0.5.6-next.0 + - @backstage/core-components@0.14.8-next.0 + - @backstage/plugin-search-react@1.7.12-next.0 + - @backstage/plugin-techdocs-react@1.2.5-next.0 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.6-next.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.6-next.0 + - @backstage/integration@1.11.0 + - @backstage/integration-react@1.1.27 + - @backstage/plugin-auth-react@0.1.3-next.0 + - @backstage/plugin-catalog-react@1.12.1-next.0 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.5 + +### Patch Changes + +- d2cc139: Update path in Readme for Plugin Techdocs to show the correct setup information. +- 5863cf7: The `techdocs.builder` config is now optional and it will default to `local`. +- Updated dependencies + - @backstage/core-compat-api@0.2.5 + - @backstage/core-components@0.14.7 + - @backstage/catalog-model@1.5.0 + - @backstage/plugin-auth-react@0.1.2 + - @backstage/plugin-catalog-react@1.12.0 + - @backstage/theme@0.5.4 + - @backstage/integration@1.11.0 + - @backstage/frontend-plugin-api@0.6.5 + - @backstage/integration-react@1.1.27 + - @backstage/plugin-search-react@1.7.11 + - @backstage/plugin-techdocs-react@1.2.4 + +## 1.10.5-next.2 + +### Patch Changes + +- 5863cf7: The `techdocs.builder` config is now optional and it will default to `local`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.0-next.2 + - @backstage/core-components@0.14.7-next.2 + - @backstage/integration@1.11.0-next.0 + - @backstage/core-compat-api@0.2.5-next.1 + - @backstage/frontend-plugin-api@0.6.5-next.1 + - @backstage/plugin-search-react@1.7.11-next.1 + - @backstage/integration-react@1.1.27-next.0 + +## 1.10.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.6-next.1 + - @backstage/plugin-catalog-react@1.11.4-next.1 + - @backstage/frontend-plugin-api@0.6.5-next.1 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-auth-react@0.1.2-next.1 + - @backstage/plugin-search-react@1.7.11-next.1 + - @backstage/plugin-techdocs-react@1.2.4-next.1 + - @backstage/core-compat-api@0.2.5-next.1 + +## 1.10.5-next.0 + +### Patch Changes + +- d2cc139: Update path in Readme for Plugin Techdocs to show the correct setup information. +- Updated dependencies + - @backstage/core-compat-api@0.2.5-next.0 + - @backstage/catalog-model@1.5.0-next.0 + - @backstage/plugin-auth-react@0.1.1-next.0 + - @backstage/theme@0.5.4-next.0 + - @backstage/core-components@0.14.5-next.0 + - @backstage/plugin-catalog-react@1.11.4-next.0 + - @backstage/plugin-techdocs-react@1.2.4-next.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.2 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.5-next.0 + - @backstage/integration@1.10.0 + - @backstage/integration-react@1.1.26 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.11-next.0 + +## 1.10.4 + +### Patch Changes + +- abfbcfc: Updated dependency `@testing-library/react` to `^15.0.0`. +- cb1e3b0: Updated dependency `@testing-library/dom` to `^10.0.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.3 + - @backstage/plugin-search-react@1.7.10 + - @backstage/plugin-auth-react@0.1.0 + - @backstage/plugin-catalog-react@1.11.3 + - @backstage/core-compat-api@0.2.4 + - @backstage/core-components@0.14.4 + - @backstage/core-plugin-api@1.9.2 + - @backstage/frontend-plugin-api@0.6.4 + - @backstage/theme@0.5.3 + - @backstage/integration-react@1.1.26 + - @backstage/integration@1.10.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-react@0.1.0-next.1 + - @backstage/frontend-plugin-api@0.6.4-next.1 + - @backstage/core-compat-api@0.2.4-next.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/integration@1.10.0-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-catalog-react@1.11.3-next.1 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.1 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## 1.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.10.0-next.0 + - @backstage/core-components@0.14.4-next.0 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/core-compat-api@0.2.4-next.0 + - @backstage/core-plugin-api@1.9.1 + - @backstage/errors@1.2.4 + - @backstage/frontend-plugin-api@0.6.4-next.0 + - @backstage/integration-react@1.1.26-next.0 + - @backstage/theme@0.5.2 + - @backstage/plugin-auth-react@0.0.4-next.0 + - @backstage/plugin-catalog-react@1.11.3-next.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/plugin-search-react@1.7.10-next.0 + - @backstage/plugin-techdocs-react@1.2.3-next.0 + +## 1.10.3 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.3 + - @backstage/plugin-techdocs-react@1.2.2 + - @backstage/plugin-catalog-react@1.11.2 + - @backstage/plugin-search-react@1.7.9 + - @backstage/frontend-plugin-api@0.6.3 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-auth-react@0.0.3 + - @backstage/core-compat-api@0.2.3 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.2 + +### Patch Changes + +- e8f026a: Use ESM exports of react-use library +- Updated dependencies + - @backstage/core-components@0.14.2 + - @backstage/plugin-techdocs-react@1.2.1 + - @backstage/plugin-catalog-react@1.11.1 + - @backstage/plugin-search-react@1.7.8 + - @backstage/frontend-plugin-api@0.6.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-auth-react@0.0.2 + - @backstage/core-compat-api@0.2.2 + - @backstage/core-plugin-api@1.9.1 + - @backstage/catalog-model@1.4.5 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.9.1 + - @backstage/theme@0.5.2 + - @backstage/plugin-search-common@1.2.11 + +## 1.10.1 + +### Patch Changes + +- 7c2d022: Fixed bug in TechDocs sidebar render that prevented scrollbar from being displayed +- 3f14e9f: Implement a client cookie refresh mechanism. +- 62bcaf8: Use the new generic refresh user cookie provider. +- 28f27f0: Added ESLint rule `no-top-level-material-ui-4-imports` to aid with the migration to Material UI v5. +- Updated dependencies + - @backstage/integration@1.9.1 + - @backstage/config@1.2.0 + - @backstage/core-components@0.14.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-react@0.0.1 + - @backstage/theme@0.5.2 + - @backstage/integration-react@1.1.25 + - @backstage/plugin-techdocs-react@1.2.0 + - @backstage/plugin-catalog-react@1.11.0 + - @backstage/plugin-search-common@1.2.11 + - @backstage/catalog-model@1.4.5 + - @backstage/core-compat-api@0.2.1 + - @backstage/core-plugin-api@1.9.1 + - @backstage/frontend-plugin-api@0.6.1 + - @backstage/plugin-search-react@1.7.7 + +## 1.10.1-next.2 + +### Patch Changes + +- 7c2d022: Fixed bug in TechDocs sidebar render that prevented scrollbar from being displayed +- 3f14e9f: Implement a client cookie refresh mechanism. +- Updated dependencies + - @backstage/integration@1.9.1-next.2 + - @backstage/plugin-techdocs-react@1.2.0-next.2 + - @backstage/core-components@0.14.1-next.2 + - @backstage/plugin-catalog-react@1.11.0-next.2 + - @backstage/integration-react@1.1.25-next.2 + - @backstage/frontend-plugin-api@0.6.1-next.2 + - @backstage/plugin-search-react@1.7.7-next.2 + - @backstage/core-compat-api@0.2.1-next.2 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.2.0-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.10.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0-next.1 + - @backstage/core-components@0.14.1-next.1 + - @backstage/plugin-catalog-react@1.10.1-next.1 + - @backstage/core-plugin-api@1.9.1-next.1 + - @backstage/integration@1.9.1-next.1 + - @backstage/integration-react@1.1.25-next.1 + - @backstage/plugin-techdocs-react@1.1.17-next.1 + - @backstage/frontend-plugin-api@0.6.1-next.1 + - @backstage/plugin-search-react@1.7.7-next.1 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/core-compat-api@0.2.1-next.1 + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/plugin-search-common@1.2.11-next.1 + +## 1.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.4-next.0 + - @backstage/theme@0.5.2-next.0 + - @backstage/core-components@0.14.1-next.0 + - @backstage/integration-react@1.1.25-next.0 + - @backstage/plugin-catalog-react@1.10.1-next.0 + - @backstage/plugin-search-common@1.2.11-next.0 + - @backstage/catalog-model@1.4.5-next.0 + - @backstage/config@1.1.2-next.0 + - @backstage/core-plugin-api@1.9.1-next.0 + - @backstage/integration@1.9.1-next.0 + - @backstage/plugin-search-react@1.7.7-next.0 + - @backstage/plugin-techdocs-react@1.1.17-next.0 + - @backstage/frontend-plugin-api@0.6.1-next.0 + - @backstage/core-compat-api@0.2.1-next.0 + +## 1.10.0 + +### Minor Changes + +- af4d147: Updated the styling for `` tags to avoid word break. + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- 3631fb4: Updated dependency `dompurify` to `^3.0.0`. + Updated dependency `@types/dompurify` to `^3.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0 + - @backstage/core-compat-api@0.2.0 + - @backstage/plugin-catalog-react@1.10.0 + - @backstage/core-components@0.14.0 + - @backstage/plugin-techdocs-react@1.1.16 + - @backstage/catalog-model@1.4.4 + - @backstage/theme@0.5.1 + - @backstage/integration@1.9.0 + - @backstage/core-plugin-api@1.9.0 + - @backstage/plugin-search-react@1.7.6 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration-react@1.1.24 + - @backstage/plugin-search-common@1.2.10 + +## 1.10.0-next.3 + +### Patch Changes + +- 3631fb4: Updated dependency `dompurify` to `^3.0.0`. + Updated dependency `@types/dompurify` to `^3.0.0`. +- 1cae748: Updated dependency `git-url-parse` to `^14.0.0`. +- Updated dependencies + - @backstage/theme@0.5.1-next.1 + - @backstage/integration@1.9.0-next.1 + - @backstage/core-components@0.14.0-next.2 + - @backstage/plugin-catalog-react@1.10.0-next.3 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/config@1.1.1 + - @backstage/core-compat-api@0.2.0-next.3 + - @backstage/core-plugin-api@1.9.0-next.1 + - @backstage/errors@1.2.3 + - @backstage/frontend-plugin-api@0.6.0-next.3 + - @backstage/integration-react@1.1.24-next.2 + - @backstage/plugin-search-common@1.2.10 + - @backstage/plugin-search-react@1.7.6-next.3 + - @backstage/plugin-techdocs-react@1.1.16-next.2 + +## 1.10.0-next.2 + +### Patch Changes + +- 8fe56a8: Widen `@types/react` dependency range to include version 18. +- Updated dependencies + - @backstage/core-components@0.14.0-next.1 + - @backstage/plugin-techdocs-react@1.1.16-next.1 + - @backstage/core-plugin-api@1.9.0-next.1 + - @backstage/frontend-plugin-api@0.6.0-next.2 + - @backstage/plugin-catalog-react@1.10.0-next.2 + - @backstage/plugin-search-react@1.7.6-next.2 + - @backstage/theme@0.5.1-next.0 + - @backstage/integration-react@1.1.24-next.1 + - @backstage/core-compat-api@0.2.0-next.2 + - @backstage/config@1.1.1 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/errors@1.2.3 + - @backstage/integration@1.9.0-next.0 + - @backstage/plugin-search-common@1.2.10 + +## 1.10.0-next.1 + +### Minor Changes + +- af4d147: Updated the styling for `` tags to avoid word break. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.6.0-next.1 + - @backstage/core-compat-api@0.2.0-next.1 + - @backstage/core-components@0.14.0-next.0 + - @backstage/catalog-model@1.4.4-next.0 + - @backstage/core-plugin-api@1.8.3-next.0 + - @backstage/integration@1.9.0-next.0 + - @backstage/plugin-catalog-react@1.9.4-next.1 + - @backstage/plugin-search-react@1.7.6-next.1 + - @backstage/integration-react@1.1.24-next.0 + - @backstage/plugin-techdocs-react@1.1.16-next.0 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.10 + +## 1.9.4-next.0 + +### Patch Changes + +- 912ca7b: Use `convertLegacyRouteRefs` to define routes in `/alpha` export plugin. +- Updated dependencies + - @backstage/core-compat-api@0.1.2-next.0 + - @backstage/plugin-catalog-react@1.9.4-next.0 + - @backstage/frontend-plugin-api@0.5.1-next.0 + - @backstage/core-components@0.13.10 + - @backstage/plugin-search-react@1.7.6-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-plugin-api@1.8.2 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/integration-react@1.1.23 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.10 + - @backstage/plugin-techdocs-react@1.1.15 + +## 1.9.3 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-compat-api@0.1.1 + - @backstage/frontend-plugin-api@0.5.0 + - @backstage/core-components@0.13.10 + - @backstage/core-plugin-api@1.8.2 + - @backstage/plugin-techdocs-react@1.1.15 + - @backstage/plugin-catalog-react@1.9.3 + - @backstage/plugin-search-react@1.7.5 + - @backstage/integration-react@1.1.23 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.10 + +## 1.9.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.1.1-next.2 + - @backstage/frontend-plugin-api@0.4.1-next.2 + - @backstage/plugin-catalog-react@1.9.3-next.2 + - @backstage/plugin-search-react@1.7.5-next.2 + - @backstage/integration-react@1.1.23-next.0 + +## 1.9.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.8.2-next.0 + - @backstage/core-components@0.13.10-next.1 + - @backstage/core-compat-api@0.1.1-next.1 + - @backstage/frontend-plugin-api@0.4.1-next.1 + - @backstage/integration-react@1.1.23-next.0 + - @backstage/plugin-catalog-react@1.9.3-next.1 + - @backstage/plugin-search-react@1.7.5-next.1 + - @backstage/plugin-techdocs-react@1.1.15-next.1 + - @backstage/integration@1.8.0 + - @backstage/config@1.1.1 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.9 + +## 1.9.3-next.0 + +### Patch Changes + +- 4016f21: Remove some unused dependencies +- Updated dependencies + - @backstage/core-components@0.13.10-next.0 + - @backstage/frontend-plugin-api@0.4.1-next.0 + - @backstage/plugin-techdocs-react@1.1.15-next.0 + - @backstage/plugin-catalog-react@1.9.3-next.0 + - @backstage/integration-react@1.1.22 + - @backstage/plugin-search-react@1.7.5-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-compat-api@0.1.1-next.0 + - @backstage/core-plugin-api@1.8.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-common@1.2.9 + +## 1.9.2 + +### Patch Changes + +- 03d0b6d: The `convertLegacyRouteRef` utility used by the alpha exports is now imported from `@backstage/core-compat-api`. +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 5814122: Updated `/alpha` exports to fit new naming patterns. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/core-compat-api@0.1.0 + - @backstage/core-plugin-api@1.8.1 + - @backstage/frontend-plugin-api@0.4.0 + - @backstage/plugin-catalog-react@1.9.2 + - @backstage/core-components@0.13.9 + - @backstage/theme@0.5.0 + - @backstage/plugin-search-react@1.7.4 + - @backstage/integration@1.8.0 + - @backstage/integration-react@1.1.22 + - @backstage/plugin-techdocs-react@1.1.14 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.9 + +## 1.9.2-next.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.9-next.3 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-compat-api@0.1.0-next.3 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/frontend-plugin-api@0.4.0-next.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/theme@0.5.0-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.3 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-search-react@1.7.4-next.3 + - @backstage/plugin-techdocs-react@1.1.14-next.3 + +## 1.9.2-next.3 + +### Patch Changes + +- a1227cc: Wrap `/alpha` export extension elements in backwards compatibility wrapper. +- 36c94b8: Refactor of the alpha exports due to API change in how extension IDs are constructed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.2 + - @backstage/theme@0.5.0-next.1 + - @backstage/core-compat-api@0.1.0-next.2 + - @backstage/plugin-catalog-react@1.9.2-next.2 + - @backstage/plugin-search-react@1.7.4-next.2 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-components@0.13.9-next.2 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/errors@1.2.3 + - @backstage/integration@1.8.0-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-search-common@1.2.8 + - @backstage/plugin-techdocs-react@1.1.14-next.2 + +## 1.9.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.4.0-next.1 + - @backstage/core-components@0.13.9-next.1 + - @backstage/core-plugin-api@1.8.1-next.1 + - @backstage/plugin-catalog-react@1.9.2-next.1 + - @backstage/plugin-search-react@1.7.4-next.1 + - @backstage/integration@1.8.0-next.1 + - @backstage/core-compat-api@0.0.1-next.1 + - @backstage/integration-react@1.1.22-next.1 + - @backstage/plugin-techdocs-react@1.1.14-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/theme@0.5.0-next.0 + - @backstage/plugin-search-common@1.2.8 + +## 1.9.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-compat-api@0.0.1-next.0 + +## 1.9.2-next.0 + +### Patch Changes + +- 03d0b6dcdc: The `convertLegacyRouteRef` utility used by the alpha exports is now imported from `@backstage/core-compat-api`. +- Updated dependencies + - @backstage/core-compat-api@0.0.2-next.0 + - @backstage/core-plugin-api@1.8.1-next.0 + - @backstage/plugin-catalog-react@1.9.2-next.0 + - @backstage/core-components@0.13.9-next.0 + - @backstage/plugin-search-react@1.7.4-next.0 + - @backstage/integration@1.8.0-next.0 + - @backstage/theme@0.5.0-next.0 + - @backstage/frontend-plugin-api@0.3.1-next.0 + - @backstage/integration-react@1.1.22-next.0 + - @backstage/plugin-techdocs-react@1.1.14-next.0 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.8 + +## 1.9.0 + +### Minor Changes + +- 17f93d5589: A new analytics event `not-found` will be published when a user visits a documentation site that does not exist + +### Patch Changes + +- 4728b3960d: Fixed navigation bug that caused users to not be scrolled to the top of a new page. Fixed navigation bug where using backwards and forwards browser navigation did not scroll users to the correct place on the TechDoc page. +- a3add7a682: Export alpha routes and nav item extension, only available for applications that uses the new Frontend system. +- 71c97e7d73: The \`spec.lifecycle' field in entities will now always be rendered as a string. +- 68fc9dc60e: Updated alpha exports according to routing changes in `@backstage/frontend-plugin-api`. +- 6c2b872153: Add official support for React 18. +- 0bf6ebda88: Added entity page content for the new plugin exported via `/alpha`. +- 67cc85bb14: Switched the conditional `react-dom/client` import to use `import(...)` rather than `require(...)`. +- 4aa43f62aa: Updated dependency `cross-fetch` to `^4.0.0`. +- 38cda52746: Added support for React 18. The new `createRoot` API from `react-dom/client` will now be used if present. +- fdb5e23602: Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency +- Updated dependencies + - @backstage/plugin-catalog-react@1.9.0 + - @backstage/core-components@0.13.8 + - @backstage/frontend-plugin-api@0.3.0 + - @backstage/integration@1.7.2 + - @backstage/integration-react@1.1.21 + - @backstage/core-plugin-api@1.8.0 + - @backstage/plugin-techdocs-react@1.1.13 + - @backstage/plugin-search-react@1.7.2 + - @backstage/theme@0.4.4 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.8 + +## 1.9.0-next.2 + +### Minor Changes + +- [#20851](https://github.com/backstage/backstage/pull/20851) [`17f93d5589`](https://github.com/backstage/backstage/commit/17f93d5589812df3dea53d956212e184b080fbac) Thanks [@agentbellnorm](https://github.com/agentbellnorm)! - A new analytics event `not-found` will be published when a user visits a documentation site that does not exist + +### Patch Changes + +- [#20842](https://github.com/backstage/backstage/pull/20842) [`fdb5e23602`](https://github.com/backstage/backstage/commit/fdb5e2360299c5faa30f4d4236fc548b94d37446) Thanks [@benjdlambert](https://github.com/benjdlambert)! - Import `MissingAnnotationEmptyState` from `@backstage/plugin-catalog-react` to remove the cyclical dependency + +- Updated dependencies + - @backstage/core-components@0.13.8-next.2 + - @backstage/frontend-plugin-api@0.3.0-next.2 + - @backstage/plugin-catalog-react@1.9.0-next.2 + - @backstage/integration-react@1.1.21-next.1 + - @backstage/plugin-search-react@1.7.2-next.2 + - @backstage/plugin-techdocs-react@1.1.13-next.2 + +## 1.8.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.2-next.0 + - @backstage/frontend-plugin-api@0.3.0-next.1 + - @backstage/plugin-catalog-react@1.9.0-next.1 + - @backstage/plugin-search-react@1.7.2-next.1 + - @backstage/integration-react@1.1.21-next.1 + - @backstage/core-components@0.13.8-next.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/core-plugin-api@1.8.0-next.0 + - @backstage/errors@1.2.3 + - @backstage/theme@0.4.4-next.0 + - @backstage/plugin-search-common@1.2.7 + - @backstage/plugin-techdocs-react@1.1.13-next.1 + +## 1.8.1-next.0 + +### Patch Changes + +- 4728b3960d: Fixed navigation bug that caused users to not be scrolled to the top of a new page. Fixed navigation bug where using backwards and forwards browser navigation did not scroll users to the correct place on the TechDoc page. +- a3add7a682: Export alpha routes and nav item extension, only available for applications that uses the new Frontend system. +- 71c97e7d73: The \`spec.lifecycle' field in entities will now always be rendered as a string. +- 68fc9dc60e: Updated alpha exports according to routing changes in `@backstage/frontend-plugin-api`. +- 6c2b872153: Add official support for React 18. +- 0bf6ebda88: Added entity page content for the new plugin exported via `/alpha`. +- 67cc85bb14: Switched the conditional `react-dom/client` import to use `import(...)` rather than `require(...)`. +- 38cda52746: Added support for React 18. The new `createRoot` API from `react-dom/client` will now be used if present. +- Updated dependencies + - @backstage/core-components@0.13.7-next.0 + - @backstage/frontend-plugin-api@0.3.0-next.0 + - @backstage/plugin-catalog-react@1.9.0-next.0 + - @backstage/integration-react@1.1.21-next.0 + - @backstage/core-plugin-api@1.8.0-next.0 + - @backstage/plugin-techdocs-react@1.1.13-next.0 + - @backstage/plugin-search-react@1.7.2-next.0 + - @backstage/theme@0.4.4-next.0 + - @backstage/integration@1.7.1 + - @backstage/catalog-model@1.4.3 + - @backstage/config@1.1.1 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-common@1.2.7 + +## 1.8.0 + +### Minor Changes + +- 27740caa2d: Added experimental support for declarative integration via the `/alpha` subpath. + +### Patch Changes + +- 4918f65ab2: Create an experimental `TechDocsSearchResultItemExtension` for declarative integration with Backstage; it can be accessed via the `/alpha` import. +- 3605370af6: Improved `DocsTable` to display pagination controls dynamically, appearing only when needed. +- 0296f272b4: The \`spec.lifecycle' field in entities will now always be rendered as a string. +- 9a1fce352e: Updated dependency `@testing-library/jest-dom` to `^6.0.0`. +- f95af4e540: Updated dependency `@testing-library/dom` to `^9.0.0`. +- 9468a67b92: Added support for React 18. The new `createRoot` API from `react-dom/client` will now be used if present. +- df449a7a31: Add kind column by default to TechDocsTable +- Updated dependencies + - @backstage/integration@1.7.1 + - @backstage/plugin-catalog-react@1.8.5 + - @backstage/frontend-plugin-api@0.2.0 + - @backstage/core-plugin-api@1.7.0 + - @backstage/core-components@0.13.6 + - @backstage/integration-react@1.1.20 + - @backstage/catalog-model@1.4.3 + - @backstage/errors@1.2.3 + - @backstage/plugin-search-react@1.7.1 + - @backstage/plugin-techdocs-react@1.1.12 + - @backstage/theme@0.4.3 + - @backstage/config@1.1.1 + - @backstage/plugin-search-common@1.2.7 + +## 1.7.1-next.2 + +### Patch Changes + +- 3605370af6: Improved `DocsTable` to display pagination controls dynamically, appearing only when needed. +- Updated dependencies + - @backstage/frontend-plugin-api@0.2.0-next.2 + - @backstage/integration-react@1.1.20-next.2 + - @backstage/core-components@0.13.6-next.2 + - @backstage/core-plugin-api@1.7.0-next.1 + - @backstage/catalog-model@1.4.3-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.2 + - @backstage/integration@1.7.1-next.1 + - @backstage/errors@1.2.3-next.0 + - @backstage/plugin-search-react@1.7.1-next.2 + - @backstage/theme@0.4.3-next.0 + - @backstage/config@1.1.1-next.0 + - @backstage/plugin-search-common@1.2.7-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.2 + +## 1.7.1-next.1 + +### Patch Changes + +- 4918f65ab2: Create an experimental `TechDocsSearchResultItemExtension` for declarative integration with Backstage; it can be accessed via the `/alpha` import. +- df449a7a31: Add kind column by default to TechDocsTable +- Updated dependencies + - @backstage/frontend-plugin-api@0.1.1-next.1 + - @backstage/core-components@0.13.6-next.1 + - @backstage/plugin-search-react@1.7.1-next.1 + - @backstage/integration-react@1.1.20-next.1 + - @backstage/plugin-catalog-react@1.8.5-next.1 + - @backstage/plugin-techdocs-react@1.1.12-next.1 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/integration@1.7.1-next.0 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + +## 1.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.7.1-next.0 + - @backstage/plugin-catalog-react@1.8.5-next.0 + - @backstage/core-plugin-api@1.7.0-next.0 + - @backstage/core-components@0.13.6-next.0 + - @backstage/integration-react@1.1.20-next.0 + - @backstage/config@1.1.0 + - @backstage/plugin-search-react@1.7.1-next.0 + - @backstage/plugin-techdocs-react@1.1.12-next.0 + - @backstage/catalog-model@1.4.2 + - @backstage/errors@1.2.2 + - @backstage/theme@0.4.2 + - @backstage/plugin-search-common@1.2.6 + +## 1.7.0 + +### Minor Changes + +- e44f45ac4515: This change allows a new annotation of `backstage.io/techdocs-entity` this ref allows you to reference another entity for its TechDocs. This allows you have a single TechDoc for all items in a system, for example you might have a frontend and a backend in the same repo. This would allow you to have TechDocs build under a `System` entity while referencing the system e.g.: `backstage.io/techdocs-entity: system:default/example` that will show the systems docs in both the TechDocs button and the TechDocs tab without needing to do duplicate builds and filling the TechDocs page with garbage. + +### Patch Changes + +- 88c9525a36f3: Fixed bug in styles that caused next and previous links in footer to overlap page content. +- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. +- 8cec7664e146: Removed `@types/node` dependency +- Updated dependencies + - @backstage/integration-react@1.1.19 + - @backstage/plugin-catalog-react@1.8.4 + - @backstage/core-components@0.13.5 + - @backstage/config@1.1.0 + - @backstage/catalog-model@1.4.2 + - @backstage/core-plugin-api@1.6.0 + - @backstage/errors@1.2.2 + - @backstage/integration@1.7.0 + - @backstage/plugin-search-common@1.2.6 + - @backstage/plugin-search-react@1.7.0 + - @backstage/plugin-techdocs-react@1.1.10 + - @backstage/theme@0.4.2 + +## 1.7.0-next.3 + +### Patch Changes + +- 406b786a2a2c: Mark package as being free of side effects, allowing more optimized Webpack builds. +- Updated dependencies + - @backstage/catalog-model@1.4.2-next.2 + - @backstage/config@1.1.0-next.2 + - @backstage/core-components@0.13.5-next.3 + - @backstage/core-plugin-api@1.6.0-next.3 + - @backstage/errors@1.2.2-next.0 + - @backstage/integration@1.7.0-next.3 + - @backstage/integration-react@1.1.19-next.3 + - @backstage/plugin-catalog-react@1.8.4-next.3 + - @backstage/plugin-search-common@1.2.6-next.2 + - @backstage/plugin-search-react@1.7.0-next.3 + - @backstage/plugin-techdocs-react@1.1.10-next.3 + - @backstage/theme@0.4.2-next.0 + +## 1.7.0-next.2 + +### Minor Changes + +- e44f45ac4515: This change allows a new annotation of `backstage.io/techdocs-entity` this ref allows you to reference another entity for its TechDocs. This allows you have a single TechDoc for all items in a system, for example you might have a frontend and a backend in the same repo. This would allow you to have TechDocs build under a `System` entity while referencing the system e.g.: `backstage.io/techdocs-entity: system:default/example` that will show the systems docs in both the TechDocs button and the TechDocs tab without needing to do duplicate builds and filling the TechDocs page with garbage. + +### Patch Changes + +- 8cec7664e146: Removed `@types/node` dependency +- Updated dependencies + - @backstage/integration-react@1.1.19-next.2 + - @backstage/core-components@0.13.5-next.2 + - @backstage/core-plugin-api@1.6.0-next.2 + - @backstage/config@1.1.0-next.1 + - @backstage/plugin-catalog-react@1.8.4-next.2 + - @backstage/plugin-search-react@1.7.0-next.2 + - @backstage/plugin-techdocs-react@1.1.10-next.2 + - @backstage/integration@1.7.0-next.2 + - @backstage/catalog-model@1.4.2-next.1 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-search-common@1.2.6-next.1 + +## 1.6.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.4-next.1 + - @backstage/core-components@0.13.5-next.1 + - @backstage/config@1.1.0-next.0 + - @backstage/integration@1.7.0-next.1 + - @backstage/plugin-search-react@1.7.0-next.1 + - @backstage/integration-react@1.1.19-next.1 + - @backstage/plugin-techdocs-react@1.1.10-next.1 + - @backstage/catalog-model@1.4.2-next.0 + - @backstage/core-plugin-api@1.6.0-next.1 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-search-common@1.2.6-next.0 + +## 1.6.8-next.0 + +### Patch Changes + +- 88c9525a36f3: Fixed bug in styles that caused next and previous links in footer to overlap page content. +- Updated dependencies + - @backstage/integration-react@1.1.18-next.0 + - @backstage/integration@1.7.0-next.0 + - @backstage/core-plugin-api@1.6.0-next.0 + - @backstage/core-components@0.13.5-next.0 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-catalog-react@1.8.3-next.0 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-search-react@1.6.5-next.0 + - @backstage/plugin-techdocs-react@1.1.10-next.0 + +## 1.6.6 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.1.16 + - @backstage/integration@1.6.0 + - @backstage/core-components@0.13.4 + - @backstage/plugin-catalog-react@1.8.1 + - @backstage/core-plugin-api@1.5.3 + - @backstage/plugin-search-react@1.6.4 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-techdocs-react@1.1.9 + +## 1.6.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.1-next.1 + - @backstage/integration-react@1.1.16-next.1 + +## 1.6.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.1.16-next.1 + - @backstage/integration@1.5.1 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/core-components@0.13.4-next.0 + - @backstage/core-plugin-api@1.5.3 + - @backstage/errors@1.2.1 + - @backstage/theme@0.4.1 + - @backstage/plugin-catalog-react@1.8.1-next.0 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-search-react@1.6.4-next.0 + - @backstage/plugin-techdocs-react@1.1.9-next.0 + +## 1.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.4-next.0 + - @backstage/core-plugin-api@1.5.3 + - @backstage/plugin-catalog-react@1.8.1-next.0 + - @backstage/plugin-search-react@1.6.4-next.0 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1 + - @backstage/integration@1.5.1 + - @backstage/integration-react@1.1.16-next.0 + - @backstage/theme@0.4.1 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-techdocs-react@1.1.9-next.0 + +## 1.6.5 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.4.1 + - @backstage/errors@1.2.1 + - @backstage/plugin-catalog-react@1.8.0 + - @backstage/core-components@0.13.3 + - @backstage/core-plugin-api@1.5.3 + - @backstage/catalog-model@1.4.1 + - @backstage/config@1.0.8 + - @backstage/integration@1.5.1 + - @backstage/integration-react@1.1.15 + - @backstage/plugin-search-common@1.2.5 + - @backstage/plugin-search-react@1.6.3 + - @backstage/plugin-techdocs-react@1.1.8 + +## 1.6.5-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.8.0-next.2 + - @backstage/theme@0.4.1-next.1 + - @backstage/core-plugin-api@1.5.3-next.1 + - @backstage/core-components@0.13.3-next.2 + - @backstage/catalog-model@1.4.1-next.0 + - @backstage/config@1.0.8 + - @backstage/errors@1.2.1-next.0 + - @backstage/integration@1.5.1-next.0 + - @backstage/integration-react@1.1.15-next.2 + - @backstage/plugin-search-common@1.2.5-next.0 + - @backstage/plugin-search-react@1.6.3-next.2 + - @backstage/plugin-techdocs-react@1.1.8-next.2 + +## 1.6.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.4.1-next.0 + - @backstage/core-components@0.13.3-next.1 + - @backstage/core-plugin-api@1.5.3-next.0 + - @backstage/integration-react@1.1.15-next.1 + - @backstage/plugin-catalog-react@1.7.1-next.1 + - @backstage/plugin-search-react@1.6.3-next.1 + - @backstage/plugin-techdocs-react@1.1.8-next.1 + - @backstage/config@1.0.8 + +## 1.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/errors@1.2.1-next.0 + - @backstage/core-components@0.13.3-next.0 + - @backstage/catalog-model@1.4.1-next.0 + - @backstage/config@1.0.8 + - @backstage/core-plugin-api@1.5.2 + - @backstage/integration@1.5.1-next.0 + - @backstage/integration-react@1.1.15-next.0 + - @backstage/theme@0.4.0 + - @backstage/plugin-catalog-react@1.7.1-next.0 + - @backstage/plugin-search-common@1.2.5-next.0 + - @backstage/plugin-search-react@1.6.3-next.0 + - @backstage/plugin-techdocs-react@1.1.8-next.0 + +## 1.6.4 + +### Patch Changes + +- 2f660eb573cc: Fix SearchBar styles & update StoryBook stories for custom styles for `notchedOutline` class. +- 956d09e8ea68: Change deprecated local references to import from shared `plugin-techdocs-react` plugin +- e33beb1f2a8e: Make the documentation pages printable (also handy for exporting to PDF) +- Updated dependencies + - @backstage/core-plugin-api@1.5.2 + - @backstage/plugin-search-react@1.6.2 + - @backstage/core-components@0.13.2 + - @backstage/theme@0.4.0 + - @backstage/integration@1.5.0 + - @backstage/plugin-catalog-react@1.7.0 + - @backstage/catalog-model@1.4.0 + - @backstage/errors@1.2.0 + - @backstage/plugin-techdocs-react@1.1.7 + - @backstage/integration-react@1.1.14 + - @backstage/config@1.0.8 + - @backstage/plugin-search-common@1.2.4 + +## 1.6.4-next.3 + +### Patch Changes + +- e33beb1f2a8e: Make the documentation pages printable (also handy for exporting to PDF) +- Updated dependencies + - @backstage/plugin-search-react@1.6.2-next.3 + - @backstage/core-components@0.13.2-next.3 + - @backstage/catalog-model@1.4.0-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.2-next.0 + - @backstage/errors@1.2.0-next.0 + - @backstage/integration@1.5.0-next.0 + - @backstage/integration-react@1.1.14-next.3 + - @backstage/theme@0.4.0-next.1 + - @backstage/plugin-catalog-react@1.7.0-next.3 + - @backstage/plugin-search-common@1.2.4-next.0 + - @backstage/plugin-techdocs-react@1.1.7-next.3 + +## 1.6.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.4.0-next.1 + - @backstage/plugin-catalog-react@1.7.0-next.2 + - @backstage/core-components@0.13.2-next.2 + - @backstage/integration-react@1.1.14-next.2 + - @backstage/plugin-search-react@1.6.1-next.2 + - @backstage/plugin-techdocs-react@1.1.7-next.2 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.2-next.0 + +## 1.6.3-next.1 + +### Patch Changes + +- 2f660eb573cc: Fix SearchBar styles & update StoryBook stories for custom styles for `notchedOutline` class. +- Updated dependencies + - @backstage/integration@1.5.0-next.0 + - @backstage/errors@1.2.0-next.0 + - @backstage/plugin-search-react@1.6.1-next.1 + - @backstage/core-components@0.13.2-next.1 + - @backstage/plugin-catalog-react@1.7.0-next.1 + - @backstage/catalog-model@1.4.0-next.0 + - @backstage/core-plugin-api@1.5.2-next.0 + - @backstage/integration-react@1.1.14-next.1 + - @backstage/plugin-techdocs-react@1.1.7-next.1 + - @backstage/config@1.0.7 + - @backstage/theme@0.4.0-next.0 + - @backstage/plugin-search-common@1.2.4-next.0 + +## 1.6.3-next.0 + +### Patch Changes + +- 956d09e8ea68: Change deprecated local references to import from shared `plugin-techdocs-react` plugin +- Updated dependencies + - @backstage/plugin-catalog-react@1.7.0-next.0 + - @backstage/theme@0.4.0-next.0 + - @backstage/plugin-techdocs-react@1.1.7-next.0 + - @backstage/integration@1.4.5 + - @backstage/config@1.0.7 + - @backstage/core-components@0.13.2-next.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/integration-react@1.1.14-next.0 + - @backstage/plugin-search-react@1.6.1-next.0 + - @backstage/catalog-model@1.3.0 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + +## 1.6.2 + +### Patch Changes + +- 863beb49498: Re-add the possibility to have trailing slashes in Techdocs navigation. +- Updated dependencies + - @backstage/theme@0.3.0 + - @backstage/plugin-catalog-react@1.6.0 + - @backstage/integration@1.4.5 + - @backstage/plugin-search-react@1.6.0 + - @backstage/core-components@0.13.1 + - @backstage/integration-react@1.1.13 + - @backstage/plugin-techdocs-react@1.1.6 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + +## 1.6.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.3.0-next.0 + - @backstage/core-components@0.13.1-next.1 + - @backstage/plugin-search-react@1.6.0-next.2 + - @backstage/integration-react@1.1.13-next.2 + - @backstage/plugin-catalog-react@1.6.0-next.2 + - @backstage/plugin-techdocs-react@1.1.6-next.1 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1 + +## 1.6.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.13.1-next.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/plugin-catalog-react@1.6.0-next.1 + - @backstage/plugin-search-react@1.6.0-next.1 + - @backstage/integration-react@1.1.13-next.1 + - @backstage/plugin-techdocs-react@1.1.6-next.0 + - @backstage/config@1.0.7 + +## 1.6.2-next.0 + +### Patch Changes + +- 863beb49498: Re-add the possibility to have trailing slashes in Techdocs navigation. +- Updated dependencies + - @backstage/plugin-catalog-react@1.6.0-next.0 + - @backstage/integration@1.4.5-next.0 + - @backstage/plugin-search-react@1.6.0-next.0 + - @backstage/integration-react@1.1.13-next.0 + - @backstage/core-components@0.13.0 + - @backstage/core-plugin-api@1.5.1 + - @backstage/catalog-model@1.3.0 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/theme@0.2.19 + - @backstage/plugin-search-common@1.2.3 + - @backstage/plugin-techdocs-react@1.1.5 + +## 1.6.1 + +### Patch Changes + +- 6c809d1a41c: Minor visual tweaks to adapt to changes in mkdocs-material v9 + +- b2e182cdfa4: Fixes a UI bug in search result item which rendered the item text with incorrect font size and color + +- 847a1eee3da: Change anchor links color in Techdocs content + + With the color (mkdocs supplied) used for anchor links the background and foreground colors do not have a sufficient contrast ratio. Using the link color from theme palette. + +- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) + +- 2e493480626: Fix a bug in sub-path navigation due to double addition of a sub-path if one was set up in `app.baseUrl`. + +- e0c6e8b9c3c: Update peer dependencies + +- Updated dependencies + - @backstage/core-components@0.13.0 + - @backstage/plugin-catalog-react@1.5.0 + - @backstage/plugin-search-react@1.5.2 + - @backstage/plugin-techdocs-react@1.1.5 + - @backstage/integration-react@1.1.12 + - @backstage/theme@0.2.19 + - @backstage/core-plugin-api@1.5.1 + - @backstage/catalog-model@1.3.0 + - @backstage/integration@1.4.4 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3 + +## 1.6.1-next.3 + +### Patch Changes + +- 2e493480626: Fix a bug in sub-path navigation due to double addition of a sub-path if one was set up in `app.baseUrl`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.5.0-next.3 + - @backstage/catalog-model@1.3.0-next.0 + - @backstage/core-components@0.13.0-next.3 + - @backstage/config@1.0.7 + - @backstage/core-plugin-api@1.5.1-next.1 + - @backstage/errors@1.1.5 + - @backstage/integration@1.4.4-next.0 + - @backstage/integration-react@1.1.12-next.3 + - @backstage/theme@0.2.19-next.0 + - @backstage/plugin-search-common@1.2.3-next.0 + - @backstage/plugin-search-react@1.5.2-next.3 + - @backstage/plugin-techdocs-react@1.1.5-next.3 + +## 1.6.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.6-next.2 + - @backstage/plugin-catalog-react@1.4.1-next.2 + - @backstage/core-plugin-api@1.5.1-next.1 + - @backstage/catalog-model@1.2.1 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/integration@1.4.4-next.0 + - @backstage/integration-react@1.1.12-next.2 + - @backstage/theme@0.2.19-next.0 + - @backstage/plugin-search-common@1.2.3-next.0 + - @backstage/plugin-search-react@1.5.2-next.2 + - @backstage/plugin-techdocs-react@1.1.5-next.2 + +## 1.6.1-next.1 + +### Patch Changes + +- 6c809d1a41c: Minor visual tweaks to adapt to changes in mkdocs-material v9 + +- 847a1eee3da: Change anchor links color in Techdocs content + + With the color (mkdocs supplied) used for anchor links the background and foreground colors do not have a sufficient contrast ratio. Using the link color from theme palette. + +- e0c6e8b9c3c: Update peer dependencies + +- Updated dependencies + - @backstage/core-components@0.12.6-next.1 + - @backstage/integration-react@1.1.12-next.1 + - @backstage/core-plugin-api@1.5.1-next.0 + - @backstage/plugin-techdocs-react@1.1.5-next.1 + - @backstage/plugin-catalog-react@1.4.1-next.1 + - @backstage/integration@1.4.4-next.0 + - @backstage/plugin-search-react@1.5.2-next.1 + - @backstage/theme@0.2.19-next.0 + - @backstage/catalog-model@1.2.1 + - @backstage/config@1.0.7 + - @backstage/errors@1.1.5 + - @backstage/plugin-search-common@1.2.3-next.0 + +## 1.6.1-next.0 + +### Patch Changes + +- b2e182cdfa4: Fixes a UI bug in search result item which rendered the item text with incorrect font size and color +- 8e00acb28db: Small tweaks to remove warnings in the console during development (mainly focusing on techdocs) +- Updated dependencies + - @backstage/core-components@0.12.6-next.0 + - @backstage/plugin-search-react@1.5.2-next.0 + - @backstage/plugin-techdocs-react@1.1.5-next.0 + - @backstage/plugin-catalog-react@1.4.1-next.0 + - @backstage/integration-react@1.1.12-next.0 + - @backstage/core-plugin-api@1.5.0 + - @backstage/config@1.0.7 + - @backstage/integration@1.4.3 + - @backstage/catalog-model@1.2.1 + - @backstage/errors@1.1.5 + - @backstage/theme@0.2.18 + - @backstage/plugin-search-common@1.2.2 + +## 1.6.0 + +### Minor Changes + +- 3f75b7607ca: Add ability to pass icon as function to have ability to customize it by search item + +### Patch Changes + +- 65454876fb2: Minor API report tweaks +- 54a1e133b56: Fix bug that caused next and previous links not to work with certain versions of mkdocs-material +- f320c299c67: The HTML tag attributes in the documentation content inserted to shadow DOM is preserved to improve accessibility +- cb8ec97cdeb: Change black & white colors to be theme aware +- c10384a9235: Switch to using `LinkButton` instead of the deprecated `Button` +- 8adfda60ae1: Updated dependency `jss` to `~10.10.0`. +- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. +- 238cf657c09: Copy to clipboard now works in a not secure context. +- Updated dependencies + - @backstage/core-components@0.12.5 + - @backstage/plugin-techdocs-react@1.1.4 + - @backstage/plugin-catalog-react@1.4.0 + - @backstage/plugin-search-react@1.5.1 + - @backstage/errors@1.1.5 + - @backstage/core-plugin-api@1.5.0 + - @backstage/catalog-model@1.2.1 + - @backstage/integration-react@1.1.11 + - @backstage/integration@1.4.3 + - @backstage/config@1.0.7 + - @backstage/theme@0.2.18 + - @backstage/plugin-search-common@1.2.2 + +## 1.6.0-next.2 + +### Patch Changes + +- 65454876fb2: Minor API report tweaks +- Updated dependencies + - @backstage/core-components@0.12.5-next.2 + - @backstage/plugin-techdocs-react@1.1.4-next.2 + - @backstage/plugin-catalog-react@1.4.0-next.2 + - @backstage/plugin-search-react@1.5.1-next.2 + - @backstage/core-plugin-api@1.5.0-next.2 + - @backstage/integration-react@1.1.11-next.2 + - @backstage/config@1.0.7-next.0 + - @backstage/integration@1.4.3-next.0 + +## 1.6.0-next.1 + +### Patch Changes + +- 54a1e133b56: Fix bug that caused next and previous links not to work with certain versions of mkdocs-material +- cb8ec97cdeb: Change black & white colors to be theme aware +- c10384a9235: Switch to using `LinkButton` instead of the deprecated `Button` +- 8adfda60ae1: Updated dependency `jss` to `~10.10.0`. +- 52b0022dab7: Updated dependency `msw` to `^1.0.0`. +- 238cf657c09: Copy to clipboard now works in a not secure context. +- Updated dependencies + - @backstage/core-components@0.12.5-next.1 + - @backstage/errors@1.1.5-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.1 + - @backstage/core-plugin-api@1.4.1-next.1 + - @backstage/integration-react@1.1.11-next.1 + - @backstage/integration@1.4.3-next.0 + - @backstage/config@1.0.7-next.0 + - @backstage/theme@0.2.18-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.1 + - @backstage/catalog-model@1.2.1-next.1 + - @backstage/plugin-search-common@1.2.2-next.0 + - @backstage/plugin-search-react@1.5.1-next.1 + +## 1.6.0-next.0 + +### Minor Changes + +- 3f75b7607c: Add ability to pass icon as function to have ability to customize it by search item + +### Patch Changes + +- f320c299c6: The HTML tag attributes in the documentation content inserted to shadow DOM is preserved to improve accessibility +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 1.5.0 + +### Minor Changes + +- 20840b36b4: Update DocsTable and EntityListDocsTable to accept overrides for Material Table options. +- 0eaa579f89: The `TechDocsSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- c8e09cc383: Fixed bug in Techdocs reader where a techdocs page with a hash in the URL did not always jump to the document anchor. + +- cad5607411: Improve view: remove footer overlay on large screen + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- 4660b63947: Create a TechDocs `` addon that allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page. + + Here's an example on how to use it in a Backstage app: + + ```diff + import { + DefaultTechDocsHome, + TechDocsIndexPage, + TechDocsReaderPage, + } from '@backstage/plugin-techdocs'; + import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha'; + +import { LightBox } from '@backstage/plugin-techdocs-module-addons-contrib'; + + const AppRoutes = () => { + + // other plugin routes + }> + + + } + > + + + + + + ; + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-react@1.1.3 + +## 1.5.0-next.2 + +### Patch Changes + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- Updated dependencies + - @backstage/catalog-model@1.2.0-next.1 + - @backstage/plugin-search-react@1.5.0-next.1 + - @backstage/core-components@0.12.4-next.1 + - @backstage/config@1.0.6 + - @backstage/core-plugin-api@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.3.0-next.2 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-react@1.1.3-next.2 + +## 1.5.0-next.1 + +### Minor Changes + +- 20840b36b4: Update DocsTable and EntityListDocsTable to accept overrides for Material Table options. +- 0eaa579f89: The `TechDocsSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4-next.0 + - @backstage/plugin-search-react@1.5.0-next.0 + - @backstage/plugin-catalog-react@1.3.0-next.1 + - @backstage/catalog-model@1.1.6-next.0 + - @backstage/config@1.0.6 + - @backstage/core-plugin-api@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-react@1.1.3-next.1 + +## 1.4.4-next.0 + +### Patch Changes + +- c8e09cc383: Fixed bug in Techdocs reader where a techdocs page with a hash in the URL did not always jump to the document anchor. +- cad5607411: Improve view: remove footer overlay on large screen +- Updated dependencies + - @backstage/plugin-catalog-react@1.3.0-next.0 + - @backstage/catalog-model@1.1.6-next.0 + - @backstage/plugin-techdocs-react@1.1.3-next.0 + - @backstage/integration-react@1.1.9 + +## 1.4.3 + +### Patch Changes + +- a74dd61534: Fix sizing of build log component to render all lines +- 80ce4e8c29: Small updates to some components to ensure theme typography properties are inherited correctly. +- 7115c7389b: Updated dependency `jss` to `~10.9.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.5 + - @backstage/plugin-catalog-react@1.2.4 + - @backstage/core-components@0.12.3 + - @backstage/plugin-search-react@1.4.0 + - @backstage/core-plugin-api@1.3.0 + - @backstage/plugin-techdocs-react@1.1.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.9 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.1 + +## 1.4.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-react@1.4.0-next.2 + - @backstage/core-plugin-api@1.3.0-next.1 + - @backstage/plugin-catalog-react@1.2.4-next.2 + - @backstage/plugin-techdocs-react@1.1.2-next.2 + - @backstage/catalog-model@1.1.5-next.1 + - @backstage/config@1.0.6-next.0 + - @backstage/core-components@0.12.3-next.2 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2-next.0 + - @backstage/integration-react@1.1.9-next.2 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.1-next.0 + +## 1.4.3-next.1 + +### Patch Changes + +- a74dd61534: Fix sizing of build log component to render all lines +- Updated dependencies + - @backstage/config@1.0.6-next.0 + - @backstage/catalog-model@1.1.5-next.1 + - @backstage/core-components@0.12.3-next.1 + - @backstage/core-plugin-api@1.2.1-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2-next.0 + - @backstage/integration-react@1.1.9-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.4-next.1 + - @backstage/plugin-search-common@1.2.1-next.0 + - @backstage/plugin-search-react@1.3.2-next.1 + - @backstage/plugin-techdocs-react@1.1.2-next.1 + +## 1.4.3-next.0 + +### Patch Changes + +- 7115c7389b: Updated dependency `jss` to `~10.9.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.5-next.0 + - @backstage/plugin-catalog-react@1.2.4-next.0 + - @backstage/core-components@0.12.3-next.0 + - @backstage/plugin-techdocs-react@1.1.2-next.0 + - @backstage/config@1.0.5 + - @backstage/core-plugin-api@1.2.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.1 + - @backstage/integration-react@1.1.9-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.0 + - @backstage/plugin-search-react@1.3.2-next.0 + +## 1.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.2 + - @backstage/integration-react@1.1.8 + - @backstage/plugin-catalog-react@1.2.3 + - @backstage/plugin-search-react@1.3.1 + - @backstage/plugin-techdocs-react@1.1.1 + +## 1.4.1 + +### Patch Changes + +- d3fea4ae0a: Internal fixes to avoid implicit usage of globals +- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. +- a19cffbeed: Update search links to only have header as linkable text +- 5d3058355d: Add `react/forbid-elements` linter rule for button, suggest Material UI `Button` +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- 786f1b1419: Support older versions of react-router +- Updated dependencies + - @backstage/plugin-techdocs-react@1.1.0 + - @backstage/core-plugin-api@1.2.0 + - @backstage/plugin-search-react@1.3.0 + - @backstage/core-components@0.12.1 + - @backstage/errors@1.1.4 + - @backstage/plugin-catalog-react@1.2.2 + - @backstage/integration-react@1.1.7 + - @backstage/integration@1.4.1 + - @backstage/plugin-search-common@1.2.0 + - @backstage/catalog-model@1.1.4 + - @backstage/config@1.0.5 + - @backstage/theme@0.2.16 + +## 1.4.1-next.4 + +### Patch Changes + +- 2e701b3796: Internal refactor to use `react-router-dom` rather than `react-router`. +- Updated dependencies + - @backstage/core-components@0.12.1-next.4 + - @backstage/plugin-catalog-react@1.2.2-next.4 + - @backstage/plugin-search-react@1.3.0-next.4 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/core-plugin-api@1.2.0-next.2 + - @backstage/errors@1.1.4-next.1 + - @backstage/integration@1.4.1-next.1 + - @backstage/integration-react@1.1.7-next.4 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.2.0-next.3 + - @backstage/plugin-techdocs-react@1.0.7-next.4 + +## 1.4.1-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.1-next.3 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/core-plugin-api@1.2.0-next.2 + - @backstage/errors@1.1.4-next.1 + - @backstage/integration@1.4.1-next.1 + - @backstage/integration-react@1.1.7-next.3 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.2-next.3 + - @backstage/plugin-search-common@1.2.0-next.2 + - @backstage/plugin-search-react@1.3.0-next.3 + - @backstage/plugin-techdocs-react@1.0.7-next.3 + +## 1.4.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.2.0-next.2 + - @backstage/plugin-search-react@1.3.0-next.2 + - @backstage/core-components@0.12.1-next.2 + - @backstage/plugin-catalog-react@1.2.2-next.2 + - @backstage/plugin-search-common@1.2.0-next.2 + - @backstage/integration-react@1.1.7-next.2 + - @backstage/plugin-techdocs-react@1.0.7-next.2 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/errors@1.1.4-next.1 + - @backstage/integration@1.4.1-next.1 + - @backstage/theme@0.2.16 + +## 1.4.1-next.1 + +### Patch Changes + +- d3fea4ae0a: Internal fixes to avoid implicit usage of globals +- a19cffbeed: Update search links to only have header as linkable text +- Updated dependencies + - @backstage/core-components@0.12.1-next.1 + - @backstage/plugin-search-react@1.2.2-next.1 + - @backstage/core-plugin-api@1.1.1-next.1 + - @backstage/plugin-catalog-react@1.2.2-next.1 + - @backstage/integration-react@1.1.7-next.1 + - @backstage/plugin-techdocs-react@1.0.7-next.1 + - @backstage/config@1.0.5-next.1 + - @backstage/integration@1.4.1-next.1 + - @backstage/catalog-model@1.1.4-next.1 + - @backstage/errors@1.1.4-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.2-next.1 + +## 1.4.1-next.0 + +### Patch Changes + +- 3280711113: Updated dependency `msw` to `^0.49.0`. +- Updated dependencies + - @backstage/plugin-techdocs-react@1.0.7-next.0 + - @backstage/core-components@0.12.1-next.0 + - @backstage/core-plugin-api@1.1.1-next.0 + - @backstage/integration-react@1.1.7-next.0 + - @backstage/integration@1.4.1-next.0 + - @backstage/plugin-catalog-react@1.2.2-next.0 + - @backstage/catalog-model@1.1.4-next.0 + - @backstage/config@1.0.5-next.0 + - @backstage/errors@1.1.4-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.2-next.0 + - @backstage/plugin-search-react@1.2.2-next.0 + +## 1.4.0 + +### Minor Changes + +- 5691baea69: Add ability to configure filters when using EntityListDocsGrid + + The following example will render two sections of cards grid: + + - One section for documentations tagged as `recommended` + - One section for documentations tagged as `runbook` + + ```js + + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + { + title: "RunBooks Documentation", + filterPredicate: entity => + entity?.metadata?.tags?.includes('runbook') ?? false, + } + ]}} /> + ``` + +- 63705e73d9: Hide document description if not provided + +- 847fc588a6: Updated TechDocs header to include label for source code icon and updated label to reflect Kind name + +### Patch Changes + +- 9e4d8e6198: Fix logic bug that broke techdocs-cli-embedded-app +- e92aa15f01: Bumped `canvas` dependency to the latest version, which has better Node.js v18 support. +- cbe11d1e23: Tweak README +- 7573b65232: Internal refactor of imports to avoid circular dependencies +- c1784a4980: Replaces in-code uses of `GitHub` with `Github` and deprecates old versions. +- 3a1a999b7b: Include query parameters when navigating to relative links in documents +- bd2aab4726: An analytics event matching the semantics of the `click` action is now captured when users click links within a TechDocs document. +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.1 + - @backstage/core-components@0.12.0 + - @backstage/core-plugin-api@1.1.0 + - @backstage/integration@1.4.0 + - @backstage/catalog-model@1.1.3 + - @backstage/plugin-techdocs-react@1.0.6 + - @backstage/integration-react@1.1.6 + - @backstage/plugin-search-react@1.2.1 + - @backstage/config@1.0.4 + - @backstage/errors@1.1.3 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.1 + +## 1.4.0-next.2 + +### Patch Changes + +- e92aa15f01: Bumped `canvas` dependency to the latest version, which has better Node.js v18 support. +- Updated dependencies + - @backstage/core-components@0.12.0-next.1 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/integration-react@1.1.6-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-react@1.2.1-next.1 + - @backstage/plugin-search-common@1.1.1-next.0 + - @backstage/plugin-search-react@1.2.1-next.1 + - @backstage/plugin-techdocs-react@1.0.6-next.1 + +## 1.4.0-next.1 + +### Patch Changes + +- 9e4d8e6198: Fix logic bug that broke techdocs-cli-embedded-app + +## 1.4.0-next.0 + +### Minor Changes + +- 5691baea69: Add ability to configure filters when using EntityListDocsGrid + + The following example will render two sections of cards grid: + + - One section for documentations tagged as `recommended` + - One section for documentations tagged as `runbook` + + ```js + + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + { + title: "RunBooks Documentation", + filterPredicate: entity => + entity?.metadata?.tags?.includes('runbook') ?? false, + } + ]}} /> + ``` + +### Patch Changes + +- cbe11d1e23: Tweak README +- 7573b65232: Internal refactor of imports to avoid circular dependencies +- c1784a4980: Replaces in-code uses of `GitHub` with `Github` and deprecates old versions. +- 3a1a999b7b: Include query parameters when navigating to relative links in documents +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.1-next.0 + - @backstage/core-components@0.12.0-next.0 + - @backstage/core-plugin-api@1.1.0-next.0 + - @backstage/integration@1.4.0-next.0 + - @backstage/catalog-model@1.1.3-next.0 + - @backstage/integration-react@1.1.6-next.0 + - @backstage/plugin-search-react@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.0.6-next.0 + - @backstage/config@1.0.4-next.0 + - @backstage/errors@1.1.3-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.1.1-next.0 + +## 1.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.2 + - @backstage/plugin-catalog-react@1.2.0 + - @backstage/core-components@0.11.2 + - @backstage/plugin-search-react@1.2.0 + - @backstage/plugin-search-common@1.1.0 + - @backstage/plugin-techdocs-react@1.0.5 + - @backstage/integration-react@1.1.5 + - @backstage/core-plugin-api@1.0.7 + - @backstage/config@1.0.3 + - @backstage/errors@1.1.2 + - @backstage/integration@1.3.2 + - @backstage/theme@0.2.16 + +## 1.3.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.0-next.2 + - @backstage/plugin-search-common@1.1.0-next.2 + - @backstage/catalog-model@1.1.2-next.2 + - @backstage/config@1.0.3-next.2 + - @backstage/core-components@0.11.2-next.2 + - @backstage/core-plugin-api@1.0.7-next.2 + - @backstage/errors@1.1.2-next.2 + - @backstage/integration@1.3.2-next.2 + - @backstage/integration-react@1.1.5-next.2 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-react@1.2.0-next.2 + - @backstage/plugin-techdocs-react@1.0.5-next.2 + +## 1.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.2.0-next.1 + - @backstage/plugin-search-react@1.2.0-next.1 + - @backstage/plugin-search-common@1.1.0-next.1 + - @backstage/core-components@0.11.2-next.1 + - @backstage/core-plugin-api@1.0.7-next.1 + - @backstage/catalog-model@1.1.2-next.1 + - @backstage/config@1.0.3-next.1 + - @backstage/errors@1.1.2-next.1 + - @backstage/integration@1.3.2-next.1 + - @backstage/integration-react@1.1.5-next.1 + - @backstage/theme@0.2.16 + - @backstage/plugin-techdocs-react@1.0.5-next.1 + +## 1.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.2-next.0 + - @backstage/core-components@0.11.2-next.0 + - @backstage/plugin-catalog-react@1.1.5-next.0 + - @backstage/plugin-techdocs-react@1.0.5-next.0 + - @backstage/integration-react@1.1.5-next.0 + - @backstage/plugin-search-react@1.1.1-next.0 + - @backstage/config@1.0.3-next.0 + - @backstage/core-plugin-api@1.0.7-next.0 + - @backstage/errors@1.1.2-next.0 + - @backstage/integration@1.3.2-next.0 + - @backstage/theme@0.2.16 + - @backstage/plugin-search-common@1.0.2-next.0 + +## 1.3.2 + +### Patch Changes + +- 817f3196f6: Updated React Router dependencies to be peer dependencies. +- eadf56bbbf: Bump `git-url-parse` version to `^13.0.0` +- 3f739be9d9: Minor API signatures cleanup +- 763fb81e82: Internal refactor to use more type safe code when dealing with route parameters. +- 7d47def9c4: Removed dependency on `@types/jest`. +- 817f3196f6: Updated the `TechDocsReaderPage` to be compatible with React Router v6 stable. +- 7a95c705fa: Fixed a bug where addons wouldn't render on sub pages when using React Route v6 stable. +- 667d917488: Updated dependency `msw` to `^0.47.0`. +- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. +- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. +- ca8d5a6eae: Use the new `SearchAutocomplete` component in the `TechDocsSearch` component to maintain consistency across search experiences and avoid code duplication. +- 829f14a9b0: Always update the title and sub-title when the location changes on a `TechDocs` reader page. +- e97d616f08: Fixed a bug where scrolling for anchors where the id starts with number didn't work for the current page. +- ef9ab322de: Minor API signatures cleanup +- Updated dependencies + - @backstage/core-components@0.11.1 + - @backstage/core-plugin-api@1.0.6 + - @backstage/plugin-catalog-react@1.1.4 + - @backstage/plugin-search-react@1.1.0 + - @backstage/plugin-techdocs-react@1.0.4 + - @backstage/integration@1.3.1 + - @backstage/catalog-model@1.1.1 + - @backstage/config@1.0.2 + - @backstage/errors@1.1.1 + - @backstage/integration-react@1.1.4 + - @backstage/plugin-search-common@1.0.1 + +## 1.3.2-next.3 + +### Patch Changes + +- 7d47def9c4: Removed dependency on `@types/jest`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.4-next.2 + - @backstage/catalog-model@1.1.1-next.0 + - @backstage/config@1.0.2-next.0 + - @backstage/core-components@0.11.1-next.3 + - @backstage/core-plugin-api@1.0.6-next.3 + - @backstage/errors@1.1.1-next.0 + - @backstage/integration@1.3.1-next.2 + - @backstage/integration-react@1.1.4-next.2 + - @backstage/plugin-techdocs-react@1.0.4-next.2 + +## 1.3.2-next.2 + +### Patch Changes + +- eadf56bbbf: Bump `git-url-parse` version to `^13.0.0` +- 7a95c705fa: Fixed a bug where addons wouldn't render on sub pages when using React Route v6 stable. +- 667d917488: Updated dependency `msw` to `^0.47.0`. +- 87ec2ba4d6: Updated dependency `msw` to `^0.46.0`. +- ca8d5a6eae: Use the new `SearchAutocomplete` component in the `TechDocsSearch` component to maintain consistency across search experiences and avoid code duplication. +- e97d616f08: Fixed a bug where scrolling for anchors where the id starts with number didn't work for the current page. +- Updated dependencies + - @backstage/integration@1.3.1-next.1 + - @backstage/core-components@0.11.1-next.2 + - @backstage/core-plugin-api@1.0.6-next.2 + - @backstage/integration-react@1.1.4-next.1 + - @backstage/plugin-search-react@1.1.0-next.2 + +## 1.3.2-next.1 + +### Patch Changes + +- 817f3196f6: Updated React Router dependencies to be peer dependencies. +- 763fb81e82: Internal refactor to use more type safe code when dealing with route parameters. +- 817f3196f6: Updated the `TechDocsReaderPage` to be compatible with React Router v6 stable. +- Updated dependencies + - @backstage/core-components@0.11.1-next.1 + - @backstage/core-plugin-api@1.0.6-next.1 + - @backstage/plugin-catalog-react@1.1.4-next.1 + - @backstage/plugin-search-react@1.0.2-next.1 + - @backstage/plugin-techdocs-react@1.0.4-next.1 + +## 1.3.2-next.0 + +### Patch Changes + +- 3f739be9d9: Minor API signatures cleanup +- bf5e9030eb: Updated dependency `msw` to `^0.45.0`. +- 829f14a9b0: Always update the title and sub-title when the location changes on a `TechDocs` reader page. +- ef9ab322de: Minor API signatures cleanup +- Updated dependencies + - @backstage/core-plugin-api@1.0.6-next.0 + - @backstage/core-components@0.11.1-next.0 + - @backstage/integration-react@1.1.4-next.0 + - @backstage/integration@1.3.1-next.0 + - @backstage/plugin-catalog-react@1.1.4-next.0 + - @backstage/plugin-search-react@1.0.2-next.0 + - @backstage/plugin-techdocs-react@1.0.4-next.0 + - @backstage/plugin-search-common@1.0.1-next.0 + +## 1.3.1 + +### Patch Changes + +- e924d2d013: Added back reduction in size, this fixes the extremely large TeachDocs headings +- b86ed4d990: Add highlight to active navigation item and navigation parents. +- 7a98c73dc8: Fixed techdocs sidebar layout bug for medium devices. +- 8acb22205c: Scroll techdocs navigation into focus and expand any nested navigation items. +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## 1.3.1-next.2 + +### Patch Changes + +- 8acb22205c: Scroll techdocs navigation into focus and expand any nested navigation items. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## 1.3.1-next.1 + +### Patch Changes + +- b86ed4d990: Add highlight to active navigation item and navigation parents. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## 1.3.1-next.0 + +### Patch Changes + +- 7a98c73dc8: Fixed techdocs sidebar layout bug for medium devices. +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## 1.3.0 + +### Minor Changes + +- ebf3eb1641: Use the same initial filter `owned` for the `TechDocsIndexPage` as for the `CatalogPage`. + + If you prefer to keep the previous behavior, you can change the default for the initial filter + to `all` (or `starred` if you rather prefer that). + + + + In general, with this change you will be able to set props at `TechDocsIndexPage`. + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 3cbebf710e: Reorder browser tab title in Techdocs pages to have the site name first. + +- 726577958f: Remove the 60% factor from the font size calculation of headers to use the exact size defined in BackstageTheme. + +- 7739141ab2: Fix: When docs are shown in an entity page under the docs tab the sidebars start overlapping with the header and tabs in the page when you scroll the documentation content. + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## 1.2.1-next.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.4-next.0 + - @backstage/core-components@0.10.0-next.3 + - @backstage/integration-react@1.1.2-next.3 + - @backstage/integration@1.2.2-next.3 + - @backstage/catalog-model@1.1.0-next.3 + - @backstage/plugin-catalog-react@1.1.2-next.3 + - @backstage/plugin-search-react@0.2.2-next.3 + - @backstage/plugin-techdocs-react@1.0.2-next.2 + +## 1.2.1-next.2 + +### Patch Changes + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 7739141ab2: Fix: When docs are shown in an entity page under the docs tab the sidebars start overlapping with the header and tabs in the page when you scroll the documentation content. + +- Updated dependencies + - @backstage/core-components@0.10.0-next.2 + - @backstage/catalog-model@1.1.0-next.2 + - @backstage/plugin-search-react@0.2.2-next.2 + - @backstage/theme@0.2.16-next.1 + - @backstage/integration@1.2.2-next.2 + - @backstage/plugin-catalog-react@1.1.2-next.2 + - @backstage/integration-react@1.1.2-next.2 + - @backstage/plugin-techdocs-react@1.0.2-next.1 + +## 1.2.1-next.1 + +### Patch Changes + +- 726577958f: Remove the 60% factor from the font size calculation of headers to use the exact size defined in BackstageTheme. +- Updated dependencies + - @backstage/core-components@0.9.6-next.1 + - @backstage/catalog-model@1.1.0-next.1 + - @backstage/errors@1.1.0-next.0 + - @backstage/theme@0.2.16-next.0 + - @backstage/integration@1.2.2-next.1 + - @backstage/integration-react@1.1.2-next.1 + - @backstage/plugin-catalog-react@1.1.2-next.1 + - @backstage/plugin-search-common@0.3.6-next.0 + - @backstage/plugin-search-react@0.2.2-next.1 + +## 1.2.1-next.0 + +### Patch Changes + +- 3cbebf710e: Reorder browser tab title in Techdocs pages to have the site name first. +- Updated dependencies + - @backstage/catalog-model@1.1.0-next.0 + - @backstage/core-components@0.9.6-next.0 + - @backstage/plugin-techdocs-react@1.0.2-next.0 + - @backstage/integration@1.2.2-next.0 + - @backstage/plugin-catalog-react@1.1.2-next.0 + - @backstage/integration-react@1.1.2-next.0 + - @backstage/plugin-search-react@0.2.2-next.0 + +## 1.2.0 + +### Minor Changes + +- fe7614ea54: Add an optional icon to the Catalog and TechDocs search results + +### Patch Changes + +- d047d81295: Use entity title as label in `TechDocsReaderPageHeader` if available + +- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. + +- bff65e6958: Updated sidebar-related logic to use `` + `useSidebarPinState()` and/or `` + `useSidebarOpenState()` from `@backstage/core-components`. + +- 915700f64f: In order to simplify analytics on top of the search experience in Backstage, the provided `<*ResultListItem />` component now captures a `discover` analytics event instead of a `click` event. This event includes the result rank as its `value` and, like a click, the URL/path clicked to as its `to` attribute. + +- 881fbd7e8d: Fix `EntityTechdocsContent` component to use objects instead of `` elements, otherwise "outlet" will be null on sub-pages and add-ons won't render. + +- 17c059dfd0: Restructures reader style transformations to improve code readability: + + - Extracts the style rules to separate files; + - Creates a hook that processes each rule; + - And creates another hook that returns a transformer responsible for injecting them into the head tag of a given element. + +- 3b45ad701f: Packages a set of tweaks to the TechDocs addons rendering process: + + - Prevents displaying sidebars until page styles are loaded and the sidebar position is updated; + - Prevents new sidebar locations from being created every time the reader page is rendered if these locations already exist; + - Centers the styles loaded event to avoid having multiple locations setting the opacity style in Shadow Dom causing the screen to flash multiple times. + +- 9b94ade898: Use entity title in `TechDocsSearch` placeholder if available. + +- 816f7475ec: Convert `sanitizeDOM` transformer to hook as part of code readability improvements in dom file. + +- 50ff56a80f: Change the `EntityDocsPage` path to be more specific and also add integration tests for `sub-routes` on this page. + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.1 + - @backstage/plugin-search-common@0.3.5 + - @backstage/plugin-search-react@0.2.1 + - @backstage/core-components@0.9.5 + - @backstage/integration@1.2.1 + - @backstage/core-plugin-api@1.0.3 + - @backstage/integration-react@1.1.1 + - @backstage/catalog-model@1.0.3 + - @backstage/plugin-techdocs-react@1.0.1 + +## 1.1.2-next.1 + +### Patch Changes + +- 8f7b1835df: Updated dependency `msw` to `^0.41.0`. +- bff65e6958: Updated sidebar-related logic to use `` + `useSidebarPinState()` and/or `` + `useSidebarOpenState()` from `@backstage/core-components`. +- Updated dependencies + - @backstage/core-components@0.9.5-next.1 + - @backstage/core-plugin-api@1.0.3-next.0 + - @backstage/integration-react@1.1.1-next.1 + - @backstage/integration@1.2.1-next.1 + - @backstage/catalog-model@1.0.3-next.0 + - @backstage/plugin-catalog-react@1.1.1-next.1 + - @backstage/plugin-search-react@0.2.1-next.0 + - @backstage/plugin-techdocs-react@1.0.1-next.1 + - @backstage/plugin-search-common@0.3.5-next.0 + +## 1.1.2-next.0 + +### Patch Changes + +- 881fbd7e8d: Fix `EntityTechdocsContent` component to use objects instead of `` elements, otherwise "outlet" will be null on sub-pages and add-ons won't render. + +- 17c059dfd0: Restructures reader style transformations to improve code readability: + + - Extracts the style rules to separate files; + - Creates a hook that processes each rule; + - And creates another hook that returns a transformer responsible for injecting them into the head tag of a given element. + +- 3b45ad701f: Packages a set of tweaks to the TechDocs addons rendering process: + + - Prevents displaying sidebars until page styles are loaded and the sidebar position is updated; + - Prevents new sidebar locations from being created every time the reader page is rendered if these locations already exist; + - Centers the styles loaded event to avoid having multiple locations setting the opacity style in Shadow Dom causing the screen to flash multiple times. + +- 816f7475ec: Convert `sanitizeDOM` transformer to hook as part of code readability improvements in dom file. + +- 50ff56a80f: Change the `EntityDocsPage` path to be more specific and also add integration tests for `sub-routes` on this page. + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.1-next.0 + - @backstage/core-components@0.9.5-next.0 + - @backstage/integration@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.0.1-next.0 + - @backstage/integration-react@1.1.1-next.0 + +## 1.1.1 + +### Patch Changes + +- 52419be116: Create a menu in the sub header of documentation pages, it is responsible for rendering TechDocs addons that allow users to customize their reading experience. +- a307a14be0: Removed dependency on `@backstage/core-app-api`. +- bed0d64ce9: Fixed bugs that prevented a 404 error from being shown when it should have been. +- 2efee91251: Add a `sub-route` path on the EntityDocs page to fix the blank screen error when navigating using sidebar links. +- 2dcb2c9678: Loading SVGs correctly with `bota` with extended characters +- 52fddad92d: The `TechDocsStorageApi` and its associated ref are now exported by `@backstage/plugin-techdocs-react`. The API interface, ref, and types are now deprecated in `@backstage/plugin-techdocs` and will be removed in a future release. +- 0ad901569f: Hidden exports related to experimental TechDocs reader functionality have been removed and can no longer be imported. In the unlikely event you were using these exports, you can now take advantage of the officially supported and generally available TechDocs Addon framework instead. +- 3a74e203a8: Updated search result components to support rendering content with highlighted matched terms +- Updated dependencies + - @backstage/core-components@0.9.4 + - @backstage/integration@1.2.0 + - @backstage/core-plugin-api@1.0.2 + - @backstage/plugin-catalog-react@1.1.0 + - @backstage/integration-react@1.1.0 + - @backstage/plugin-techdocs-react@1.0.0 + - @backstage/config@1.0.1 + - @backstage/plugin-search-react@0.2.0 + - @backstage/plugin-search-common@0.3.4 + - @backstage/catalog-model@1.0.2 + +## 1.1.1-next.3 + +### Patch Changes + +- cc8ddd0979: revert dependency `event-source-polyfill` to `1.0.25` +- Updated dependencies + - @backstage/core-components@0.9.4-next.2 + +## 1.1.1-next.2 + +### Patch Changes + +- 52419be116: Create a menu in the sub header of documentation pages, it is responsible for rendering TechDocs addons that allow users to customize their reading experience. +- 1af133f779: Updated dependency `event-source-polyfill` to `1.0.26`. +- 2dcb2c9678: Loading SVGs correctly with `bota` with extended characters +- 3a74e203a8: Updated search result components to support rendering content with highlighted matched terms +- Updated dependencies + - @backstage/core-components@0.9.4-next.1 + - @backstage/plugin-techdocs-react@0.1.1-next.2 + - @backstage/config@1.0.1-next.0 + - @backstage/plugin-search-react@0.2.0-next.2 + - @backstage/plugin-search-common@0.3.4-next.0 + - @backstage/plugin-catalog-react@1.1.0-next.2 + - @backstage/catalog-model@1.0.2-next.0 + - @backstage/core-plugin-api@1.0.2-next.1 + - @backstage/integration@1.2.0-next.1 + - @backstage/integration-react@1.1.0-next.2 + +## 1.1.1-next.1 + +### Patch Changes + +- 52fddad92d: The `TechDocsStorageApi` and its associated ref are now exported by `@backstage/plugin-techdocs-react`. The API interface, ref, and types are now deprecated in `@backstage/plugin-techdocs` and will be removed in a future release. +- Updated dependencies + - @backstage/core-components@0.9.4-next.0 + - @backstage/core-plugin-api@1.0.2-next.0 + - @backstage/plugin-catalog-react@1.1.0-next.1 + - @backstage/plugin-search-react@0.2.0-next.1 + - @backstage/plugin-techdocs-react@0.1.1-next.1 + - @backstage/integration-react@1.1.0-next.1 + +## 1.1.1-next.0 + +### Patch Changes + +- a307a14be0: Removed dependency on `@backstage/core-app-api`. +- bed0d64ce9: Fixed bugs that prevented a 404 error from being shown when it should have been. +- Updated dependencies + - @backstage/integration@1.2.0-next.0 + - @backstage/plugin-catalog-react@1.1.0-next.0 + - @backstage/integration-react@1.1.0-next.0 + - @backstage/plugin-search-react@0.1.1-next.0 + - @backstage/plugin-techdocs-react@0.1.1-next.0 + +## 1.1.0 + +### Minor Changes + +- ace749b785: TechDocs supports a new, experimental method of customization: addons! + + To customize the standalone TechDocs reader page experience, update your `/packages/app/src/App.tsx` in the following way: + + ```diff + import { TechDocsIndexPage, TechDocsReaderPage } from '@backstage/plugin-techdocs'; + + import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; + + import { SomeAddon } from '@backstage/plugin-some-plugin'; + + // ... + + } /> + } + > + + + + + + + + + // ... + ``` + + To customize the TechDocs reader experience on the Catalog entity page, update your `packages/app/src/components/catalog/EntityPage.tsx` in the following way: + + ```diff + import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; + + import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; + + import { SomeAddon } from '@backstage/plugin-some-plugin'; + + // ... + + + + {overviewContent} + + + + - + + + + + + + + + + + + + + // ... + ``` + + If you do not wish to customize your TechDocs reader experience in this way at this time, no changes are necessary! + +### Patch Changes + +- ab230a433f: imports from `@backstage/plugin-search-react` instead of `@backstage/plugin-search` + +- 7c7919777e: build(deps-dev): bump `@testing-library/react-hooks` from 7.0.2 to 8.0.0 + +- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 + +- 230ad0826f: Bump to using `@types/node` v16 + +- f0fb9153b7: Fix broken query selectors on techdocs + +- 9975ff9852: Applied the fix from version 1.0.1 of this package, which is part of the v1.0.2 release of Backstage. + +- 3ba256c389: Fixed a bug preventing custom TechDocs reader page implementations from rendering without being double-wrapped in the `` component. + +- fe53fe97d7: Fix permalink scrolling for anchors where the id starts with a number. + +- 0152c0de22: Some documentation layout tweaks: + + - drawer toggle margins + - code block margins + - sidebar drawer width + - inner content width + - footer link width + - sidebar table of contents scroll + +- 3ba256c389: Fixed a bug that caused addons in the `Subheader` location to break the default TechDocs reader page layout. + +- Updated dependencies + - @backstage/integration@1.1.0 + - @backstage/plugin-catalog-react@1.0.1 + - @backstage/catalog-model@1.0.1 + - @backstage/core-app-api@1.0.1 + - @backstage/core-components@0.9.3 + - @backstage/core-plugin-api@1.0.1 + - @backstage/plugin-search-react@0.1.0 + - @backstage/plugin-techdocs-react@0.1.0 + - @backstage/integration-react@1.0.1 + +## 1.1.0-next.3 + +### Minor Changes + +- ace749b785: TechDocs supports a new, experimental method of customization: addons! + + To customize the standalone TechDocs reader page experience, update your `/packages/app/src/App.tsx` in the following way: + + ```diff + import { TechDocsIndexPage, TechDocsReaderPage } from '@backstage/plugin-techdocs'; + + import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; + + import { SomeAddon } from '@backstage/plugin-some-plugin'; + + // ... + + } /> + } + > + + + + + + + + + // ... + ``` + + To customize the TechDocs reader experience on the Catalog entity page, update your `packages/app/src/components/catalog/EntityPage.tsx` in the following way: + + ```diff + import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; + + import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; + + import { SomeAddon } from '@backstage/plugin-some-plugin'; + + // ... + + + + {overviewContent} + + + + - + + + + + + + + + + + + + + // ... + ``` + + If you do not wish to customize your TechDocs reader experience in this way at this time, no changes are necessary! + +### Patch Changes + +- ab230a433f: imports from `@backstage/plugin-search-react` instead of `@backstage/plugin-search` +- 24254fd433: build(deps): bump `@testing-library/user-event` from 13.5.0 to 14.0.0 +- 230ad0826f: Bump to using `@types/node` v16 +- Updated dependencies + - @backstage/core-app-api@1.0.1-next.1 + - @backstage/core-components@0.9.3-next.2 + - @backstage/core-plugin-api@1.0.1-next.0 + - @backstage/integration-react@1.0.1-next.2 + - @backstage/plugin-catalog-react@1.0.1-next.3 + - @backstage/plugin-search-react@0.1.0-next.0 + - @backstage/integration@1.1.0-next.2 + - @backstage/plugin-techdocs-react@0.1.0-next.0 + +## 1.0.1-next.2 + +### Patch Changes + +- f0fb9153b7: Fix broken query selectors on techdocs +- 9975ff9852: Applied the fix from version 1.0.1 of this package, which is part of the v1.0.2 release of Backstage. +- Updated dependencies + - @backstage/core-components@0.9.3-next.1 + - @backstage/plugin-catalog-react@1.0.1-next.2 + - @backstage/catalog-model@1.0.1-next.1 + +## 1.0.1 + +### Patch Changes + +- Pin the `event-source-polyfill` dependency to version 1.0.25 + +## 1.0.1-next.1 + +### Patch Changes + +- 0152c0de22: Some documentation layout tweaks: + + - drawer toggle margins + - code block margins + - sidebar drawer width + - inner content width + - footer link width + - sidebar table of contents scroll + +- Updated dependencies + - @backstage/integration@1.1.0-next.1 + - @backstage/plugin-catalog-react@1.0.1-next.1 + - @backstage/integration-react@1.0.1-next.1 + +## 1.0.1-next.0 + +### Patch Changes + +- fe53fe97d7: Fix permalink scrolling for anchors where the id starts with a number. +- Updated dependencies + - @backstage/catalog-model@1.0.1-next.0 + - @backstage/plugin-search@0.7.5-next.0 + - @backstage/integration@1.0.1-next.0 + - @backstage/plugin-catalog-react@1.0.1-next.0 + - @backstage/core-components@0.9.3-next.0 + - @backstage/integration-react@1.0.1-next.0 + +## 1.0.0 + +### Major Changes + +- b58c70c223: This package has been promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy). + +### Minor Changes + +- 700d93ff41: Removed deprecated exports, including: + + - deprecated `DocsResultListItem` is now deleted and fully replaced with `TechDocsSearchResultListItem` + - deprecated `TechDocsPage` is now deleted and fully replaced with `TechDocsReaderPage` + - deprecated `TechDocsPageHeader` is now deleted and fully replaced with `TechDocsReaderPageHeader` + - deprecated `TechDocsPageHeaderProps` is now deleted and fully replaced with `TechDocsReaderPageHeaderProps` + - deprecated `TechDocsPageRenderFunction` is now deleted and fully replaced with `TechDocsReaderPageRenderFunction` + - deprecated config `techdocs.requestUrl` is now deleted and fully replaced with the discoveryApi + +### Patch Changes + +- a422d7ce5e: chore(deps): bump `@testing-library/react` from 11.2.6 to 12.1.3 +- c689d7a94c: Switched to using `CatalogFilterLayout` from `@backstage/plugin-catalog-react`. +- f24ef7864e: Minor typo fixes +- 06af9e8d17: Long sidebars will no longer overflow the footer and will properly show a scrollbar when needed. +- Updated dependencies + - @backstage/core-components@0.9.2 + - @backstage/core-plugin-api@1.0.0 + - @backstage/integration-react@1.0.0 + - @backstage/plugin-catalog-react@1.0.0 + - @backstage/plugin-search@0.7.4 + - @backstage/catalog-model@1.0.0 + - @backstage/integration@1.0.0 + - @backstage/config@1.0.0 + - @backstage/errors@1.0.0 + +## 0.15.1 + +### Patch Changes + +- 7a1dbe6ce9: The panels of `TechDocsCustomHome` now use the `useEntityOwnership` hook to resolve ownership when the `'ownedByUser'` filter predicate is used. +- Updated dependencies + - @backstage/plugin-catalog@0.10.0 + - @backstage/plugin-catalog-react@0.9.0 + - @backstage/core-components@0.9.1 + - @backstage/catalog-model@0.13.0 + - @backstage/plugin-search@0.7.3 + - @backstage/integration-react@0.1.25 + +## 0.15.1-next.0 + +### Patch Changes + +- 7a1dbe6ce9: The panels of `TechDocsCustomHome` now use the `useEntityOwnership` hook to resolve ownership when the `'ownedByUser'` filter predicate is used. +- Updated dependencies + - @backstage/plugin-catalog@0.10.0-next.0 + - @backstage/plugin-catalog-react@0.9.0-next.0 + - @backstage/core-components@0.9.1-next.0 + - @backstage/catalog-model@0.13.0-next.0 + - @backstage/plugin-search@0.7.3-next.0 + - @backstage/integration-react@0.1.25-next.0 + +## 0.15.0 + +### Minor Changes + +- ee3d6c6f10: **BREAKING:** + Table column utilities `createNameColumn`, `createOwnerColumn`, `createTypeColumn` as well as actions utilities `createCopyDocsUrlAction` and `createStarEntityAction` are no longer directly exported. Instead accessible through DocsTable and EntityListDocsTable. + + Use as following: + + ```tsx + DocsTable.columns.createNameColumn(); + DocsTable.columns.createOwnerColumn(); + DocsTable.columns.createTypeColumn(); + + DocsTable.actions.createCopyDocsUrlAction(); + DocsTable.actions.createStarEntityAction(); + ``` + + - Renamed `DocsResultListItem` to `TechDocsSearchResultListItem`, leaving the old name in place as a deprecations. + + - Renamed `TechDocsPage` to `TechDocsReaderPage`, leaving the old name in place as a deprecations. + + - Renamed `TechDocsPageRenderFunction` to `TechDocsPageRenderFunction`, leaving the old name in place as a deprecations. + + - Renamed `TechDocsPageHeader` to `TechDocsReaderPageHeader`, leaving the old name in place as a deprecations. + + - `LegacyTechDocsHome` marked as deprecated and will be deleted in next release, use `TechDocsCustomHome` instead. + + - `LegacyTechDocsPage` marked as deprecated and will be deleted in next release, use `TechDocsReaderPage` instead. + +### Patch Changes + +- 64b430f80d: chore(deps): bump `react-text-truncate` from 0.17.0 to 0.18.0 +- 899f196af5: Use `getEntityByRef` instead of `getEntityByName` in the catalog client +- f41a293231: - **DEPRECATION**: Deprecated `formatEntityRefTitle` in favor of the new `humanizeEntityRef` method instead. Please migrate to using the new method instead. +- c5fda066b1: Collapse techdocs sidebar on small devices +- f590d1681b: Removed usage of deprecated favorite utility methods. +- 5b0f9a75fa: Remove copyright from old footer in documentation generated with previous version of `mkdocs-techdocs-plugin` (`v0.2.2`). +- 0c3ba547a6: Show feedback when copying code snippet to clipboard. +- 0ca964ee0e: Fixed a bug that could cause searches in the in-context TechDocs search bar to show results from a different TechDocs site. +- 36aa63022b: Use `CompoundEntityRef` instead of `EntityName`, and `getCompoundEntityRef` instead of `getEntityName`, from `@backstage/catalog-model`. +- Updated dependencies + - @backstage/catalog-model@0.12.0 + - @backstage/core-components@0.9.0 + - @backstage/plugin-search@0.7.2 + - @backstage/plugin-catalog@0.9.1 + - @backstage/plugin-catalog-react@0.8.0 + - @backstage/integration@0.8.0 + - @backstage/core-plugin-api@0.8.0 + - @backstage/integration-react@0.1.24 + +## 0.14.0 + +### Minor Changes + +- 2262fe19c9: **BREAKING**: Removed support for passing in an explicit `entity` prop to entity page extensions, which has been deprecated for a long time. This is only a breaking change at the TypeScript level, as this property was already ignored. +- 4faae902eb: Adjust the Tech Docs page theme as a side effect of the `mkdocs-material` theme update. + + If you use the `spofify/techdocs` image to build your documentation, make sure you use version `spotify/techdocs:v0.3.7`. + + **Breaking**: The `PyMdown` extensions have also been updated and some syntax may have changed, so it is recommended that you check the extension's documentation if something stops working. + For example, the syntax of tags below was deprecated in `PyMdown` extensions `v.7.0` and in `v.8.0.0` it has been removed. This means that the old syntax specified below no longer works. + + ````markdown + ```markdown tab="tab" + This is some markdown + ``` + + ```markdown tab="tab 2" + This is some markdown in tab 2 + ``` + ```` + +### Patch Changes + +- 3bbb4d98c6: Changed to use from createApp +- ed09ad8093: Updated usage of the `LocationSpec` type from `@backstage/catalog-model`, which is deprecated. +- b776ce5aab: Replaced use of deprecated `useEntityListProvider` hook with `useEntityList`. +- d4f67fa728: Removed import of deprecated hook. +- 45e1706328: Continuation of [#9569](https://github.com/backstage/backstage/pull/9569), fix Tech Docs Reader search position to be the same width as content. +- 919cf2f836: Minor updates to match the new `targetRef` field of relations, and to stop consuming the `target` field +- Updated dependencies + - @backstage/plugin-catalog@0.9.0 + - @backstage/core-components@0.8.10 + - @backstage/plugin-catalog-react@0.7.0 + - @backstage/catalog-model@0.11.0 + - @backstage/core-plugin-api@0.7.0 + - @backstage/integration@0.7.5 + - @backstage/plugin-search@0.7.1 + - @backstage/integration-react@0.1.23 + +## 0.13.4 + +### Patch Changes + +- 1ed305728b: Bump `node-fetch` to version 2.6.7 and `cross-fetch` to version 3.1.5 +- c77c5c7eb6: Added `backstage.role` to `package.json` +- 6553985cd4: Match text size of admonitions to main content text size. +- 9df7b43e1a: Improve overall appearance of highlighted code in docs. +- Updated dependencies + - @backstage/core-components@0.8.9 + - @backstage/core-plugin-api@0.6.1 + - @backstage/errors@0.2.1 + - @backstage/integration@0.7.3 + - @backstage/integration-react@0.1.22 + - @backstage/plugin-catalog@0.8.0 + - @backstage/plugin-catalog-react@0.6.15 + - @backstage/plugin-search@0.7.0 + - @backstage/catalog-model@0.10.0 + - @backstage/config@0.1.14 + - @backstage/theme@0.2.15 + +## 0.13.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8 + - @backstage/plugin-search@0.6.2 + - @backstage/plugin-catalog-react@0.6.14 + - @backstage/plugin-catalog@0.7.12 + - @backstage/integration-react@0.1.21 + +## 0.13.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.8.8-next.0 + - @backstage/plugin-search@0.6.2-next.0 + - @backstage/plugin-catalog-react@0.6.14-next.0 + - @backstage/integration-react@0.1.21-next.0 + - @backstage/plugin-catalog@0.7.12-next.0 + +## 0.13.2 + +### Patch Changes + +- 742434a6ba: Fixed a bug where links to files within a TechDocs site that use the `download` attribute would result in a 404 in cases where the TechDocs backend and Backstage frontend application are on the same host. +- 359c31e31d: Added support for documentation using the raw `` tag to point to relative resources like audio or video files. +- 18317a08db: Fixed a bug where copy-to-clipboard buttons were appended to unintended elements. +- Updated dependencies + - @backstage/core-components@0.8.7 + - @backstage/plugin-catalog-react@0.6.13 + - @backstage/integration-react@0.1.20 + - @backstage/plugin-catalog@0.7.11 + - @backstage/plugin-search@0.6.1 + +## 0.13.2-next.1 + +### Patch Changes + +- 742434a6ba: Fixed a bug where links to files within a TechDocs site that use the `download` attribute would result in a 404 in cases where the TechDocs backend and Backstage frontend application are on the same host. +- Updated dependencies + - @backstage/core-components@0.8.7-next.1 + - @backstage/plugin-catalog-react@0.6.13-next.1 + - @backstage/plugin-catalog@0.7.11-next.1 + +## 0.13.2-next.0 + +### Patch Changes + +- 359c31e31d: Added support for documentation using the raw `` tag to point to relative resources like audio or video files. +- Updated dependencies + - @backstage/core-components@0.8.7-next.0 + - @backstage/integration-react@0.1.20-next.0 + - @backstage/plugin-catalog@0.7.11-next.0 + - @backstage/plugin-catalog-react@0.6.13-next.0 + - @backstage/plugin-search@0.6.1-next.0 + +## 0.13.1 + +### Patch Changes + +- bdc53553eb: chore(deps): bump `react-text-truncate` from 0.16.0 to 0.17.0 +- a64f99f734: Code snippets now include a "copy to clipboard" button. +- Updated dependencies + - @backstage/core-components@0.8.6 + - @backstage/plugin-search@0.6.0 + - @backstage/plugin-catalog@0.7.10 + +## 0.13.0 + +### Minor Changes + +- aecfe4f403: Make `TechDocsClient` and `TechDocsStorageClient` use the `FetchApi`. You now + need to pass in an instance of that API when constructing the client, if you + create a custom instance in your app. + + If you are replacing the factory: + + ```diff + +import { fetchApiRef } from '@backstage/core-plugin-api'; + + createApiFactory({ + api: techdocsStorageApiRef, + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + identityApi: identityApiRef, + + fetchApi: fetchApiRef, + }, + factory: ({ + configApi, + discoveryApi, + identityApi, + + fetchApi, + }) => + new TechDocsStorageClient({ + configApi, + discoveryApi, + identityApi, + + fetchApi, + }), + }), + createApiFactory({ + api: techdocsApiRef, + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + - identityApi: identityApiRef, + + fetchApi: fetchApiRef, + }, + factory: ({ + configApi, + discoveryApi, + - identityApi, + + fetchApi, + }) => + new TechDocsClient({ + configApi, + discoveryApi, + - identityApi, + + fetchApi, + }), + }), + ``` + + If instantiating directly: + + ```diff + +import { fetchApiRef } from '@backstage/core-plugin-api'; + + +const fetchApi = useApi(fetchApiRef); + const storageClient = new TechDocsStorageClient({ + configApi, + discoveryApi, + identityApi, + + fetchApi, + }); + const techdocsClient = new TechDocsClient({ + configApi, + discoveryApi, + - identityApi, + + fetchApi, + }), + ``` + +### Patch Changes + +- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. +- 29710c91c2: use lighter color for block quotes and horizontal rulers +- Updated dependencies + - @backstage/core-components@0.8.5 + - @backstage/integration@0.7.2 + - @backstage/plugin-search@0.5.6 + - @backstage/core-plugin-api@0.6.0 + - @backstage/plugin-catalog@0.7.9 + - @backstage/plugin-catalog-react@0.6.12 + - @backstage/config@0.1.13 + - @backstage/catalog-model@0.9.10 + - @backstage/integration-react@0.1.19 + +## 0.12.15-next.0 + +### Patch Changes + +- 51fbedc445: Migrated usage of deprecated `IdentityApi` methods. +- 29710c91c2: use lighter color for block quotes and horizontal rulers +- Updated dependencies + - @backstage/core-components@0.8.5-next.0 + - @backstage/core-plugin-api@0.6.0-next.0 + - @backstage/plugin-catalog@0.7.9-next.0 + - @backstage/config@0.1.13-next.0 + - @backstage/plugin-catalog-react@0.6.12-next.0 + - @backstage/plugin-search@0.5.6-next.0 + - @backstage/catalog-model@0.9.10-next.0 + - @backstage/integration-react@0.1.19-next.0 + - @backstage/integration@0.7.2-next.0 + +## 0.12.14 + +### Patch Changes + +- 5333451def: Cleaned up API exports +- 1628ca3f49: Fix an issue where the TechDocs sidebar is hidden when the Backstage sidebar is pinned at smaller screen sizes +- Updated dependencies + - @backstage/config@0.1.12 + - @backstage/integration@0.7.1 + - @backstage/core-components@0.8.4 + - @backstage/core-plugin-api@0.5.0 + - @backstage/plugin-catalog-react@0.6.11 + - @backstage/errors@0.2.0 + - @backstage/catalog-model@0.9.9 + - @backstage/integration-react@0.1.18 + - @backstage/plugin-catalog@0.7.8 + - @backstage/plugin-search@0.5.5 + +## 0.12.13 + +### Patch Changes + +- fe9de6c25b: Adds support for opening internal Techdocs links in a new tab with CTRL+Click or CMD+Click +- 4ce51ab0f1: Internal refactor of the `react-use` imports to use `react-use/lib/*` instead. +- e0271456d8: Updated Techdocs footer navigation to dynamically resize to the width of the dom, resolving an issue where a pinned sidebar causes navigation to go off of the screen +- Updated dependencies + - @backstage/plugin-search@0.5.4 + - @backstage/core-plugin-api@0.4.1 + - @backstage/plugin-catalog-react@0.6.10 + - @backstage/core-components@0.8.3 + - @backstage/plugin-catalog@0.7.7 + +## 0.12.12 + +### Patch Changes + +- aa8f764a3e: Add the techdocs.sanitizer.allowedIframeHosts config. + This config allows all iframes which have the host of the attribute src in the 'allowedIframehosts' list to be displayed in the documentation. +- Updated dependencies + - @backstage/plugin-search@0.5.3 + - @backstage/plugin-catalog@0.7.6 + - @backstage/plugin-catalog-react@0.6.9 + - @backstage/integration@0.7.0 + - @backstage/integration-react@0.1.17 + +## 0.12.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search@0.5.2 + - @backstage/core-plugin-api@0.4.0 + - @backstage/plugin-catalog-react@0.6.8 + - @backstage/core-components@0.8.2 + - @backstage/plugin-catalog@0.7.5 + - @backstage/integration-react@0.1.16 + +## 0.12.10 + +### Patch Changes + +- e7cce2b603: Fix issue where assets weren't being fetched from the correct URL path for doc URLs without trailing slashes +- Updated dependencies + - @backstage/core-plugin-api@0.3.1 + - @backstage/core-components@0.8.1 + - @backstage/catalog-model@0.9.8 + - @backstage/plugin-catalog-react@0.6.7 + +## 0.12.9 + +### Patch Changes + +- cd450844f6: Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used. +- d90dad84b0: Switch to using `LogViewer` component from `@backstage/core-components` to display build logs. +- 3421826ca8: The problem of lowercase entity triplets which causes docs to not load on entity page is fixed. +- Updated dependencies + - @backstage/core-components@0.8.0 + - @backstage/core-plugin-api@0.3.0 + - @backstage/plugin-catalog@0.7.4 + - @backstage/integration-react@0.1.15 + - @backstage/plugin-catalog-react@0.6.5 + - @backstage/plugin-search@0.5.1 + +## 0.12.8 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@0.6.10 + - @backstage/core-components@0.7.6 + - @backstage/theme@0.2.14 + - @backstage/core-plugin-api@0.2.2 + - @backstage/plugin-search@0.5.0 + +## 0.12.7 + +### Patch Changes + +- bab752e2b3: Change default port of backend from 7000 to 7007. + + This is due to the AirPlay Receiver process occupying port 7000 and preventing local Backstage instances on MacOS to start. + + You can change the port back to 7000 or any other value by providing an `app-config.yaml` with the following values: + + backend: + listen: 0.0.0.0:7123 + baseUrl: http://localhost:7123 + + More information can be found here: + +- Updated dependencies + - @backstage/errors@0.1.5 + - @backstage/core-plugin-api@0.2.1 + - @backstage/core-components@0.7.5 + +## 0.12.6 + +### Patch Changes + +- a125278b81: Refactor out the deprecated path and icon from RouteRefs +- c1858c4cf9: Fixed entity triplet case handling for certain locales. +- f7703981a9: Use a better checkbox rendering in a task list. +- e266687580: Updates reader component used to display techdocs documentation. A previous change made this component not usable out of a page which don't have entityRef in url parameters. Reader component EntityRef parameter is now used instead of url parameters. Techdocs documentation component can now be used in our custom pages. +- Updated dependencies + - @backstage/plugin-catalog@0.7.3 + - @backstage/catalog-model@0.9.7 + - @backstage/plugin-catalog-react@0.6.4 + - @backstage/plugin-search@0.4.18 + - @backstage/core-components@0.7.4 + - @backstage/core-plugin-api@0.2.0 + - @backstage/integration-react@0.1.14 + +## 0.12.5 + +### Patch Changes + +- fe5738fe1c: Lazy load `LazyLog` as it is rarely used. +- 53c9ad7e04: Update font weight for headings in TechDocs +- Updated dependencies + - @backstage/core-components@0.7.3 + - @backstage/theme@0.2.13 + - @backstage/plugin-search@0.4.17 + - @backstage/core-plugin-api@0.1.13 + - @backstage/plugin-catalog-react@0.6.3 + +## 0.12.4 + +### Patch Changes + +- a9a8c6f7c5: Reader will now scroll to the top of the page when navigating between pages +- 106a5dc3ad: Restore original casing for `kind`, `namespace` and `name` in `DefaultTechDocsCollator`. +- Updated dependencies + - @backstage/config@0.1.11 + - @backstage/theme@0.2.12 + - @backstage/errors@0.1.4 + - @backstage/integration@0.6.9 + - @backstage/core-components@0.7.2 + - @backstage/integration-react@0.1.13 + - @backstage/plugin-catalog-react@0.6.2 + - @backstage/catalog-model@0.9.6 + - @backstage/plugin-search@0.4.16 + - @backstage/core-plugin-api@0.1.12 + +## 0.12.3 + +### Patch Changes + +- ba5b75ed2f: Add `` as an alternative to `` that + shows a grid of card instead of table. + + Extend `` to display the entity title of the entity instead of the + name if available. + +- 177401b571: Display entity title (if defined) in titles of TechDocs search results + +- cdf8ca6111: Only replace the shadow dom if the content is changed to avoid a flickering UI. + +- Updated dependencies + - @backstage/core-components@0.7.1 + - @backstage/errors@0.1.3 + - @backstage/core-plugin-api@0.1.11 + - @backstage/plugin-catalog@0.7.2 + - @backstage/plugin-catalog-react@0.6.1 + - @backstage/catalog-model@0.9.5 + +## 0.12.2 + +### Patch Changes + +- 76fef740fe: Refactored `` component internals to support future extensibility. +- Updated dependencies + - @backstage/plugin-catalog-react@0.6.0 + - @backstage/plugin-catalog@0.7.1 + - @backstage/integration@0.6.8 + - @backstage/core-components@0.7.0 + - @backstage/theme@0.2.11 + - @backstage/plugin-search@0.4.15 + - @backstage/integration-react@0.1.12 + +## 0.12.1 + +### Patch Changes + +- 81a41ec249: Added a `name` key to all extensions in order to improve Analytics API metadata. +- Updated dependencies + - @backstage/core-components@0.6.1 + - @backstage/core-plugin-api@0.1.10 + - @backstage/plugin-catalog@0.7.0 + - @backstage/plugin-catalog-react@0.5.2 + - @backstage/catalog-model@0.9.4 + - @backstage/integration@0.6.7 + - @backstage/plugin-search@0.4.14 + +## 0.12.0 + +### Minor Changes + +- 82bb0842a3: Adds support for being able to customize and compose your TechDocs reader page in the App. + + You can likely upgrade to this version without issue. If, however, you have + imported the `` component in your custom code, the name of a property + has changed. You will need to make the following change anywhere you use it: + + ```diff + - + + + ``` + +### Patch Changes + +- 79ebee7a6b: Add "data-testid" for e2e tests and fix techdocs entity not found error. +- 3df2e8532b: Fixed the URL for the "Click to copy documentation link to clipboard" action +- 0a8bec0877: Added a check for the TechDocs annotation on the entity +- Updated dependencies + - @backstage/integration@0.6.6 + - @backstage/core-plugin-api@0.1.9 + - @backstage/core-components@0.6.0 + - @backstage/integration-react@0.1.11 + - @backstage/plugin-catalog@0.6.17 + - @backstage/plugin-catalog-react@0.5.1 + - @backstage/plugin-search@0.4.13 + +## 0.11.3 + +### Patch Changes + +- be13dfe61a: Make techdocs context search bar width adjust on smaller screens. +- Updated dependencies + - @backstage/core-components@0.5.0 + - @backstage/integration@0.6.5 + - @backstage/plugin-catalog@0.6.16 + - @backstage/plugin-catalog-react@0.5.0 + - @backstage/catalog-model@0.9.3 + - @backstage/config@0.1.10 + - @backstage/integration-react@0.1.10 + - @backstage/plugin-search@0.4.12 + +## 0.11.2 + +### Patch Changes + +- 1d346ba903: Modify TechDocsCollator to be aware of new TechDocs URL pattern. Modify tech docs in context search to use correct casing when creating initial filter. +- 9f1362dcc1: Upgrade `@material-ui/lab` to `4.0.0-alpha.57`. +- 96fef17a18: Upgrade git-parse-url to v11.6.0 +- Updated dependencies + - @backstage/core-components@0.4.2 + - @backstage/integration@0.6.4 + - @backstage/integration-react@0.1.9 + - @backstage/plugin-catalog@0.6.15 + - @backstage/plugin-catalog-react@0.4.6 + - @backstage/plugin-search@0.4.11 + - @backstage/core-plugin-api@0.1.8 + +## 0.11.1 + +### Patch Changes + +- 30ed662a3: Adding in-context search to TechDocs Reader component. Using existing search-backend to query for indexed search results scoped into a specific entity's techdocs. Needs TechDocsCollator enabled on the backend to work. + + Adding extra information to indexed tech docs documents for search. + +- 434dfc5d4: Display [metadata.title](https://backstage.io/docs/features/software-catalog/descriptor-format#title-optional) for components on the TechDocs homepage, if defined; otherwise fall back to `metadata.name` as displayed before. + +- Updated dependencies + - @backstage/plugin-catalog-react@0.4.5 + - @backstage/integration@0.6.3 + - @backstage/core-components@0.4.0 + - @backstage/plugin-catalog@0.6.14 + - @backstage/plugin-search@0.4.9 + - @backstage/catalog-model@0.9.1 + - @backstage/integration-react@0.1.8 + +## 0.11.0 + +### Minor Changes + +- c772d9a84: TechDocs sites can now be accessed using paths containing entity triplets of + any case (e.g. `/docs/namespace/KIND/name` or `/docs/namespace/kind/name`). + + If you do not use an external storage provider for serving TechDocs, this is a + transparent change and no action is required from you. + + If you _do_ use an external storage provider for serving TechDocs (one of\* GCS, + AWS S3, or Azure Blob Storage), you must run a migration command against your + storage provider before updating. + + [A migration guide is available here](https://backstage.io/docs/features/techdocs/how-to-guides#how-to-migrate-from-techdocs-alpha-to-beta). + + - (\*) We're seeking help from the community to bring OpenStack Swift support + [to feature parity](https://github.com/backstage/backstage/issues/6763) with the above. + +- 787bc0826: The TechDocs plugin has completed the migration to the Composability API. In + order to update to this version, please ensure you've made all necessary + changes to your `App.tsx` file as outlined in the [create-app changelog][cacl]. + + [cacl]: https://github.com/backstage/backstage/blob/master/packages/create-app/CHANGELOG.md + +### Patch Changes + +- 90c68a2ca: Fix Techdocs feedback icon link for GitHub URLs +- Updated dependencies + - @backstage/plugin-catalog@0.6.13 + - @backstage/plugin-catalog-react@0.4.4 + - @backstage/core-components@0.3.3 + - @backstage/integration@0.6.2 + - @backstage/config@0.1.8 + +## 0.10.4 + +### Patch Changes + +- a440d3b38: Expose a new composable `TechDocsIndexPage` and a `DefaultTechDocsHome` with support for starring docs and filtering on owned, starred, owner, and tags. + + You can migrate to the new UI view by making the following changes in your `App.tsx`: + + ```diff + - } /> + + }> + + + + + + } + + /> + ``` + +- 56c773909: Switched `@types/react` dependency to request `*` rather than a specific version. + +- 8a3e46591: Switch `EventSource` implementation with header support from a Node.js API-based one to an XHR-based one. + +- Updated dependencies + - @backstage/integration@0.6.0 + - @backstage/core-components@0.3.1 + - @backstage/core-plugin-api@0.1.6 + - @backstage/plugin-catalog@0.6.11 + - @backstage/plugin-catalog-react@0.4.2 + - @backstage/integration-react@0.1.7 + +## 0.10.3 + +### Patch Changes + +- 260c053b9: Fix All Material UI Warnings +- db58cf06c: Avoid sanitize safe links in the header of document pages. +- 1d65bd490: Fix Techdocs feedback icon link for GitLab URLs with subgroup(s) in path +- Updated dependencies + - @backstage/core-components@0.3.0 + - @backstage/config@0.1.6 + - @backstage/core-plugin-api@0.1.5 + - @backstage/integration@0.5.9 + - @backstage/integration-react@0.1.6 + - @backstage/plugin-catalog-react@0.4.1 + +## 0.10.2 + +### Patch Changes + +- 9d40fcb1e: - Bumping `material-ui/core` version to at least `4.12.2` as they made some breaking changes in later versions which broke `Pagination` of the `Table`. + - Switching out `material-table` to `@material-table/core` for support for the later versions of `material-ui/core` + - This causes a minor API change to `@backstage/core-components` as the interface for `Table` re-exports the `prop` from the underlying `Table` components. + - `onChangeRowsPerPage` has been renamed to `onRowsPerPageChange` + - `onChangePage` has been renamed to `onPageChange` + - Migration guide is here: +- 11c370af2: Optimize load times by only fetching entities with the `backstage.io/techdocs-ref` annotation +- 2b1ac002d: TechDocs now uses a "safe by default" sanitization library, rather than relying on its own, hard-coded list of allowable tags and attributes. +- Updated dependencies + - @backstage/core-components@0.2.0 + - @backstage/plugin-catalog-react@0.4.0 + - @backstage/core-plugin-api@0.1.4 + - @backstage/integration-react@0.1.5 + - @backstage/theme@0.2.9 + +## 0.10.1 + +### Patch Changes + +- 9266b80ab: Add search list item to display tech docs search results + +- 03bf17e9b: Improve the responsiveness of the EntityPage UI. With this the Header component should scale with the screen size & wrapping should not cause overflowing/blocking of links. Additionally enforce the Pages using the Grid Layout to use it across all screen sizes & to wrap as intended. + + To benefit from the improved responsive layout, the `EntityPage` in existing Backstage applications should be updated to set the `xs` column size on each grid item in the page, as this does not default. For example: + + ```diff + - + + + ``` + +- 378cc6a54: Only update the `path` when the content is updated. + If content and path are updated independently, the frontend rendering is triggered twice on each navigation: Once for the `path` change (with the old content) and once for the new content. + This might result in a flickering rendering that is caused by the async frontend preprocessing, and the fact that replacing the shadow dom content is expensive. + +- 214e7c52d: Refactor the techdocs transformers to return `Promise`s and await all transformations. + +- e35b13afa: Handle error responses in `getTechDocsMetadata` and `getEntityMetadata` such that `` doesn't throw errors. + +- Updated dependencies + - @backstage/core-components@0.1.6 + - @backstage/plugin-catalog-react@0.3.1 + +## 0.10.0 + +### Minor Changes + +- 94a54dd47: Added a `migrateDocsCase()` method to TechDocs publishers, along with + implementations for AWS, Azure, and GCS. + + This change is in support of a future update to TechDocs that will allow for + case-insensitive entity triplet URL access to documentation pages which will + require a migration of existing documentation objects in external storage + solutions. + + See [#4367](https://github.com/backstage/backstage/issues/4367) for details. + +### Patch Changes + +- 537c37b0f: Fix displaying owned documents list by fetching associated entity relations +- 136a91974: Show a "Refresh" button to if the content is stale. + This removes the need to do a full page-reload to display more recent TechDocs content. +- f1200f44c: Rewrite the `/sync/:namespace/:kind/:name` endpoint to support an event-stream as response. + This change allows the sync process to take longer than a normal HTTP timeout. + The stream also emits log events, so the caller can follow the build process in the frontend. +- 3af126cdd: Provide a Drawer component to follow a running build. + This can be used to debug the rendering and get build logs in case an error occurs. +- 2a4a3b32d: Techdocs: fix sidebars not adjusting position automatically +- Updated dependencies + - @backstage/plugin-catalog-react@0.3.0 + +## 0.9.9 + +### Patch Changes + +- 0172d3424: Fixed bug preventing scroll bar from showing up on code blocks in a TechDocs site. +- Updated dependencies + - @backstage/integration@0.5.8 + - @backstage/core-components@0.1.5 + - @backstage/catalog-model@0.9.0 + - @backstage/plugin-catalog-react@0.2.6 + +## 0.9.8 + +### Patch Changes + +- 99a2873c7: Include cookies when making fetch requests for SVG from techdocs plugin +- a444c7431: Filter fetched entity fields to optimize loading techdocs list +- Updated dependencies + - @backstage/plugin-catalog-react@0.2.5 + - @backstage/core-components@0.1.4 + - @backstage/integration@0.5.7 + +## 0.9.7 + +### Patch Changes + +- aefd54da6: Fix the overlapping between the sidebar and the tabs navigation when enabled in mkdocs (features: navigation.tabs) +- 48c9fcd33: Migrated to use the new `@backstage/core-*` packages rather than `@backstage/core`. +- 1dfec7a2a: Refactor the implicit logic from `` into an explicit state machine. This resolves some state synchronization issues when content is refreshed or rebuilt in the backend. +- Updated dependencies + - @backstage/core-plugin-api@0.1.3 + - @backstage/catalog-model@0.8.4 + - @backstage/integration-react@0.1.4 + - @backstage/plugin-catalog-react@0.2.4 + +## 0.9.6 + +### Patch Changes + +- 938aee2fb: Fix the link to the documentation page when no owned documents are displayed +- 2e1fbe203: Do not add trailing slash for .html pages during doc links rewriting +- 9b57fda8b: Fixes a bug that could prevent some externally hosted images (like icons or + build badges) from rendering within TechDocs documentation. +- 667656c8b: Adding support for user owned document filter for TechDocs custom Homepage +- Updated dependencies + - @backstage/plugin-catalog-react@0.2.3 + - @backstage/catalog-model@0.8.3 + - @backstage/core@0.7.13 + +## 0.9.5 + +### Patch Changes + +- aad98c544: Fixes multiple XSS and sanitization bypass vulnerabilities in TechDocs. +- Updated dependencies [e7c5e4b30] +- Updated dependencies [ebe802bc4] +- Updated dependencies [49d7ec169] +- Updated dependencies [1cf1d351f] +- Updated dependencies [deaba2e13] +- Updated dependencies [8e919a6f8] + - @backstage/theme@0.2.8 + - @backstage/catalog-model@0.8.1 + - @backstage/integration@0.5.5 + - @backstage/core@0.7.12 + - @backstage/plugin-catalog-react@0.2.1 + +## 0.9.4 + +### Patch Changes + +- 4ea9df9d3: Set admonition font size to 1rem in TechDocs to align with the rest of the document's font sizes. + Fixes #5448 and #5541. +- bf805b467: Fixes #5529, a bug that prevented TechDocs from rendering pages containing malformed links. +- 203ce6f6f: TechDocs now respects the `download` attribute on anchor tags in generated + markup, allowing documentation authors to bundle downloadable files with their + documentation. +- Updated dependencies [0fd4ea443] +- Updated dependencies [add62a455] +- Updated dependencies [cc592248b] +- Updated dependencies [17c497b81] +- Updated dependencies [704875e26] + - @backstage/integration@0.5.4 + - @backstage/catalog-model@0.8.0 + - @backstage/core@0.7.11 + - @backstage/plugin-catalog-react@0.2.0 + +## 0.9.3 + +### Patch Changes + +- 65e6c4541: Remove circular dependencies +- a62cfe068: Bug fix on sidebar position when Tab-Bar is enabled +- 35e091604: Handle URLs with a `#hash` correctly when rewriting link URLs. +- Updated dependencies [f7f7783a3] +- Updated dependencies [65e6c4541] +- Updated dependencies [68fdbf014] +- Updated dependencies [5da6a561d] + - @backstage/catalog-model@0.7.10 + - @backstage/core@0.7.10 + - @backstage/integration@0.5.3 + +## 0.9.2 + +### Patch Changes + +- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8 +- 675a569a9: chore: bump `react-use` dependency in all packages +- Updated dependencies [062bbf90f] +- Updated dependencies [10c008a3a] +- Updated dependencies [889d89b6e] +- Updated dependencies [16be1d093] +- Updated dependencies [3f988cb63] +- Updated dependencies [675a569a9] + - @backstage/core@0.7.9 + - @backstage/integration-react@0.1.2 + - @backstage/plugin-catalog-react@0.1.6 + - @backstage/catalog-model@0.7.9 + +## 0.9.1 + +### Patch Changes + +- 2e05277e0: Fix navigation in a page using the table of contents. +- 4075c6367: Make git config optional for techdocs feedback links +- Updated dependencies [38ca05168] +- Updated dependencies [f65adcde7] +- Updated dependencies [81c54d1f2] +- Updated dependencies [80888659b] +- Updated dependencies [7b8272fb7] +- Updated dependencies [d8b81fd28] + - @backstage/integration@0.5.2 + - @backstage/core@0.7.8 + - @backstage/plugin-catalog-react@0.1.5 + - @backstage/theme@0.2.7 + - @backstage/catalog-model@0.7.8 + - @backstage/config@0.1.5 + +## 0.9.0 + +### Minor Changes + +- 21fddf452: Make `techdocsStorageApiRef` and `techdocsApiRef` use interfaces instead of the + actual implementation classes. + + This renames the classes `TechDocsApi` to `TechDocsClient` and `TechDocsStorageApi` + to `TechDocsStorageClient` and renames the interfaces `TechDocs` to `TechDocsApi` + and `TechDocsStorage` to `TechDocsStorageApi` to comply the pattern elsewhere in + the project. This also fixes the types returned by some methods on those + interfaces. + +### Patch Changes + +- 6fbd7beca: Use `EntityRefLink` in header and use relations to reference the owner of the + document. +- 15cbe6815: Fix TechDocs landing page table wrong copied link +- 39bdaa004: Add customization and exportable components for TechDocs landing page +- cb8c848a3: Disable color transitions on links to avoid issues in dark mode. +- 17915e29b: Rework state management to avoid rendering multiple while navigating between pages. +- Updated dependencies [9afcac5af] +- Updated dependencies [e0c9ed759] +- Updated dependencies [6eaecbd81] + - @backstage/core@0.7.7 + +## 0.8.0 + +### Minor Changes + +- ac6025f63: Add feedback link icon in Techdocs Reader that directs to GitLab or GitHub repo issue page with pre-filled title and source link. + For link to appear, requires `repo_url` and `edit_uri` to be filled in mkdocs.yml, as per . An `edit_uri` will need to be specified for self-hosted GitLab/GitHub instances with a different host name. + To identify issue URL format as GitHub or GitLab, the host name of source in `repo_url` is checked if it contains `gitlab` or `github`. Alternately this is determined by matching to `host` values from `integrations` in app-config.yaml. + +### Patch Changes + +- e292e393f: Add a test id to the shadow root element of the Reader to access it easily in e2e tests +- Updated dependencies [94da20976] +- Updated dependencies [d8cc7e67a] +- Updated dependencies [99fbef232] +- Updated dependencies [ab07d77f6] +- Updated dependencies [931b21a12] +- Updated dependencies [937ed39ce] +- Updated dependencies [9a9e7a42f] +- Updated dependencies [50ce875a0] + - @backstage/core@0.7.6 + - @backstage/theme@0.2.6 + +## 0.7.2 + +### Patch Changes + +- fef852ecd: Reworked the TechDocs plugin to support using the configured company name instead of + 'Backstage' in the page title. +- 18f7345a6: Add borders to TechDocs tables and increase font size. Fixes #5264 and #5276. +- Updated dependencies [bb5055aee] +- Updated dependencies [d0d1c2f7b] +- Updated dependencies [5d0740563] +- Updated dependencies [5cafcf452] +- Updated dependencies [86a95ba67] +- Updated dependencies [e27cb6c45] + - @backstage/catalog-model@0.7.7 + - @backstage/core@0.7.5 + +## 0.7.1 + +### Patch Changes + +- bebd1c4fe: Remove the `@backstage/techdocs-common` dependency to not pull in backend config schemas in the frontend. +- Updated dependencies [9f48b548c] +- Updated dependencies [8488a1a96] + - @backstage/plugin-catalog-react@0.1.4 + - @backstage/catalog-model@0.7.5 + +## 0.7.0 + +### Minor Changes + +- aaeb7ecf3: When newer documentation available but not built, show older documentation while async building newer + TechDocs backend: /sync endpoint added to support above, returns immediate success if docs don't need a build, returns delayed success after build if needed + TechDocs backend: /docs endpoint removed as frontend can directly request to techdocs.storageUrl or /static/docs +- 3139f83af: Add sticky sidebars and footer navigation links to TechDocs Reader + +### Patch Changes + +- ea9d977e7: Introduce workaround for admonition icons of MkDocs. +- 2aab54319: TechDocs: links at sidebar and bottom reset scroll position to top +- Updated dependencies [01ccef4c7] +- Updated dependencies [fcc3ada24] +- Updated dependencies [4618774ff] +- Updated dependencies [df59930b3] + - @backstage/plugin-catalog-react@0.1.3 + - @backstage/core@0.7.3 + - @backstage/theme@0.2.5 + +## 0.6.2 + +### Patch Changes + +- 83bfc98a3: On TechDocs page header, change the breadcrumbs link to be static and point to TechDocs homepage. +- e7baa0d2e: Separate techdocs-backend and frontend config schema declarations +- c8b54c370: Extended TechDocs HomePage with owned documents +- Updated dependencies [0434853a5] +- Updated dependencies [8686eb38c] +- Updated dependencies [9ca0e4009] +- Updated dependencies [34ff49b0f] +- Updated dependencies [8686eb38c] +- Updated dependencies [424742dc1] +- Updated dependencies [4e0b5055a] + - @backstage/config@0.1.4 + - @backstage/core@0.7.2 + - @backstage/plugin-catalog-react@0.1.2 + - @backstage/techdocs-common@0.4.5 + - @backstage/test-utils@0.1.9 + +## 0.6.1 + +### Patch Changes + +- aa095e469: OpenStack Swift publisher added for tech-docs. +- 2089de76b: Make use of the new core `ItemCardGrid` and `ItemCardHeader` instead of the deprecated `ItemCard`. +- 868e4cdf2: - Adds a link to the owner entity + - Corrects the link to the component which includes the namespace +- ca4a904f6: Add an optional configuration option for setting the url endpoint for AWS S3 publisher: `techdocs.publisher.awsS3.endpoint` +- Updated dependencies [d7245b733] +- Updated dependencies [0b42fff22] +- Updated dependencies [0b42fff22] +- Updated dependencies [2ef5bc7ea] +- Updated dependencies [ff4d666ab] +- Updated dependencies [aa095e469] +- Updated dependencies [2089de76b] +- Updated dependencies [dc1fc92c8] +- Updated dependencies [bc46435f5] +- Updated dependencies [a501128db] +- Updated dependencies [ca4a904f6] + - @backstage/techdocs-common@0.4.4 + - @backstage/catalog-model@0.7.4 + - @backstage/core@0.7.1 + - @backstage/theme@0.2.4 + +## 0.6.0 + +### Minor Changes + +- 813c6a4f2: Add authorization header on techdocs api requests. Breaking change as clients now needs the Identity API. + +### Patch Changes + +- Updated dependencies [12d8f27a6] +- Updated dependencies [f43192207] +- Updated dependencies [40c0fdbaa] +- Updated dependencies [2a271d89e] +- Updated dependencies [bece09057] +- Updated dependencies [169f48deb] +- Updated dependencies [8a1566719] +- Updated dependencies [9d455f69a] +- Updated dependencies [4c049a1a1] +- Updated dependencies [02816ecd7] +- Updated dependencies [61299519f] + - @backstage/catalog-model@0.7.3 + - @backstage/techdocs-common@0.4.3 + - @backstage/core@0.7.0 + - @backstage/plugin-catalog-react@0.1.1 + +## 0.5.8 + +### Patch Changes + +- f37992797: Got rid of some `attr` and cleaned up a bit in the TechDocs config schema. +- 2499f6cde: Add support for assuming role in AWS integrations +- Updated dependencies [3a58084b6] +- Updated dependencies [e799e74d4] +- Updated dependencies [dc12852c9] +- Updated dependencies [d0760ecdf] +- Updated dependencies [1407b34c6] +- Updated dependencies [88f1f1b60] +- Updated dependencies [bad21a085] +- Updated dependencies [9615e68fb] +- Updated dependencies [49f9b7346] +- Updated dependencies [5c2e2863f] +- Updated dependencies [3a58084b6] +- Updated dependencies [2499f6cde] +- Updated dependencies [a1f5e6545] +- Updated dependencies [1e4ddd71d] +- Updated dependencies [2c1f2a7c2] + - @backstage/core@0.6.3 + - @backstage/test-utils@0.1.8 + - @backstage/plugin-catalog-react@0.1.0 + - @backstage/catalog-model@0.7.2 + - @backstage/techdocs-common@0.4.2 + - @backstage/config@0.1.3 + +## 0.5.7 + +### Patch Changes + +- Updated dependencies [fd3f2a8c0] +- Updated dependencies [fb28da212] +- Updated dependencies [d34d26125] +- Updated dependencies [0af242b6d] +- Updated dependencies [f4c2bcf54] +- Updated dependencies [10a0124e0] +- Updated dependencies [07e226872] +- Updated dependencies [26e143e60] +- Updated dependencies [c6655413d] +- Updated dependencies [44414239f] +- Updated dependencies [b0a41c707] +- Updated dependencies [f62e7abe5] +- Updated dependencies [96f378d10] +- Updated dependencies [688b73110] + - @backstage/core@0.6.2 + - @backstage/techdocs-common@0.4.1 + - @backstage/plugin-catalog-react@0.0.4 + +## 0.5.6 + +### Patch Changes + +- f5e564cd6: Improve display of error messages +- 41af18227: Migrated to new composability API, exporting the plugin instance as `techdocsPlugin`, the top-level page as `TechdocsPage`, and the entity content as `EntityTechdocsContent`. +- 8f3443427: Enhance API calls to support trapping 500 errors from techdocs-backend +- Updated dependencies [77ad0003a] +- Updated dependencies [b51ee6ece] +- Updated dependencies [19d354c78] +- Updated dependencies [08142b256] +- Updated dependencies [08142b256] +- Updated dependencies [b51ee6ece] + - @backstage/techdocs-common@0.4.0 + - @backstage/test-utils@0.1.7 + - @backstage/plugin-catalog-react@0.0.3 + - @backstage/core@0.6.1 + +## 0.5.5 + +### Patch Changes + +- 5fa3bdb55: Add `href` in addition to `onClick` to `ItemCard`. Ensure that the height of a + `ItemCard` with and without tags is equal. +- e44925723: `techdocs.requestUrl` and `techdocs.storageUrl` are now optional configs and the discovery API will be used to get the URL where techdocs plugin is hosted. +- 019fe39a0: Switch dependency from `@backstage/plugin-catalog` to `@backstage/plugin-catalog-react`. +- Updated dependencies [c777df180] +- Updated dependencies [12ece98cd] +- Updated dependencies [d82246867] +- Updated dependencies [7fc89bae2] +- Updated dependencies [c810082ae] +- Updated dependencies [5fa3bdb55] +- Updated dependencies [6e612ce25] +- Updated dependencies [e44925723] +- Updated dependencies [025e122c3] +- Updated dependencies [21e624ba9] +- Updated dependencies [da9f53c60] +- Updated dependencies [32c95605f] +- Updated dependencies [7881f2117] +- Updated dependencies [f0320190d] +- Updated dependencies [54c7d02f7] +- Updated dependencies [11cb5ef94] + - @backstage/techdocs-common@0.3.7 + - @backstage/core@0.6.0 + - @backstage/plugin-catalog-react@0.0.2 + - @backstage/theme@0.2.3 + - @backstage/catalog-model@0.7.1 + +## 0.5.4 + +### Patch Changes + +- a5e27d5c1: Create type for TechDocsMetadata (#3716) + + This change introduces a new type (TechDocsMetadata) in packages/techdocs-common. This type is then introduced in the endpoint response in techdocs-backend and in the api interface in techdocs (frontend). + +- Updated dependencies [def2307f3] + +- Updated dependencies [efd6ef753] + +- Updated dependencies [593632f07] + +- Updated dependencies [33846acfc] + +- Updated dependencies [a187b8ad0] + +- Updated dependencies [f04db53d7] + +- Updated dependencies [53c9c51f2] + +- Updated dependencies [a5e27d5c1] + +- Updated dependencies [a93f42213] + - @backstage/catalog-model@0.7.0 + - @backstage/core@0.5.0 + - @backstage/plugin-catalog@0.2.12 + - @backstage/techdocs-common@0.3.5 + +## 0.5.3 + +### Patch Changes + +- dbe4450c3: Google Cloud authentication in TechDocs has been improved. + + 1. `techdocs.publisher.googleGcs.credentials` is now optional. If it is missing, `GOOGLE_APPLICATION_CREDENTIALS` + environment variable (and some other methods) will be used to authenticate. + Read more here + + 2. `techdocs.publisher.googleGcs.projectId` is no longer used. You can remove it from your `app-config.yaml`. + +- a6f9dca0d: Remove dependency on `@backstage/core-api`. No plugin should ever depend on that package; it's an internal concern whose important bits are re-exported by `@backstage/core` which is the public facing dependency to use. + +- b3b9445df: AWS S3 authentication in TechDocs has been improved. + + 1. `techdocs.publisher.awsS3.bucketName` is now the only required config. `techdocs.publisher.awsS3.credentials` and `techdocs.publisher.awsS3.region` are optional. + + 2. If `techdocs.publisher.awsS3.credentials` and `techdocs.publisher.awsS3.region` are missing, the AWS environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_REGION` will be used. There are more better ways of setting up AWS authentication. Read the guide at + +- e5d12f705: Use `history.pushState` for hash link navigation. + +- Updated dependencies [68ad5af51] + +- Updated dependencies [f3b064e1c] + +- Updated dependencies [371f67ecd] + +- Updated dependencies [f1e74777a] + +- Updated dependencies [dbe4450c3] + +- Updated dependencies [c00488983] + +- Updated dependencies [265a7ab30] + +- Updated dependencies [5826d0973] + +- Updated dependencies [b3b9445df] + +- Updated dependencies [abbee6fff] + +- Updated dependencies [147fadcb9] + - @backstage/techdocs-common@0.3.3 + - @backstage/catalog-model@0.6.1 + - @backstage/plugin-catalog@0.2.11 + - @backstage/core@0.4.4 + +## 0.5.2 + +### Patch Changes + +- 359f9d2d8: Added configuration schema for the commonly used properties of techdocs and techdocs-backend plugins +- Updated dependencies [a08c32ced] +- Updated dependencies [7e0b8cac5] +- Updated dependencies [8804e8981] +- Updated dependencies [87c0c53c2] +- Updated dependencies [86c3c652a] +- Updated dependencies [27f2af935] + - @backstage/core-api@0.2.8 + - @backstage/core@0.4.3 + - @backstage/plugin-catalog@0.2.9 + - @backstage/techdocs-common@0.3.1 + +## 0.5.1 + +### Patch Changes + +- Updated dependencies [d681db2b5] +- Updated dependencies [1dc445e89] +- Updated dependencies [342270e4d] +- Updated dependencies [1dc445e89] +- Updated dependencies [a8573e53b] + - @backstage/core-api@0.2.7 + - @backstage/core@0.4.2 + - @backstage/test-utils@0.1.6 + - @backstage/plugin-catalog@0.2.8 + - @backstage/techdocs-common@0.3.0 + +## 0.5.0 + +### Minor Changes + +- dae4f3983: _Breaking changes_ + + 1. Added option to use Google Cloud Storage as a choice to store the static generated files for TechDocs. + It can be configured using `techdocs.publisher.type` option in `app-config.yaml`. + Step-by-step guide to configure GCS is available here + Set `techdocs.publisher.type` to `'local'` if you want to continue using local filesystem to store TechDocs files. + + 2. `techdocs.builder` is now required and can be set to `'local'` or `'external'`. (Set it to `'local'` for now, since CI/CD build + workflow for TechDocs will be available soon (in few weeks)). + If builder is set to 'local' and you open a TechDocs page, `techdocs-backend` will try to generate the docs, publish to storage and + show the generated docs afterwords. + If builder is set to `'external'`, `techdocs-backend` will only fetch the docs and will NOT try to generate and publish. In this case of `'external'`, + we assume that docs are being built in the CI/CD pipeline of the repository. + TechDocs will not assume a default value for `techdocs.builder`. It is better to explicitly define it in the `app-config.yaml`. + + 3. When configuring TechDocs in your backend, there is a difference in how a new publisher is created. + + --- const publisher = new LocalPublish(logger, discovery); + +++ const publisher = Publisher.fromConfig(config, logger, discovery); + + Based on the config `techdocs.publisher.type`, the publisher could be either Local publisher or Google Cloud Storage publisher. + + 4. `techdocs.storageUrl` is now a required config. Should be `http://localhost:7000/api/techdocs/static/docs` in most setups. + + 5. Parts of `@backstage/plugin-techdocs-backend` have been moved to a new package `@backstage/techdocs-common` to generate docs. Also to publish docs + to-and-fro between TechDocs and a storage (either local or external). However, a Backstage app does NOT need to import the `techdocs-common` package - + app should only import `@backstage/plugin-techdocs` and `@backstage/plugin-techdocs-backend`. + + _Patch changes_ + + 1. See all of TechDocs config options and its documentation + + 2. Logic about serving static files and metadata retrieval have been abstracted away from the router in `techdocs-backend` to the instance of publisher. + + 3. Removed Material UI Spinner from TechDocs header. Spinners cause unnecessary UX distraction. + Case 1 (when docs are built and are to be served): Spinners appear for a split second before the name of site shows up. This unnecessarily distracts eyes because spinners increase the size of the Header. A dot (.) would do fine. Definitely more can be done. + Case 2 (when docs are being generated): There is already a linear progress bar (which is recommended in Storybook). + +### Patch Changes + +- Updated dependencies [c911061b7] +- Updated dependencies [dae4f3983] +- Updated dependencies [8ef71ed32] +- Updated dependencies [0e6298f7e] +- Updated dependencies [7dd2ef7d1] +- Updated dependencies [ac3560b42] + - @backstage/catalog-model@0.6.0 + - @backstage/techdocs-common@0.2.0 + - @backstage/core@0.4.1 + - @backstage/core-api@0.2.6 + - @backstage/plugin-catalog@0.2.7 + +## 0.4.0 + +### Minor Changes + +- 87a33d2fe: Removed modifyCss transformer and moved the css to injectCss transformer + Fixed issue where some internal doc links would cause a reload of the page + +### Patch Changes + +- Updated dependencies [b6557c098] +- Updated dependencies [2527628e1] +- Updated dependencies [6011b7d3e] +- Updated dependencies [e1f4e24ef] +- Updated dependencies [1c69d4716] +- Updated dependencies [d8d5a17da] +- Updated dependencies [83b6e0c1f] +- Updated dependencies [1665ae8bb] +- Updated dependencies [04f26f88d] +- Updated dependencies [ff243ce96] + - @backstage/core-api@0.2.5 + - @backstage/core@0.4.0 + - @backstage/plugin-catalog@0.2.6 + - @backstage/test-utils@0.1.5 + - @backstage/catalog-model@0.5.0 + - @backstage/theme@0.2.2 + +## 0.3.1 + +### Patch Changes + +- da2ad65cb: Use type EntityName from catalog-model for entities +- Updated dependencies [b4488ddb0] +- Updated dependencies [08835a61d] +- Updated dependencies [a9fd599f7] +- Updated dependencies [bcc211a08] +- Updated dependencies [ebf37bbae] + - @backstage/core-api@0.2.4 + - @backstage/catalog-model@0.4.0 + - @backstage/plugin-catalog@0.2.5 + - @backstage/test-utils@0.1.4 + +## 0.3.0 + +### Minor Changes + +- 4b53294a6: - Use techdocs annotation to add repo_url if missing in mkdocs.yml. Having repo_url creates a Edit button on techdocs pages. + - techdocs-backend: API endpoint `/metadata/mkdocs/*` renamed to `/metadata/techdocs/*` + +### Patch Changes + +- Updated dependencies [6f70ed7a9] +- Updated dependencies [ab94c9542] +- Updated dependencies [2daf18e80] +- Updated dependencies [069cda35f] +- Updated dependencies [700a212b4] + - @backstage/plugin-catalog@0.2.4 + - @backstage/catalog-model@0.3.1 + - @backstage/core-api@0.2.3 + +## 0.2.3 + +### Patch Changes + +- Updated dependencies [475fc0aaa] +- Updated dependencies [1166fcc36] +- Updated dependencies [1185919f3] + - @backstage/core@0.3.2 + - @backstage/catalog-model@0.3.0 + - @backstage/plugin-catalog@0.2.3 + +## 0.2.2 + +### Patch Changes + +- 1722cb53c: Added configuration schema +- Updated dependencies [1722cb53c] +- Updated dependencies [8b7737d0b] + - @backstage/core@0.3.1 + - @backstage/plugin-catalog@0.2.2 + - @backstage/test-utils@0.1.3 + +## 0.2.1 + +### Patch Changes + +- Updated dependencies [c5bab94ab] +- Updated dependencies [7b37d65fd] +- Updated dependencies [4aca74e08] +- Updated dependencies [e8f69ba93] +- Updated dependencies [0c0798f08] +- Updated dependencies [0c0798f08] +- Updated dependencies [199237d2f] +- Updated dependencies [6627b626f] +- Updated dependencies [4577e377b] +- Updated dependencies [2d0bd1be7] + - @backstage/core-api@0.2.1 + - @backstage/core@0.3.0 + - @backstage/theme@0.2.1 + - @backstage/plugin-catalog@0.2.1 + +## 0.2.0 + +### Minor Changes + +- 28edd7d29: Create backend plugin through CLI +- 8351ad79b: Add a message if techdocs takes long time to load + + Fixes #2416. + + The UI after the change should look like this: + + ![techdocs-progress-bar](https://user-images.githubusercontent.com/33940798/94189286-296ac980-fec8-11ea-9051-1b3db938d12f.gif) + +### Patch Changes + +- 782f3b354: add test case for Progress component +- 57b54c8ed: While techdocs fetches site name and metadata for the component, the page title was displayed as '[object Object] | Backstage'. This has now been fixed to display the component ID if site name is not present or being fetched. +- Updated dependencies [28edd7d29] +- Updated dependencies [819a70229] +- Updated dependencies [3a4236570] +- Updated dependencies [ae5983387] +- Updated dependencies [0d4459c08] +- Updated dependencies [cbbd271c4] +- Updated dependencies [482b6313d] +- Updated dependencies [e0be86b6f] +- Updated dependencies [f70a52868] +- Updated dependencies [12b5fe940] +- Updated dependencies [368fd8243] +- Updated dependencies [1c60f716e] +- Updated dependencies [144c66d50] +- Updated dependencies [a768a07fb] +- Updated dependencies [b79017fd3] +- Updated dependencies [6d97d2d6f] +- Updated dependencies [5adfc005e] +- Updated dependencies [f0aa01bcc] +- Updated dependencies [0aecfded0] +- Updated dependencies [93a3fa3ae] +- Updated dependencies [782f3b354] +- Updated dependencies [8b9c8196f] +- Updated dependencies [2713f28f4] +- Updated dependencies [406015b0d] +- Updated dependencies [82759d3e4] +- Updated dependencies [60d40892c] +- Updated dependencies [ac8d5d5c7] +- Updated dependencies [2ebcfac8d] +- Updated dependencies [fa56f4615] +- Updated dependencies [ebca83d48] +- Updated dependencies [aca79334f] +- Updated dependencies [c0d5242a0] +- Updated dependencies [b3d57961c] +- Updated dependencies [0b956f21b] +- Updated dependencies [26e69ab1a] +- Updated dependencies [97c2cb19b] +- Updated dependencies [3beb5c9fc] +- Updated dependencies [cbab5bbf8] +- Updated dependencies [754e31db5] +- Updated dependencies [1611c6dbc] + - @backstage/plugin-catalog@0.2.0 + - @backstage/core-api@0.2.0 + - @backstage/core@0.2.0 + - @backstage/catalog-model@0.2.0 + - @backstage/theme@0.2.0 + - @backstage/test-utils@0.1.2 + +## @backstage/ui@0.9.0-next.1 + +### Minor Changes + +- 5c614ff: **BREAKING**: Migrated Checkbox component from Base UI to React Aria Components. + + API changes required: + + - `checked` → `isSelected` + - `defaultChecked` → `defaultSelected` + - `disabled` → `isDisabled` + - `required` → `isRequired` + - `label` prop removed - use `children` instead + - CSS: `bui-CheckboxLabel` class removed + - Data attribute: `data-checked` → `data-selected` + - Use without label is no longer supported + + Migration examples: + + Before: + + ```tsx + + ``` + + After: + + ```tsx + + Accept terms + + ``` + + Before: + + ```tsx + + ``` + + After: + + ```tsx + Option + ``` + + Before: + + ```tsx + + ``` + + After: + + ```tsx + + Accessible label + + ``` + +- b78fc45: **BREAKING**: Changed className prop behavior to augment default styles instead of being ignored or overriding them. + + Affected components: + + - Menu, MenuListBox, MenuAutocomplete, MenuAutocompleteListbox, MenuItem, MenuListBoxItem, MenuSection, MenuSeparator + - Switch + - Skeleton + - FieldLabel + - Header, HeaderToolbar + - HeaderPage + - Tabs, TabList, Tab, TabPanel + + If you were passing custom className values to any of these components that relied on the previous behavior, you may need to adjust your styles to account for the default classes now being applied alongside your custom classes. + +### Patch Changes + +- ff9f0c3: Enable tree-shaking of imports other than `*.css`. +- 1ef3ca4: Added new VisuallyHidden component for hiding content visually while keeping it accessible to screen readers. + +## @backstage/plugin-notifications-backend-module-email@0.3.16-next.0 + +# @backstage/plugin-notifications-backend-module-email + +## 0.3.15-next.0 + +### Patch Changes + +- 22a5362: Updated `AWS SES` client to version 2 to support `nodemailer` version 7. +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.21-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/integration-aws-node@0.1.19-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/catalog-client@1.12.1-next.0 + - @backstage/types@1.2.2 + - @backstage/plugin-catalog-node@1.19.2-next.0 + - @backstage/plugin-notifications-common@0.1.2-next.0 + +## 0.3.14 + +### Patch Changes + +- b8cf31a: chore(deps): bump `nodemailer` from 6.9.16 to 7.0.7 +- f5e0963: Removed unused dependencies +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/integration-aws-node@0.1.18 + - @backstage/plugin-catalog-node@1.19.1 + - @backstage/plugin-notifications-common@0.1.1 + - @backstage/plugin-notifications-node@0.2.20 + +## 0.3.14-next.1 + +### Patch Changes + +- b8cf31a: chore(deps): bump `nodemailer` from 6.9.16 to 7.0.7 +- f5e0963: Removed unused dependencies + +## 0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration-aws-node@0.1.18-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-notifications-common@0.1.1-next.0 + - @backstage/plugin-catalog-node@1.19.1-next.0 + - @backstage/plugin-notifications-node@0.2.20-next.0 + - @backstage/catalog-client@1.12.0 + +## 0.3.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.19.0 + - @backstage/catalog-client@1.12.0 + - @backstage/types@1.2.2 + - @backstage/plugin-notifications-node@0.2.19 + - @backstage/backend-plugin-api@1.4.3 + +## 0.3.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.12.0-next.0 + - @backstage/plugin-catalog-node@1.19.0-next.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-notifications-node@0.2.19-next.1 + +## 0.3.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-catalog-node@1.18.1-next.0 + - @backstage/plugin-notifications-node@0.2.19-next.0 + +## 0.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0 + - @backstage/plugin-catalog-node@1.18.0 + - @backstage/plugin-notifications-common@0.1.0 + - @backstage/plugin-notifications-node@0.2.18 + - @backstage/backend-plugin-api@1.4.2 + +## 0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.11.0-next.0 + - @backstage/plugin-catalog-node@1.18.0-next.0 + - @backstage/plugin-notifications-node@0.2.18-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.10 + +## 0.3.11 + +### Patch Changes + +- f92c9fc: Add optional config for `ses` mail options with `sourceArn`, `fromArn`, `configurationSetName` +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/catalog-client@1.10.2 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-catalog-node@1.17.2 + - @backstage/plugin-notifications-common@0.0.10 + - @backstage/plugin-notifications-node@0.2.17 + +## 0.3.11-next.1 + +### Patch Changes + +- f92c9fc: Add optional config for `ses` mail options with `sourceArn`, `fromArn`, `configurationSetName` + +## 0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/catalog-client@1.10.2-next.0 + - @backstage/integration-aws-node@0.1.17-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-notifications-common@0.0.10-next.0 + - @backstage/plugin-catalog-node@1.17.2-next.0 + - @backstage/plugin-notifications-node@0.2.17-next.0 + +## 0.3.10 + +### Patch Changes + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## 0.3.10-next.2 + +### Patch Changes + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.1 + +## 0.3.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1-next.0 + - @backstage/plugin-notifications-common@0.0.9-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.1 + - @backstage/plugin-notifications-node@0.2.16-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## 0.3.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/plugin-catalog-node@1.17.1-next.0 + - @backstage/plugin-notifications-node@0.2.16-next.0 + +## 0.3.9 + +### Patch Changes + +- aa3a63a: Enable the ability to configure the endpoint for the SES connection used in the notifications email module. This enables the configuration of alternate endpoints as required, for example for local testing or alternative stacks. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-node@1.17.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/integration-aws-node@0.1.16 + - @backstage/catalog-client@1.10.0 + - @backstage/config@1.3.2 + - @backstage/plugin-notifications-node@0.2.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + +## 0.3.9-next.3 + +### Patch Changes + +- aa3a63a: Enable the ability to configure the endpoint for the SES connection used in the notifications email module. This enables the configuration of alternate endpoints as required, for example for local testing or alternative stacks. +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1-next.2 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.17.0-next.2 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.15-next.2 + +## 0.3.9-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-aws-node@0.1.16-next.0 + - @backstage/config@1.3.2 + - @backstage/plugin-notifications-node@0.2.15-next.1 + - @backstage/backend-plugin-api@1.3.1-next.1 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.17.0-next.1 + - @backstage/plugin-notifications-common@0.0.8 + +## 0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.0-next.1 + - @backstage/backend-plugin-api@1.3.1-next.1 + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.15-next.1 + +## 0.3.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.0-next.0 + - @backstage/plugin-catalog-node@1.17.0-next.0 + - @backstage/backend-plugin-api@1.3.1-next.0 + - @backstage/plugin-notifications-node@0.2.15-next.0 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + +## 0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.16.3 + - @backstage/backend-plugin-api@1.3.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.14 + +## 0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.16.3-next.0 + - @backstage/backend-plugin-api@1.2.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.13 + +## 0.3.7 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-aws-node@0.1.15 + - @backstage/backend-plugin-api@1.2.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.16.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.13 + +## 0.3.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.1-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.16.1-next.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.13-next.2 + +## 0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.1-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.16.1-next.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.13-next.1 + +## 0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.16.1-next.0 + - @backstage/plugin-notifications-node@0.2.13-next.0 + +## 0.3.6 + +### Patch Changes + +- 6259aa9: Add transport for Azure Communication Service +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0 + - @backstage/plugin-catalog-node@1.16.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12 + +## 0.3.6-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.16.0-next.3 + - @backstage/backend-plugin-api@1.2.0-next.2 + - @backstage/plugin-notifications-node@0.2.12-next.2 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + +## 0.3.6-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.2.0-next.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-node@1.16.0-next.2 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12-next.1 + +## 0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.16.0-next.1 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12-next.0 + +## 0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.2-next.0 + - @backstage/backend-plugin-api@1.2.0-next.0 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.12-next.0 + +## 0.3.5 + +### Patch Changes + +- bed5f35: Added more examples of the plugin configuration +- Updated dependencies + - @backstage/types@1.2.1 + - @backstage/backend-plugin-api@1.1.1 + - @backstage/catalog-client@1.9.1 + - @backstage/catalog-model@1.7.3 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.15 + - @backstage/plugin-catalog-node@1.15.1 + - @backstage/plugin-notifications-common@0.0.8 + - @backstage/plugin-notifications-node@0.2.11 + +## 0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.1-next.0 + - @backstage/backend-plugin-api@1.1.1-next.1 + - @backstage/catalog-model@1.7.3-next.0 + - @backstage/config@1.3.2-next.0 + - @backstage/plugin-catalog-node@1.15.1-next.1 + - @backstage/integration-aws-node@0.1.15-next.0 + - @backstage/plugin-notifications-node@0.2.11-next.1 + - @backstage/catalog-client@1.9.1-next.0 + - @backstage/plugin-notifications-common@0.0.8-next.0 + +## 0.3.5-next.0 + +### Patch Changes + +- bed5f35: Added more examples of the plugin configuration +- Updated dependencies + - @backstage/backend-plugin-api@1.1.1-next.0 + - @backstage/catalog-client@1.9.0 + - @backstage/catalog-model@1.7.2 + - @backstage/config@1.3.1 + - @backstage/integration-aws-node@0.1.14 + - @backstage/types@1.2.0 + - @backstage/plugin-catalog-node@1.15.1-next.0 + - @backstage/plugin-notifications-common@0.0.7 + - @backstage/plugin-notifications-node@0.2.11-next.0 + +## 0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.1.0 + - @backstage/plugin-catalog-node@1.15.0 + - @backstage/catalog-client@1.9.0 + - @backstage/plugin-notifications-node@0.2.10 + - @backstage/catalog-model@1.7.2 + - @backstage/config@1.3.1 + - @backstage/integration-aws-node@0.1.14 + - @backstage/types@1.2.0 + - @backstage/plugin-notifications-common@0.0.7 + +## 0.3.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.1.0-next.2 + - @backstage/plugin-catalog-node@1.15.0-next.2 + - @backstage/plugin-notifications-node@0.2.10-next.2 + - @backstage/catalog-client@1.9.0-next.2 + - @backstage/catalog-model@1.7.2-next.0 + - @backstage/config@1.3.1-next.0 + - @backstage/integration-aws-node@0.1.14-next.0 + - @backstage/types@1.2.0 + - @backstage/plugin-notifications-common@0.0.7-next.0 + +## 0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.15.0-next.1 + - @backstage/catalog-client@1.9.0-next.1 + - @backstage/plugin-notifications-node@0.2.10-next.1 + - @backstage/backend-plugin-api@1.1.0-next.1 + - @backstage/catalog-model@1.7.1 + - @backstage/config@1.3.0 + - @backstage/integration-aws-node@0.1.13 + - @backstage/types@1.2.0 + - @backstage/plugin-notifications-common@0.0.6 + +## 0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.3-next.0 + - @backstage/catalog-client@1.8.1-next.0 + - @backstage/catalog-model@1.7.1 + - @backstage/config@1.3.0 + - @backstage/integration-aws-node@0.1.13 + - @backstage/types@1.2.0 + - @backstage/plugin-catalog-node@1.14.1-next.0 + - @backstage/plugin-notifications-common@0.0.6 + - @backstage/plugin-notifications-node@0.2.10-next.0 + +## 0.3.3 + +### Patch Changes + +- d52d7f9: Support ISO and ms string forms of durations in config too +- 5d74716: Remove unused backend-common dependency +- Updated dependencies + - @backstage/catalog-client@1.8.0 + - @backstage/config@1.3.0 + - @backstage/types@1.2.0 + - @backstage/integration-aws-node@0.1.13 + - @backstage/plugin-catalog-node@1.14.0 + - @backstage/backend-plugin-api@1.0.2 + - @backstage/plugin-notifications-common@0.0.6 + - @backstage/plugin-notifications-node@0.2.9 + - @backstage/catalog-model@1.7.1 + +## 0.3.3-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-aws-node@0.1.13-next.0 + - @backstage/backend-plugin-api@1.0.2-next.2 + - @backstage/catalog-client@1.8.0-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.14.0-next.2 + - @backstage/plugin-notifications-common@0.0.6-next.0 + - @backstage/plugin-notifications-node@0.2.9-next.3 + +## 0.3.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.8.0-next.1 + - @backstage/plugin-catalog-node@1.14.0-next.2 + - @backstage/plugin-notifications-node@0.2.9-next.2 + - @backstage/backend-plugin-api@1.0.2-next.2 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.6-next.0 + +## 0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.0.2-next.1 + - @backstage/catalog-client@1.8.0-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.14.0-next.1 + - @backstage/plugin-notifications-common@0.0.6-next.0 + - @backstage/plugin-notifications-node@0.2.9-next.1 + +## 0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.14.0-next.0 + - @backstage/plugin-notifications-common@0.0.6-next.0 + - @backstage/catalog-client@1.8.0-next.0 + - @backstage/backend-plugin-api@1.0.2-next.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-node@0.2.9-next.0 + +## 0.3.1 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.7 + - @backstage/plugin-catalog-node@1.13.1 + - @backstage/catalog-client@1.7.1 + - @backstage/backend-plugin-api@1.0.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.13.1-next.1 + - @backstage/catalog-client@1.7.1-next.0 + - @backstage/backend-plugin-api@1.0.1-next.1 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.7-next.1 + +## 0.3.1-next.0 + +### Patch Changes + +- 094eaa3: Remove references to in-repo backend-common +- Updated dependencies + - @backstage/plugin-notifications-node@0.2.7-next.0 + - @backstage/backend-plugin-api@1.0.1-next.0 + - @backstage/catalog-client@1.7.0 + - @backstage/catalog-model@1.7.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.13.1-next.0 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.3.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0 + - @backstage/backend-plugin-api@1.0.0 + - @backstage/catalog-model@1.7.0 + - @backstage/catalog-client@1.7.0 + - @backstage/plugin-catalog-node@1.13.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6 + +## 0.3.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.2 + - @backstage/backend-plugin-api@1.0.0-next.2 + - @backstage/catalog-client@1.7.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.2 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.2 + +## 0.3.0-next.1 + +### Patch Changes + +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.1 + +## 0.3.0-next.0 + +### Minor Changes + +- d425fc4: **BREAKING**: The return values from `createBackendPlugin`, `createBackendModule`, and `createServiceFactory` are now simply `BackendFeature` and `ServiceFactory`, instead of the previously deprecated form of a function that returns them. For this reason, `createServiceFactory` also no longer accepts the callback form where you provide direct options to the service. This also affects all `coreServices.*` service refs. + + This may in particular affect tests; if you were effectively doing `createBackendModule({...})()` (note the parentheses), you can now remove those extra parentheses at the end. You may encounter cases of this in your `packages/backend/src/index.ts` too, where you add plugins, modules, and services. If you were using `createServiceFactory` with a function as its argument for the purpose of passing in options, this pattern has been deprecated for a while and is no longer supported. You may want to explore the new multiton patterns to achieve your goals, or moving settings to app-config. + + As part of this change, the `IdentityFactoryOptions` type was removed, and can no longer be used to tweak that service. The identity service was also deprecated some time ago, and you will want to [migrate to the new auth system](https://backstage.io/docs/tutorials/auth-service-migration) if you still rely on it. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-notifications-node@0.2.6-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.2.0 + +### Minor Changes + +- def53a7: **BREAKING** Following `NotificationTemplateRenderer` methods now return a Promise and **must** be awaited: `getSubject`, `getText` and `getHtml`. + + Required changes and example usage: + + ```diff + import { notificationsEmailTemplateExtensionPoint } from '@backstage/plugin-notifications-backend-module-email'; + import { Notification } from '@backstage/plugin-notifications-common'; + +import { getNotificationSubject, getNotificationTextContent, getNotificationHtmlContent } from 'my-notification-processing-library` + export const notificationsModuleEmailDecorator = createBackendModule({ + pluginId: 'notifications', + moduleId: 'email.templates', + register(reg) { + reg.registerInit({ + deps: { + emailTemplates: notificationsEmailTemplateExtensionPoint, + }, + async init({ emailTemplates }) { + emailTemplates.setTemplateRenderer({ + - getSubject(notification) { + + async getSubject(notification) { + - return `New notification from ${notification.source}`; + + const subject = await getNotificationSubject(notification); + + return `New notification from ${subject}`; + }, + - getText(notification) { + + async getText(notification) { + - return notification.content; + + const text = await getNotificationTextContent(notification); + + return text; + }, + - getHtml(notification) { + + async getHtml(notification) { + - return `

    ${notification.content}

    `; + + const html = await getNotificationHtmlContent(notification); + + return html; + }, + }); + }, + }); + }, + }); + ``` + +### Patch Changes + +- d55b8e3: Avoid sending broadcast emails as a fallback in case the entity-typed notification user can not be resolved. +- cdb630d: Add support for stream transport for debugging purposes +- 83faf24: Notification email processor supports allowing or denying specific email addresses from receiving notifications +- Updated dependencies + - @backstage/backend-plugin-api@0.8.0 + - @backstage/backend-common@0.24.0 + - @backstage/plugin-notifications-node@0.2.4 + - @backstage/catalog-model@1.6.0 + - @backstage/catalog-client@1.6.6 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.2.0-next.3 + +### Patch Changes + +- 83faf24: Notification email processor supports allowing or denying specific email addresses from receiving notifications +- Updated dependencies + - @backstage/backend-plugin-api@0.8.0-next.3 + - @backstage/backend-common@0.23.4-next.3 + - @backstage/catalog-model@1.6.0-next.0 + - @backstage/catalog-client@1.6.6-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.3 + +## 0.2.0-next.2 + +### Patch Changes + +- cdb630d: Add support for stream transport for debugging purposes +- Updated dependencies + - @backstage/backend-plugin-api@0.8.0-next.2 + - @backstage/plugin-notifications-node@0.2.4-next.2 + - @backstage/backend-common@0.23.4-next.2 + - @backstage/integration-aws-node@0.1.12 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## 0.2.0-next.1 + +### Minor Changes + +- def53a7: **BREAKING** Following `NotificationTemplateRenderer` methods now return a Promise and **must** be awaited: `getSubject`, `getText` and `getHtml`. + + Required changes and example usage: + + ```diff + import { notificationsEmailTemplateExtensionPoint } from '@backstage/plugin-notifications-backend-module-email'; + import { Notification } from '@backstage/plugin-notifications-common'; + +import { getNotificationSubject, getNotificationTextContent, getNotificationHtmlContent } from 'my-notification-processing-library` + export const notificationsModuleEmailDecorator = createBackendModule({ + pluginId: 'notifications', + moduleId: 'email.templates', + register(reg) { + reg.registerInit({ + deps: { + emailTemplates: notificationsEmailTemplateExtensionPoint, + }, + async init({ emailTemplates }) { + emailTemplates.setTemplateRenderer({ + - getSubject(notification) { + + async getSubject(notification) { + - return `New notification from ${notification.source}`; + + const subject = await getNotificationSubject(notification); + + return `New notification from ${subject}`; + }, + - getText(notification) { + + async getText(notification) { + - return notification.content; + + const text = await getNotificationTextContent(notification); + + return text; + }, + - getHtml(notification) { + + async getHtml(notification) { + - return `

    ${notification.content}

    `; + + const html = await getNotificationHtmlContent(notification); + + return html; + }, + }); + }, + }); + }, + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.7.1-next.1 + - @backstage/backend-common@0.23.4-next.1 + - @backstage/integration-aws-node@0.1.12 + - @backstage/catalog-client@1.6.5 + - @backstage/catalog-model@1.5.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.4-next.1 + +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.4-next.0 + - @backstage/backend-plugin-api@0.7.1-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.5 + - @backstage/plugin-notifications-node@0.2.4-next.0 + +## 0.1.3 + +### Patch Changes + +- 4e4ef2b: Move notification processor filter parsing to common package +- Updated dependencies + - @backstage/backend-plugin-api@0.7.0 + - @backstage/backend-common@0.23.3 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.3 + - @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 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.23.3-next.1 + - @backstage/backend-plugin-api@0.6.22-next.1 + - @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.3-next.1 + +## 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 + +## 0.1.0 + +### Minor Changes + +- 07a789b: add notification filters + +### 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/plugin-notifications-node@0.2.0 + - @backstage/plugin-notifications-common@0.0.4 + - @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 + +## 0.1.0-next.3 + +### Patch Changes + +- d44a20a: Added additional plugin metadata to `package.json`. +- Updated dependencies + - @backstage/backend-plugin-api@0.6.19-next.3 + - @backstage/plugin-notifications-common@0.0.4-next.0 + - @backstage/plugin-notifications-node@0.2.0-next.3 + - @backstage/backend-common@0.23.0-next.3 + - @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 + +## 0.1.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.19-next.2 + - @backstage/backend-common@0.23.0-next.2 + - @backstage/plugin-notifications-node@0.2.0-next.2 + - @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.3 + +## 0.1.0-next.1 + +### Minor Changes + +- 07a789b: add notification filters + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.6.19-next.1 + - @backstage/plugin-notifications-node@0.2.0-next.1 + - @backstage/backend-common@0.23.0-next.1 + +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.22.1-next.0 + - @backstage/backend-plugin-api@0.6.19-next.0 + - @backstage/plugin-notifications-node@0.1.5-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.3 + +## 0.0.1 + +### Patch Changes + +- d541ff6: Fixed email processor `esm` issue and config reading +- e538b10: Support relative links in notifications sent via email +- dbf2696: Allow sending notifications by email with the new notifications module +- Updated dependencies + - @backstage/catalog-model@1.5.0 + - @backstage/backend-common@0.22.0 + - @backstage/plugin-notifications-node@0.1.4 + - @backstage/backend-plugin-api@0.6.18 + - @backstage/catalog-client@1.6.5 + +## 0.0.1-next.1 + +### Patch Changes + +- d541ff6: Fixed email processor `esm` issue and config reading +- e538b10: Support relative links in notifications sent via email +- Updated dependencies + - @backstage/backend-common@0.22.0-next.2 + +## 0.0.1-next.0 + +### Patch Changes + +- dbf2696: Allow sending notifications by email with the new notifications module +- Updated dependencies + - @backstage/plugin-notifications-node@0.1.4-next.1 + - @backstage/backend-common@0.22.0-next.1 + - @backstage/backend-plugin-api@0.6.18-next.1 + +## @backstage/create-app@0.7.6-next.1 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/dev-utils@1.1.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + +## @backstage/plugin-mui-to-bui@0.2.1-next.1 + +### Patch Changes + +- 5c614ff: Updated BUI checkbox preview example to align with new component API. +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + +## example-app@0.2.115-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + - @backstage/plugin-mui-to-bui@0.2.1-next.1 + +## example-app-next@0.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + +## techdocs-cli-embedded-app@0.2.114-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 diff --git a/docs/releases/v1.45.0-next.2-changelog.md b/docs/releases/v1.45.0-next.2-changelog.md new file mode 100644 index 0000000000..4bac9094e7 --- /dev/null +++ b/docs/releases/v1.45.0-next.2-changelog.md @@ -0,0 +1,1448 @@ +# Release v1.45.0-next.2 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.45.0-next.2](https://backstage.github.io/upgrade-helper/?to=1.45.0-next.2) + +## @backstage/backend-app-api@1.3.0-next.1 + +### Minor Changes + +- a17d9df: Updates API for `instanceMetadata` service to return a list of plugins not features. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/backend-plugin-api@1.5.0-next.1 + +### Minor Changes + +- a17d9df: Promote `instanceMetadata` service to main entrypoint. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/ui@0.9.0-next.2 + +### Minor Changes + +- 539cf26: **BREAKING**: Migrated Avatar component from Base UI to custom implementation with size changes: + + - Base UI-specific props are no longer supported + - Size values have been updated: + - New `x-small` size added (1.25rem / 20px) + - `small` size unchanged (1.5rem / 24px) + - `medium` size unchanged (2rem / 32px, default) + - `large` size **changed from 3rem to 2.5rem** (40px) + - New `x-large` size added (3rem / 48px) + + Migration: + + ```diff + # Remove Base UI-specific props + - + + + + # Update large size usage to x-large for same visual size + - + + + ``` + + Added `purpose` prop for accessibility control (`'informative'` or `'decoration'`). + +- 134151f: Fixing styles on SearchField in Backstage UI after migration to CSS modules. `SearchField` has now its own set of class names. We previously used class names from `TextField` but this approach was creating some confusion so going forward in your theme you'll be able to theme `TextField` and `SearchField` separately. + +### Patch Changes + +- d01de00: Fix broken external links in Backstage UI Header component. +- deaa427: Fixed Text component to prevent `truncate` prop from being spread to the underlying DOM element. +- 1059f95: Improved the Link component structure in Backstage UI. +- 6874094: Migrated CellProfile component from Base UI Avatar to Backstage UI Avatar component. +- 719d772: Avatar components in x-small and small sizes now display only one initial instead of two, improving readability at smaller dimensions. +- 3b18d80: Fixed RadioGroup radio button ellipse distortion by preventing flex shrink and grow. +- e16ece5: Set the color-scheme property depending on theme + +## @backstage/plugin-catalog@1.32.0-next.1 + +### Minor Changes + +- a521911: Add support for customizable icons in `SearchResultListItemBlueprint` and related components + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-catalog-backend@3.2.0-next.1 + +### Minor Changes + +- 2d229b2: Enable YAML merge keys in yamlPlaceholderResolver +- 9d3ec06: Make YAML merge (<<:) support configurable in the Backstage Catalog instead of always being enabled +- 8c26af4: Enable YAML merge keys in yamlPlaceholderResolver + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.12.0-next.1 + +### Minor Changes + +- 980f240: Moved from `ldapjs` dependency to `ldapts` + + ### Breaking Changes + + **Type Migration** + + Custom transformers must now accept `Entry` from ldapts instead of `SearchEntry` + from ldapjs The Entry type provides direct property access without need for + `.object()` or `.raw()` methods. + + If you have custom user or group transformers, update the signature from: + + ```typescript + (vendor: LdapVendor, config: UserConfig, entry: SearchEntry) => + Promise; + ``` + + to + + ```typescript + (vendor: LdapVendor, config: UserConfig, entry: Entry) => + Promise; + ``` + + **Search Options** + + Updated LDAP search configuration `typesOnly: false` → `attributeValues: true` + This inverts the boolean logic: ldapjs used negative form while ldapts uses + positive form. Both achieve the same result: retrieving attribute values rather + than just attribute names. + + Update LDAP search options in configuration from + + ```yaml + options: + typesOnly: false + ``` + + to + + ```yaml + options: + attributeValues: true + ``` + + **API Changes** Removed `LdapClient.searchStreaming()` method. Users should + migrate to `LdapClient.search()` instead + + If you're using `searchStreaming` directly: + + ```typescript + // Before + await client.searchStreaming(dn, options, async entry => { + // process each entry + }); + + // After + const entries = await client.search(dn, options); + for (const entry of entries) { + // process each entry + } + ``` + + > **_NOTE:_**: Both methods have always loaded all entries into memory. The + > searchStreaming method was only needed internally to handle ldapjs's + > event-based API. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-node@1.20.0-next.1 + +### Minor Changes + +- 9d3ec06: Make YAML merge (<<:) support configurable in the Backstage Catalog instead of always being enabled +- 8c26af4: Enable YAML merge keys in yamlPlaceholderResolver + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-gateway-backend@1.1.0-next.1 + +### Minor Changes + +- a17d9df: Update usage of the `instanceMetadata` service. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.10.0-next.1 + +### Minor Changes + +- ff96d7e: fix scaffolder action createDeployToken to allow usage of oauth tokens + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-search@1.5.0-next.1 + +### Minor Changes + +- a521911: Add support for customizable icons in `SearchResultListItemBlueprint` and related components + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-search-react@1.10.0-next.1 + +### Minor Changes + +- a521911: Add support for customizable icons in `SearchResultListItemBlueprint` and related components + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + +## @backstage/plugin-techdocs@1.16.0-next.1 + +### Minor Changes + +- a521911: Add support for customizable icons in `SearchResultListItemBlueprint` and related components + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/backend-defaults@0.13.1-next.1 + +### Patch Changes + +- 91ab2eb: Fix a bug in the Gitlab URL reader where `search` did not handle multiple globs +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-app-api@1.3.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/backend-dynamic-feature-service@0.7.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-app-node@0.1.39-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/backend-openapi-utils@0.6.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/backend-test-utils@1.10.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-app-api@1.3.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/cli@0.34.5-next.1 + +### Patch Changes + +- da19cb5: Fix inconsistent behavior in the `new` command for the `@internal` scope: it now consistently defaults to the `backstage-plugin-` infix whether the `--scope` option is not set or it's set to `internal`. +- b2bef92: Convert all enums to erasable-syntax compliant patterns + +## @backstage/core-app-api@1.19.2-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.1 + +## @backstage/core-components@0.18.3-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.1 + +## @backstage/core-plugin-api@1.11.2-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns + +## @backstage/create-app@0.7.6-next.2 + +### Patch Changes + +- 9f939a6: Added `@backstage/plugin-app-visualizer` to the app in the `--next` template. + +## @backstage/frontend-plugin-api@0.12.2-next.1 + +### Patch Changes + +- 878c251: Updated to `ExtensionInput` to make all type parameters optional. +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + +## @backstage/repo-tools@0.15.4-next.1 + +### Patch Changes + +- 8f56eae: Updated knip-reports to detect dependencies in dev/alpha pattern +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-api-docs@0.13.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-app-backend@0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-app-node@0.1.39-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-app-node@0.1.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-app-visualizer@0.1.25-next.1 + +### Patch Changes + +- e81b3f0: Improve tree visualizer to use a horizontal layout and fill the content space. +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + +## @backstage/plugin-auth-backend@0.25.6-next.1 + +### Patch Changes + +- 51ff7d8: Allow configuring dynamic client registration token expiration with config `auth.experimentalDynamicClientRegistration.tokenExpiration`. + + Maximum expiration for the DCR token is 24 hours. Default expiration is 1 hour. + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-backend@0.25.6-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-backend@0.25.6-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-openshift-provider@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-auth-node@0.6.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-azure@0.3.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.11.2-next.1 + +### Patch Changes + +- 999d1c1: Added configurable `pageSizes` for GitHub GraphQL API queries to prevent `RESOURCE_LIMITS_EXCEEDED` errors with organizations with large number of repositories. Please see the [GitHub Discovery documentation](https://backstage.io/docs/integrations/github/discovery#configuration) for new configuration options. +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.16-next.1 + +### Patch Changes + +- 999d1c1: Added configurable `pageSizes` for GitHub GraphQL API queries to prevent `RESOURCE_LIMITS_EXCEEDED` errors with organizations with large number of teams and members. Please see the [GitHub Org Data documentation](https://backstage.io/docs/integrations/github/org#configuration-details) for new configuration options. +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-catalog-backend-module-github@0.11.2-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-catalog-backend-module-gitlab@0.7.5-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.6-next.1 + +### Patch Changes + +- 70745c5: Correctly handle entity removal computation when DB count query returns string +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-logs@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.8.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.16-next.1 + +### Patch Changes + +- a5bcb2a: fix wrong dereferencing for AsyncApi 3 documents +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-catalog-graph@0.5.3-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-catalog-react@1.21.3-next.1 + +### Patch Changes + +- 2b7924b: Apply default ordering of templates +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-devtools-backend@0.5.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-devtools-common@0.1.19-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-devtools-common@0.1.19-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.1 + +## @backstage/plugin-events-backend@0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-azure@0.2.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-gerrit@0.2.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-github@0.4.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-gitlab@0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-backend-module-kafka@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-events-node@0.4.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-kubernetes-backend@0.20.4-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-kubernetes-node@0.3.6-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-kubernetes-node@0.3.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-mcp-actions-backend@0.1.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-notifications-backend@0.5.12-next.1 + +### Patch Changes + +- 15fb764: Show default settings for notifications even before receiving first notification. + + Previously, it was not possible for the users to see or modify their notification settings until they had received at + least one notification from specific origin or topic. + This update ensures that default settings are displayed from the outset, + allowing users to customize their preferences immediately. + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-notifications-node@0.2.21-next.1 + - @backstage/plugin-signals-node@0.1.26-next.1 + +## @backstage/plugin-notifications-backend-module-email@0.3.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-notifications-node@0.2.21-next.1 + +## @backstage/plugin-notifications-backend-module-slack@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-notifications-node@0.2.21-next.1 + +## @backstage/plugin-notifications-node@0.2.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-signals-node@0.1.26-next.1 + +## @backstage/plugin-permission-backend@0.7.6-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## @backstage/plugin-permission-common@0.9.3-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns + +## @backstage/plugin-permission-node@0.10.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + +## @backstage/plugin-proxy-backend@0.6.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-proxy-node@0.1.10-next.1 + +## @backstage/plugin-proxy-node@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-scaffolder-backend@3.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.10.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.16-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.15-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-notifications-node@0.2.21-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.15-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.16-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.3.5-next.1 + +## @backstage/plugin-scaffolder-node@0.12.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-test-utils@1.10.0-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + +## @backstage/plugin-search-backend@2.0.8-next.1 + +### Patch Changes + +- b2bef92: Convert all enums to erasable-syntax compliant patterns +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-catalog@0.3.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.8-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-explore@0.3.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-pg@0.5.50-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## @backstage/plugin-search-backend-module-techdocs@0.4.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + - @backstage/plugin-techdocs-node@1.13.9-next.1 + +## @backstage/plugin-search-backend-node@1.3.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + +## @backstage/plugin-signals@0.0.25-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- f0f006e: Fixes a bug where the `SignalClient` would try to subscribe to the same channel twice after an error, instead of just once. +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/core-compat-api@0.5.4-next.0 + +## @backstage/plugin-signals-backend@0.3.10-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-signals-node@0.1.26-next.1 + +## @backstage/plugin-signals-node@0.1.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + +## @backstage/plugin-techdocs-backend@2.1.2-next.1 + +### Patch Changes + +- 71c22f3: Removed/moved unused dependencies +- Updated dependencies + - @backstage/plugin-catalog-node@1.20.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-techdocs-node@1.13.9-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.1 + +### Patch Changes + +- 6929480: ExpandableCollapse Techdocs Addon was breaking native sidebar collapse on Firefox +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + +## @backstage/plugin-techdocs-node@1.13.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## @backstage/plugin-user-settings-backend@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-signals-node@0.1.26-next.1 + +## example-app@0.2.115-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-signals@0.0.25-next.1 + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-search@1.5.0-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + - @backstage/plugin-catalog-graph@0.5.3-next.1 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/plugin-api-docs@0.13.1-next.1 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + +## example-app-next@0.0.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-signals@0.0.25-next.1 + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-search@1.5.0-next.1 + - @backstage/plugin-app-visualizer@0.1.25-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + - @backstage/plugin-catalog-graph@0.5.3-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/plugin-api-docs@0.13.1-next.1 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + +## example-backend@0.0.44-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.7.8-next.1 + - @backstage/plugin-kubernetes-backend@0.20.4-next.1 + - @backstage/plugin-techdocs-backend@2.1.2-next.1 + - @backstage/plugin-signals-backend@0.3.10-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/plugin-notifications-backend@0.5.12-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.16-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-backend@0.7.6-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-search-backend@2.0.8-next.1 + - @backstage/plugin-auth-backend@0.25.6-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.8-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.6-next.1 + - @backstage/plugin-mcp-actions-backend@0.1.5-next.1 + - @backstage/plugin-scaffolder-backend@3.0.1-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.10-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.8-next.1 + - @backstage/plugin-app-backend@0.5.8-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.9-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.14-next.1 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.2-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-devtools-backend@0.5.11-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.6-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.14-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-proxy-backend@0.6.8-next.1 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.1 + - @backstage/plugin-search-backend-module-explore@0.3.9-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## techdocs-cli-embedded-app@0.2.114-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + +## @internal/plugin-todo-list-backend@1.0.45-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 diff --git a/docs/tooling/cli/03-commands.md b/docs/tooling/cli/03-commands.md index d176278655..ce8f862c98 100644 --- a/docs/tooling/cli/03-commands.md +++ b/docs/tooling/cli/03-commands.md @@ -177,11 +177,12 @@ Usage: backstage-cli package start [options] Start a package for local development Options: - --config Config files to load instead of app-config.yaml (default: []) - --role Run the command with an explicit package role - --check Enable type checking and linting if available - --inspect Enable debugger in Node.js environments - --inspect-brk Enable debugger in Node.js environments, breaking before code starts + --config Config files to load instead of app-config.yaml (default: []) + --role Run the command with an explicit package role + --check Enable type checking and linting if available + --inspect Enable debugger in Node.js environments + --inspect-brk Enable debugger in Node.js environments, breaking before code starts + --entrypoint Entry directory path (uses index file) or entry file path (without extension). Defaults to "dev" ``` ## package build diff --git a/docs/tooling/cli/04-templates.md b/docs/tooling/cli/04-templates.md index c3bfb57d11..894cc7efd0 100644 --- a/docs/tooling/cli/04-templates.md +++ b/docs/tooling/cli/04-templates.md @@ -90,6 +90,7 @@ When defining the `templates` array it will override the default set of template "@backstage/cli/templates/plugin-common-library", "@backstage/cli/templates/web-library", "@backstage/cli/templates/node-library", + "@backstage/cli/templates/catalog-provider-module", "@backstage/cli/templates/scaffolder-backend-module" ] } @@ -147,3 +148,13 @@ The `role` property in the template yaml file is used to determine what input wi | `plugin-web-library` | `pluginId` | `plugins` | none | | `plugin-node-library` | `pluginId` | `plugins` | none | | `plugin-common-library` | `pluginId` | `plugins` | none | + +## Dependency Versioning + +The `yarn new` command automatically detects if the [Backstage Yarn plugin](https://github.com/backstage/backstage/tree/master/packages/yarn-plugin) is installed in your repository and adjusts dependency versioning accordingly. + +When the Backstage Yarn plugin is installed (detected via `.yarnrc.yml`), `yarn new` will generate `backstage:^` ranges for all `@backstage/*` dependencies. This ensures that new packages use the same Backstage version as defined in your `backstage.json` file. + +When the plugin is not installed, `yarn new` uses the standard npm version ranges (e.g., `^1.0.0`) for all dependencies, maintaining backward compatibility. + +Regardless of plugin installation, `workspace:` ranges found in your `yarn.lock` file will always take precedence over both `backstage:^` and npm ranges. This ensures that packages within monorepos continue to use workspace linking when available. diff --git a/docs/tooling/local-dev/debugging.md b/docs/tooling/local-dev/debugging.md index 662f04151a..6e12bb9f5f 100644 --- a/docs/tooling/local-dev/debugging.md +++ b/docs/tooling/local-dev/debugging.md @@ -65,7 +65,8 @@ In your `.vscode/launch.json`, add a new entry with the following, "runtimeExecutable": "yarn", // Specifies the runtime to execute the application. In this case, it uses `yarn` to run the script. "args": ["start", "--inspect"], // Arguments passed to the `yarn` command. Here, it runs `yarn start` with the `--inspect` flag to enable debugging. "skipFiles": ["/**"], // Tells the debugger to skip stepping into Node.js internal files during debugging. - "console": "integratedTerminal" // Specifies that the debugger should use the integrated terminal for input/output. + "console": "integratedTerminal", // Specifies that the debugger should use the integrated terminal for input/output. + "experimentalNetworking": "off" // Since Node.js 22.15.0 an additional parameter --experimental-network-inspection is added but currently not supported by Yarn } ] } diff --git a/docs/tooling/package-metadata.md b/docs/tooling/package-metadata.md index ad9d5ec5a0..3911ada413 100644 --- a/docs/tooling/package-metadata.md +++ b/docs/tooling/package-metadata.md @@ -96,6 +96,32 @@ This field can be generated by the `backstage-cli repo fix --publish` command. T The presence of this field is checked by the `backstage-cli package prepack` command, which is used to prepare a package for publishing. You can read more about this requirement in the section on [metadata for published packages](#metadata-for-published-packages). +### `backstage.features` + +This field declares where to find Backstage features exported from the package. It is a map of features export paths to their feature type, similar to the `exports` field. + +```js title="Example usage of the backstage.features field" +{ + "name": "@backstage/plugin-catalog", + "backstage": { + "features": { + "./alpha": "@backstage/FrontendPlugin" + } + } +} +``` + +This field is automatically generated by the `backstage-cli package prepack` command when publishing a package and therefore does not need to be committed to the repository. + +If you are using your own tooling to publish a package, you need to populate this field manually, using the following feature types: + +- `@backstage/BackendFeature` +- `@backstage/FrontendPlugin` +- `@backstage/FrontendModule` +- `@backstage/FrontendFeatureLoader` + +You can read more about the feature types in the [backend system](../backend-system/architecture/01-index.md) and [frontend system](../frontend-system/architecture/00-index.md) documentation. + ### `backstage.pluginPackages` For any package that is part of a plugin, this field should be set to a list of all packages that are directly part of the same plugin. This includes frontend and backend plugin packages as well as related libraries, but not modules. diff --git a/docs/tutorials/configuring-plugin-databases.md b/docs/tutorials/configuring-plugin-databases.md index c6d9869d38..2bbe83557c 100644 --- a/docs/tutorials/configuring-plugin-databases.md +++ b/docs/tutorials/configuring-plugin-databases.md @@ -1,7 +1,6 @@ --- id: configuring-plugin-databases title: Configuring Plugin Databases -# prettier-ignore description: Guide on how to configure Backstage databases. --- diff --git a/docs/tutorials/integrating-event-driven-updates-with-entity-providers.md b/docs/tutorials/integrating-event-driven-updates-with-entity-providers.md new file mode 100644 index 0000000000..66175a34ce --- /dev/null +++ b/docs/tutorials/integrating-event-driven-updates-with-entity-providers.md @@ -0,0 +1,213 @@ +--- +id: integrating-event-driven-updates-with-entity-providers +title: Integrating Event-Driven Updates with Entity Providers +description: A guide on integrating the events system into an EntityProvider to enable immediate updates to the catalog. +--- + +This guide walks you through setting up an HTTP endpoint to receive events and integrating the Events System into an EntityProvider to enable immediate updates to the catalog. While the Events system supports other use cases, this guide focuses specifically on using HTTP-based events in an EntityProvider. + +In the example provided, we demonstrate how to ingest entities from an external fictional service called `Frobs`. + +Basic flow: + +- An external service (`Frobs` in this example) sends events to an HTTP endpoint exposed by the `@backstage/plugin-events-backend` plugin. This endpoint corresponds to a topic you define (e.g., `frobs`). + +- A module to extend the `@backstage/plugin-events-backend` plugin that exposes a custom Router, processes incoming events on this generic topic and routes them to more specific sub-topics based on the contents of each event’s payload. + +- An `EntityProvider` subscribes to these specific sub-topic events and, upon receiving them, takes an action to add/update/delete entities in the catalog accordingly. + +## Receiving Events via HTTP Endpoints + +The `@backstage/plugin-events-backend` plugin provides out-of-the-box support for receiving events via HTTP endpoints. These events are then published to the `EventsService`. + +To create HTTP endpoints for specific topics, you need to configure them in your app-config.yaml: + +``` +events: + http: + topics: + - frobs +``` + +Only topics explicitly listed in this configuration will result in available HTTP endpoints. + +The example above would create the following endpoints: + +`POST /api/events/http/frobs` + +You can use this URL as the payload URL when setting up your webhooks from external services. When an event is sent to this endpoint, the events-backend will publish it to the Events Service, making it available to any subscribed entity providers. + +## Routing General Topics to Specific Subtopics + +To effectively manage events, you can extend the event system to route general topics to more specific subtopics by creating a module for the `events-backend` plugin. + +For example, when setting up a webhook for the `Frobs` service using the `POST /api/events/http/frobs` endpoint, all incoming events are initially published under the generic `frobs` topic. However, by republishing these events under more specific subtopics based on their payload — such as the type field — you allow your EntityProvider to subscribe only to the relevant subtopics it needs, rather than processing every event under the broader `frobs` topic. + +Here's an example of a `SubTopicEventRouter` that subscribes to a generic `frobs` topic and then publishes events under a more concrete sub-topic based on the `$.type` provided in the event payload: + +```ts +import { + EventParams, + EventsService, + SubTopicEventRouter, +} from '@backstage/plugin-events-node'; + +/** + * Subscribes to the generic `frobs` topic + * and publishes the events under the more concrete sub-topic + * depending on the `$.type` provided in the event payload. + * + * @public + */ +export class FrobsEventRouter extends SubTopicEventRouter { + constructor(options: { events: EventsService }) { + super({ + events: options.events, + topic: 'frobs', + }); + } + + protected getSubscriberId(): string { + return 'FrobsEventRouter'; + } + + protected determineSubTopic(params: EventParams): string | undefined { + if ('type' in (params.eventPayload as object)) { + const payload = params.eventPayload as { type: string }; + return payload.type; + } + + return undefined; + } +} +``` + +## Integrating Events into an Entity Provider + +Your entity provider can subscribe to specific event topics and react to incoming events. This allows for immediate updates to your catalog based on external triggers. + +Here is the basic structure of an EntityProvider that incorporates event subscription. Check out the numbered markings below for a breakdown of each step: + +```ts title="plugins/catalog-backend-module-frobs/src/FrobsProvider.ts" +import { Entity } from '@backstage/catalog-model'; +import { + EntityProvider, + EntityProviderConnection, +} from '@backstage/plugin-catalog-node'; +import { + SchedulerServiceTaskRunner, + UrlReaderService, +} from '@backstage/backend-plugin-api'; +import { EventsService, EventParams } from '@backstage/plugin-events-node'; + +/** + * Provides entities from the fictional Frobs service. + */ +export class FrobsProvider implements EntityProvider { + private readonly env: string; + private readonly reader: UrlReaderService; + private readonly taskRunner: SchedulerServiceTaskRunner; + private readonly events?: EventsService; + private connection?: EntityProviderConnection; + + constructor( + env: string, + reader: UrlReaderService, + taskRunner: SchedulerServiceTaskRunner, + /** [1] */ + events?: EventsService, + ) { + this.env = env; + this.reader = reader; + this.taskRunner = taskRunner; + this.events = events; + } + + getProviderName(): string { + return `frobs-${this.env}`; + } + + async connect(connection: EntityProviderConnection): Promise { + this.connection = connection; + + /** [2] */ + await this.events?.subscribe({ + id: this.getProviderName(), + topics: ['frobs-add', 'frobs-delete', 'frobs-modify'], + /** [3] */ + onEvent: async (params: EventParams) => { + const id = params.eventPayload.id; + const baseUrl = `https://frobs-${id}.example.com/data`; + + const response = await this.reader.readUrl(baseUrl); + const data = JSON.parse((await response.buffer()).toString()); + const entities: Entity[] = frobsToEntities(data); + + if (params.topic === 'frobs-add') { + await this.connection!.applyMutation({ + type: 'delta', + added: entities, + removed: [], + }); + } else if (params.topic === 'frobs-delete') { + await this.connection!.applyMutation({ + type: 'delta', + added: [], + removed: entities, + }); + } else if (params.topic === 'frobs-modify') { + const oldResponse = await this.reader.readUrl( + `${baseUrl}/previous-state`, + ); + const oldData = JSON.parse((await oldResponse.buffer()).toString()); + const oldEntities: Entity[] = frobsToEntities(oldData); + + await this.connection!.applyMutation({ + type: 'delta', + added: entities, + removed: oldEntities, + }); + } + }, + }); + + await this.taskRunner.run({ + id: this.getProviderName(), + fn: async () => { + await this.run(); + }, + }); + } + + async run(): Promise { + if (!this.connection) { + throw new Error('FrobsProvider not initialized'); + } + + const response = await this.reader.readUrl( + `https://frobs-${this.env}.example.com/data`, + ); + const data = JSON.parse((await response.buffer()).toString()); + const entities: Entity[] = frobsToEntities(data); + + await this.connection.applyMutation({ + type: 'full', + entities: entities.map(entity => ({ + entity, + locationKey: `frobs-provider:${this.env}`, + })), + }); + } +} +``` + +Let's break down the key parts of this integration: + +1. **Add EventsService as a Dependency**: In the EntityProvider's constructor, include `EventsService` as an optional dependency. This allows your provider to interact with the event system. + +2. **Subscribe to Topics in connect**: Within the connect function, subscribe to the specific event topics that your plugin needs to react to (e.g., 'frobs-add', 'frobs-delete', 'frobs-modify'). + +3. **Implement the `onEvent` Method**: The `onEvent` method is crucial. It will be invoked whenever your provider receives an event for a subscribed topic. Inside this method: + + - Based on the event payload information (accessible through `params.eventPayload`), implement the logic to decide which entities should be added, deleted, or modified. + - Use a delta mutation to explicitly upsert or delete entities. This approach is more efficient than updating the entire catalog from scratch. For more details on mutations, refer to the ["Provider Mutations" section](https://backstage.io/docs/features/software-catalog/external-integrations#provider-mutations). diff --git a/docs/tutorials/manual-knex-rollback.md b/docs/tutorials/manual-knex-rollback.md index 14e00d6659..442a48e2f5 100644 --- a/docs/tutorials/manual-knex-rollback.md +++ b/docs/tutorials/manual-knex-rollback.md @@ -1,7 +1,6 @@ --- id: manual-knex-rollback title: Manual Rollback using Knex -# prettier-ignore description: Guide on how to rollback Knex migrations. --- @@ -24,7 +23,7 @@ You can interact with Knex running the commands below in the project root: We want to check the migration status: ```sh -$ node_modules/.bin/knex migrate:status --connection "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/backstage_plugin_app" --client pg --migrations-directory node_modules/@backstage/plugin-catalog-backend/migrations/ +$ node_modules/.bin/knex migrate:status --connection "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/backstage_plugin_catalog" --client pg --migrations-directory node_modules/@backstage/plugin-catalog-backend/migrations/ Using environment: production Found 2 Completed Migration file/files. 20211229105307_init.js @@ -35,7 +34,7 @@ No Pending Migration files Found. Now lets rollback a specific migration called `20240113144027_assets-namespace.js`: ```sh -$ node_modules/.bin/knex migrate:down 20240113144027_assets-namespace.js --connection "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/backstage_plugin_app" --client pg --migrations-directory node_modules/@backstage/plugin-catalog-backend/migrations/ +$ node_modules/.bin/knex migrate:down 20240113144027_assets-namespace.js --connection "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/backstage_plugin_catalog" --client pg --migrations-directory node_modules/@backstage/plugin-catalog-backend/migrations/ Using environment: production Batch 2 rolled back the following migrations: 20240113144027_assets-namespace.js @@ -44,7 +43,7 @@ Batch 2 rolled back the following migrations: Now we can check the migration status again to confirm the rollback: ```sh -$ node_modules/.bin/knex migrate:status --connection "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/backstage_plugin_app" --client pg --migrations-directory node_modules/@backstage/plugin-catalog-backend/migrations/ +$ node_modules/.bin/knex migrate:status --connection "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/backstage_plugin_catalog" --client pg --migrations-directory node_modules/@backstage/plugin-catalog-backend/migrations/ Using environment: production Found 1 Completed Migration file/files. 20211229105307_init.js @@ -55,7 +54,7 @@ Found 1 Pending Migration file/files. Now lets use `migrate:currentVersion` which retrieves the current migration version. If there aren't any migrations run yet, it will return "none". ```sh -$ node_modules/.bin/knex migrate:currentVersion --connection "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/backstage_plugin_app" --client pg +$ node_modules/.bin/knex migrate:currentVersion --connection "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/backstage_plugin_catalog" --client pg Using environment: production Current Version: 20240113144027 ``` diff --git a/docs/tutorials/quickstart-app-plugin.md b/docs/tutorials/quickstart-app-plugin.md index e9b670c3ba..e9821f3f70 100644 --- a/docs/tutorials/quickstart-app-plugin.md +++ b/docs/tutorials/quickstart-app-plugin.md @@ -246,7 +246,7 @@ const auth = useApi(githubAuthApiRef); 2. The access token we need to make our GitHub request and the request itself is obtained in an asynchronous manner. -3. Add the useAsync block inside the ExampleFetchComponent +3. Add the `useAsync` block inside the ExampleFetchComponent ```tsx const { value, loading, error } = useAsync(async (): Promise => { diff --git a/docs/tutorials/setup-opentelemetry.md b/docs/tutorials/setup-opentelemetry.md index 23cd71b10f..4803933736 100644 --- a/docs/tutorials/setup-opentelemetry.md +++ b/docs/tutorials/setup-opentelemetry.md @@ -4,9 +4,9 @@ title: Setup OpenTelemetry description: Tutorial to setup OpenTelemetry metrics and traces exporters in Backstage --- -Backstage uses [OpenTelemetery](https://opentelemetry.io/) to instrument its components by reporting traces and metrics. +Backstage uses [OpenTelemetry](https://opentelemetry.io/) to instrument its components by reporting traces and metrics. -This tutorial shows how to setup exporters in your Backstage backend package. For demonstration purposes we will use a Prometheus exporter, but you can adjust your solution to use another one that suits your needs; see for example the article on [OTLP exporters](https://opentelemetry.io/docs/instrumentation/js/exporters/). +This tutorial shows how to setup exporters in your Backstage backend package. For demonstration purposes we will use a Prometheus exporter, but you can adjust your solution to use another one that suits your needs; see for example the article on [OTLP exporters](https://opentelemetry.io/docs/instrumentation/js/exporters/). This tutorial also includes exporting traces using the JSON/HTTP exporter with Jaeger being the ideal target, but this too can be adjusted to fit your needs by seeing the supported tooling in the [OTLP exporters](https://opentelemetry.io/docs/instrumentation/js/exporters/) documentation. ## Install dependencies @@ -19,14 +19,15 @@ The `auto-instrumentations-node` will automatically create spans for code called yarn --cwd packages/backend add \ @opentelemetry/sdk-node \ @opentelemetry/auto-instrumentations-node \ - @opentelemetry/exporter-prometheus + @opentelemetry/exporter-prometheus \ + @opentelemetry/exporter-trace-otlp-http ``` ## Configure In your `packages/backend/src` folder, create an `instrumentation.js` file. -```typescript title="in packages/backend/src/instrumentation.js" +```js title="in packages/backend/src/instrumentation.js" // Prevent from running more than once (due to worker threads) const { isMainThread } = require('node:worker_threads'); @@ -36,12 +37,20 @@ if (isMainThread) { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node'); const { PrometheusExporter } = require('@opentelemetry/exporter-prometheus'); + const { + OTLPTraceExporter, + } = require('@opentelemetry/exporter-trace-otlp-http'); // By default exports the metrics on localhost:9464/metrics - const prometheus = new PrometheusExporter(); + const prometheusExporter = new PrometheusExporter(); + // We post the traces to localhost:4318/v1/traces + const otlpTraceExporter = new OTLPTraceExporter({ + // Default Jaeger URL trace endpoint. + url: 'http://localhost:4318/v1/traces', + }); const sdk = new NodeSDK({ - // You can add a traceExporter field here too - metricReader: prometheus, + metricReader: prometheusExporter, + traceExporter: otlpTraceExporter, instrumentations: [getNodeAutoInstrumentations()], }); @@ -52,6 +61,42 @@ if (isMainThread) { You probably won't need all of the instrumentation inside `getNodeAutoInstrumentations()` so make sure to check the [documentation](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) and tweak it properly. +### Views + +The default histogram buckets for OpenTelemetry are in milliseconds, but the histograms that are created for Catalog processing emit metrics in second. You might want to adjust this to what fits your need. To do this you can use the [Views feature](https://opentelemetry.io/docs/concepts/signals/metrics/#views) like this: + +```js +const prometheus = new PrometheusExporter(); +const sdk = new NodeSDK({ + metricReader: prometheus, + views: [ + new View({ + instrumentName: 'catalog.test', + aggregation: new ExplicitBucketHistogramAggregation([ + 0.01, 0.1, 0.5, 1, 5, 10, 25, 50, 100, 500, 1000, + ]), + }), + ], +}); +``` + +The above will make all the histogram buckets use the same config. If you would like to take a more targeted approach you can do this: + +```js +const prometheus = new PrometheusExporter(); +const sdk = new NodeSDK({ + metricReader: prometheus, + views: [ + new View({ + instrumentName: 'catalog.test', + aggregation: new ExplicitBucketHistogramAggregation([ + 0, 0.01, 0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 30, 60, 120, 300, 1000, + ]), + }), + ], +}); +``` + ## Local Development Setup It's important to setup the NodeSDK and the automatic instrumentation **before** @@ -67,13 +112,35 @@ For local development, you can add the required flag in your `packages/backend/p ... ``` -You can now start your Backstage instance as usual, using `yarn start`. +You can now start your Backstage instance as usual, using `yarn start` and you'll be able to see your metrics at: + +### Troubleshooting + +If you are having issues getting metrics or traces working there are some helpful diagnostic tools from OpenTelemetry you can use that can help. + +First we need to the `@opentelemetry/api` package: + +```bash +yarn --cwd packages/backend add @opentelemetry/api +``` + +Then we want to add the following snippet before the `sdk.start()` call: + +```js +const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api'); + +diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG); +``` + +This will then add OpenTelemetry debug logs that you can then look at to help get a better idea of why something may not be working as expected. + +We don't recommend shipping this in production because of the log density. ## Production Setup In your `.dockerignore`, add this line: -``` +```text !packages/backend/src/instrumentation.js ``` diff --git a/docs/tutorials/switching-sqlite-postgres.md b/docs/tutorials/switching-sqlite-postgres.md index aec9ca2ee9..4fc405c61c 100644 --- a/docs/tutorials/switching-sqlite-postgres.md +++ b/docs/tutorials/switching-sqlite-postgres.md @@ -1,7 +1,6 @@ --- id: switching-sqlite-postgres title: Switching Backstage from SQLite to PostgreSQL -# prettier-ignore description: How to get ready for deploying Backstage to production with PostgreSQL --- diff --git a/docs/tutorials/using-backstage-proxy-within-plugin.md b/docs/tutorials/using-backstage-proxy-within-plugin.md index c82db9ff6c..58e973d891 100644 --- a/docs/tutorials/using-backstage-proxy-within-plugin.md +++ b/docs/tutorials/using-backstage-proxy-within-plugin.md @@ -1,7 +1,6 @@ --- id: using-backstage-proxy-within-plugin title: Using the Backstage Proxy from Within a Plugin -# prettier-ignore description: Guide on how to create a set of API bindings that interface with a backend via the backstage proxy --- diff --git a/lerna.json b/lerna.json deleted file mode 100644 index 4621689664..0000000000 --- a/lerna.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "packages": ["packages/*", "plugins/*"], - "npmClient": "yarn", - "useWorkspaces": true, - "version": "0.0.0" -} diff --git a/microsite/blog/2020-05-22-phase-2-service-catalog.mdx b/microsite/blog/2020-05-22-phase-2-service-catalog.mdx index 81c99c7c07..9e681b9da3 100644 --- a/microsite/blog/2020-05-22-phase-2-service-catalog.mdx +++ b/microsite/blog/2020-05-22-phase-2-service-catalog.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Starting Phase 2: The Service Catalog" +title: 'Starting Phase 2: The Service Catalog' author: Stefan Ålund, Spotify authorURL: http://twitter.com/stalund authorImageURL: https://pbs.twimg.com/profile_images/121166861/6919c047c0d0edaace78c3009b28e917-user-full-200-130.generated_400x400.jpg diff --git a/microsite/blog/2020-09-08-announcing-tech-docs.mdx b/microsite/blog/2020-09-08-announcing-tech-docs.mdx index 40ab40e5f0..9235eeb401 100644 --- a/microsite/blog/2020-09-08-announcing-tech-docs.mdx +++ b/microsite/blog/2020-09-08-announcing-tech-docs.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Announcing TechDocs: Spotify’s docs-like-code plugin for Backstage" +title: 'Announcing TechDocs: Spotify’s docs-like-code plugin for Backstage' author: Gary Niemen, Spotify authorURL: https://github.com/garyniemen --- @@ -118,7 +117,7 @@ Code-like-docs, what? Okay, it’s just my little play on words. This is what I ### Golden Paths -At Spotify, we have the concept of [Golden Paths](https://engineering.atspotify.com/2020/08/17/how-we-use-golden-paths-to-solve-fragmentation-in-our-software-ecosystem/) — one for each engineering discipline. My favourite definition of Golden Path is that it is the “opinionated and supported path”. Each Golden Path has an accompanying Golden Path tutorial that walks you through the opinionated and supported path. +At Spotify, we have the concept of [Golden Paths](https://engineering.atspotify.com/2020/08/how-we-use-golden-paths-to-solve-fragmentation-in-our-software-ecosystem/) — one for each engineering discipline. My favourite definition of Golden Path is that it is the “opinionated and supported path”. Each Golden Path has an accompanying Golden Path tutorial that walks you through the opinionated and supported path. The Golden Path tutorials are Spotify’s most used and important documents and have shown themselves to be the most challenging to manage within a docs-like-code environment. One reason for this is that they are long, divided into many parts, and ownership is typically spread among many different teams. We have had to make use of GitHub codeowners to handle ownership and had to create datasets and data pipelines to be able to attach GitHub Issues to the specific parts or files that a team owns. Another challenge of the Golden Path tutorials is that parts are often dependent on other parts. We are just starting to look into how we can solve these dependency challenges in order to remove friction for engineers writing tutorial documentation. diff --git a/microsite/blog/2020-10-22-cost-insights-plugin.mdx b/microsite/blog/2020-10-22-cost-insights-plugin.mdx index 1ffddd3303..293cd1c927 100644 --- a/microsite/blog/2020-10-22-cost-insights-plugin.mdx +++ b/microsite/blog/2020-10-22-cost-insights-plugin.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "New Cost Insights plugin: The engineer’s solution to taming cloud costs" +title: 'New Cost Insights plugin: The engineer’s solution to taming cloud costs' author: Janisa Anandamohan, Spotify authorURL: https://twitter.com/janisa_a --- diff --git a/microsite/blog/2021-01-12-new-backstage-feature-kubernetes-for-service-owners.mdx b/microsite/blog/2021-01-12-new-backstage-feature-kubernetes-for-service-owners.mdx index c1232a5f12..1303f0dd15 100644 --- a/microsite/blog/2021-01-12-new-backstage-feature-kubernetes-for-service-owners.mdx +++ b/microsite/blog/2021-01-12-new-backstage-feature-kubernetes-for-service-owners.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "New Backstage feature: Kubernetes for Service owners" +title: 'New Backstage feature: Kubernetes for Service owners' author: Matthew Clarke, Spotify authorURL: https://github.com/mclarke47 --- diff --git a/microsite/blog/2021-05-20-adopting-backstage.mdx b/microsite/blog/2021-05-20-adopting-backstage.mdx index 9fc1e36618..6d4204633c 100644 --- a/microsite/blog/2021-05-20-adopting-backstage.mdx +++ b/microsite/blog/2021-05-20-adopting-backstage.mdx @@ -14,7 +14,7 @@ One of the greatest strengths of Backstage also presents a never-ending challeng Before providing recommendations on getting started with Backstage, it’s helpful to have a bit of context as to why Spotify made the design decisions we did. No two companies are identical — and thus, no two Backstage implementations are the same. -Rolling back the clock just a few years, [Spotify was challenged](https://engineering.atspotify.com/2021/05/18/a-product-story-the-lessons-of-backstage-and-spotifys-autonomous-culture/) to continue to scale our engineering team (and the number of features and components built) but retain the speed of product development. Some user research with Spotify developers highlighted a clear problem: there was simply too much non-documented institutional knowledge needed to get things done. No one could find anything and everyone was interrupting everyone else trying to figure things out. +Rolling back the clock just a few years, [Spotify was challenged](https://engineering.atspotify.com/2021/05/a-product-story-the-lessons-of-backstage-and-spotifys-autonomous-culture/) to continue to scale our engineering team (and the number of features and components built) but retain the speed of product development. Some user research with Spotify developers highlighted a clear problem: there was simply too much non-documented institutional knowledge needed to get things done. No one could find anything and everyone was interrupting everyone else trying to figure things out. Spotify’s developers were facing three big challenges on a daily basis: diff --git a/microsite/blog/2021-06-22-spotify-backstage-is-growing.mdx b/microsite/blog/2021-06-22-spotify-backstage-is-growing.mdx index 308effaeab..8c6ee78671 100644 --- a/microsite/blog/2021-06-22-spotify-backstage-is-growing.mdx +++ b/microsite/blog/2021-06-22-spotify-backstage-is-growing.mdx @@ -7,7 +7,7 @@ authorURL: https://www.linkedin.com/in/austinlamon [![The Backstage community is growing! In just over a year, Backstage has gone from a few open source building blocks to a thriving platform used by engineering orgs with thousands of developers. But even with 30+ adopting companies and 400+ contributors, we are still in the very early stages of reaching the platform’s potential.](assets/21-06-22/spotify-backstage-header.gif)](https://backstage.spotify.com/) _[backstage.spotify.com](https://backstage.spotify.com)_ -The Backstage community is growing! In just over [a year](https://engineering.atspotify.com/2021/03/16/happy-birthday-backstage-spotifys-biggest-open-source-project-grows-up-fast/), Backstage has gone from a few open source building blocks to a thriving platform used by engineering orgs with thousands of developers. But even with 30+ [adopting companies](https://github.com/backstage/backstage/blob/master/ADOPTERS.md) and 400+ contributors, we are still in the very early stages of reaching the platform’s potential. +The Backstage community is growing! In just over [a year](https://engineering.atspotify.com/2021/03/happy-birthday-backstage-spotifys-biggest-open-source-project-grows-up-fast/), Backstage has gone from a few open source building blocks to a thriving platform used by engineering orgs with thousands of developers. But even with 30+ [adopting companies](https://github.com/backstage/backstage/blob/master/ADOPTERS.md) and 400+ contributors, we are still in the very early stages of reaching the platform’s potential. In order to grow Backstage further, Spotify is increasing the support we provide both adopters (the people integrating Backstage into their organizations) and contributors (the people building features and improving the code). The more companies that adopt Backstage, the more support the project gets, the stronger the platform becomes for everyone. diff --git a/microsite/blog/2021-06-24-announcing-backstage-search-platform.mdx b/microsite/blog/2021-06-24-announcing-backstage-search-platform.mdx index bb30a3b9ec..8ac14b14d4 100644 --- a/microsite/blog/2021-06-24-announcing-backstage-search-platform.mdx +++ b/microsite/blog/2021-06-24-announcing-backstage-search-platform.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Announcing the Backstage Search platform: a customizable search tool built just for you" +title: 'Announcing the Backstage Search platform: a customizable search tool built just for you' author: Emma Indal, Spotify authorURL: https://www.linkedin.com/in/emma-indal --- diff --git a/microsite/blog/2022-03-17-backstage-1.0.mdx b/microsite/blog/2022-03-17-backstage-1.0.mdx index 6f9dd3ee09..3cade0d79f 100644 --- a/microsite/blog/2022-03-17-backstage-1.0.mdx +++ b/microsite/blog/2022-03-17-backstage-1.0.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "New release: Backstage 1.0" +title: 'New release: Backstage 1.0' author: Francesco Corti, Spotify authorURL: https://github.com/fcorti/ authorImageURL: https://avatars.githubusercontent.com/u/6010860?v=4 diff --git a/microsite/blog/2022-05-13-techdocs-addon-framework.mdx b/microsite/blog/2022-05-13-techdocs-addon-framework.mdx index 7f2a588834..37d746b3c2 100644 --- a/microsite/blog/2022-05-13-techdocs-addon-framework.mdx +++ b/microsite/blog/2022-05-13-techdocs-addon-framework.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Introducing the TechDocs Addon Framework" +title: 'Introducing the TechDocs Addon Framework' author: Gary Niemen, Spotify authorURL: https://github.com/garyniemen/ authorImageURL: https://avatars.githubusercontent.com/u/65337273?v=4 diff --git a/microsite/blog/2022-07-19-releasing-backstage-search-1.0.mdx b/microsite/blog/2022-07-19-releasing-backstage-search-1.0.mdx index 1936dd4fc3..9ff3539b0d 100644 --- a/microsite/blog/2022-07-19-releasing-backstage-search-1.0.mdx +++ b/microsite/blog/2022-07-19-releasing-backstage-search-1.0.mdx @@ -1,5 +1,4 @@ --- -# prettier-ignore title: Releasing Backstage Search 1.0 author: Emma Indal, Spotify authorURL: https://www.linkedin.com/in/emma-indal diff --git a/microsite/blog/2022-08-23-backstage-security-audit.mdx b/microsite/blog/2022-08-23-backstage-security-audit.mdx index 6b9f2f6463..9c6de6eeeb 100644 --- a/microsite/blog/2022-08-23-backstage-security-audit.mdx +++ b/microsite/blog/2022-08-23-backstage-security-audit.mdx @@ -1,5 +1,4 @@ --- -# prettier-ignore title: Backstage Security Audit & Updates author: Patrik Oldsberg, Spotify authorURL: https://github.com/Rugvip diff --git a/microsite/blog/2022-09-08-fyi-plugin-analytics-api.mdx b/microsite/blog/2022-09-08-fyi-plugin-analytics-api.mdx index aff30752ec..b07dfffc06 100644 --- a/microsite/blog/2022-09-08-fyi-plugin-analytics-api.mdx +++ b/microsite/blog/2022-09-08-fyi-plugin-analytics-api.mdx @@ -1,5 +1,4 @@ --- -# prettier-ignore title: FYI 📣 The Plugin Analytics API author: Eric Peterson, Spotify authorURL: https://github.com/iamEAP diff --git a/microsite/blog/2023-07-08-stash-adopter-post.mdx b/microsite/blog/2023-07-08-stash-adopter-post.mdx index 6c1edea764..c5fe9e03b4 100644 --- a/microsite/blog/2023-07-08-stash-adopter-post.mdx +++ b/microsite/blog/2023-07-08-stash-adopter-post.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Adopter Spotlight: How Stash simplified monitoring, ownership and true app health with microservices" +title: 'Adopter Spotlight: How Stash simplified monitoring, ownership and true app health with microservices' author: Taylor Webber, Staff Engineer, Stash --- diff --git a/microsite/blog/2023-07-28-frontside-adopter-post.mdx b/microsite/blog/2023-07-28-frontside-adopter-post.mdx index c6f3cba403..5ea73fb089 100644 --- a/microsite/blog/2023-07-28-frontside-adopter-post.mdx +++ b/microsite/blog/2023-07-28-frontside-adopter-post.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Five common traits of successful Backstage adopters" +title: 'Five common traits of successful Backstage adopters' author: Taras Mankovski, CXO, Frontside --- diff --git a/microsite/blog/2023-08-17-expedia-proof-of-value-metrics-2.mdx b/microsite/blog/2023-08-17-expedia-proof-of-value-metrics-2.mdx index 9c6e67fcf1..f7f6ddfe77 100644 --- a/microsite/blog/2023-08-17-expedia-proof-of-value-metrics-2.mdx +++ b/microsite/blog/2023-08-17-expedia-proof-of-value-metrics-2.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Expedia Group shares Backstage proof of value metrics 2.0" +title: 'Expedia Group shares Backstage proof of value metrics 2.0' author: Guillermo Manzo, Expedia Group authorURL: https://www.linkedin.com/in/guillermomanzo --- diff --git a/microsite/blog/2023-09-29-chicago-traiding-company-adopter-spotlight.mdx b/microsite/blog/2023-09-29-chicago-traiding-company-adopter-spotlight.mdx index 8b4f332d54..bd479a6a86 100644 --- a/microsite/blog/2023-09-29-chicago-traiding-company-adopter-spotlight.mdx +++ b/microsite/blog/2023-09-29-chicago-traiding-company-adopter-spotlight.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Adopter Spotlight: How Chicago Trading Company saved 18 months of developer effort with Backstage" +title: 'Adopter Spotlight: How Chicago Trading Company saved 18 months of developer effort with Backstage' author: Tiffany Cox, Spotify --- diff --git a/microsite/blog/2023-11-15-backstagecon-kubecon-23.mdx b/microsite/blog/2023-11-15-backstagecon-kubecon-23.mdx index 7b7f7c0f0b..cdb2d9e582 100644 --- a/microsite/blog/2023-11-15-backstagecon-kubecon-23.mdx +++ b/microsite/blog/2023-11-15-backstagecon-kubecon-23.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Wrap up: BackstageCon ‘23, KubeCon + Cloud Native NA" +title: 'Wrap up: BackstageCon ‘23, KubeCon + Cloud Native NA' author: Jorge Lainfiesta, Spotify authorURL: https://www.linkedin.com/in/jrlainfiesta/ authorImageURL: https://avatars.githubusercontent.com/u/4451393?v=4 diff --git a/microsite/blog/2024-03-27-backstagecon-kubecon-24.mdx b/microsite/blog/2024-03-27-backstagecon-kubecon-24.mdx index 2164a8732e..6dd8691d82 100644 --- a/microsite/blog/2024-03-27-backstagecon-kubecon-24.mdx +++ b/microsite/blog/2024-03-27-backstagecon-kubecon-24.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Backstage in Paris: Wrapping up BackstageCon and KubeCon + CloudNativeCon Europe 2024" +title: 'Backstage in Paris: Wrapping up BackstageCon and KubeCon + CloudNativeCon Europe 2024' author: André Wanlin, Spotify authorURL: https://github.com/awanlin authorImageURL: https://avatars.githubusercontent.com/u/67169551?v=4 diff --git a/microsite/blog/2024-04-19-community-plugins.mdx b/microsite/blog/2024-04-19-community-plugins.mdx index 49d1765bce..801a2f7437 100644 --- a/microsite/blog/2024-04-19-community-plugins.mdx +++ b/microsite/blog/2024-04-19-community-plugins.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Introducing the Backstage Community Plugins Repository" +title: 'Introducing the Backstage Community Plugins Repository' author: Ben Lambert, Spotify authorURL: https://github.com/benjdlambert authorImageURL: https://avatars.githubusercontent.com/u/3645856?v=4 diff --git a/microsite/blog/2024-06-27-backstage-engineer-journey.mdx b/microsite/blog/2024-06-27-backstage-engineer-journey.mdx index b9bfc20e4e..9180a4b6d7 100644 --- a/microsite/blog/2024-06-27-backstage-engineer-journey.mdx +++ b/microsite/blog/2024-06-27-backstage-engineer-journey.mdx @@ -1,12 +1,11 @@ --- -# prettier-ignore -title: "1,186 days with Backstage: A journey through the eyes of a developer" +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. +**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/?c=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) diff --git a/microsite/blog/2024-12-09-kubecon-slc-24.mdx b/microsite/blog/2024-12-09-kubecon-slc-24.mdx index c3fa2f70a8..c77d82d1aa 100644 --- a/microsite/blog/2024-12-09-kubecon-slc-24.mdx +++ b/microsite/blog/2024-12-09-kubecon-slc-24.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Backstage in Salt Lake City: Highlights from BackstageCon and KubeCon + CloudNativeCon North America 2024" +title: 'Backstage in Salt Lake City: Highlights from BackstageCon and KubeCon + CloudNativeCon North America 2024' author: André Wanlin, Spotify & Camila Loiola, Spotify --- diff --git a/microsite/blog/2024-12-17-backstage-security-audit-2024.mdx b/microsite/blog/2024-12-17-backstage-security-audit-2024.mdx index f9a1afef9e..5d4294b6c6 100644 --- a/microsite/blog/2024-12-17-backstage-security-audit-2024.mdx +++ b/microsite/blog/2024-12-17-backstage-security-audit-2024.mdx @@ -1,5 +1,4 @@ --- -# prettier-ignore title: The 2024 Backstage Security Audit author: Patrik Oldsberg, Spotify authorURL: https://github.com/Rugvip diff --git a/microsite/blog/2024-12-18-backstage-wrapped-2024.mdx b/microsite/blog/2024-12-18-backstage-wrapped-2024.mdx index a136d644b5..f0e4eb8a05 100644 --- a/microsite/blog/2024-12-18-backstage-wrapped-2024.mdx +++ b/microsite/blog/2024-12-18-backstage-wrapped-2024.mdx @@ -1,5 +1,4 @@ --- -# prettier-ignore title: "Backstage Wrapped 2024: The year's Top 5 milestones and highlights" author: Patrik Oldsberg, Spotify & Ben Lambert, Spotify --- diff --git a/microsite/blog/2025-04-29-backstagecon-kubecon-25-london.mdx b/microsite/blog/2025-04-29-backstagecon-kubecon-25-london.mdx index 99da880900..3eca9563a9 100644 --- a/microsite/blog/2025-04-29-backstagecon-kubecon-25-london.mdx +++ b/microsite/blog/2025-04-29-backstagecon-kubecon-25-london.mdx @@ -1,6 +1,5 @@ --- -# prettier-ignore -title: "Backstage in London: Highlights from BackstageCon and KubeCon + CloudNativeCon Europe 2025" +title: 'Backstage in London: Highlights from BackstageCon and KubeCon + CloudNativeCon Europe 2025' author: André Wanlin, Spotify authorURL: https://github.com/awanlin authorImageURL: https://avatars.githubusercontent.com/u/67169551?v=4 diff --git a/microsite/blog/2025-05-12-from-zero-to-maintainer-my-opensource-journey-with-backstage.mdx b/microsite/blog/2025-05-12-from-zero-to-maintainer-my-opensource-journey-with-backstage.mdx new file mode 100644 index 0000000000..96a4a8e140 --- /dev/null +++ b/microsite/blog/2025-05-12-from-zero-to-maintainer-my-opensource-journey-with-backstage.mdx @@ -0,0 +1,63 @@ +--- +title: 'From Zero to Maintainer: My Open Source Journey with Backstage' +author: Kashish Mittal, Red Hat +authorURL: https://github.com/04kash +authorImageURL: https://avatars.githubusercontent.com/u/113269381?v=4 +--- + +My path to becoming a maintainer in the Backstage project wasn’t paved with years of prior open source experience. As a student interning at Red Hat, I started with a relatively fresh perspective. This is the story of that journey – how I navigated the complexities of Backstage, with the support of its community, allowing me to grow and learn, and how open source can empower anyone to do the same. Whether you’re new to open source or a seasoned developer, I believe you’ll find something valuable here. For those just starting out, I hope this inspires you to take that first step. And for experienced developers, I hope this offers a fresh perspective – a look at how a new contributor navigates a complex project, and perhaps, a reminder of our own beginnings. +This journey wasn’t made in a single leap, but through a series of progressive stages. I’ll walk you through these stages, highlighting the key learnings and contributions along the way. + +![The Stages of my Journey](assets/2025-05-12/stages.png) +{/* truncate */} + +## Stage 1: Laying the foundation + +![Getting Familiar with the Backstage Tech Stack](assets/2025-05-12/tech_stack.png) + +When I first encountered Backstage, I wasn’t deeply familiar with the tech stack it relied on — Node.js, TypeScript, and React. My only exposure previously had been through hackathons, where the focus is speed over deep understanding. Another major hurdle was Git. Up until that point, I had mainly used GitHub Desktop, rarely venturing into the command line or advanced Git concepts. Realizing that effective contribution required a deeper understanding, I dedicated a week to intensively reviewing these core technologies. + +But that wasn’t all. I wanted to see Backstage in action, to really grasp what it was all about. That’s when I came across the [Spotify Learning Path for Backstage](https://backstage.spotify.com/learn/). Specifically, the [“Standing up Backstage”](https://backstage.spotify.com/learn/standing-up-backstage/) section was incredibly useful. It walked me through setting up a local running instance with a Postgres database and GitHub authentication. From there, I explored the Backstage documentation and experimented with adding features to my local instance. Honestly, for me, this stage was all about building confidence. It was about facing my knowledge gaps head-on and taking the time to learn. + +## Stage 2: First contributions + +![First contributions to Backstage: learning the process and connecting with the community](assets/2025-05-12/first_contributions.png) + +With my foundational skills in place, it was time to take the leap and make my first contributions to Backstage. [My first pull request](https://github.com/backstage/community-plugins/pull/497) (PR) was quite simple — fixing broken links in the documentation. This seemingly minor fix was my first step, and it paved the way for more substantial contributions. It helped me to get comfortable with the contributing process, learn how to submit a PR, and understand the review workflow. After that, I started looking for open issues in the [community-plugins repository](https://github.com/backstage/community-plugins). I found an issue about [linking npm releases of plugins to specific Git commits](https://github.com/backstage/community-plugins/issues/489) — a task that pushed me outside my comfort zone once again. At the time, I knew very little about GitHub Actions and workflows. Learning on the fly, I relied heavily on guidance from maintainers who were incredibly welcoming. +This experience was really helpful, not just for the task itself, but also because it introduced me to key community resources like the [Backstage Discord](https://discord.com/invite/backstage-687207715902193673) and [Special Interest Groups](https://github.com/backstage/community/tree/main/sigs) (or SIGs for short). While the content of the pull requests in this stage was certainly useful, the real value came from learning the project’s workflows and community processes. + +## Stage 3: Making substantial contributions + +As my confidence grew, so did the complexity of the contributions that I took on. Two of my first feature-related contributions were related to Catalog Permissions and the LDAP Processor. +First, with Catalog Permissions, I noticed that two endpoints in the Catalog plugin, `/analyze-location` and `/validate-entity` weren’t restricted by permissions, posing a security risk. To address this, I needed a deep understanding of Backstage’s permissions system. I spent a lot of time reading through documentation and existing code, and asking questions on Discord. When I had [a PR](https://github.com/backstage/backstage/pull/25924) ready, I went to the Framework SIG meetings to discuss my implementation and to make sure that I was on the same page as the maintainers. Following this process, my PR was successfully merged! +Shortly after, I tackled an open issue with the [LDAP processor](https://github.com/backstage/backstage/issues/26225). This issue highlighted a problem where Backstage couldn’t correctly map user-group relationships with certain LDAP server configurations that used attribute names that were different from the ones hardcoded within the plugin. I implemented [a solution](https://github.com/backstage/backstage/pull/26511) that allowed users to override these default values. Testing against a real LDAP instance wasn’t something I could do locally, but the original issue reporter stepped in, validating my changes in their environment. It was a beautiful example of open source collaboration in action. + +![My first commits in the backstage CHANGELOG](assets/2025-05-12/changelog.png) +_My first commits in the backstage CHANGELOG_ + +These two tasks were a significant step up from my initial contributions. They required a deeper understanding of Backstage’s architecture and a greater level of problem-solving. Seeing my commits in the [CHANGELOG](https://backstage.io/docs/releases/v1.31.0/#new-catalog-permissions) was an accomplishment I was proud of, and it solidified my confidence so I could take on even more substantial roles within the Backstage community. + +## Stage 4: Becoming an active community member + +![Engaging with the Open Source Community at the CNCF meetup in Toronto](assets/2025-05-12/cncf_1.jpeg) +_(Source: https://www.linkedin.com/posts/mwijay_you-totally-missed-last-nights-first-cncf-ugcPost-7311005210628235264-8BES)_ + +![Engaging with the Open Source Community at the CNCF meetup in Toronto](assets/2025-05-12/cncf_2.png) +_Engaging with the Open Source Community at the CNCF meetup in Toronto (Source: https://community.cncf.io/events/details/cncf-cloud-native-toronto-presents-cncf-2025-kickoff-at-shopify/)_ + +One of the ways I got more involved was by helping with the maintenance of the [community-plugins repository](https://github.com/backstage/community-plugins). For instance, I helped address a security vulnerability — specifically, that the `@backstage/backend-common package` relied on a vulnerable version of `jsonpath-plus` through `@kubernetes/client-node`. I proactively removed this vulnerable dependency from eight plugins, effectively safeguarding those plugins from potential risks. I also focused on improving dependency management by implementing Knip reports. These reports help us identify and remove unused dependencies, keeping the repository clean and efficient. + +Beyond repository maintenance, I also began focusing on community engagement. I began reviewing pull requests regularly, helping maintain code quality and lightening the load on other maintainers. This not only deepened my understanding of the codebase but also exposed me to new features and patterns across the ecosystem. I actively participated in SIG meetings and offered guidance to fellow contributors on Discord. + +This marked a turning point in my journey, as I transitioned from a contributor to an active community member. Eventually, this growing involvement led to me becoming a maintainer for the community-plugins repository. It was a fulfilling step forward, and it felt rewarding to be trusted with more responsibility in guiding the project. + +## What’s next: future steps as a maintainer + +![Presenting "From Zero to Contributor: My Open Source Journey with Backstage" at the CNCF 2025 Kickoff event at Shopify, Toronto](assets/2025-05-12/cncf_3.jpeg) +_Presenting "From Zero to Contributor: My Open Source Journey with Backstage" at the CNCF 2025 Kickoff event at Shopify, Toronto (Source: https://www.linkedin.com/posts/mwijay_you-totally-missed-last-nights-first-cncf-ugcPost-7311005210628235264-8BES)_ + +As a maintainer, my focus is on supporting others in their open source journey and improving the overall contributor experience. I actively review PRs, guide new contributors through constructive reviews, and point them to good first issues to help them get started. +Furthermore, I aim to actively contribute to the community-plugins SIG meetings, offering suggestions and participating in discussions to help guide the project’s direction. +Ultimately, my goal is to help the community-plugins repository thrive and become an even more valuable resource for the Backstage community. I’m excited to collaborate with fellow maintainers and contributors to achieve this vision. + +My journey with Backstage has been incredibly rewarding, and I’m grateful for the opportunities, support, and growth the community has given me. I’m excited to continue contributing and to see where this journey takes me next. diff --git a/microsite/blog/2025-08-08-migrating-legacy-services-to-a-modern-developer-portal.mdx b/microsite/blog/2025-08-08-migrating-legacy-services-to-a-modern-developer-portal.mdx new file mode 100644 index 0000000000..268fd4933b --- /dev/null +++ b/microsite/blog/2025-08-08-migrating-legacy-services-to-a-modern-developer-portal.mdx @@ -0,0 +1,185 @@ +--- +title: 'Migrating legacy services to a modern developer portal: A technical guide to Backstage integration' +author: Damola Obaleke +authorURL: https://github.com/damolaobaleke +authorImageURL: https://avatars.githubusercontent.com/u/45045727?v=4 +--- + +**TL;DR:** As part of our efforts to streamline service management and improve developer experience, our engineering org migrated from a legacy service catalogue to the Backstage Software Catalog. In this post, I'll share what we learned from that journey --- including how to build an automated script to migrate services from an existing internal service catalogue to a modern internal developer portal (IDP) like Backstage. I'll also outline strategies to help drive adoption across your organization, along with tips for addressing both the cultural and technical roadblocks you might encounter along the way. + +![migration flowchart](assets/2025-08-08/image01.png) +{/* truncate */} + +## Why and How a Modern Developer Portal Was Rolled Out + +Historically, many organizations utilized internally built software tools for managing their service inventories. While these tools served their purpose, there's a growing need for more robust service +catalogues that require less maintenance and reduce over-engineered tooling. Frameworks like Backstage have emerged as powerful solutions. + +The decision is often made to establish a single source of truth for services and engineering teams. The vision is typically for reliability or platform teams to envision a world where every software development +team, regardless of size or domain, can efficiently manage projects, access tools and resources, and foster a collaborative culture. A modern developer portal aims to become the go-to platform for developers, infrastructure teams, and product managers to collaborate, accelerate development cycles, and deliver high-quality software. It serves as a centralized hub, consolidating all necessary information, tools, and services that developers require throughout the software development lifecycle. + +## Internal Services Landscape + +![internal services](assets/2025-08-08/image02.png) + +In large organizations, it's common to manage thousands of GitHub repositories, encompassing a wide array of assets such as front end web applications, backend web services, mobile applications, and APIs. For instance, a typical enterprise might have: + +- Hundreds or thousands of APIs +- Hundreds or thousands Services +- Dozens of Web applications +- Various libraries, infrastructure components, etc. + +Migrating these internal services from various engineering teams requires a systematic approach to retrieve the existing service definitions and transform them into a format compatible with the new +developer portal. This often involves automated scripts to ensure efficient ingestion. For example, successfully migrating hundreds of services into a new portal is a common achievement in such initiatives. + +## GitHub Requests Architecture for Migration + +**Using an Entity Provider and a Scripted Migration** + +In our Backstage setup, we took a hybrid approach: we used an automated script to generate and submit `catalog-info.yaml` files to service repositories, and relied on the GitHub Entity Provider defined in our +`app-config.yaml` to ingest them into the catalog. This gave us the best of both worlds. + +The script handled the heavy lifting of migrating metadata from for example legacy `(.appcatalog.yaml)` files, transforming them into the modern format expected by Backstage. It also empowered teams by +submitting pull requests they could review and enrich adding ownership metadata, documentation links, or system context before merging. Once merged, the GitHub Entity Provider took over, ingesting the files on a +scheduled basis and ensuring Backstage stayed up to date. This pattern reduced manual overhead, maintained decentralization, and eliminated the need for a persistent integration with the legacy system. Since the old catalog was being decommissioned, this also aligned with our goal of moving forward cleanly without syncing two sources of truth. + +![api orchestration](assets/2025-08-08/image03.png) + +Several technical steps are typically involved in retrieving existing service definition files `(e.g., appcatalog.yaml)`, an example yaml file, and then converting them into the modern developer portal\'s preferred +format `(e.g.catalog-info.yaml` for Backstage). Rather than manually creating new definition files, an automated Python script can be developed to generate and add them to the respective repositories or services. Without creating and using these automated scripts, doing these tasks manually can take several hours and could become extremely tedious. For example, in the case of Backstage, it would mean having to explicitly create the `catalog-info.yaml` hundreds of times in hundreds of repositories which can also result in hundreds of errors and manual lift. + +**Requirement One: GitHub Apps** + +A dedicated GitHub App can be utilized to extend functionality, granting the necessary permissions to submit pull requests across multiple repositories. GitHub Apps are integrations that extend GitHub's functionality and can automate tasks, interacting with and extending GitHub's features. + +A private key `(.pem)` is retrieved for the GitHub App, and a JSON Web Token (JWT) is created. These two keys are combined to generate an Authentication Token, which is an encoded JSON Web Token. + +**Requirement Two: An Access Token and Bearer Token** + +The Authentication Token (encoded JWT) is used to make a `GET` request to the GitHub API endpoint `/app/installations` at `api.github.com.` This request retrieves an access token URL. Once that access token URL is received, another request is made to this URL to obtain the Bearer token. This Bearer token is then used for major requests to GitHub API endpoints, such as `https://api.github.com/repos/{owner}/{repo}/contents/{path}.` + +**Base64 and YAML Processing** + +With the Bearer token, a request can be made to retrieve the contents of GitHub repositories containing the legacy service definition files `(e.g. .appcatalog.yaml)`. GitHub typically returns these contents in +Base64 format, a binary-to-text encoding scheme that converts binary data into an ASCII string, often used for secure data transmission over HTTP. + +Upon receiving the encoded Base64 content, it must be decoded to YAML. The decoded YAML is then compared to the desired key-value pairings for the new catalog-info.yaml file. This is where a custom Mapper comes into +play. A template for catalog-info.yaml is created following the developer portal\'s guidelines. The key-value pairs from this template are then mapped to the values received from the legacy service +definition file. For example: + +```python +results['metadata']['title'] = data['appInfo']['appName'] +# In the new format: metadata.title +# From the legacy file: appInfo.appName +``` + +After the comparisons and correct mapping for the new format, the data is dumped into the `catalog-info.yaml` file and finally encoded back to Base64 for submission to the GitHub repository. + +An example excerpt code of encoding YAML file to base64 + +```python +def encode_to_base64(file): + catalog_info_data = load_yaml(file) + print(catalog_info_data) #json + catalog_yaml = yaml.dump_all(catalog_info_data) #yaml + print('\n') + print(catalog_yaml) + + logger({'data': catalog_yaml,'method':'encode_to_base64','level': 'debug'}) + + #yaml k:v (dict) to string + dict_to_string = str(catalog_yaml) + encoded = base64.b64encode(bytes(dict_to_string, 'utf-8')) # bytes + print("\n") + #decode to convert into to explicit string and remove b prefix in encoded + enc_dec = encoded.decode('utf-8') + print(enc_dec) + return enc_dec +``` + +**Submitting Changes to the GitHub Repository** +Submitting the file back to the GitHub repository involves a few more steps. A `GET` request is made to the Git branches endpoint, `/repos/{owner}/{repo}/branches/{branch}`, to check if a new branch `(e.g. +update/developer-portal-opt-in)` already exists. + +If the branch does not exist, it is created from the main or master branch, depending on which one is present in the repository, using `refs/heads/{branch_name}\'.format(\*\*locals()).` Finally, the pull +request with the encoded Base64 YAML is submitted to the branch using the GitHub endpoint `/repos/{owner}/{repo}/pulls.` + +## Adoption and Impact + +![adoption challenges](assets/2025-08-08/image04.png) + +Initially, the adoption of a new developer portal can face challenges +for several reasons: + +- Engineering teams may be hesitant to merge unfamiliar pull requests into their repositories or services. +- Some teams or engineers might lack a robust understanding of the new portal's purpose or value. +- The new tooling might not be a strictly defined, top-down mandated requirement from leadership. +- Access requests might still be required, even for a centralized portal. +- Customer adoption can be slow, sometimes requiring individual demonstrations even after widespread presentations. +- Some individuals might understand what the portal is but not its full capabilities or limitations. + +**Gaining Traction and Growth** + +Despite initial hurdles, a new developer portal can gain immense traction and adoption after numerous pitches to various teams. A key factor in widespread adoption often includes contributions from various engineering teams beyond the initial implementation group. + +The transformation can primarily be driven by a concerted effort to understand team needs, strategically "sell" the platform's value, and address early friction points. The key to this success lies in demonstrating tangible benefits and integrating features that directly solved developer pain points. + +#### Understanding Team Needs + +During the discovery and initial implementation phases, it became clear what capabilities teams truly desired from a developer portal: + +- **Visibility into Ownership and Relationships:** Teams were highly interested in features like a **dependency graph** or **organizational chart**. They wanted clear visibility into service ownership and relationships between different services, enabling them to quickly identify whom to contact for specific issues or collaborations. +- **Service Discoverability:** Once they grasped the concept and value of having their services represented in a central catalogue, teams actively sought to have their services migrated or ingested using the scaffolder. Their motivation was clear: they wanted other engineers to easily find and understand their services within the portal. + +## Strategies for Selling the Idea + +A combined approach was crucial to effectively "sell" the developer portal idea to various teams: + +1. **Clear Roadmap:** Presenting a comprehensive roadmap that outlined the portal's current state and its future potential helped teams envision its long-term value. +2. **Engaging Presentations and RFCs:** Conducting engineering presentations to numerous teams and sharing Requests for Comments (RFCs) allowed for broader review, gathered valuable insights, and fostered a sense of community involvement. +3. **Highlighting Discoverability:** Emphasizing that their services would be easily discoverable by other teams and that the portal would serve as a single source of truth for all component information related to their services was a powerful selling point. +4. **Personalized Demos:** Conducting 1:1 Slack huddles with individual engineers to demo the platform provided a personalized experience and allowed for direct addressing of questions. +5. **Visual Aids:** Utilizing diagrams of various components and illustrating their benefits helped simplify complex concepts and showcase the portal's advantages. +6. **Addressing Codebase Concerns:** When submitting the automated pull requests with the migration script, it was crucial to explain to teams that these changes would not result in any loss of functionality, nor would they have any adverse effects or modifications to their existing codebase. + +### Addressing Early Friction + +Despite these efforts, initial friction was inevitable: + +1. **Pushback on Automated PRs:** There was initial pushback regarding the automated pull requests submitted to their repositories. +2. **Reluctance to Merge:** Engineering teams were hesitant to merge a "random" PR into their repositories, especially without a full understanding of its purpose. +3. **Lack of Understanding:** Some teams simply didn\'t have a robust understanding of what the portal was or its value, leading them to either not merge the `catalog-info.yaml` PR or, in some cases, + even delete it. + +Through persistent engagement, clear communication, and demonstrating tangible value, these initial resistances can be gradually overcome. The strategic addition of features and the active involvement of other +engineering teams, particularly those focused on reliability platforms and SRE, proved instrumental in demonstrating the platform's utility and appeal. + +## Feature Additions Driving Adoption + +![plugin ecosystem](assets/2025-08-08/image06.png) + +The addition of components like a [Tech Radar](https://www.thoughtworks.com/en-us/radar) can significantly increase engineer interest. A Tech Radar is typically implemented to help engineers and cross-functional teams understand the "paved road" technology stack, what should be used for new systems andwhat existing systems should aspire to move towards. Thoughtworks created this system and can be seen here: +[https://www.thoughtworks.com/en-us/radar](https://www.thoughtworks.com/en-us/radar) + +Some other [plugins](https://backstage.io/plugins/) that +can increase widespread adoption of a developer portal: + +1. Q/A Plugin +2. Groups or teams plugins +3. Kubernetes plugin +4. Managing External services + +A critical component that contributes to widespread adoption is the **linter plugin**. For developers migrating services to the new developer portal, ensuring the `catalog-info.yaml.` file is correct and accurate is paramount. The linter plugin, often integrated with an external API, provides an invaluable and accurate way to validate these files, making the process of creating and maintaining them much easier and less error-prone for developers. One of the most accurate ways to implement the linter plugin is making a request to [Entity validator](https://github.com/RoadieHQ/backstage-entity-validator) to make sure it is correct. + +Complementing this, a **Scaffolder** feature also plays a vital role. The Scaffolder allows developers to generate new service or component `catalog-info.yaml` files (and often entire project structures) from +pre-defined templates. This capability effectively eliminates the need for developers to manually create these files from scratch or worry about linting them, as the generated output is inherently compliant with the portal's schema. + +Ultimately, such efforts can successfully ingest hundreds of services, leading to a significant number of components residing within the new developer portal. + +## Conclusion + +The migration of legacy internal services to a modern developer portal like Backstage represents a significant leap forward in standardizing and streamlining developer experiences. By transitioning from an internally maintained "App Catalogue" to a centralized, community-driven "Developer Portal," organizations can lay the groundwork for enhanced collaboration, improved resource accessibility, and accelerated development cycles. Despite initial adoption challenges, the strategic implementation of features like the Tech Radar and the linter plugin, coupled with persistent outreach and contributions from various engineering teams, proves instrumental in demonstrating the inherent value of such a platform. The successful ingestion of hundreds of services stands as a testament to the effectiveness of automated migration scripts and the dedication of the teams involved. This endeavor not only provides a robust and less over-engineered service catalogue but also fosters a culture of shared ownership and continuous improvement within the engineering organization. + +## What's Next + +My involvement as a software engineer with open source tools and developer portal projects like Backstage, including implementation and service migration, has provided me valuable opportunities to contribute to their open-source documentation and repositories. This can be seen in contributions such as [Update app-custom-theme.md](https://github.com/backstage/backstage/pull/12863) and [Update getting-started.md](https://github.com/backstage/backstage/pull/12714), which deepen understanding of custom themes and style components. I’m now looking at future efforts focusing on contributing more to the open-source project (e.g., Model context protocol with A.I (MCP) at [RFC: Distributed Actions with MCP in Backstage](https://github.com/backstage/backstage/issues/30218)) and continuing to improve and scale this critical developer portal for engineers across the world. diff --git a/microsite/blog/2025-10-15-backstage-contribfest-kubecon-guide.mdx b/microsite/blog/2025-10-15-backstage-contribfest-kubecon-guide.mdx new file mode 100644 index 0000000000..6ec142cc7c --- /dev/null +++ b/microsite/blog/2025-10-15-backstage-contribfest-kubecon-guide.mdx @@ -0,0 +1,74 @@ +--- +title: 'Get ready for Backstage ContribFest at KubeCon!' +author: André Wanlin, Spotify +authorURL: https://github.com/awanlin +authorImageURL: https://avatars.githubusercontent.com/u/67169551?v=4 +--- + +![Get ready for Backstage ContribFest at KubeCon!](assets/2025-10-15/backstage-contribfest-kubecon-guide-header.png) + +Pack your laptop and mark your calendars! Backstage will once again be taking part in the ContribFest track at KubeCon! Join us at KubeCon 2025 North America in Atlanta on Monday, November 13. Feel free to [bookmark it on your schedule](https://kccncna2025.sched.com/event/27Nl6/contribfest-level-up-your-open-source-journey-hands-on-backstage-contributions-andre-wanlin-patrik-oldsberg-emma-indal-spotify-aramis-sennyey-doordash-kurt-king-procore). Then read on to get yourself prepared for the session beforehand to maximize your time working with other contributors and Backstage experts during the session. + +{/* truncate */} + +## Contrib-what? + +Before we dive into preparation for the Backstage ContribFest session we should probably take a detour and answer the question: What the heck is ContribFest? + +ContribFest is a track at KubeCon where various CNCF projects will host hands-on sessions working with their respective communities on contributions towards their projects. You don't have to be a past contributor to participate — new community members are encouraged to join! + +These sessions are 75 minutes long and take place in a room with roughly a dozen circular tables that seat about eight people making it easy to work and collaborate. They usually lead off with some getting started steps and then give attendees the rest of the time to work on their contributions with the aid of experts from the project. + +## What to prepare before you get there + +For the Backstage ContribFest session, there are some preparation steps you can complete on your own well before the session. Let's cover those now: + +### 1. Fork the repos + +You'll have the option to contribute to the Backstage repo or the Backstage Community Plugins repo. To get those onto your system, you need to follow the GitHub ["Forking a repository"](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo#forking-a-repository) guide and fork these: + +- Backstage: [https://github.com/backstage/backstage](https://github.com/backstage/backstage) +- Backstage Community Plugins: [https://github.com/backstage/community-plugins](https://github.com/backstage/community-plugins) + +### 2. Update Node.js and Yarn + +Backstage has [a few prerequisites](https://backstage.io/docs/getting-started/#prerequisites) that you'll need to have in place before you can run Backstage or the various Backstage Community Plugins. Here's what you need: + +- Backstage uses Node.js — you'll want to install version 22 for the session. + - To make this easier, we recommend you use Node Version Manager nvm, you can [follow these instructions to install it](https://github.com/nvm-sh/nvm#install--update-script). + - Once you have nvm installed, you can run this command to get Node 22 installed and activated: `nvm install 22` +- Yarn is the package manager used by Backstage — you'll want to install it as well. + + - Simply run `corepack enable` to do so. + +### 3. Test your setups + +Now let's do a quick test to confirm that everything is working. + +First, let's check that you can run the Backstage codebase: + +1. Navigate to your cloned fork of the Backstage repo +2. From the root, run `yarn install` +3. Then run `yarn tsc` +4. Finally run `yarn start` +5. Backstage will open in a new browser window or tab + +Now, let's check the Backstage Community Plugins: + +1. Navigate to your your cloned fork of the Backstage Community Plugins repo +2. This repo is structured in a way where there are many plugins that live in their own dedicated workspace — for this test, we'll use the `linguist` workspace. From the root, run `cd workspaces/linguist` +3. From here run `yarn install` +4. Then run `yarn tsc` +5. Finally run `yarn start` +6. An example Backstage app will open in a new browser window or tab + +### Bonus: Check out the contribution guides + +At this point, you have all the prerequisites in place and are ready to take part in the Backstage ContribFest session. From here, we recommend you take some time to read the contributions guides as that will get you more familiar with the overall process. Here they are: + +- [Backstage Contribution Guide](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) +- [Backstage Community Plugins Contribution Guide](https://github.com/backstage/community-plugins/blob/main/CONTRIBUTING.md) + +## 👋 See you in Atlanta! + +On behalf of myself and the other co-hosts of Backstage ContribFest, thanks for following along! We look forward to seeing you in Atlanta and working with you on your contributions. Make sure to say hello! diff --git a/microsite/blog/assets/2025-05-12/changelog.png b/microsite/blog/assets/2025-05-12/changelog.png new file mode 100644 index 0000000000..4a97d31a55 Binary files /dev/null and b/microsite/blog/assets/2025-05-12/changelog.png differ diff --git a/microsite/blog/assets/2025-05-12/cncf_1.jpeg b/microsite/blog/assets/2025-05-12/cncf_1.jpeg new file mode 100644 index 0000000000..7157be6805 Binary files /dev/null and b/microsite/blog/assets/2025-05-12/cncf_1.jpeg differ diff --git a/microsite/blog/assets/2025-05-12/cncf_2.png b/microsite/blog/assets/2025-05-12/cncf_2.png new file mode 100644 index 0000000000..1a7766d665 Binary files /dev/null and b/microsite/blog/assets/2025-05-12/cncf_2.png differ diff --git a/microsite/blog/assets/2025-05-12/cncf_3.jpeg b/microsite/blog/assets/2025-05-12/cncf_3.jpeg new file mode 100644 index 0000000000..cf9070a35b Binary files /dev/null and b/microsite/blog/assets/2025-05-12/cncf_3.jpeg differ diff --git a/microsite/blog/assets/2025-05-12/first_contributions.png b/microsite/blog/assets/2025-05-12/first_contributions.png new file mode 100644 index 0000000000..26ecf77565 Binary files /dev/null and b/microsite/blog/assets/2025-05-12/first_contributions.png differ diff --git a/microsite/blog/assets/2025-05-12/stages.png b/microsite/blog/assets/2025-05-12/stages.png new file mode 100644 index 0000000000..1d6aea0b64 Binary files /dev/null and b/microsite/blog/assets/2025-05-12/stages.png differ diff --git a/microsite/blog/assets/2025-05-12/tech_stack.png b/microsite/blog/assets/2025-05-12/tech_stack.png new file mode 100644 index 0000000000..6af9194488 Binary files /dev/null and b/microsite/blog/assets/2025-05-12/tech_stack.png differ diff --git a/microsite/blog/assets/2025-08-08/image01.png b/microsite/blog/assets/2025-08-08/image01.png new file mode 100644 index 0000000000..88fcc53ec0 Binary files /dev/null and b/microsite/blog/assets/2025-08-08/image01.png differ diff --git a/microsite/blog/assets/2025-08-08/image02.png b/microsite/blog/assets/2025-08-08/image02.png new file mode 100644 index 0000000000..29137f7ae0 Binary files /dev/null and b/microsite/blog/assets/2025-08-08/image02.png differ diff --git a/microsite/blog/assets/2025-08-08/image03.png b/microsite/blog/assets/2025-08-08/image03.png new file mode 100644 index 0000000000..bdbf588533 Binary files /dev/null and b/microsite/blog/assets/2025-08-08/image03.png differ diff --git a/microsite/blog/assets/2025-08-08/image04.png b/microsite/blog/assets/2025-08-08/image04.png new file mode 100644 index 0000000000..f667020419 Binary files /dev/null and b/microsite/blog/assets/2025-08-08/image04.png differ diff --git a/microsite/blog/assets/2025-08-08/image06.png b/microsite/blog/assets/2025-08-08/image06.png new file mode 100644 index 0000000000..15fb78fa56 Binary files /dev/null and b/microsite/blog/assets/2025-08-08/image06.png differ diff --git a/microsite/blog/assets/2025-10-15/backstage-contribfest-kubecon-guide-header.png b/microsite/blog/assets/2025-10-15/backstage-contribfest-kubecon-guide-header.png new file mode 100644 index 0000000000..23ed0309c1 Binary files /dev/null and b/microsite/blog/assets/2025-10-15/backstage-contribfest-kubecon-guide-header.png differ diff --git a/microsite/data/plugins/analytics-module-ga.yaml b/microsite/data/plugins/analytics-module-ga.yaml index 968b1831ab..3dcb27bcd5 100644 --- a/microsite/data/plugins/analytics-module-ga.yaml +++ b/microsite/data/plugins/analytics-module-ga.yaml @@ -3,8 +3,8 @@ title: 'Analytics Module: Google Analytics' author: Spotify authorUrl: https://github.com/spotify category: Monitoring -description: Track usage of your Backstage instance using Google Analytics. -documentation: https://github.com/backstage/community-plugins/blob/main/workspaces/analytics/plugins/analytics-module-ga/README.md +description: Track usage of your Backstage instance using Google Analytics 4. +documentation: https://github.com/backstage/community-plugins/tree/main/workspaces/analytics/plugins/analytics-module-ga4#readme iconUrl: /img/ga-icon.png -npmPackageName: '@backstage/plugin-analytics-module-ga' +npmPackageName: '@backstage/plugin-analytics-module-ga4' addedDate: '2021-10-07' diff --git a/microsite/data/plugins/apicurio-registry.yaml b/microsite/data/plugins/apicurio-registry.yaml new file mode 100644 index 0000000000..3750fbaa69 --- /dev/null +++ b/microsite/data/plugins/apicurio-registry.yaml @@ -0,0 +1,10 @@ +--- +title: Apicurio Registry +author: simonnepomuk +authorUrl: https://www.linkedin.com/in/simon-nepomuk-wagner/ +category: API Management +description: View content and metadata of your API schemas stored in your Apicurio Registry. +documentation: https://github.com/simonnepomuk/backstage-plugin-apicurio-registry +iconUrl: https://avatars.githubusercontent.com/u/28107283?s=200&v=4 +npmPackageName: '@simonnepomuk/backstage-plugin-apicurio-registry' +addedDate: '2025-08-31' diff --git a/microsite/data/plugins/daily-weather-update.yaml b/microsite/data/plugins/daily-weather-update.yaml new file mode 100644 index 0000000000..4118a4d5d6 --- /dev/null +++ b/microsite/data/plugins/daily-weather-update.yaml @@ -0,0 +1,10 @@ +--- +title: Daily Weather +author: Infosys Limited +authorUrl: https://github.com/Infosys +category: Utility +description: The Daily Weather Plugin for Backstage provides real-time weather information for a specified location using the Weatherstack API. +documentation: https://github.com/Infosys/daily-weather-plugin/tree/main/plugins/weather +iconUrl: https://github.com/Infosys/daily-weather-plugin/blob/main/plugins/weather/src/docs/plugin-logo.png?raw=true +npmPackageName: '@infosys_ltd/daily-weather-plugin' +addedDate: '2025-04-16' diff --git a/microsite/data/plugins/datacontract.yaml b/microsite/data/plugins/datacontract.yaml new file mode 100644 index 0000000000..a267730496 --- /dev/null +++ b/microsite/data/plugins/datacontract.yaml @@ -0,0 +1,10 @@ +--- +title: Data Contract +author: Jan Remunda +authorUrl: https://www.remunda.cz/#backstage +category: Discovery +description: Ingest and visualize Data Contracts to your catalog via API Entities. +documentation: https://www.npmjs.com/package/@remunda/backstage-plugin-datacontract +iconUrl: https://www.remunda.cz/logos/datacontract.png +npmPackageName: '@remunda/backstage-plugin-datacontract' +addedDate: '2025-08-19' diff --git a/microsite/data/plugins/datadog-entity-sync.yaml b/microsite/data/plugins/datadog-entity-sync.yaml new file mode 100644 index 0000000000..2f0cd06cd5 --- /dev/null +++ b/microsite/data/plugins/datadog-entity-sync.yaml @@ -0,0 +1,10 @@ +--- +title: Datadog Entity Sync +author: datadog +authorUrl: https://www.datadoghq.com/ +category: Development +description: Sync entities from the Backstage catalog to the Datadog Software Catalog. +documentation: https://github.com/DataDog/datadog-backstage-plugins/tree/main/plugins/datadog-entity-sync-backend#installation +iconUrl: https://imgix.datadoghq.com/img/about/presskit/logo-v/dd_vertical_purple.png?auto=format&fit=max&w=847&dpr=2 +npmPackageName: '@datadog/backstage-plugin-datadog-entity-sync-backend' +addedDate: '2025-09-19' diff --git a/microsite/data/plugins/hetzner-cloud.yaml b/microsite/data/plugins/hetzner-cloud.yaml new file mode 100644 index 0000000000..6f1fbe3f25 --- /dev/null +++ b/microsite/data/plugins/hetzner-cloud.yaml @@ -0,0 +1,10 @@ +--- +title: Hetzner Cloud +author: Gluo NV +authorUrl: https://github.com/gluobe +category: Infrastructure +description: Integrate Hetzner Cloud resources into Backstage. +documentation: https://github.com/gluobe/hetzner-backstage-plugin/blob/main/README.md +iconUrl: https://avatars.githubusercontent.com/u/18439789?s=200&v=4 +npmPackageName: '@gluo-nv/backstage-plugin-hetzner' +addedDate: '2025-06-03' diff --git a/microsite/data/plugins/holiday-tracker.yaml b/microsite/data/plugins/holiday-tracker.yaml new file mode 100644 index 0000000000..3232088582 --- /dev/null +++ b/microsite/data/plugins/holiday-tracker.yaml @@ -0,0 +1,10 @@ +--- +title: Holiday Tracker +author: Infosys Limited +authorUrl: https://github.com/Infosys +category: Utility +description: The Holiday Tracker Plugin for Backstage provides real-time public holiday information for a specified country or region using the Calendarific API. +documentation: https://github.com/Infosys/holiday-tracker-plugin/blob/main/plugins/holiday-tracker/README.md +iconUrl: https://github.com/Infosys/holiday-tracker-plugin/blob/main/plugins/holiday-tracker/src/docs/holiday-tracker-plugin.logo.png?raw=true +npmPackageName: '@infosys_ltd/holiday-tracker-plugin' +addedDate: '2025-07-23' diff --git a/microsite/data/plugins/kwirthlog.yaml b/microsite/data/plugins/kwirthlog.yaml new file mode 100644 index 0000000000..49863c2d4e --- /dev/null +++ b/microsite/data/plugins/kwirthlog.yaml @@ -0,0 +1,10 @@ +--- +title: KwirthLog for Backstage +author: Julio Fernandez +authorUrl: https://github.com/jfvilas +category: Monitoring +description: With KwirthLog you can view real-time log streams of Kubernetes objects linked to Backstage entities (source entities can be grouped and merged) +documentation: https://github.com/jfvilas/plugin-kwirth-log +iconUrl: https://raw.githubusercontent.com/jfvilas/plugin-kwirth-log/master/src/assets/kwirthlog-logo.png +npmPackageName: '@jfvilas/plugin-kwirth-log' +addedDate: '2025-09-18' diff --git a/microsite/data/plugins/kwirthmetrics.yaml b/microsite/data/plugins/kwirthmetrics.yaml new file mode 100644 index 0000000000..9a8c069eda --- /dev/null +++ b/microsite/data/plugins/kwirthmetrics.yaml @@ -0,0 +1,10 @@ +--- +title: KwirthMetrics for Backstage +author: Julio Fernandez +authorUrl: https://github.com/jfvilas +category: Monitoring +description: Shows live-streaming charts of Kubernetes resources metrics like CPU, memory, I/O... (you can group and merge data). +documentation: https://github.com/jfvilas/plugin-kwirth-metrics +iconUrl: https://raw.githubusercontent.com/jfvilas/plugin-kwirth-metrics/master/src/assets/kwirthmetrics-logo.png +npmPackageName: '@jfvilas/plugin-kwirth-metrics' +addedDate: '2025-09-14' diff --git a/microsite/data/plugins/microcks.yaml b/microsite/data/plugins/microcks.yaml index 4f94e5b465..0ac7a0c00a 100644 --- a/microsite/data/plugins/microcks.yaml +++ b/microsite/data/plugins/microcks.yaml @@ -5,7 +5,7 @@ authorUrl: https://microcks.io category: Discovery description: Import API definitions (OpenAPI, AsyncAPI, gRPC) from Microcks instances, linking to their mock endpoints and test results. documentation: https://github.com/microcks/microcks-backstage-provider -iconUrl: https://microcks.io/images/microcks-logo-blue.png +iconUrl: https://raw.githubusercontent.com/microcks/.github/refs/heads/main/assets/microcks-logo-blue.png npmPackageName: '@microcks/microcks-backstage-provider' tags: - mock diff --git a/microsite/data/plugins/parseable-dataset.yaml b/microsite/data/plugins/parseable-dataset.yaml new file mode 100644 index 0000000000..4624d3429f --- /dev/null +++ b/microsite/data/plugins/parseable-dataset.yaml @@ -0,0 +1,11 @@ +title: Parseable Dataset Plugin +author: Parseable +authorUrl: https://parseable.com +category: Monitoring +description: View and explore telemetry datasets from Parseable directly inside Backstage. This plugin enables teams to query, visualize, and troubleshoot logs and metrics from Parseable without leaving your internal developer portal. +documentation: https://github.com/parseablehq/backstage-plugin/blob/main/parseable-backstage-plugin/plugins/parseable-logstream/README.md +iconUrl: https://raw.githubusercontent.com/parseablehq/.github/main/images/logo.svg +npmPackageName: '@parseable/backstage-plugin-logstream' +tags: + - monitoring +addedDate: '2025-07-14' diff --git a/microsite/data/plugins/scalr b/microsite/data/plugins/scalr.yaml similarity index 100% rename from microsite/data/plugins/scalr rename to microsite/data/plugins/scalr.yaml diff --git a/microsite/data/plugins/signadot.yaml b/microsite/data/plugins/signadot.yaml new file mode 100644 index 0000000000..9b6b162901 --- /dev/null +++ b/microsite/data/plugins/signadot.yaml @@ -0,0 +1,10 @@ +--- +title: Signadot +author: Signadot +authorUrl: https://www.signadot.com/ +category: Kubernetes +description: View and manage lightweight ephemeral Kubernetes environments (Sandboxes) for testing microservices in pull requests and local development. +documentation: https://github.com/signadot/backstage-plugin +iconUrl: https://avatars.githubusercontent.com/u/57196635 +npmPackageName: '@signadot-lib/backstage-plugin' +addedDate: '2025-07-09' diff --git a/microsite/data/plugins/spacelift-io.yaml b/microsite/data/plugins/spacelift-io.yaml new file mode 100644 index 0000000000..fe9b48139f --- /dev/null +++ b/microsite/data/plugins/spacelift-io.yaml @@ -0,0 +1,10 @@ +--- +title: Spacelift.io +author: Spacelift.io +authorUrl: https://spacelift.io/ +category: Infrastructure +description: The Spacelift plugin allows you to manage your infrastructure directly from Backstage. Visualize your IaC stacks and trigger runs with ease. +documentation: https://docs.spacelift.io/integrations/external-integrations/backstage +iconUrl: https://avatars.githubusercontent.com/u/53318513?s=200&v=4 +npmPackageName: '@spacelift-io/backstage-integration-frontend' +addedDate: '2025-06-10' diff --git a/microsite/data/plugins/stackoverflow-teams.yaml b/microsite/data/plugins/stackoverflow-teams.yaml new file mode 100644 index 0000000000..262a6e9c69 --- /dev/null +++ b/microsite/data/plugins/stackoverflow-teams.yaml @@ -0,0 +1,10 @@ +--- +title: Stack Overflow for Teams +author: Stack Overflow +authorUrl: https://github.com/StackExchange/ +category: Discovery +description: Provide seamless access to Stack Overflow Teams most relevant data, allowing you to display the top users, top tags, and top questions directly within Backstage. It also allows to securely create SO Teams questions from Backstage. +documentation: https://stackoverflowteams.help/en/articles/9692515-backstage-io-integration +iconUrl: /img/stack-overflow-logo.svg +npmPackageName: '@stackoverflow/backstage-plugin-stack-overflow-teams' +addedDate: '2025-06-10' diff --git a/microsite/data/plugins/targetboard.yaml b/microsite/data/plugins/targetboard.yaml new file mode 100644 index 0000000000..2cac367eec --- /dev/null +++ b/microsite/data/plugins/targetboard.yaml @@ -0,0 +1,10 @@ +--- +title: TargetBoard +author: TargetBoard +authorUrl: https://www.targetboard.ai +category: Metrics +description: Embed TargetBoard dashboards and metric cards inside Backstage to visualize real-time engineering performance, KPIs, and delivery metrics. +documentation: https://github.com/targetboard/backstage-plugin/blob/main/README.md +iconUrl: https://app.targetboard.ai/assets/TargetBoard-Backstage-logo.svg +npmPackageName: '@targetboard/backstage-plugin' +addedDate: '2025-11-02' diff --git a/microsite/data/plugins/wheel-of-names.yaml b/microsite/data/plugins/wheel-of-names.yaml new file mode 100644 index 0000000000..0377742ab0 --- /dev/null +++ b/microsite/data/plugins/wheel-of-names.yaml @@ -0,0 +1,10 @@ +--- +title: Wheel of Names +author: intive +authorUrl: https://www.intive.com/ +category: Utility +description: This plugin provides a customizable spinning wheel that can be used for random selection, decision making, or just for fun in your Backstage instance. +documentation: https://github.com/backstage/community-plugins/blob/main/workspaces/wheel-of-names/plugins/wheel-of-names/README.md +iconUrl: /img/wheel-of-names.svg +npmPackageName: '@backstage-community/plugin-wheel-of-names' +addedDate: '2025-05-21' diff --git a/microsite/docusaurus.config.ts b/microsite/docusaurus.config.ts index 71331710d5..850e6058af 100644 --- a/microsite/docusaurus.config.ts +++ b/microsite/docusaurus.config.ts @@ -269,6 +269,10 @@ const config: Config = { from: '/docs/plugins/url-reader/', to: '/docs/backend-system/core-services/url-reader', }, + { + from: '/docs/getting-started/app-custom-theme', + to: '/docs/conf/user-interface', + }, ], }), [ @@ -297,6 +301,11 @@ const config: Config = { specPath: '../plugins/search-backend/src/schema/openapi.yaml', outputDir: '../docs/features/search/api', } satisfies OpenApiPlugin.Options, + scaffolder: { + ...defaultOpenApiOptions, + specPath: '../plugins/scaffolder-backend/src/schema/openapi.yaml', + outputDir: '../docs/features/software-templates/api', + } satisfies OpenApiPlugin.Options, }, }, ], @@ -343,13 +352,14 @@ const config: Config = { ], colorMode: { + disableSwitch: false, defaultMode: 'dark', - disableSwitch: true, }, navbar: { logo: { alt: 'Backstage Software Catalog and Developer Platform', - src: 'img/logo.svg', + src: 'img/logo-black.svg', + srcDark: 'img/logo.svg', }, items: [ { @@ -482,7 +492,7 @@ const config: Config = { copyright: `

    Made with ❤️ at Spotify

    `, }, algolia: { - apiKey: '1f0ba86672ccfc3576faa94583e5b318', + apiKey: '60d2643a9c6306463f15f8c3556e7f2e', // Owned by @Rugvip indexName: 'crawler_Backstage Docusaurus 2', appId: 'JCMFNHCHI8', searchParameters: {}, diff --git a/microsite/sidebars.ts b/microsite/sidebars.ts index 1f8d3defb7..9a4f03620f 100644 --- a/microsite/sidebars.ts +++ b/microsite/sidebars.ts @@ -14,14 +14,16 @@ const catalogSidebar = tryToLoadCustomSidebar( const searchSidebar = tryToLoadCustomSidebar( '../docs/features/search/api/sidebar.ts', ); +const scaffolderSidebar = tryToLoadCustomSidebar( + '../docs/features/software-templates/api/sidebar.ts', +); export default { docs: { Overview: [ 'overview/what-is-backstage', + 'overview/technical-overview', 'overview/architecture-overview', - 'overview/background', - 'overview/vision', 'overview/roadmap', 'overview/threat-model', 'overview/versioning-policy', @@ -35,7 +37,6 @@ export default { 'getting-started/config/database', 'getting-started/config/authentication', 'getting-started/configure-app-with-plugins', - 'getting-started/app-custom-theme', 'getting-started/homepage', ], }, @@ -61,6 +62,42 @@ export default { 'overview/support', 'getting-started/keeping-backstage-updated', ], + ...(process.env.GOLDEN_PATH + ? { + 'Golden Paths': [ + { + type: 'category', + label: '001 - create-app', + items: [ + 'golden-path/create-app/index', + 'golden-path/create-app/npx-create-app', + 'golden-path/create-app/local-development', + 'golden-path/create-app/installing-plugins', + 'golden-path/create-app/logging-in', + 'golden-path/create-app/custom-theme', + 'golden-path/create-app/keeping-backstage-updated', + ], + }, + { + type: 'category', + label: '002 - Plugins', + items: [ + 'golden-path/plugins/index', + 'golden-path/plugins/why-build-plugins', + 'golden-path/plugins/sustainable-plugin-development', + { + type: 'category', + label: 'Backend Plugins', + items: [ + 'golden-path/plugins/backend/001-first-steps', + 'golden-path/plugins/backend/002-poking-around', + ], + }, + ], + }, + ], + } + : {}), 'Core Features': [ { type: 'category', @@ -229,6 +266,22 @@ export default { 'features/software-templates/dry-run-testing', 'features/software-templates/experimental', 'features/software-templates/templating-extensions', + { + type: 'category', + label: 'API', + link: + scaffolderSidebar.length > 0 + ? { + type: 'generated-index', + title: 'Scaffolder API', + slug: '/category/scaffolder-api', + } + : { + type: 'doc', + id: 'openapi/generated-docs/404', + }, + items: scaffolderSidebar, + }, ], }, { @@ -330,7 +383,7 @@ export default { { type: 'category', label: 'Gitea', - items: ['integrations/gitea/locations'], + items: ['integrations/gitea/locations', 'integrations/gitea/discovery'], }, { type: 'category', @@ -462,6 +515,8 @@ export default { 'backend-system/core-services/token-manager', 'backend-system/core-services/url-reader', 'backend-system/core-services/user-info', + 'backend-system/core-services/actions-registry', + 'backend-system/core-services/actions', ], }, ], @@ -540,6 +595,16 @@ export default { 'tooling/package-metadata', ], }, + { + type: 'category', + label: 'User Interface', + items: [ + 'conf/user-interface/index', + 'conf/user-interface/logo', + 'conf/user-interface/icons', + 'conf/user-interface/sidebar', + ], + }, ], Tutorials: [ { 'Non-technical': ['overview/adopting'] }, @@ -552,6 +617,7 @@ export default { 'tutorials/using-backstage-proxy-within-plugin', 'tutorials/enable-public-entry', 'tutorials/setup-opentelemetry', + 'tutorials/integrating-event-driven-updates-with-entity-providers', 'accessibility/index', ], }, diff --git a/microsite/src/components/bannerSection/bannerSection.module.scss b/microsite/src/components/bannerSection/bannerSection.module.scss index 64f4967d11..f6fe0536dc 100644 --- a/microsite/src/components/bannerSection/bannerSection.module.scss +++ b/microsite/src/components/bannerSection/bannerSection.module.scss @@ -38,13 +38,12 @@ } &:global(.greyBackground) { - background: linear-gradient(90.49deg, #121212 15.36%, #282828 70.44%); + background: var(--ifm-grey-background); } &:global(.greenGradientBackground) { - background: linear-gradient(70.44deg, #121212 55%, #5d817b); + background: var(--ifm-green-gradient-background); } - &:global(.greenBottomGradientBackground) { background: linear-gradient( 178.64deg, diff --git a/microsite/src/components/pluginsSearch/pluginsSearch.tsx b/microsite/src/components/pluginsSearch/pluginsSearch.tsx new file mode 100644 index 0000000000..68f9a2831a --- /dev/null +++ b/microsite/src/components/pluginsSearch/pluginsSearch.tsx @@ -0,0 +1,19 @@ +import React from 'react'; + +type Props = { + searchTerm: string; + onSearchTermChange: (newTerm: string) => void; +}; + +export const PluginsSearch = (props: Props) => { + const { searchTerm, onSearchTermChange } = props; + return ( + onSearchTermChange((e.target as HTMLInputElement).value)} + value={searchTerm} + placeholder="Search plugins..." + className="DocSearch-Input search" + /> + ); +}; diff --git a/microsite/src/pages/community/index.tsx b/microsite/src/pages/community/index.tsx index 8c1736e1e9..9770c91e8e 100644 --- a/microsite/src/pages/community/index.tsx +++ b/microsite/src/pages/community/index.tsx @@ -5,6 +5,8 @@ import { BannerSectionGrid } from '@site/src/components/bannerSection/bannerSect import Layout from '@theme/Layout'; import { clsx } from 'clsx'; import React from 'react'; +import ThemedImage from '@theme/ThemedImage'; +import useBaseUrl from '@docusaurus/useBaseUrl'; import { ContentBlock } from '../../components/contentBlock/contentBlock'; import communityStyles from './community.module.scss'; @@ -83,47 +85,47 @@ const Community = () => { { name: 'Frontside Software', url: 'https://frontside.com/backstage/', - logo: 'img/partner-logo-frontside.png', + logo: 'img/partner-logo-frontside', }, { name: 'RedHat', url: 'https://developers.redhat.com/rhdh', - logo: 'img/partner-logo-redhat.png', + logo: 'img/partner-logo-redhat', }, { name: 'Roadie', url: 'https://roadie.io/', - logo: 'img/partner-logo-roadie.png', + logo: 'img/partner-logo-roadie', }, { name: 'solo.io', url: 'https://www.solo.io/spotlight/', - logo: 'img/partner-logo-solo.png', + logo: 'img/partner-logo-solo', }, { name: 'ThoughtWorks', url: 'https://www.thoughtworks.com/about-us/partnerships/technology/backstage-by-spotify', - logo: 'img/partner-logo-thoughtworks.png', + logo: 'img/partner-logo-thoughtworks', }, { name: 'VMWare', url: 'https://tanzu.vmware.com/developer-portal', - logo: 'img/partner-logo-tanzubybroadcom.png', + logo: 'img/partner-logo-tanzubybroadcom', }, { name: 'StatusNeo', url: 'https://statusneo.com/backstage', - logo: 'img/partner-logo-statusneo.png', + logo: 'img/partner-logo-statusneo', }, { name: 'Alauda', url: 'https://www.alauda.io/community/169249', - logo: 'img/partner-logo-alauda.png', + logo: 'img/partner-logo-alauda', }, { name: 'Liatrio', url: 'https://www.liatrio.com/service-offerings/backstage', - logo: 'img/partner-logo-liatrio.png', + logo: 'img/partner-logo-liatrio', }, ]; //#endregion @@ -233,7 +235,13 @@ const Community = () => { {partners.map(({ name, url, logo }, index) => (
    - {name} +
    ))} diff --git a/microsite/src/pages/demos/index.tsx b/microsite/src/pages/demos/index.tsx index 9f4a4c28c3..7b2253b555 100644 --- a/microsite/src/pages/demos/index.tsx +++ b/microsite/src/pages/demos/index.tsx @@ -31,7 +31,7 @@ const Demos = () => {

    Watch the videos below to get an introduction to Backstage and to see how we use different plugins to customize{' '} - + our internal version of Backstage at Spotify

    diff --git a/microsite/src/pages/home/_home.tsx b/microsite/src/pages/home/_home.tsx index c0cf39ad9c..00691e8a75 100644 --- a/microsite/src/pages/home/_home.tsx +++ b/microsite/src/pages/home/_home.tsx @@ -7,9 +7,10 @@ import { ContentBlock } from '@site/src/components/contentBlock/contentBlock'; import Layout from '@theme/Layout'; import { clsx } from 'clsx'; import React, { useState } from 'react'; - +import ThemedImage from '@theme/ThemedImage'; import homeStyles from './home.module.scss'; import { HubSpotNewAdoptersForm } from './_hubSpotNewAdoptersForm'; +import useBaseUrl from '@docusaurus/useBaseUrl'; const hiddenNewsletterBannerKey = 'hiddenNewsletterBanner'; @@ -528,10 +529,13 @@ const HomePage = () => { incubation project
  • - CNCF Logo
    diff --git a/microsite/src/pages/plugins/index.tsx b/microsite/src/pages/plugins/index.tsx index 2abdbabf4b..1a87f9c0af 100644 --- a/microsite/src/pages/plugins/index.tsx +++ b/microsite/src/pages/plugins/index.tsx @@ -5,10 +5,11 @@ import { truncateDescription } from '@site/src/util/truncateDescription'; import { ChipCategory } from '@site/src/util/types'; import Layout from '@theme/Layout'; import clsx from 'clsx'; -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { IPluginData, PluginCard } from './_pluginCard'; import pluginsStyles from './plugins.module.scss'; +import { PluginsSearch } from '@site/src/components/pluginsSearch/pluginsSearch'; interface IPluginsList { corePlugins: IPluginData[]; @@ -55,6 +56,7 @@ const Plugins = () => { const [selectedCategories, setSelectedCategories] = useState([]); const [showCoreFeatures, setShowCoreFeatures] = useState(true); const [showOtherPlugins, setShowOtherPlugins] = useState(true); + const [searchTerm, setSearchTerm] = useState(''); const handleChipClick = (categoryName: string) => { const isSelected = @@ -97,6 +99,34 @@ const Plugins = () => { } }; + const matchesSearch = (pluginData: IPluginData, term: string) => { + if (!term) return true; + const lowerTerm = term.toLowerCase(); + return ( + pluginData.title.toLowerCase().includes(lowerTerm) || + pluginData.description.toLowerCase().includes(lowerTerm) || + pluginData.category.toLowerCase().includes(lowerTerm) || + (pluginData.author && pluginData.author.toLowerCase().includes(lowerTerm)) + ); + }; + + const matchesCategory = (pluginData: IPluginData, categories: string[]) => { + if (categories.length === 0) return true; + return categories.includes(pluginData.category); + }; + + const corePlugins = useMemo(() => { + return plugins.corePlugins + .filter(pluginData => matchesCategory(pluginData, selectedCategories)) + .filter(pluginData => matchesSearch(pluginData, searchTerm)); + }, [selectedCategories, searchTerm]); + + const otherPlugins = useMemo(() => { + return plugins.otherPlugins + .filter(pluginData => matchesCategory(pluginData, selectedCategories)) + .filter(pluginData => matchesSearch(pluginData, searchTerm)); + }, [selectedCategories, searchTerm]); + return (
    { categories={categories} handleChipClick={handleChipClick} /> +
    - {showCoreFeatures && ( + {corePlugins.length === 0 && otherPlugins.length === 0 && ( +
    +

    No plugins found

    +

    + We couldn't find any plugins matching your criteria. Please try + adjusting your search or filter settings. +

    +
    + )} + + {showCoreFeatures && corePlugins.length > 0 && (
    -

    Core Features

    +

    Core Features ({corePlugins.length})

    - {plugins.corePlugins - .filter( - pluginData => - !selectedCategories.length || - selectedCategories.includes(pluginData.category), - ) - .map(pluginData => ( - - ))} + {corePlugins.map(pluginData => ( + + ))}
    )} - {showOtherPlugins && ( + {showOtherPlugins && otherPlugins.length > 0 && (
    -

    All Plugins

    +

    All Plugins ({otherPlugins.length})

    Friendly reminder: While we love the variety and contributions of our open source plugins, they haven't been fully vetted by the @@ -158,18 +193,9 @@ const Plugins = () => { your due diligence before installing. Happy exploring!

    - {plugins.otherPlugins - .filter( - pluginData => - !selectedCategories.length || - selectedCategories.includes(pluginData.category), - ) - .map(pluginData => ( - - ))} + {otherPlugins.map(pluginData => ( + + ))}
    )} diff --git a/microsite/src/pages/plugins/plugins.module.scss b/microsite/src/pages/plugins/plugins.module.scss index fb17e90625..a17e4bc5c0 100644 --- a/microsite/src/pages/plugins/plugins.module.scss +++ b/microsite/src/pages/plugins/plugins.module.scss @@ -76,6 +76,20 @@ height: 1rem; } + :global(.search) { + float: right; + margin-bottom: 1rem; + margin-right: 1rem; + font-size: calc(0.875rem * var(--ifm-button-size-multiplier)); + font-weight: var(--ifm-button-font-weight); + background-color: transparent; + border: var(--ifm-button-border-width) solid var(--ifm-color-primary); + border-radius: var(--ifm-button-border-radius); + color: var(--ifm-color-primary); + width: 220px; + height: 2.2rem; + } + :global(.dropdown) { float: right; margin-bottom: 1rem; diff --git a/microsite/src/theme/customTheme.scss b/microsite/src/theme/customTheme.scss index 51615ed0dc..823327b28f 100644 --- a/microsite/src/theme/customTheme.scss +++ b/microsite/src/theme/customTheme.scss @@ -7,6 +7,61 @@ --ifm-color-primary-darker: #2e9e8a; --ifm-color-primary-darkest: #268271; } + +html[data-theme='dark'] { + --ifm-grey-background: linear-gradient( + 90.49deg, + #121212 15.36%, + #282828 70.44% + ); + --ifm-green-gradient-background: linear-gradient( + 70.44deg, + #121212 55%, + #5d817b + ); + --bullet-line-color: linear-gradient( + 89.75deg, + #9bf0e1 -1.5%, + rgba(155, 240, 225, 0) 111.48% + ); + --ifm-button-border-color: var(--ifm-color-primary-darker); + + /* Logo */ + --backstage-logo: url(/img/logo.svg); +} + +html[data-theme='light'] { + --ifm-color-primary: var(--ifm-color-primary-darkest); + --ifm-grey-background: linear-gradient( + 90.49deg, + #e0e0e0 15.36%, + #f5f5f5 70.44% + ); + --ifm-green-gradient-background: linear-gradient( + 70.44deg, + #e0f7f4 55%, + #a3d9d2 + ); + --ifm-breadcrumb-item-background-active: #f8f8f8; + --bullet-line-color: linear-gradient( + 89.75deg, + var(--ifm-color-primary-dark) -1.5%, + rgba(155, 240, 225, 0) 111.48% + ); + --ifm-font-color-base: #000000; + --ifm-menu-color: #6E; + --feedback-button-dark-text-color: #f8f8f8; + + /* Active Colors */ + --ifm-breadcrumb-color-active: var(--ifm-color-primary-darkest); + --ifm-menu-color-active: var(--ifm-color-primary-darkest); + --ifm-link-color: var(--ifm-color-primary-darkest); + --ifm-link-color-hover: var(--ifm-color-primary-darkest); + + /* Logo */ + --backstage-logo: url(/img/logo-black.svg); +} + // for docs and releases #__docusaurus { .theme-doc-markdown { @@ -46,7 +101,7 @@ } } .footerLogo { - background-image: url(/img/logo.svg); + background-image: var(--backstage-logo); background-repeat: no-repeat; height: 40px; width: 180px; @@ -86,11 +141,7 @@ /* #region Utility component styles */ .bulletLine { height: 3px; - background: linear-gradient( - 89.75deg, - #9bf0e1 -1.5%, - rgba(155, 240, 225, 0) 111.48% - ); + background: var(--bullet-line-color); } /* #endregion */ @@ -120,6 +171,11 @@ border-left: 3px solid rgb(255, 255, 255, 0.5); } +table { + width: 100%; + display: table; +} + /* #endregion */ /* For the docusaurus-pushfeedback plugin */ diff --git a/microsite/static/img/backstage-search-platform.svg b/microsite/static/img/backstage-search-platform.svg index 0c058386ad..9ddc3fbb2e 100644 --- a/microsite/static/img/backstage-search-platform.svg +++ b/microsite/static/img/backstage-search-platform.svg @@ -3,8 +3,8 @@ 05 Logo_Black \ No newline at end of file diff --git a/microsite/static/img/partner-logo-alauda-blk.png b/microsite/static/img/partner-logo-alauda-blk.png new file mode 100644 index 0000000000..3d93eb1444 Binary files /dev/null and b/microsite/static/img/partner-logo-alauda-blk.png differ diff --git a/microsite/static/img/partner-logo-frontside-blk.png b/microsite/static/img/partner-logo-frontside-blk.png new file mode 100644 index 0000000000..16b14ac588 Binary files /dev/null and b/microsite/static/img/partner-logo-frontside-blk.png differ diff --git a/microsite/static/img/partner-logo-liatrio-blk.png b/microsite/static/img/partner-logo-liatrio-blk.png new file mode 100644 index 0000000000..a3b599c98c Binary files /dev/null and b/microsite/static/img/partner-logo-liatrio-blk.png differ diff --git a/microsite/static/img/partner-logo-redhat-blk.png b/microsite/static/img/partner-logo-redhat-blk.png new file mode 100644 index 0000000000..8279127da9 Binary files /dev/null and b/microsite/static/img/partner-logo-redhat-blk.png differ diff --git a/microsite/static/img/partner-logo-roadie-blk.png b/microsite/static/img/partner-logo-roadie-blk.png new file mode 100644 index 0000000000..a837d3f6f5 Binary files /dev/null and b/microsite/static/img/partner-logo-roadie-blk.png differ diff --git a/microsite/static/img/partner-logo-solo-blk.png b/microsite/static/img/partner-logo-solo-blk.png new file mode 100644 index 0000000000..d9da222f22 Binary files /dev/null and b/microsite/static/img/partner-logo-solo-blk.png differ diff --git a/microsite/static/img/partner-logo-statusneo-blk.png b/microsite/static/img/partner-logo-statusneo-blk.png new file mode 100644 index 0000000000..78fb9bd10e Binary files /dev/null and b/microsite/static/img/partner-logo-statusneo-blk.png differ diff --git a/microsite/static/img/partner-logo-tanzubybroadcom-blk.png b/microsite/static/img/partner-logo-tanzubybroadcom-blk.png new file mode 100644 index 0000000000..0b66842336 Binary files /dev/null and b/microsite/static/img/partner-logo-tanzubybroadcom-blk.png differ diff --git a/microsite/static/img/partner-logo-thoughtworks-blk.png b/microsite/static/img/partner-logo-thoughtworks-blk.png new file mode 100644 index 0000000000..a9a4894ccf Binary files /dev/null and b/microsite/static/img/partner-logo-thoughtworks-blk.png differ diff --git a/microsite/static/img/wheel-of-names.svg b/microsite/static/img/wheel-of-names.svg new file mode 100644 index 0000000000..d6f19a06fb --- /dev/null +++ b/microsite/static/img/wheel-of-names.svg @@ -0,0 +1,4 @@ + + + + diff --git a/microsite/yarn.lock b/microsite/yarn.lock index e6454c4e82..9040e75d86 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -4430,12 +4430,12 @@ __metadata: linkType: hard "brace-expansion@npm:^1.1.7": - version: 1.1.11 - resolution: "brace-expansion@npm:1.1.11" + version: 1.1.12 + resolution: "brace-expansion@npm:1.1.12" dependencies: balanced-match: "npm:^1.0.0" concat-map: "npm:0.0.1" - checksum: 10/faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + checksum: 10/12cb6d6310629e3048cadb003e1aca4d8c9bb5c67c3c321bafdd7e7a50155de081f78ea3e0ed92ecc75a9015e784f301efc8132383132f4f7904ad1ac529c562 languageName: node linkType: hard @@ -5353,7 +5353,7 @@ __metadata: languageName: node linkType: hard -"create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": +"create-hash@npm:^1.1.0, create-hash@npm:^1.2.0": version: 1.2.0 resolution: "create-hash@npm:1.2.0" dependencies: @@ -5366,7 +5366,19 @@ __metadata: languageName: node linkType: hard -"create-hmac@npm:^1.1.4, create-hmac@npm:^1.1.7": +"create-hash@npm:~1.1.3": + version: 1.1.3 + resolution: "create-hash@npm:1.1.3" + dependencies: + cipher-base: "npm:^1.0.1" + inherits: "npm:^2.0.1" + ripemd160: "npm:^2.0.0" + sha.js: "npm:^2.4.0" + checksum: 10/b9f675719321dd3a3c3540bb46afcbdaf7182366ce93da9265318290e928be881e5edeff8c48a5ee9263c342e5e3f705fad5eb48f2e2cddc5fed1eb54077e076 + languageName: node + linkType: hard + +"create-hmac@npm:^1.1.7": version: 1.1.7 resolution: "create-hmac@npm:1.1.7" dependencies: @@ -5942,11 +5954,11 @@ __metadata: linkType: hard "docusaurus-pushfeedback@npm:^1.0.0": - version: 1.0.3 - resolution: "docusaurus-pushfeedback@npm:1.0.3" + version: 1.0.9 + resolution: "docusaurus-pushfeedback@npm:1.0.9" peerDependencies: "@docusaurus/core": 3.x - checksum: 10/ee80ae0c1fc079b2c317cab86d83ba50cce18938a6ce0ac647aad25dc68fc0ad659e55c11e93d0e7c23270c503c3cb300111dfbdd04785ef7aaf6fb123b57eae + checksum: 10/cb6ee78f3918b6bdc7a351a4383531f1da019f2b576722c2a9a90a93dbfdea94abc61b9d559779cc00af750ef498e656c90d92aad20d1a4dbbce80b40dbc01ed languageName: node linkType: hard @@ -7288,6 +7300,15 @@ __metadata: languageName: node linkType: hard +"hash-base@npm:^2.0.0": + version: 2.0.2 + resolution: "hash-base@npm:2.0.2" + dependencies: + inherits: "npm:^2.0.1" + checksum: 10/e39f3f2bb91679ed350bd2eb81035acb1e1e6e9bb86d9f1197fcfdc3cf39a2c56bf82a1870f000fae651477883b4c107fd6ac0c640a18ab06298b87c39939396 + languageName: node + linkType: hard + "hash-base@npm:^3.0.0": version: 3.1.0 resolution: "hash-base@npm:3.1.0" @@ -8327,7 +8348,7 @@ __metadata: languageName: node linkType: hard -"is-typed-array@npm:^1.1.3": +"is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.3": version: 1.1.15 resolution: "is-typed-array@npm:1.1.15" dependencies: @@ -8366,6 +8387,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:^2.0.5": + version: 2.0.5 + resolution: "isarray@npm:2.0.5" + checksum: 10/1d8bc7911e13bb9f105b1b3e0b396c787a9e63046af0b8fe0ab1414488ab06b2b099b87a2d8a9e31d21c9a6fad773c7fc8b257c4880f2d957274479d28ca3414 + languageName: node + linkType: hard + "isarray@npm:~1.0.0": version: 1.0.0 resolution: "isarray@npm:1.0.0" @@ -11289,15 +11317,16 @@ __metadata: linkType: hard "pbkdf2@npm:^3.1.2": - version: 3.1.2 - resolution: "pbkdf2@npm:3.1.2" + version: 3.1.3 + resolution: "pbkdf2@npm:3.1.3" dependencies: - create-hash: "npm:^1.1.2" - create-hmac: "npm:^1.1.4" - ripemd160: "npm:^2.0.1" - safe-buffer: "npm:^5.0.1" - sha.js: "npm:^2.4.8" - checksum: 10/40bdf30df1c9bb1ae41ec50c11e480cf0d36484b7c7933bf55e4451d1d0e3f09589df70935c56e7fccc5702779a0d7b842d012be8c08a187b44eb24d55bb9460 + create-hash: "npm:~1.1.3" + create-hmac: "npm:^1.1.7" + ripemd160: "npm:=2.0.1" + safe-buffer: "npm:^5.2.1" + sha.js: "npm:^2.4.11" + to-buffer: "npm:^1.2.0" + checksum: 10/980cf2977aa84ec3166fde195a28464ab494131c0a5778fc8f20b8894410747e502159c19ef2b41842c728bc52ba49ffee6847e3ee61ac0d482689f85d8a1b30 languageName: node linkType: hard @@ -12876,6 +12905,16 @@ __metadata: languageName: node linkType: hard +"ripemd160@npm:=2.0.1": + version: 2.0.1 + resolution: "ripemd160@npm:2.0.1" + dependencies: + hash-base: "npm:^2.0.0" + inherits: "npm:^2.0.1" + checksum: 10/f1a20b72b3ef897a981544c72a1fe15c2bd580f6f40e3062f7839af8e81232f746aa860964686e4b81e90929ad086f14823a9864e4e4bed3367e597fe14a0968 + languageName: node + linkType: hard + "ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": version: 2.0.2 resolution: "ripemd160@npm:2.0.2" @@ -13243,15 +13282,16 @@ __metadata: languageName: node linkType: hard -"sha.js@npm:^2.4.0, sha.js@npm:^2.4.8": - version: 2.4.11 - resolution: "sha.js@npm:2.4.11" +"sha.js@npm:^2.4.0, sha.js@npm:^2.4.11, sha.js@npm:^2.4.8": + version: 2.4.12 + resolution: "sha.js@npm:2.4.12" dependencies: - inherits: "npm:^2.0.1" - safe-buffer: "npm:^5.0.1" + inherits: "npm:^2.0.4" + safe-buffer: "npm:^5.2.1" + to-buffer: "npm:^1.2.0" bin: - sha.js: ./bin.js - checksum: 10/d833bfa3e0a67579a6ce6e1bc95571f05246e0a441dd8c76e3057972f2a3e098465687a4369b07e83a0375a88703577f71b5b2e966809e67ebc340dbedb478c7 + sha.js: bin.js + checksum: 10/39c0993592c2ab34eb2daae2199a2a1d502713765aecb611fd97c0c4ab7cd53e902d628e1962aaf384bafd28f55951fef46dcc78799069ce41d74b03aa13b5a7 languageName: node linkType: hard @@ -14041,6 +14081,17 @@ __metadata: languageName: node linkType: hard +"to-buffer@npm:^1.2.0": + version: 1.2.1 + resolution: "to-buffer@npm:1.2.1" + dependencies: + isarray: "npm:^2.0.5" + safe-buffer: "npm:^5.2.1" + typed-array-buffer: "npm:^1.0.3" + checksum: 10/f8d03f070b8567d9c949f1b59c8d47c83ed2e59b50b5449258f931df9a1fcb751aa8bb8756a9345adc529b6b1822521157c48e1a7d01779a47185060d7bf96d4 + languageName: node + linkType: hard + "to-fast-properties@npm:^2.0.0": version: 2.0.0 resolution: "to-fast-properties@npm:2.0.0" @@ -14144,6 +14195,17 @@ __metadata: languageName: node linkType: hard +"typed-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "typed-array-buffer@npm:1.0.3" + dependencies: + call-bound: "npm:^1.0.3" + es-errors: "npm:^1.3.0" + is-typed-array: "npm:^1.1.14" + checksum: 10/3fb91f0735fb413b2bbaaca9fabe7b8fc14a3fa5a5a7546bab8a57e755be0e3788d893195ad9c2b842620592de0e68d4c077d4c2c41f04ec25b8b5bb82fa9a80 + languageName: node + linkType: hard + "typedarray-to-buffer@npm:^3.1.5": version: 3.1.5 resolution: "typedarray-to-buffer@npm:3.1.5" diff --git a/mkdocs.yml b/mkdocs.yml index 688ca1a078..45fdd2c9d6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -28,7 +28,7 @@ nav: - Database: 'getting-started/config/database.md' - Authentication: 'getting-started/config/authentication.md' - Configuring App with plugins: 'getting-started/configure-app-with-plugins.md' - - Customize the look-and-feel of your App: 'getting-started/app-custom-theme.md' + - Customize the look-and-feel of your App: 'conf/user-interface/index.md' - Customizing your Homepage: 'getting-started/homepage.md' - Deployment: - Deploying Backstage: 'deployment/index.md' @@ -126,6 +126,9 @@ nav: - GitLab: - Locations: 'integrations/gitlab/locations.md' - Discovery: 'integrations/gitlab/discovery.md' + - Gitea: + - Locations: 'integrations/gitea/locations.md' + - Discovery: 'integrations/gitea/discovery.md' - Google GCS: - Locations: 'integrations/google-cloud-storage/locations.md' - LDAP: diff --git a/package.json b/package.json index 5f8bf49205..cbefee8708 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.39.0-next.3", + "version": "1.45.0-next.2", "backstage": { "cli": { "new": { @@ -23,11 +23,12 @@ ] }, "scripts": { - "build-storybook": "yarn ./storybook run build-storybook", + "build-storybook": "storybook build --output-dir dist-storybook", + "build-storybook:chromatic": "STORYBOOK_STORY_SET=chromatic storybook build --stats-json --output-dir dist-storybook", "build:all": "backstage-cli repo build --all", - "build:api-docs": "LANG=en_EN yarn build:api-reports --docs --exclude 'plugins/@(adr|adr-backend|adr-common|airbrake|airbrake-backend|allure|analytics-module-ga|analytics-module-ga4|analytics-module-newrelic-browser|apache-airflow|api-docs|api-docs-module-protoc-gen-doc|apollo-explorer|app-visualizer|azure-devops|azure-devops-backend|azure-devops-common|azure-sites|azure-sites-backend|azure-sites-common|badges|badges-backend|bazaar|bazaar-backend|bitbucket-cloud-common|bitrise|catalog-graph|catalog-graphql|catalog-import|catalog-unprocessed-entities|cicd-statistics|cicd-statistics-module-gitlab|circleci|cloudbuild|code-climate|code-coverage|code-coverage-backend|codescene|config-schema|cost-insights|cost-insights-common|dynatrace|entity-feedback|entity-feedback-backend|entity-feedback-common|entity-validation|example-todo-list|example-todo-list-backend|example-todo-list-common|firehydrant|fossa|gcalendar|gcp-projects|git-release-manager|github-actions|github-deployments|github-issues|github-pull-requests-board|gitops-profiles|gocd|graphiql|graphql-backend|graphql-voyager|ilert|jenkins|jenkins-backend|jenkins-common|kafka|kafka-backend|lighthouse|lighthouse-backend|lighthouse-common|linguist|linguist-backend|linguist-common|microsoft-calendar|newrelic|newrelic-dashboard|nomad|nomad-backend|octopus-deploy|opencost|pagerduty|periskop|periskop-backend|playlist|playlist-backend|playlist-common|proxy-backend|puppetdb|rollbar|rollbar-backend|sentry|shortcuts|splunk-on-call|stack-overflow|stack-overflow-backend|stackstorm|tech-radar|tech-radar-2|todo|todo-backend|xcmetrics)'", + "build:api-docs": "LANG=en_EN yarn build:api-reports --docs --exclude 'plugins/@(api-docs|api-docs-module-protoc-gen-doc|app-visualizer|catalog-graph|catalog-import|catalog-unprocessed-entities|config-schema|example-todo-list|example-todo-list-backend)'", "build:api-reports": "yarn build:api-reports:only --tsc", - "build:api-reports:only": "LANG=en_US.UTF-8 NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --sql-reports --allow-warnings 'packages/backend-app-api,packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-undocumented,ae-wrong-input-file-type --validate-release-tags", + "build:api-reports:only": "LANG=en_US.UTF-8 NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --sql-reports --allow-warnings 'packages/backend-app-api,packages/core-components,plugins/+(catalog|catalog-import|kubernetes)' -o ae-undocumented,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", @@ -40,9 +41,11 @@ "postinstall": "husky || true", "lint": "backstage-cli repo lint --since origin/master", "lint:all": "backstage-cli repo lint", + "lint:circular-deps": "madge --circular .", "lint:docs": "node ./scripts/check-docs-quality", "lint:peer-deps": "backstage-repo-tools peer-deps", "lint:type-deps": "backstage-repo-tools type-deps", + "mui-to-bui": "node scripts/mui-to-bui/backstage-migration-analytics.js", "new": "backstage-cli new", "prepare": "husky", "prettier:check": "prettier --check .", @@ -52,9 +55,10 @@ "snyk:test:package": "yarn snyk:test --include", "start": "backstage-cli repo start", "start-backend": "echo \"Use 'yarn start example-backend' instead\"", + "start:docker": "docker compose -f docker-compose.deps.yml up --wait && BACKSTAGE_ENV=docker yarn start", "start:microsite": "cd microsite/ && yarn start", "start:next": "yarn start example-app-next example-backend", - "storybook": "yarn ./storybook run storybook", + "storybook": "storybook dev -p 6006", "sync-issue-templates": "node ./.github/ISSUE_TEMPLATE/sync.js", "techdocs-cli": "node scripts/techdocs-cli.js", "techdocs-cli:dev": "cross-env TECHDOCS_CLI_DEV_MODE=true node scripts/techdocs-cli.js", @@ -103,12 +107,17 @@ "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "@yarnpkg/plugin-npm@npm:^3.1.0": "patch:@yarnpkg/plugin-npm@npm%3A3.1.0#~/.yarn/patches/@yarnpkg-plugin-npm-npm-3.1.0-6533d0f5a1.patch", + "GendocuPublicApis": "npm:gendocu-public-apis@^1.0.0", "ast-types@0.14.2": "patch:ast-types@npm%3A0.14.2#./.yarn/patches/ast-types-npm-0.14.2-43c4ac4b0d.patch", "ast-types@^0.14.1": "patch:ast-types@npm%3A0.14.2#./.yarn/patches/ast-types-npm-0.14.2-43c4ac4b0d.patch", + "ast-types@npm:0.14.2": "patch:ast-types@npm%3A0.16.1#./.yarn/patches/ast-types-npm-0.16.1-43c4ac4b0d.patch", + "ast-types@npm:^0.13.4": "patch:ast-types@npm%3A0.16.1#./.yarn/patches/ast-types-npm-0.16.1-43c4ac4b0d.patch", + "ast-types@npm:^0.16.1": "patch:ast-types@npm%3A0.16.1#./.yarn/patches/ast-types-npm-0.16.1-43c4ac4b0d.patch", "csstype@npm:^3.0.2": "3.0.9", "csstype@npm:^3.1.2": "3.0.9", "csstype@npm:^3.1.3": "3.0.9", - "jest-haste-map@^29.7.0": "patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch" + "jest-haste-map@^29.7.0": "patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch", + "recast@npm:0.23.9>ast-types": "patch:ast-types@npm%3A0.16.1#./.yarn/patches/ast-types-npm-0.16.1-43c4ac4b0d.patch" }, "dependencies": { "@backstage/errors": "workspace:^", @@ -122,11 +131,17 @@ "@backstage/codemods": "workspace:*", "@backstage/create-app": "workspace:*", "@backstage/e2e-test-utils": "workspace:*", + "@backstage/eslint-plugin": "workspace:*", "@backstage/repo-tools": "workspace:*", "@changesets/cli": "^2.14.0", "@octokit/rest": "^19.0.3", "@playwright/test": "^1.32.3", "@spotify/eslint-plugin": "^15.0.0", + "@storybook/addon-a11y": "^9.1.7", + "@storybook/addon-docs": "^9.1.7", + "@storybook/addon-links": "^9.1.7", + "@storybook/addon-themes": "^9.1.7", + "@storybook/react-vite": "^9.1.7", "@techdocs/cli": "workspace:*", "@types/cacheable-request": "^8.3.6", "@types/memjs": "^1.3.3", @@ -143,6 +158,7 @@ "fs-extra": "^11.2.0", "husky": "^9.0.0", "lint-staged": "^15.0.0", + "madge": "^8.0.0", "minimist": "^1.2.5", "node-gyp": "^10.0.0", "prettier": "^2.2.1", @@ -150,11 +166,31 @@ "shx": "^0.4.0", "sloc": "^0.3.1", "sort-package-json": "^2.8.0", + "storybook": "^9.1.7", + "ts-morph": "^24.0.0", "typedoc": "^0.28.0", - "typescript": "~5.6.0" + "typescript": "~5.7.0", + "vite": "^7.1.5" }, "packageManager": "yarn@4.8.1", "engines": { "node": "20 || 22" + }, + "madge": { + "fileExtensions": [ + "ts", + "tsx", + "js", + "jsx" + ], + "detectiveOptions": { + "ts": { + "skipTypeImports": true + }, + "tsx": { + "skipTypeImports": true + } + }, + "tsConfig": "./tsconfig.json" } } diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index e15b844a8d..fbbbdf6569 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,170 @@ # @backstage/app-defaults +## 1.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/theme@0.7.0 + +## 1.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/theme@0.7.0 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-permission-react@0.4.37 + +## 1.7.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + +## 1.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + +## 1.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/theme@0.6.8 + - @backstage/plugin-permission-react@0.4.36 + +## 1.7.0 + +### Minor Changes + +- 9956704: Add and configure the OpenShift authentication provider to the default APIs. + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/core-app-api@1.19.0 + +## 1.6.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.6-next.0 + +## 1.6.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/theme@0.6.8 + +## 1.6.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.8-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-permission-react@0.4.36 + +## 1.6.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-app-api@1.18.0 + - @backstage/plugin-permission-react@0.4.36 + +## 1.6.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/core-plugin-api@1.10.9-next.0 + +## 1.6.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-permission-react@0.4.36-next.0 + +## 1.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-permission-react@0.4.35 + +## 1.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-permission-react@0.4.35 + +## 1.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-permission-react@0.4.34 + +## 1.6.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-permission-react@0.4.34 + ## 1.6.2-next.2 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 18a5106385..8cd48112b2 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.6.2-next.2", + "version": "1.7.2-next.0", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" diff --git a/packages/app-defaults/src/defaults/apis.ts b/packages/app-defaults/src/defaults/apis.ts index 63ace7b4d5..97989dff91 100644 --- a/packages/app-defaults/src/defaults/apis.ts +++ b/packages/app-defaults/src/defaults/apis.ts @@ -35,6 +35,7 @@ import { FetchMiddlewares, VMwareCloudAuth, FrontendHostDiscovery, + OpenShiftAuth, } from '@backstage/core-app-api'; import { @@ -58,6 +59,7 @@ import { bitbucketServerAuthApiRef, atlassianAuthApiRef, vmwareCloudAuthApiRef, + openshiftAuthApiRef, } from '@backstage/core-plugin-api'; import { permissionApiRef, @@ -275,6 +277,22 @@ export const apis = [ }); }, }), + createApiFactory({ + api: openshiftAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => { + return OpenShiftAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + environment: configApi.getOptionalString('auth.environment'), + }); + }, + }), createApiFactory({ api: permissionApiRef, deps: { diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index f39080a253..74ba940174 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,108 @@ # app-next-example-plugin +## 0.0.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + +## 0.0.28 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/frontend-plugin-api@0.12.1 + +## 0.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + +## 0.0.27 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/core-components@0.18.0 + +## 0.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/core-components@0.17.6-next.0 + +## 0.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5 + - @backstage/frontend-plugin-api@0.11.0 + +## 0.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/core-components@0.17.5-next.0 + +## 0.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/frontend-plugin-api@0.10.4 + +## 0.0.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## 0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/frontend-plugin-api@0.10.3 + +## 0.0.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + +## 0.0.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## 0.0.23 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/core-components@0.17.2 + ## 0.0.23-next.1 ### Patch Changes diff --git a/packages/app-next-example-plugin/knip-report.md b/packages/app-next-example-plugin/knip-report.md index e01cd18c93..0f2b9c5ebc 100644 --- a/packages/app-next-example-plugin/knip-report.md +++ b/packages/app-next-example-plugin/knip-report.md @@ -4,6 +4,6 @@ | Name | Location | Severity | | :---------- | :----------- | :------- | -| cross-fetch | package.json | error | -| msw | package.json | error | +| cross-fetch | packages/app-next-example-plugin/package.json | error | +| msw | packages/app-next-example-plugin/package.json | error | diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index e0fd8ffff7..5415d793b3 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.23-next.1", + "version": "0.0.29-next.0", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", diff --git a/packages/app-next-example-plugin/report.api.md b/packages/app-next-example-plugin/report.api.md index 636d735914..12346d908c 100644 --- a/packages/app-next-example-plugin/report.api.md +++ b/packages/app-next-example-plugin/report.api.md @@ -4,15 +4,15 @@ ```ts import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; +import { ExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; -import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { JSX as JSX_2 } from 'react'; import { JSX as JSX_3 } from 'react/jsx-runtime'; +import { OverridableFrontendPlugin } from '@backstage/frontend-plugin-api'; import { RouteRef } from '@backstage/frontend-plugin-api'; // @public (undocumented) -const examplePlugin: FrontendPlugin< +const examplePlugin: OverridableFrontendPlugin< {}, {}, { @@ -26,9 +26,9 @@ const examplePlugin: FrontendPlugin< path?: string | undefined; }; output: - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< + | ExtensionDataRef + | ExtensionDataRef + | ExtensionDataRef< RouteRef, 'core.routing.ref', { @@ -37,7 +37,8 @@ const examplePlugin: FrontendPlugin< >; inputs: {}; params: { - defaultPath: string; + defaultPath?: [Error: `Use the 'path' param instead`]; + path: string; loader: () => Promise; routeRef?: RouteRef; }; diff --git a/packages/app-next-example-plugin/src/plugin.tsx b/packages/app-next-example-plugin/src/plugin.tsx index 7e1e7a1bd6..40000dcd91 100644 --- a/packages/app-next-example-plugin/src/plugin.tsx +++ b/packages/app-next-example-plugin/src/plugin.tsx @@ -21,7 +21,7 @@ import { export const ExamplePage = PageBlueprint.make({ params: { - defaultPath: '/example', + path: '/example', loader: () => import('./Component').then(m => ), }, }); diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index c7f21def01..c632471817 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,993 @@ # example-app-next +## 0.0.29-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-signals@0.0.25-next.1 + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-search@1.5.0-next.1 + - @backstage/plugin-app-visualizer@0.1.25-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + - @backstage/plugin-catalog-graph@0.5.3-next.1 + - @backstage/frontend-plugin-api@0.12.2-next.1 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/plugin-api-docs@0.13.1-next.1 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + +## 0.0.29-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + +## 0.0.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.5-next.0 + - @backstage/ui@0.8.2-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-techdocs@1.15.2-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + - @backstage/plugin-auth@0.1.2-next.0 + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-signals@0.0.25-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.23-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/frontend-app-api@0.13.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/app-defaults@1.7.2-next.0 + - @backstage/core-compat-api@0.5.4-next.0 + - @backstage/frontend-defaults@0.3.3-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-api-docs@0.13.1-next.0 + - @backstage/plugin-app@0.3.2-next.0 + - @backstage/plugin-app-visualizer@0.1.25-next.0 + - @backstage/plugin-auth-react@0.1.21-next.0 + - @backstage/plugin-catalog@1.31.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-graph@0.5.3-next.0 + - @backstage/plugin-home@0.8.14-next.0 + - @backstage/plugin-kubernetes@0.12.13-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.31-next.0 + - @backstage/plugin-notifications@0.5.11-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-search@1.4.32-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.0 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## 0.0.28 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.8.0 + - @backstage/plugin-catalog-graph@0.5.2 + - @backstage/plugin-scaffolder-react@1.19.2 + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/plugin-app@0.3.1 + - @backstage/plugin-signals@0.0.24 + - @backstage/cli@0.34.4 + - @backstage/plugin-home@0.8.13 + - @backstage/plugin-org@0.6.45 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/plugin-scaffolder@1.34.2 + - @backstage/plugin-search-react@1.9.5 + - @backstage/plugin-search@1.4.31 + - @backstage/plugin-notifications@0.5.10 + - @backstage/plugin-api-docs@0.13.0 + - @backstage/config@1.3.5 + - @backstage/plugin-user-settings@0.8.27 + - @backstage/plugin-app-visualizer@0.1.24 + - @backstage/theme@0.7.0 + - @backstage/plugin-kubernetes-cluster@0.0.30 + - @backstage/plugin-kubernetes@0.12.12 + - @backstage/core-compat-api@0.5.3 + - @backstage/frontend-app-api@0.13.1 + - @backstage/plugin-catalog@1.31.4 + - @backstage/app-defaults@1.7.1 + - @backstage/plugin-auth@0.1.1 + - @backstage/plugin-techdocs@1.15.1 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/frontend-defaults@0.3.2 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-auth-react@0.1.20 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-import@0.13.6 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22 + - @backstage/plugin-permission-react@0.4.37 + - @backstage/plugin-search-common@1.2.20 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29 + +## 0.0.28-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.2-next.2 + - @backstage/plugin-org@0.6.45-next.2 + - @backstage/cli@0.34.4-next.2 + - @backstage/ui@0.7.2-next.1 + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/plugin-scaffolder@1.34.2-next.2 + - @backstage/app-defaults@1.7.1-next.2 + - @backstage/plugin-app@0.3.1-next.2 + - @backstage/plugin-auth@0.1.1-next.1 + - @backstage/plugin-home@0.8.13-next.2 + - @backstage/plugin-notifications@0.5.10-next.2 + - @backstage/plugin-search-react@1.9.5-next.2 + - @backstage/plugin-signals@0.0.24-next.2 + - @backstage/plugin-techdocs@1.15.1-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/plugin-user-settings@0.8.27-next.2 + +## 0.0.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/cli@0.34.4-next.1 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-app-api@0.13.1-next.1 + - @backstage/frontend-defaults@0.3.2-next.1 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-catalog-import@0.13.6-next.1 + - @backstage/plugin-home@0.8.13-next.1 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/plugin-techdocs@1.15.1-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/app-defaults@1.7.1-next.1 + - @backstage/core-compat-api@0.5.3-next.1 + - @backstage/plugin-api-docs@0.13.0-next.1 + - @backstage/plugin-catalog@1.31.4-next.1 + - @backstage/plugin-catalog-graph@0.5.2-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-notifications@0.5.10-next.1 + - @backstage/plugin-org@0.6.45-next.1 + - @backstage/plugin-scaffolder@1.34.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.2-next.1 + - @backstage/plugin-search@1.4.31-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + - @backstage/plugin-signals@0.0.24-next.1 + - @backstage/plugin-user-settings@0.8.27-next.1 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-app@0.3.1-next.1 + - @backstage/plugin-app-visualizer@0.1.24-next.1 + - @backstage/plugin-auth-react@0.1.20-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.1 + - @backstage/plugin-kubernetes@0.12.12-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.30-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.1 + - @backstage/plugin-auth@0.1.1-next.0 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## 0.0.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.2-next.0 + - @backstage/plugin-catalog-graph@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/cli@0.34.4-next.0 + - @backstage/plugin-scaffolder@1.34.2-next.0 + - @backstage/plugin-api-docs@0.13.0-next.0 + - @backstage/core-compat-api@0.5.3-next.0 + - @backstage/plugin-catalog@1.31.4-next.0 + - @backstage/plugin-catalog-import@0.13.6-next.0 + - @backstage/plugin-home@0.8.13-next.0 + - @backstage/plugin-kubernetes@0.12.12-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.30-next.0 + - @backstage/plugin-org@0.6.45-next.0 + - @backstage/plugin-scaffolder-react@1.19.2-next.0 + - @backstage/plugin-search@1.4.31-next.0 + - @backstage/plugin-techdocs@1.15.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.0 + - @backstage/plugin-user-settings@0.8.27-next.0 + - @backstage/app-defaults@1.7.1-next.0 + - @backstage/frontend-defaults@0.3.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-app@0.3.1-next.0 + - @backstage/plugin-app-visualizer@0.1.24-next.0 + - @backstage/plugin-auth@0.1.1-next.0 + - @backstage/plugin-auth-react@0.1.20-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.0 + - @backstage/plugin-notifications@0.5.10-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/plugin-signals@0.0.24-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/frontend-app-api@0.13.1-next.0 + - @backstage/theme@0.6.8 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + +## 0.0.27 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.2 + - @backstage/ui@0.7.1 + - @backstage/plugin-techdocs@1.15.0 + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-notifications@0.5.9 + - @backstage/app-defaults@1.7.0 + - @backstage/plugin-catalog-graph@0.5.0 + - @backstage/plugin-org@0.6.44 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-auth-react@0.1.19 + - @backstage/plugin-auth@0.1.0 + - @backstage/plugin-home@0.8.12 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-scaffolder@1.34.1 + - @backstage/plugin-app@0.3.0 + - @backstage/plugin-user-settings@0.8.26 + - @backstage/plugin-catalog@1.31.3 + - @backstage/core-components@0.18.0 + - @backstage/frontend-app-api@0.13.0 + - @backstage/frontend-defaults@0.3.1 + - @backstage/core-compat-api@0.5.2 + - @backstage/plugin-scaffolder-react@1.19.1 + - @backstage/core-app-api@1.19.0 + - @backstage/plugin-api-docs@0.12.11 + - @backstage/plugin-app-visualizer@0.1.23 + - @backstage/plugin-catalog-import@0.13.5 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21 + - @backstage/plugin-kubernetes@0.12.11 + - @backstage/plugin-search@1.4.30 + - @backstage/plugin-search-react@1.9.4 + - @backstage/plugin-signals@0.0.23 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28 + - @backstage/integration-react@1.2.10 + - @backstage/plugin-kubernetes-cluster@0.0.29 + +## 0.0.27-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.1-next.0 + - @backstage/plugin-auth-react@0.1.19-next.1 + - @backstage/plugin-auth@0.1.0-next.0 + - @backstage/plugin-home@0.8.12-next.2 + - @backstage/plugin-scaffolder@1.34.1-next.2 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/plugin-user-settings@0.8.26-next.2 + - @backstage/plugin-scaffolder-react@1.19.1-next.2 + - @backstage/plugin-catalog@1.31.3-next.2 + - @backstage/cli@0.34.2-next.2 + - @backstage/plugin-catalog-graph@0.4.23-next.2 + - @backstage/plugin-catalog-import@0.13.5-next.2 + - @backstage/plugin-org@0.6.44-next.2 + - @backstage/plugin-techdocs@1.14.2-next.2 + - @backstage/core-compat-api@0.5.2-next.2 + - @backstage/plugin-api-docs@0.12.11-next.2 + - @backstage/plugin-kubernetes@0.12.11-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.2 + - @backstage/plugin-search@1.4.30-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28-next.0 + +## 0.0.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/cli@0.34.2-next.1 + - @backstage/core-components@0.17.6-next.0 + - @backstage/core-compat-api@0.5.2-next.1 + - @backstage/frontend-app-api@0.12.1-next.0 + - @backstage/frontend-defaults@0.3.1-next.0 + - @backstage/plugin-api-docs@0.12.11-next.1 + - @backstage/plugin-app@0.2.1-next.0 + - @backstage/plugin-app-visualizer@0.1.23-next.0 + - @backstage/plugin-catalog@1.31.3-next.1 + - @backstage/plugin-catalog-graph@0.4.23-next.1 + - @backstage/plugin-catalog-import@0.13.5-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.1 + - @backstage/plugin-home@0.8.12-next.1 + - @backstage/plugin-kubernetes@0.12.11-next.1 + - @backstage/plugin-notifications@0.5.9-next.1 + - @backstage/plugin-org@0.6.44-next.1 + - @backstage/plugin-scaffolder@1.34.1-next.1 + - @backstage/plugin-scaffolder-react@1.19.1-next.1 + - @backstage/plugin-search@1.4.30-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + - @backstage/plugin-signals@0.0.23-next.1 + - @backstage/plugin-techdocs@1.14.2-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28-next.0 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/plugin-user-settings@0.8.26-next.1 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/app-defaults@1.6.6-next.0 + - @backstage/plugin-auth-react@0.1.19-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.1 + +## 0.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.1-next.0 + - @backstage/plugin-org@0.6.44-next.0 + - @backstage/plugin-techdocs@1.14.2-next.0 + - @backstage/core-compat-api@0.5.2-next.0 + - @backstage/plugin-catalog@1.31.3-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/app-defaults@1.6.5 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-app-api@0.12.0 + - @backstage/frontend-defaults@0.3.0 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8 + - @backstage/ui@0.7.0 + - @backstage/plugin-api-docs@0.12.11-next.0 + - @backstage/plugin-app@0.2.0 + - @backstage/plugin-app-visualizer@0.1.22 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-graph@0.4.23-next.0 + - @backstage/plugin-catalog-import@0.13.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.0 + - @backstage/plugin-home@0.8.12-next.0 + - @backstage/plugin-kubernetes@0.12.11-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.0 + - @backstage/plugin-notifications@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder@1.34.1-next.0 + - @backstage/plugin-scaffolder-react@1.19.1-next.0 + - @backstage/plugin-search@1.4.30-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-signals@0.0.23-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27 + - @backstage/plugin-techdocs-react@1.3.2 + - @backstage/plugin-user-settings@0.8.26-next.0 + +## 0.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2 + - @backstage/plugin-org@0.6.42 + - @backstage/core-components@0.17.5 + - @backstage/frontend-defaults@0.3.0 + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-scaffolder-react@1.19.0 + - @backstage/plugin-scaffolder@1.34.0 + - @backstage/frontend-app-api@0.12.0 + - @backstage/plugin-app@0.2.0 + - @backstage/ui@0.7.0 + - @backstage/cli@0.34.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20 + - @backstage/core-compat-api@0.5.0 + - @backstage/plugin-app-visualizer@0.1.22 + - @backstage/plugin-catalog-import@0.13.4 + - @backstage/plugin-catalog-graph@0.4.22 + - @backstage/plugin-notifications@0.5.8 + - @backstage/plugin-user-settings@0.8.25 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-kubernetes@0.12.10 + - @backstage/plugin-api-docs@0.12.10 + - @backstage/plugin-techdocs@1.14.0 + - @backstage/plugin-search@1.4.29 + - @backstage/plugin-home@0.8.11 + - @backstage/plugin-signals@0.0.22 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/app-defaults@1.6.5 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-kubernetes-cluster@0.0.28 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27 + - @backstage/plugin-techdocs-react@1.3.2 + +## 0.0.26-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-defaults@0.3.0-next.2 + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/frontend-app-api@0.12.0-next.2 + - @backstage/cli@0.34.0-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.2 + - @backstage/core-compat-api@0.5.0-next.2 + - @backstage/plugin-app-visualizer@0.1.22-next.1 + - @backstage/plugin-catalog-import@0.13.4-next.2 + - @backstage/plugin-catalog-graph@0.4.22-next.2 + - @backstage/plugin-notifications@0.5.8-next.2 + - @backstage/plugin-user-settings@0.8.25-next.2 + - @backstage/plugin-search-react@1.9.3-next.1 + - @backstage/plugin-kubernetes@0.12.10-next.2 + - @backstage/plugin-scaffolder@1.34.0-next.2 + - @backstage/plugin-api-docs@0.12.10-next.2 + - @backstage/plugin-techdocs@1.14.0-next.2 + - @backstage/plugin-catalog@1.31.2-next.2 + - @backstage/plugin-search@1.4.29-next.2 + - @backstage/plugin-home@0.8.11-next.2 + - @backstage/plugin-app@0.2.0-next.1 + - @backstage/ui@0.7.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/plugin-signals@0.0.22-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.1 + - @backstage/plugin-org@0.6.42-next.2 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + +## 0.0.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/plugin-scaffolder@1.34.0-next.1 + - @backstage/ui@0.7.0-next.1 + - @backstage/plugin-home@0.8.11-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.1 + - @backstage/frontend-app-api@0.11.5-next.1 + - @backstage/core-compat-api@0.4.5-next.1 + - @backstage/plugin-catalog-import@0.13.4-next.1 + - @backstage/plugin-notifications@0.5.8-next.1 + - @backstage/plugin-kubernetes@0.12.10-next.1 + - @backstage/plugin-api-docs@0.12.10-next.1 + - @backstage/plugin-techdocs@1.14.0-next.1 + - @backstage/plugin-signals@0.0.22-next.1 + - @backstage/plugin-search@1.4.29-next.1 + - @backstage/plugin-app@0.2.0-next.0 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/cli@0.33.2-next.0 + - @backstage/frontend-defaults@0.2.5-next.1 + - @backstage/plugin-catalog-graph@0.4.22-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.1 + - @backstage/plugin-org@0.6.42-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27-next.0 + - @backstage/plugin-user-settings@0.8.25-next.1 + - @backstage/plugin-app-visualizer@0.1.22-next.0 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + +## 0.0.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-org@0.6.42-next.0 + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/ui@0.7.0-next.0 + - @backstage/plugin-catalog@1.31.2-next.0 + - @backstage/frontend-defaults@0.2.5-next.0 + - @backstage/core-compat-api@0.4.5-next.0 + - @backstage/plugin-api-docs@0.12.10-next.0 + - @backstage/plugin-catalog-graph@0.4.22-next.0 + - @backstage/plugin-catalog-import@0.13.4-next.0 + - @backstage/plugin-home@0.8.11-next.0 + - @backstage/plugin-kubernetes@0.12.10-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.0 + - @backstage/plugin-scaffolder@1.33.1-next.0 + - @backstage/plugin-scaffolder-react@1.18.1-next.0 + - @backstage/plugin-search@1.4.29-next.0 + - @backstage/plugin-techdocs@1.13.3-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26 + - @backstage/plugin-user-settings@0.8.25-next.0 + - @backstage/frontend-app-api@0.11.5-next.0 + - @backstage/plugin-app-visualizer@0.1.21 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.0 + - @backstage/plugin-notifications@0.5.8-next.0 + - @backstage/plugin-signals@0.0.22-next.0 + - @backstage/cli@0.33.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-app@0.1.11 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-search-react@1.9.2 + +## 0.0.25 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.8.10 + - @backstage/plugin-techdocs@1.13.2 + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/plugin-catalog-graph@0.4.21 + - @backstage/config@1.3.3 + - @backstage/frontend-app-api@0.11.4 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-scaffolder@1.33.0 + - @backstage/ui@0.6.0 + - @backstage/cli@0.33.1 + - @backstage/plugin-scaffolder-react@1.18.0 + - @backstage/plugin-catalog@1.31.1 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-org@0.6.41 + - @backstage/theme@0.6.7 + - @backstage/plugin-catalog-import@0.13.3 + - @backstage/core-app-api@1.18.0 + - @backstage/plugin-user-settings@0.8.24 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-app@0.1.11 + - @backstage/plugin-signals@0.0.21 + - @backstage/app-defaults@1.6.4 + - @backstage/core-compat-api@0.4.4 + - @backstage/frontend-defaults@0.2.4 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/plugin-api-docs@0.12.9 + - @backstage/plugin-app-visualizer@0.1.21 + - @backstage/plugin-auth-react@0.1.17 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19 + - @backstage/plugin-kubernetes@0.12.9 + - @backstage/plugin-kubernetes-cluster@0.0.27 + - @backstage/plugin-notifications@0.5.7 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search@1.4.28 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26 + - @backstage/plugin-techdocs-react@1.3.1 + +## 0.0.25-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.8.10-next.2 + - @backstage/canon@0.6.0-next.1 + - @backstage/cli@0.33.1-next.2 + - @backstage/plugin-scaffolder-react@1.18.0-next.2 + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/plugin-user-settings@0.8.24-next.2 + - @backstage/plugin-scaffolder@1.33.0-next.2 + - @backstage/plugin-signals@0.0.21-next.2 + - @backstage/app-defaults@1.6.4-next.2 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-app-api@0.11.4-next.2 + - @backstage/plugin-api-docs@0.12.9-next.1 + - @backstage/plugin-catalog@1.31.1-next.2 + - @backstage/plugin-catalog-graph@0.4.21-next.1 + - @backstage/plugin-catalog-import@0.13.3-next.1 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/plugin-notifications@0.5.7-next.1 + - @backstage/plugin-org@0.6.41-next.1 + - @backstage/plugin-search@1.4.28-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/plugin-techdocs@1.13.2-next.1 + +## 0.0.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/frontend-app-api@0.11.4-next.1 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/cli@0.33.1-next.1 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-defaults@0.2.4-next.1 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-catalog-import@0.13.3-next.1 + - @backstage/plugin-home@0.8.10-next.1 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-techdocs@1.13.2-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-catalog@1.31.1-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-org@0.6.41-next.1 + - @backstage/plugin-scaffolder@1.32.1-next.1 + - @backstage/plugin-scaffolder-react@1.17.1-next.1 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/plugin-api-docs@0.12.9-next.1 + - @backstage/plugin-catalog-graph@0.4.21-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.1 + - @backstage/plugin-kubernetes@0.12.9-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.1 + - @backstage/plugin-user-settings@0.8.24-next.1 + - @backstage/app-defaults@1.6.4-next.1 + - @backstage/core-compat-api@0.4.4-next.1 + - @backstage/plugin-notifications@0.5.7-next.1 + - @backstage/plugin-search@1.4.28-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/plugin-signals@0.0.21-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-app@0.1.11-next.1 + - @backstage/plugin-app-visualizer@0.1.21-next.1 + - @backstage/plugin-auth-react@0.1.17-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.1 + +## 0.0.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/plugin-catalog-graph@0.4.21-next.0 + - @backstage/canon@0.6.0-next.0 + - @backstage/plugin-scaffolder@1.32.1-next.0 + - @backstage/plugin-catalog-import@0.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + - @backstage/plugin-app@0.1.11-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-home@0.8.10-next.0 + - @backstage/plugin-notifications@0.5.7-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-signals@0.0.21-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/plugin-user-settings@0.8.24-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/frontend-defaults@0.2.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-api-docs@0.12.9-next.0 + - @backstage/plugin-app-visualizer@0.1.21-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + - @backstage/plugin-kubernetes@0.12.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + - @backstage/plugin-org@0.6.41-next.0 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search@1.4.28-next.0 + - @backstage/plugin-search-common@1.2.18 + +## 0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0 + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/plugin-scaffolder@1.32.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18 + - @backstage/plugin-app-visualizer@0.1.20 + - @backstage/plugin-catalog-import@0.13.1 + - @backstage/plugin-catalog-graph@0.4.20 + - @backstage/plugin-notifications@0.5.6 + - @backstage/plugin-user-settings@0.8.23 + - @backstage/plugin-kubernetes@0.12.8 + - @backstage/plugin-api-docs@0.12.8 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/plugin-signals@0.0.20 + - @backstage/plugin-search@1.4.27 + - @backstage/plugin-home@0.8.9 + - @backstage/plugin-app@0.1.10 + - @backstage/plugin-org@0.6.40 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-app-api@0.11.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/frontend-defaults@0.2.3 + - @backstage/plugin-search-react@1.9.1 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/plugin-kubernetes-cluster@0.0.26 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search-common@1.2.18 + +## 0.0.24-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.33.0-next.2 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/canon@0.5.0-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/frontend-defaults@0.2.3-next.1 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-api-docs@0.12.8-next.2 + - @backstage/plugin-app@0.1.10-next.1 + - @backstage/plugin-app-visualizer@0.1.20-next.1 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-graph@0.4.20-next.2 + - @backstage/plugin-catalog-import@0.13.1-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.2 + - @backstage/plugin-home@0.8.9-next.2 + - @backstage/plugin-kubernetes@0.12.8-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.2 + - @backstage/plugin-notifications@0.5.6-next.2 + - @backstage/plugin-org@0.6.40-next.2 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder@1.32.0-next.2 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + - @backstage/plugin-search@1.4.27-next.2 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/plugin-signals@0.0.20-next.1 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/plugin-user-settings@0.8.23-next.2 + +## 0.0.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/cli@0.33.0-next.1 + - @backstage/canon@0.5.0-next.2 + - @backstage/plugin-notifications@0.5.6-next.2 + - @backstage/plugin-scaffolder@1.32.0-next.2 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-catalog-import@0.13.1-next.2 + - @backstage/plugin-home@0.8.9-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-api-docs@0.12.8-next.2 + - @backstage/plugin-app@0.1.10-next.1 + - @backstage/plugin-app-visualizer@0.1.20-next.1 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-catalog-graph@0.4.20-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.2 + - @backstage/plugin-kubernetes@0.12.8-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.2 + - @backstage/plugin-org@0.6.40-next.2 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + - @backstage/plugin-search@1.4.27-next.2 + - @backstage/plugin-signals@0.0.20-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/plugin-user-settings@0.8.23-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/frontend-defaults@0.2.3-next.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-search-common@1.2.18 + +## 0.0.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0-next.1 + - @backstage/cli@0.32.2-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.1 + - @backstage/plugin-techdocs@1.13.0-next.1 + - @backstage/plugin-org@0.6.40-next.1 + - @backstage/plugin-user-settings@0.8.23-next.1 + - @backstage/plugin-notifications@0.5.6-next.1 + - @backstage/plugin-catalog@1.31.0-next.1 + - @backstage/plugin-catalog-graph@0.4.20-next.1 + - @backstage/plugin-catalog-import@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/plugin-home@0.8.9-next.1 + - @backstage/plugin-scaffolder@1.31.1-next.1 + - @backstage/plugin-scaffolder-react@1.16.1-next.1 + - @backstage/app-defaults@1.6.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-compat-api@0.4.3-next.1 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.0 + - @backstage/frontend-defaults@0.2.3-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-api-docs@0.12.8-next.1 + - @backstage/plugin-app@0.1.10-next.0 + - @backstage/plugin-app-visualizer@0.1.20-next.0 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.1 + - @backstage/plugin-kubernetes@0.12.8-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.1 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-search@1.4.27-next.1 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-signals@0.0.20-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## 0.0.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.31.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.0 + - @backstage/plugin-app-visualizer@0.1.20-next.0 + - @backstage/plugin-catalog-import@0.13.1-next.0 + - @backstage/plugin-catalog-graph@0.4.20-next.0 + - @backstage/plugin-notifications@0.5.6-next.0 + - @backstage/plugin-user-settings@0.8.23-next.0 + - @backstage/plugin-kubernetes@0.12.8-next.0 + - @backstage/plugin-api-docs@0.12.8-next.0 + - @backstage/plugin-techdocs@1.13.0-next.0 + - @backstage/plugin-catalog@1.31.0-next.0 + - @backstage/plugin-signals@0.0.20-next.0 + - @backstage/plugin-search@1.4.27-next.0 + - @backstage/plugin-home@0.8.9-next.0 + - @backstage/plugin-app@0.1.10-next.0 + - @backstage/plugin-org@0.6.40-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/frontend-defaults@0.2.3-next.0 + - @backstage/frontend-app-api@0.11.3-next.0 + - @backstage/canon@0.5.0-next.0 + - @backstage/core-compat-api@0.4.3-next.0 + - @backstage/plugin-scaffolder-react@1.16.1-next.0 + - @backstage/cli@0.32.1 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.0 + - @backstage/integration-react@1.2.7 + +## 0.0.23 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/canon@0.4.0 + - @backstage/cli@0.32.1 + - @backstage/plugin-user-settings@0.8.22 + - @backstage/core-components@0.17.2 + - @backstage/plugin-home@0.8.8 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-scaffolder@1.31.0 + - @backstage/frontend-app-api@0.11.2 + - @backstage/core-compat-api@0.4.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.17 + - @backstage/plugin-app-visualizer@0.1.19 + - @backstage/plugin-catalog-import@0.13.0 + - @backstage/plugin-catalog-graph@0.4.19 + - @backstage/plugin-notifications@0.5.5 + - @backstage/plugin-kubernetes@0.12.7 + - @backstage/plugin-api-docs@0.12.7 + - @backstage/plugin-techdocs@1.12.6 + - @backstage/plugin-catalog@1.30.0 + - @backstage/plugin-signals@0.0.19 + - @backstage/plugin-search@1.4.26 + - @backstage/plugin-app@0.1.9 + - @backstage/plugin-org@0.6.39 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-scaffolder-react@1.16.0 + - @backstage/plugin-kubernetes-cluster@0.0.25 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-defaults@0.2.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.24 + - @backstage/app-defaults@1.6.2 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-search-common@1.2.18 + ## 0.0.23-next.3 ### Patch Changes diff --git a/packages/app-next/app-config.yaml b/packages/app-next/app-config.yaml index 9d2bcf198a..dcaddfb9bf 100644 --- a/packages/app-next/app-config.yaml +++ b/packages/app-next/app-config.yaml @@ -1,17 +1,41 @@ app: - experimental: - packages: 'all' # ✨ + packages: 'all' # ✨ routes: bindings: catalog.viewTechDoc: techdocs.docRoot - catalog.createComponent: catalog-import.importPage org.catalogIndex: catalog.catalogIndex + pluginOverrides: + - match: + pluginId: pages + info: + description: 'This description was overridden in packages/app-next/app-config.yaml' + - match: + pluginId: /^catalog(-.*)?$/ + info: + ownerEntityRefs: [cubic-belugas] + - match: + packageName: '@backstage/plugin-scaffolder' + info: + ownerEntityRefs: [cubic-belugas] + extensions: + - entity-card:org/members-list: + config: + showAggregateMembersToggle: true + initialRelationAggregation: aggregated + # - apis.plugin.graphiql.browse.gitlab: true # - graphiql-endpoint:graphiql/gitlab: true + - nav-item:search: false + - nav-item:user-settings: false + - nav-item:catalog + - nav-item:api-docs + - nav-item:scaffolder + - nav-item:app-visualizer + # Pages - page:catalog/entity: config: @@ -56,7 +80,10 @@ app: - entity-card:org/group-profile - entity-card:org/members-list - entity-card:org/ownership - - entity-card:org/user-profile + - entity-card:org/user-profile: + config: + maxRelations: 5 + hideIcons: true # - entity-card:azure-devops/readme # Entity page contents diff --git a/packages/app-next/knip-report.md b/packages/app-next/knip-report.md index c30e426318..8513269386 100644 --- a/packages/app-next/knip-report.md +++ b/packages/app-next/knip-report.md @@ -1,47 +1,43 @@ # Knip report -## Unused dependencies (30) +## Unused dependencies (26) | Name | Location | Severity | | :----------------------------------------------- | :----------- | :------- | -| @backstage/plugin-techdocs-module-addons-contrib | package.json | error | -| @backstage/plugin-catalog-unprocessed-entities | package.json | error | -| @backstage/plugin-kubernetes-cluster | package.json | error | -| @backstage/plugin-permission-react | package.json | error | -| @backstage/plugin-scaffolder-react | package.json | error | -| @backstage/plugin-catalog-common | package.json | error | -| @backstage/plugin-techdocs-react | package.json | error | -| @backstage/plugin-catalog-graph | package.json | error | -| @backstage/plugin-notifications | package.json | error | -| @backstage/plugin-search-common | package.json | error | -| @backstage/plugin-search-react | package.json | error | -| @backstage/integration-react | package.json | error | -| @backstage/plugin-auth-react | package.json | error | -| @backstage/plugin-scaffolder | package.json | error | -| @backstage/frontend-app-api | package.json | error | -| @backstage/core-plugin-api | package.json | error | -| @backstage/plugin-api-docs | package.json | error | -| @backstage/plugin-catalog | package.json | error | -| @backstage/plugin-signals | package.json | error | -| @backstage/catalog-model | package.json | error | -| @backstage/plugin-search | package.json | error | -| @backstage/app-defaults | package.json | error | -| @backstage/plugin-app | package.json | error | -| @backstage/plugin-org | package.json | error | -| @backstage/config | package.json | error | -| @material-ui/lab | package.json | error | -| zen-observable | package.json | error | -| @octokit/rest | package.json | error | -| react-use | package.json | error | -| history | package.json | error | +| @backstage/plugin-techdocs-module-addons-contrib | packages/app-next/package.json | error | +| @backstage/plugin-catalog-unprocessed-entities | packages/app-next/package.json | error | +| @backstage/plugin-kubernetes-cluster | packages/app-next/package.json | error | +| @backstage/plugin-permission-react | packages/app-next/package.json | error | +| @backstage/plugin-scaffolder-react | packages/app-next/package.json | error | +| @backstage/plugin-catalog-common | packages/app-next/package.json | error | +| @backstage/plugin-techdocs-react | packages/app-next/package.json | error | +| @backstage/plugin-catalog-graph | packages/app-next/package.json | error | +| @backstage/plugin-search-common | packages/app-next/package.json | error | +| @backstage/plugin-search-react | packages/app-next/package.json | error | +| @backstage/integration-react | packages/app-next/package.json | error | +| @backstage/plugin-auth-react | packages/app-next/package.json | error | +| @backstage/plugin-scaffolder | packages/app-next/package.json | error | +| @backstage/core-plugin-api | packages/app-next/package.json | error | +| @backstage/plugin-api-docs | packages/app-next/package.json | error | +| @backstage/plugin-catalog | packages/app-next/package.json | error | +| @backstage/plugin-signals | packages/app-next/package.json | error | +| @backstage/app-defaults | packages/app-next/package.json | error | +| @backstage/plugin-app | packages/app-next/package.json | error | +| @backstage/plugin-org | packages/app-next/package.json | error | +| @backstage/config | packages/app-next/package.json | error | +| @material-ui/lab | packages/app-next/package.json | error | +| zen-observable | packages/app-next/package.json | error | +| @octokit/rest | packages/app-next/package.json | error | +| react-use | packages/app-next/package.json | error | +| history | packages/app-next/package.json | error | ## Unused devDependencies (5) | Name | Location | Severity | | :-------------------------- | :----------- | :------- | -| @testing-library/user-event | package.json | error | -| @types/zen-observable | package.json | error | -| @testing-library/dom | package.json | error | -| @types/jquery | package.json | error | -| cross-env | package.json | error | +| @testing-library/user-event | packages/app-next/package.json | error | +| @types/zen-observable | packages/app-next/package.json | error | +| @testing-library/dom | packages/app-next/package.json | error | +| @types/jquery | packages/app-next/package.json | error | +| cross-env | packages/app-next/package.json | error | diff --git a/packages/app-next/package.json b/packages/app-next/package.json index 66e6d1ffc5..5dae3c9750 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.23-next.3", + "version": "0.0.29-next.2", "backstage": { "role": "frontend" }, @@ -35,7 +35,6 @@ }, "dependencies": { "@backstage/app-defaults": "workspace:^", - "@backstage/canon": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/config": "workspace:^", @@ -50,6 +49,7 @@ "@backstage/plugin-api-docs": "workspace:^", "@backstage/plugin-app": "workspace:^", "@backstage/plugin-app-visualizer": "workspace:^", + "@backstage/plugin-auth": "workspace:^", "@backstage/plugin-auth-react": "workspace:^", "@backstage/plugin-catalog": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", @@ -74,6 +74,7 @@ "@backstage/plugin-techdocs-react": "workspace:^", "@backstage/plugin-user-settings": "workspace:^", "@backstage/theme": "workspace:^", + "@backstage/ui": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", diff --git a/packages/app-next/public/index.html b/packages/app-next/public/index.html index 63ab0bec0c..74387edea3 100644 --- a/packages/app-next/public/index.html +++ b/packages/app-next/public/index.html @@ -4,6 +4,7 @@ + tree similar to collectLegacyRoutes convertLegacyPageExtension(TechDocsIndexPage, { name: 'index', - defaultPath: '/docs', + path: '/docs', }), convertLegacyPageExtension(TechDocsReaderPage, { - defaultPath: '/docs/:namespace/:kind/:name/*', + path: '/docs/:namespace/:kind/:name/*', }), convertLegacyEntityContentExtension(EntityTechdocsContent), ], @@ -114,7 +116,7 @@ const notFoundErrorPageModule = createFrontendModule({ extensions: [notFoundErrorPage], }); -const collectedLegacyPlugins = convertLegacyApp( +const collectedLegacyPlugins = convertLegacyAppRoot( } /> , @@ -129,9 +131,13 @@ const app = createApp({ appVisualizerPlugin, kubernetesPlugin, notFoundErrorPageModule, + appModuleNav, customHomePageModule, ...collectedLegacyPlugins, ], + advanced: { + pluginInfoResolver, + }, /* Handled through config instead */ // bindRoutes({ bind }) { // bind(pagesPlugin.externalRoutes, { pageX: pagesPlugin.routes.pageX }); diff --git a/packages/app-next/src/examples/notFoundErrorPageExtension.tsx b/packages/app-next/src/examples/notFoundErrorPageExtension.tsx index a636b2b220..7f690f90cb 100644 --- a/packages/app-next/src/examples/notFoundErrorPageExtension.tsx +++ b/packages/app-next/src/examples/notFoundErrorPageExtension.tsx @@ -15,14 +15,14 @@ */ import { - createComponentExtension, - coreComponentRefs, + SwappableComponentBlueprint, + NotFoundErrorPage, } from '@backstage/frontend-plugin-api'; import Box from '@material-ui/core/Box'; import Typography from '@material-ui/core/Typography'; import { Button } from '@backstage/core-components'; -export function CustomNotFoundErrorPage() { +function CustomNotFoundErrorPage() { return ( CustomNotFoundErrorPage }, + params: define => + define({ + component: NotFoundErrorPage, + loader: () => CustomNotFoundErrorPage, + }), }); diff --git a/packages/app-next/src/examples/pagesPlugin.tsx b/packages/app-next/src/examples/pagesPlugin.tsx index ddd080c28b..35426b589b 100644 --- a/packages/app-next/src/examples/pagesPlugin.tsx +++ b/packages/app-next/src/examples/pagesPlugin.tsx @@ -21,7 +21,10 @@ import { createExternalRouteRef, useRouteRef, PageBlueprint, + FrontendPluginInfo, + useAppNode, } from '@backstage/frontend-plugin-api'; +import { useEffect, useState } from 'react'; import { Route, Routes } from 'react-router-dom'; const indexRouteRef = createRouteRef(); @@ -36,10 +39,26 @@ export const pageXRouteRef = createRouteRef(); // path: '/page2', // }); +function PluginInfo() { + const node = useAppNode(); + const [info, setInfo] = useState(undefined); + + useEffect(() => { + node?.spec.plugin?.info().then(setInfo); + }, [node]); + + return ( +
    +

    Plugin Info

    +
    {JSON.stringify(info, null, 2)}
    +
    + ); +} + const IndexPage = PageBlueprint.make({ name: 'index', params: { - defaultPath: '/', + path: '/', routeRef: indexRouteRef, loader: async () => { const Component = () => { @@ -64,6 +83,7 @@ const IndexPage = PageBlueprint.make({
    Settings
    + ); }; @@ -75,7 +95,7 @@ const IndexPage = PageBlueprint.make({ const Page1 = PageBlueprint.make({ name: 'page1', params: { - defaultPath: '/page1', + path: '/page1', routeRef: page1RouteRef, loader: async () => { const Component = () => { @@ -111,7 +131,7 @@ const Page1 = PageBlueprint.make({ const ExternalPage = PageBlueprint.make({ name: 'pageX', params: { - defaultPath: '/pageX', + path: '/pageX', routeRef: pageXRouteRef, loader: async () => { const Component = () => { @@ -139,6 +159,10 @@ export const pagesPlugin = createFrontendPlugin({ // // OR // // 'page1' // }, + info: { + packageJson: () => import('../../package.json'), + manifest: () => import('../../catalog-info.yaml'), + }, routes: { page1: page1RouteRef, pageX: pageXRouteRef, diff --git a/packages/app-next/src/index-public-experimental.tsx b/packages/app-next/src/index-public-experimental.tsx index 24c4a9d66a..ce558ed4f0 100644 --- a/packages/app-next/src/index-public-experimental.tsx +++ b/packages/app-next/src/index-public-experimental.tsx @@ -15,9 +15,13 @@ */ import ReactDOM from 'react-dom/client'; -import { createPublicSignInApp } from '@backstage/frontend-defaults'; -import '@backstage/canon/css/styles.css'; +import { createApp } from '@backstage/frontend-defaults'; +import { appModulePublicSignIn } from '@backstage/plugin-app/alpha'; -const app = createPublicSignInApp(); +import '@backstage/ui/css/styles.css'; + +const app = createApp({ + features: [appModulePublicSignIn], +}); ReactDOM.createRoot(document.getElementById('root')!).render(app.createRoot()); diff --git a/packages/app-next/src/index.tsx b/packages/app-next/src/index.tsx index 82b9595c84..fd86261385 100644 --- a/packages/app-next/src/index.tsx +++ b/packages/app-next/src/index.tsx @@ -17,6 +17,6 @@ import '@backstage/cli/asset-types'; import ReactDOM from 'react-dom/client'; import app from './App'; -import '@backstage/canon/css/styles.css'; +import '@backstage/ui/css/styles.css'; ReactDOM.createRoot(document.getElementById('root')!).render(app); diff --git a/packages/app-next/src/modules/appModuleNav.tsx b/packages/app-next/src/modules/appModuleNav.tsx new file mode 100644 index 0000000000..aa7d92bd1b --- /dev/null +++ b/packages/app-next/src/modules/appModuleNav.tsx @@ -0,0 +1,142 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { compatWrapper } from '@backstage/core-compat-api'; +import { + Link, + Sidebar, + sidebarConfig, + SidebarDivider, + SidebarGroup, + SidebarItem, + SidebarScrollWrapper, + SidebarSpace, + useSidebarOpenState, +} from '@backstage/core-components'; +import SearchIcon from '@material-ui/icons/Search'; +import MenuIcon from '@material-ui/icons/Menu'; +import BuildIcon from '@material-ui/icons/Build'; +import { + createFrontendModule, + NavContentBlueprint, +} from '@backstage/frontend-plugin-api'; +import { SidebarSearchModal } from '@backstage/plugin-search'; +import { NotificationsSidebarItem } from '@backstage/plugin-notifications'; +import { + Settings, + UserSettingsSignInAvatar, +} from '@backstage/plugin-user-settings'; +import { makeStyles } from '@material-ui/core/styles'; + +const useSidebarLogoStyles = makeStyles({ + root: { + width: sidebarConfig.drawerWidthClosed, + height: 3 * sidebarConfig.logoHeight, + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + marginBottom: -14, + }, + link: { + width: sidebarConfig.drawerWidthClosed, + marginLeft: 24, + }, +}); + +const SidebarLogo = () => { + const classes = useSidebarLogoStyles(); + const { isOpen } = useSidebarOpenState(); + + return ( +
    + + {isOpen ? ( + + + + ) : ( + + + + )} + +
    + ); +}; + +export const appModuleNav = createFrontendModule({ + pluginId: 'app', + extensions: [ + NavContentBlueprint.make({ + params: { + component: ({ items }) => { + return compatWrapper( + + + } to="/search"> + + + + }> + + {items.map((item, index) => ( + + ))} + + + + + + } + to="/settings" + > + + + + + , + ); + }, + }, + }), + ], +}); diff --git a/packages/app-next/src/pluginInfoResolver.ts b/packages/app-next/src/pluginInfoResolver.ts new file mode 100644 index 0000000000..12f730875c --- /dev/null +++ b/packages/app-next/src/pluginInfoResolver.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { FrontendPluginInfoResolver } from '@backstage/frontend-app-api'; + +// This file shows an example of what it looks like to extend the plugin info +// resolution with custom logic and fields. In this case we're reading the +// `spec.type` field from the plugin manifest (catalog-info.yaml). +// +// Using module augmentation we extend the `FrontendPluginInfo` interface to +// include our custom fields. This makes these fields available throughout our project. + +declare module '@backstage/frontend-plugin-api' { + export interface FrontendPluginInfo { + /** + * **DO NOT USE** + * + * This field is added in the example app to showcase module augmentation + * for extending the plugin info in internal apps. It only exists as an + * example in this project. + */ + exampleFieldDoNotUse?: string; + } +} + +export const pluginInfoResolver: FrontendPluginInfoResolver = async ctx => { + const manifest = (await ctx.manifest?.()) as Entity | undefined; + const { info: defaultInfo } = await ctx.defaultResolver({ + packageJson: await ctx.packageJson(), + manifest: manifest, + }); + return { + info: { + ...defaultInfo, + exampleFieldDoNotUse: manifest?.spec?.type?.toString(), + }, + }; +}; diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index add9e984a7..4609f1810a 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,904 @@ # example-app +## 0.2.115-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-signals@0.0.25-next.1 + - @backstage/plugin-search-react@1.10.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/plugin-search@1.5.0-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.1 + - @backstage/plugin-catalog-react@1.21.3-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + - @backstage/plugin-catalog-graph@0.5.3-next.1 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/plugin-api-docs@0.13.1-next.1 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + +## 0.2.115-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + - @backstage/plugin-mui-to-bui@0.2.1-next.1 + +## 0.2.115-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.5-next.0 + - @backstage/ui@0.8.2-next.0 + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/plugin-techdocs@1.15.2-next.0 + - @backstage/plugin-user-settings@0.8.29-next.0 + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/plugin-search-react@1.9.6-next.0 + - @backstage/plugin-signals@0.0.25-next.0 + - @backstage/plugin-catalog-react@1.21.3-next.0 + - @backstage/plugin-scaffolder@1.34.3-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.23-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/frontend-app-api@0.13.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/plugin-catalog-import@0.13.7-next.0 + - @backstage/app-defaults@1.7.2-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-api-docs@0.13.1-next.0 + - @backstage/plugin-auth-react@0.1.21-next.0 + - @backstage/plugin-catalog@1.31.5-next.0 + - @backstage/plugin-catalog-common@1.1.7-next.0 + - @backstage/plugin-catalog-graph@0.5.3-next.0 + - @backstage/plugin-devtools@0.1.33-next.0 + - @backstage/plugin-home@0.8.14-next.0 + - @backstage/plugin-kubernetes@0.12.13-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.31-next.0 + - @backstage/plugin-mui-to-bui@0.2.1-next.0 + - @backstage/plugin-notifications@0.5.11-next.0 + - @backstage/plugin-org@0.6.46-next.0 + - @backstage/plugin-search@1.4.32-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.30-next.0 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## 0.2.114 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.8.0 + - @backstage/plugin-mui-to-bui@0.2.0 + - @backstage/plugin-catalog-graph@0.5.2 + - @backstage/plugin-scaffolder-react@1.19.2 + - @backstage/plugin-catalog-react@1.21.2 + - @backstage/core-components@0.18.2 + - @backstage/plugin-signals@0.0.24 + - @backstage/cli@0.34.4 + - @backstage/plugin-home@0.8.13 + - @backstage/plugin-org@0.6.45 + - @backstage/plugin-scaffolder@1.34.2 + - @backstage/plugin-search-react@1.9.5 + - @backstage/plugin-search@1.4.31 + - @backstage/plugin-notifications@0.5.10 + - @backstage/plugin-api-docs@0.13.0 + - @backstage/config@1.3.5 + - @backstage/plugin-user-settings@0.8.27 + - @backstage/theme@0.7.0 + - @backstage/plugin-kubernetes-cluster@0.0.30 + - @backstage/plugin-kubernetes@0.12.12 + - @backstage/frontend-app-api@0.13.1 + - @backstage/plugin-catalog@1.31.4 + - @backstage/app-defaults@1.7.1 + - @backstage/plugin-techdocs@1.15.1 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + - @backstage/plugin-auth-react@0.1.20 + - @backstage/plugin-catalog-common@1.1.6 + - @backstage/plugin-catalog-import@0.13.6 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22 + - @backstage/plugin-devtools@0.1.32 + - @backstage/plugin-permission-react@0.4.37 + - @backstage/plugin-search-common@1.2.20 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29 + +## 0.2.114-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-mui-to-bui@0.2.0-next.0 + - @backstage/plugin-scaffolder-react@1.19.2-next.2 + - @backstage/plugin-org@0.6.45-next.2 + - @backstage/cli@0.34.4-next.2 + - @backstage/ui@0.7.2-next.1 + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/plugin-scaffolder@1.34.2-next.2 + - @backstage/app-defaults@1.7.1-next.2 + - @backstage/plugin-home@0.8.13-next.2 + - @backstage/plugin-notifications@0.5.10-next.2 + - @backstage/plugin-search-react@1.9.5-next.2 + - @backstage/plugin-signals@0.0.24-next.2 + - @backstage/plugin-techdocs@1.15.1-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/plugin-user-settings@0.8.27-next.2 + +## 0.2.114-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/cli@0.34.4-next.1 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/frontend-app-api@0.13.1-next.1 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/plugin-catalog-import@0.13.6-next.1 + - @backstage/plugin-home@0.8.13-next.1 + - @backstage/plugin-permission-react@0.4.37-next.0 + - @backstage/plugin-techdocs@1.15.1-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/app-defaults@1.7.1-next.1 + - @backstage/plugin-api-docs@0.13.0-next.1 + - @backstage/plugin-catalog@1.31.4-next.1 + - @backstage/plugin-catalog-graph@0.5.2-next.1 + - @backstage/plugin-catalog-react@1.21.2-next.1 + - @backstage/plugin-notifications@0.5.10-next.1 + - @backstage/plugin-org@0.6.45-next.1 + - @backstage/plugin-scaffolder@1.34.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.2-next.1 + - @backstage/plugin-search@1.4.31-next.1 + - @backstage/plugin-search-react@1.9.5-next.1 + - @backstage/plugin-signals@0.0.24-next.1 + - @backstage/plugin-user-settings@0.8.27-next.1 + - @backstage/plugin-auth-react@0.1.20-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.1 + - @backstage/plugin-devtools@0.1.32-next.1 + - @backstage/plugin-kubernetes@0.12.12-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.30-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.1 + - @backstage/plugin-catalog-common@1.1.6-next.0 + - @backstage/plugin-search-common@1.2.20-next.0 + +## 0.2.114-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.2-next.0 + - @backstage/plugin-catalog-graph@0.5.2-next.0 + - @backstage/plugin-catalog-react@1.21.2-next.0 + - @backstage/core-components@0.18.2-next.0 + - @backstage/cli@0.34.4-next.0 + - @backstage/plugin-scaffolder@1.34.2-next.0 + - @backstage/plugin-api-docs@0.13.0-next.0 + - @backstage/plugin-catalog@1.31.4-next.0 + - @backstage/plugin-catalog-import@0.13.6-next.0 + - @backstage/plugin-home@0.8.13-next.0 + - @backstage/plugin-kubernetes@0.12.12-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.30-next.0 + - @backstage/plugin-org@0.6.45-next.0 + - @backstage/plugin-scaffolder-react@1.19.2-next.0 + - @backstage/plugin-search@1.4.31-next.0 + - @backstage/plugin-techdocs@1.15.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.29-next.0 + - @backstage/plugin-user-settings@0.8.27-next.0 + - @backstage/app-defaults@1.7.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-auth-react@0.1.20-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.22-next.0 + - @backstage/plugin-devtools@0.1.32-next.0 + - @backstage/plugin-notifications@0.5.10-next.0 + - @backstage/plugin-search-react@1.9.5-next.0 + - @backstage/plugin-signals@0.0.24-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/frontend-app-api@0.13.1-next.0 + - @backstage/theme@0.6.8 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + +## 0.2.113 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.2 + - @backstage/ui@0.7.1 + - @backstage/plugin-techdocs@1.15.0 + - @backstage/plugin-catalog-react@1.21.0 + - @backstage/plugin-notifications@0.5.9 + - @backstage/app-defaults@1.7.0 + - @backstage/plugin-catalog-graph@0.5.0 + - @backstage/plugin-org@0.6.44 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/plugin-auth-react@0.1.19 + - @backstage/plugin-home@0.8.12 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-scaffolder@1.34.1 + - @backstage/plugin-user-settings@0.8.26 + - @backstage/plugin-catalog@1.31.3 + - @backstage/core-components@0.18.0 + - @backstage/frontend-app-api@0.13.0 + - @backstage/plugin-scaffolder-react@1.19.1 + - @backstage/core-app-api@1.19.0 + - @backstage/plugin-api-docs@0.12.11 + - @backstage/plugin-catalog-import@0.13.5 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21 + - @backstage/plugin-devtools@0.1.31 + - @backstage/plugin-kubernetes@0.12.11 + - @backstage/plugin-search@1.4.30 + - @backstage/plugin-search-react@1.9.4 + - @backstage/plugin-signals@0.0.23 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28 + - @backstage/integration-react@1.2.10 + - @backstage/plugin-kubernetes-cluster@0.0.29 + +## 0.2.113-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.7.1-next.0 + - @backstage/plugin-auth-react@0.1.19-next.1 + - @backstage/plugin-home@0.8.12-next.2 + - @backstage/plugin-scaffolder@1.34.1-next.2 + - @backstage/plugin-catalog-react@1.21.0-next.2 + - @backstage/core-components@0.17.6-next.1 + - @backstage/plugin-user-settings@0.8.26-next.2 + - @backstage/plugin-scaffolder-react@1.19.1-next.2 + - @backstage/plugin-catalog@1.31.3-next.2 + - @backstage/cli@0.34.2-next.2 + - @backstage/plugin-catalog-graph@0.4.23-next.2 + - @backstage/plugin-catalog-import@0.13.5-next.2 + - @backstage/plugin-org@0.6.44-next.2 + - @backstage/plugin-techdocs@1.14.2-next.2 + - @backstage/plugin-api-docs@0.12.11-next.2 + - @backstage/plugin-kubernetes@0.12.11-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.2 + - @backstage/plugin-search@1.4.30-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28-next.0 + +## 0.2.113-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.20.2-next.1 + - @backstage/cli@0.34.2-next.1 + - @backstage/core-components@0.17.6-next.0 + - @backstage/frontend-app-api@0.12.1-next.0 + - @backstage/plugin-api-docs@0.12.11-next.1 + - @backstage/plugin-catalog@1.31.3-next.1 + - @backstage/plugin-catalog-graph@0.4.23-next.1 + - @backstage/plugin-catalog-import@0.13.5-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.1 + - @backstage/plugin-devtools@0.1.31-next.1 + - @backstage/plugin-home@0.8.12-next.1 + - @backstage/plugin-kubernetes@0.12.11-next.1 + - @backstage/plugin-notifications@0.5.9-next.1 + - @backstage/plugin-org@0.6.44-next.1 + - @backstage/plugin-scaffolder@1.34.1-next.1 + - @backstage/plugin-scaffolder-react@1.19.1-next.1 + - @backstage/plugin-search@1.4.30-next.1 + - @backstage/plugin-search-react@1.9.4-next.0 + - @backstage/plugin-signals@0.0.23-next.1 + - @backstage/plugin-techdocs@1.14.2-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.28-next.0 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/plugin-user-settings@0.8.26-next.1 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/app-defaults@1.6.6-next.0 + - @backstage/plugin-auth-react@0.1.19-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.1 + +## 0.2.113-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.1-next.0 + - @backstage/plugin-org@0.6.44-next.0 + - @backstage/plugin-techdocs@1.14.2-next.0 + - @backstage/plugin-catalog@1.31.3-next.0 + - @backstage/plugin-catalog-react@1.20.2-next.0 + - @backstage/app-defaults@1.6.5 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/frontend-app-api@0.12.0 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8 + - @backstage/ui@0.7.0 + - @backstage/plugin-api-docs@0.12.11-next.0 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-graph@0.4.23-next.0 + - @backstage/plugin-catalog-import@0.13.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.21-next.0 + - @backstage/plugin-devtools@0.1.31-next.0 + - @backstage/plugin-home@0.8.12-next.0 + - @backstage/plugin-kubernetes@0.12.11-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.29-next.0 + - @backstage/plugin-notifications@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder@1.34.1-next.0 + - @backstage/plugin-scaffolder-react@1.19.1-next.0 + - @backstage/plugin-search@1.4.30-next.0 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-signals@0.0.23-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27 + - @backstage/plugin-techdocs-react@1.3.2 + - @backstage/plugin-user-settings@0.8.26-next.0 + +## 0.2.112 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2 + - @backstage/plugin-org@0.6.42 + - @backstage/core-components@0.17.5 + - @backstage/plugin-scaffolder-react@1.19.0 + - @backstage/plugin-scaffolder@1.34.0 + - @backstage/frontend-app-api@0.12.0 + - @backstage/ui@0.7.0 + - @backstage/cli@0.34.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20 + - @backstage/plugin-catalog-import@0.13.4 + - @backstage/plugin-catalog-graph@0.4.22 + - @backstage/plugin-notifications@0.5.8 + - @backstage/plugin-user-settings@0.8.25 + - @backstage/plugin-search-react@1.9.3 + - @backstage/plugin-kubernetes@0.12.10 + - @backstage/plugin-api-docs@0.12.10 + - @backstage/plugin-devtools@0.1.30 + - @backstage/plugin-techdocs@1.14.0 + - @backstage/plugin-search@1.4.29 + - @backstage/plugin-home@0.8.11 + - @backstage/plugin-signals@0.0.22 + - @backstage/plugin-catalog-react@1.20.0 + - @backstage/theme@0.6.8 + - @backstage/app-defaults@1.6.5 + - @backstage/plugin-auth-react@0.1.18 + - @backstage/plugin-kubernetes-cluster@0.0.28 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27 + - @backstage/plugin-techdocs-react@1.3.2 + +## 0.2.112-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.12.0-next.2 + - @backstage/cli@0.34.0-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.2 + - @backstage/plugin-catalog-import@0.13.4-next.2 + - @backstage/plugin-catalog-graph@0.4.22-next.2 + - @backstage/plugin-notifications@0.5.8-next.2 + - @backstage/plugin-user-settings@0.8.25-next.2 + - @backstage/plugin-search-react@1.9.3-next.1 + - @backstage/plugin-kubernetes@0.12.10-next.2 + - @backstage/plugin-scaffolder@1.34.0-next.2 + - @backstage/plugin-api-docs@0.12.10-next.2 + - @backstage/plugin-devtools@0.1.30-next.2 + - @backstage/plugin-techdocs@1.14.0-next.2 + - @backstage/plugin-catalog@1.31.2-next.2 + - @backstage/plugin-search@1.4.29-next.2 + - @backstage/plugin-home@0.8.11-next.2 + - @backstage/ui@0.7.0-next.2 + - @backstage/plugin-catalog-react@1.20.0-next.2 + - @backstage/plugin-signals@0.0.22-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.1 + - @backstage/plugin-org@0.6.42-next.2 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + +## 0.2.112-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.1 + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/plugin-scaffolder@1.34.0-next.1 + - @backstage/ui@0.7.0-next.1 + - @backstage/plugin-home@0.8.11-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.1 + - @backstage/frontend-app-api@0.11.5-next.1 + - @backstage/plugin-catalog-import@0.13.4-next.1 + - @backstage/plugin-notifications@0.5.8-next.1 + - @backstage/plugin-kubernetes@0.12.10-next.1 + - @backstage/plugin-api-docs@0.12.10-next.1 + - @backstage/plugin-devtools@0.1.30-next.1 + - @backstage/plugin-techdocs@1.14.0-next.1 + - @backstage/plugin-signals@0.0.22-next.1 + - @backstage/plugin-search@1.4.29-next.1 + - @backstage/plugin-catalog-react@1.20.0-next.1 + - @backstage/theme@0.6.8-next.0 + - @backstage/cli@0.33.2-next.0 + - @backstage/plugin-catalog-graph@0.4.22-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.1 + - @backstage/plugin-org@0.6.42-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.27-next.0 + - @backstage/plugin-user-settings@0.8.25-next.1 + - @backstage/plugin-search-react@1.9.3-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-auth-react@0.1.18-next.0 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search-common@1.2.19 + +## 0.2.112-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-org@0.6.42-next.0 + - @backstage/plugin-catalog-react@1.19.2-next.0 + - @backstage/ui@0.7.0-next.0 + - @backstage/plugin-catalog@1.31.2-next.0 + - @backstage/plugin-api-docs@0.12.10-next.0 + - @backstage/plugin-catalog-graph@0.4.22-next.0 + - @backstage/plugin-catalog-import@0.13.4-next.0 + - @backstage/plugin-home@0.8.11-next.0 + - @backstage/plugin-kubernetes@0.12.10-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.28-next.0 + - @backstage/plugin-scaffolder@1.33.1-next.0 + - @backstage/plugin-scaffolder-react@1.18.1-next.0 + - @backstage/plugin-search@1.4.29-next.0 + - @backstage/plugin-techdocs@1.13.3-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26 + - @backstage/plugin-user-settings@0.8.25-next.0 + - @backstage/frontend-app-api@0.11.5-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.20-next.0 + - @backstage/plugin-devtools@0.1.30-next.0 + - @backstage/plugin-notifications@0.5.8-next.0 + - @backstage/plugin-signals@0.0.22-next.0 + - @backstage/cli@0.33.1 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-search-react@1.9.2 + +## 0.2.111 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.8.10 + - @backstage/plugin-techdocs@1.13.2 + - @backstage/plugin-catalog-react@1.19.1 + - @backstage/plugin-catalog-graph@0.4.21 + - @backstage/config@1.3.3 + - @backstage/frontend-app-api@0.11.4 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-scaffolder@1.33.0 + - @backstage/ui@0.6.0 + - @backstage/cli@0.33.1 + - @backstage/plugin-scaffolder-react@1.18.0 + - @backstage/plugin-catalog@1.31.1 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/plugin-org@0.6.41 + - @backstage/theme@0.6.7 + - @backstage/plugin-catalog-import@0.13.3 + - @backstage/core-app-api@1.18.0 + - @backstage/plugin-user-settings@0.8.24 + - @backstage/integration-react@1.2.9 + - @backstage/plugin-signals@0.0.21 + - @backstage/app-defaults@1.6.4 + - @backstage/plugin-api-docs@0.12.9 + - @backstage/plugin-auth-react@0.1.17 + - @backstage/plugin-catalog-common@1.1.5 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19 + - @backstage/plugin-devtools@0.1.29 + - @backstage/plugin-kubernetes@0.12.9 + - @backstage/plugin-kubernetes-cluster@0.0.27 + - @backstage/plugin-notifications@0.5.7 + - @backstage/plugin-permission-react@0.4.36 + - @backstage/plugin-search@1.4.28 + - @backstage/plugin-search-common@1.2.19 + - @backstage/plugin-search-react@1.9.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26 + - @backstage/plugin-techdocs-react@1.3.1 + +## 0.2.111-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.8.10-next.2 + - @backstage/canon@0.6.0-next.1 + - @backstage/cli@0.33.1-next.2 + - @backstage/plugin-scaffolder-react@1.18.0-next.2 + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/plugin-user-settings@0.8.24-next.2 + - @backstage/plugin-scaffolder@1.33.0-next.2 + - @backstage/plugin-signals@0.0.21-next.2 + - @backstage/app-defaults@1.6.4-next.2 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/frontend-app-api@0.11.4-next.2 + - @backstage/plugin-api-docs@0.12.9-next.1 + - @backstage/plugin-catalog@1.31.1-next.2 + - @backstage/plugin-catalog-graph@0.4.21-next.1 + - @backstage/plugin-catalog-import@0.13.3-next.1 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/plugin-notifications@0.5.7-next.1 + - @backstage/plugin-org@0.6.41-next.1 + - @backstage/plugin-search@1.4.28-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/plugin-techdocs@1.13.2-next.1 + +## 0.2.111-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/frontend-app-api@0.11.4-next.1 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.1 + - @backstage/cli@0.33.1-next.1 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/plugin-catalog-import@0.13.3-next.1 + - @backstage/plugin-home@0.8.10-next.1 + - @backstage/plugin-permission-react@0.4.36-next.0 + - @backstage/plugin-techdocs@1.13.2-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-catalog@1.31.1-next.1 + - @backstage/plugin-catalog-common@1.1.5-next.0 + - @backstage/plugin-org@0.6.41-next.1 + - @backstage/plugin-scaffolder@1.32.1-next.1 + - @backstage/plugin-scaffolder-react@1.17.1-next.1 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/plugin-api-docs@0.12.9-next.1 + - @backstage/plugin-catalog-graph@0.4.21-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.1 + - @backstage/plugin-kubernetes@0.12.9-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.1 + - @backstage/plugin-user-settings@0.8.24-next.1 + - @backstage/app-defaults@1.6.4-next.1 + - @backstage/plugin-notifications@0.5.7-next.1 + - @backstage/plugin-search@1.4.28-next.1 + - @backstage/plugin-search-react@1.9.2-next.1 + - @backstage/plugin-signals@0.0.21-next.1 + - @backstage/plugin-auth-react@0.1.17-next.1 + - @backstage/plugin-devtools@0.1.29-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.1 + +## 0.2.111-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/plugin-catalog-graph@0.4.21-next.0 + - @backstage/canon@0.6.0-next.0 + - @backstage/plugin-scaffolder@1.32.1-next.0 + - @backstage/plugin-catalog-import@0.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-home@0.8.10-next.0 + - @backstage/plugin-notifications@0.5.7-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-signals@0.0.21-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/plugin-user-settings@0.8.24-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/plugin-api-docs@0.12.9-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + - @backstage/plugin-devtools@0.1.29-next.0 + - @backstage/plugin-kubernetes@0.12.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + - @backstage/plugin-org@0.6.41-next.0 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search@1.4.28-next.0 + - @backstage/plugin-search-common@1.2.18 + +## 0.2.110 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0 + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/plugin-scaffolder@1.32.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18 + - @backstage/plugin-catalog-import@0.13.1 + - @backstage/plugin-catalog-graph@0.4.20 + - @backstage/plugin-notifications@0.5.6 + - @backstage/plugin-user-settings@0.8.23 + - @backstage/plugin-kubernetes@0.12.8 + - @backstage/plugin-api-docs@0.12.8 + - @backstage/plugin-devtools@0.1.28 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/plugin-signals@0.0.20 + - @backstage/plugin-search@1.4.27 + - @backstage/plugin-home@0.8.9 + - @backstage/plugin-org@0.6.40 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-search-react@1.9.1 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/plugin-kubernetes-cluster@0.0.26 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search-common@1.2.18 + +## 0.2.110-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.33.0-next.2 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/canon@0.5.0-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-api-docs@0.12.8-next.2 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-graph@0.4.20-next.2 + - @backstage/plugin-catalog-import@0.13.1-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.2 + - @backstage/plugin-devtools@0.1.28-next.2 + - @backstage/plugin-home@0.8.9-next.2 + - @backstage/plugin-kubernetes@0.12.8-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.2 + - @backstage/plugin-notifications@0.5.6-next.2 + - @backstage/plugin-org@0.6.40-next.2 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-scaffolder@1.32.0-next.2 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + - @backstage/plugin-search@1.4.27-next.2 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/plugin-signals@0.0.20-next.1 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/plugin-user-settings@0.8.23-next.2 + +## 0.2.110-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/cli@0.33.0-next.1 + - @backstage/canon@0.5.0-next.2 + - @backstage/plugin-notifications@0.5.6-next.2 + - @backstage/plugin-scaffolder@1.32.0-next.2 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-catalog-react@1.19.0-next.2 + - @backstage/plugin-catalog-import@0.13.1-next.2 + - @backstage/plugin-home@0.8.9-next.2 + - @backstage/plugin-search-react@1.9.1-next.1 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-api-docs@0.12.8-next.2 + - @backstage/plugin-auth-react@0.1.16-next.0 + - @backstage/plugin-catalog-graph@0.4.20-next.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.2 + - @backstage/plugin-devtools@0.1.28-next.2 + - @backstage/plugin-kubernetes@0.12.8-next.2 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.2 + - @backstage/plugin-org@0.6.40-next.2 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + - @backstage/plugin-search@1.4.27-next.2 + - @backstage/plugin-signals@0.0.20-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/plugin-user-settings@0.8.23-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-search-common@1.2.18 + +## 0.2.110-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0-next.1 + - @backstage/cli@0.32.2-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.1 + - @backstage/plugin-techdocs@1.13.0-next.1 + - @backstage/plugin-org@0.6.40-next.1 + - @backstage/plugin-user-settings@0.8.23-next.1 + - @backstage/plugin-notifications@0.5.6-next.1 + - @backstage/plugin-catalog@1.31.0-next.1 + - @backstage/plugin-catalog-graph@0.4.20-next.1 + - @backstage/plugin-catalog-import@0.13.1-next.1 + - @backstage/plugin-catalog-react@1.18.1-next.1 + - @backstage/plugin-home@0.8.9-next.1 + - @backstage/plugin-scaffolder@1.31.1-next.1 + - @backstage/plugin-scaffolder-react@1.16.1-next.1 + - @backstage/app-defaults@1.6.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/frontend-app-api@0.11.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/plugin-api-docs@0.12.8-next.1 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.1 + - @backstage/plugin-devtools@0.1.28-next.1 + - @backstage/plugin-kubernetes@0.12.8-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.1 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-search@1.4.27-next.1 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-signals@0.0.20-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## 0.2.110-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder@1.31.1-next.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18-next.0 + - @backstage/plugin-catalog-import@0.13.1-next.0 + - @backstage/plugin-catalog-graph@0.4.20-next.0 + - @backstage/plugin-notifications@0.5.6-next.0 + - @backstage/plugin-user-settings@0.8.23-next.0 + - @backstage/plugin-kubernetes@0.12.8-next.0 + - @backstage/plugin-api-docs@0.12.8-next.0 + - @backstage/plugin-devtools@0.1.28-next.0 + - @backstage/plugin-techdocs@1.13.0-next.0 + - @backstage/plugin-catalog@1.31.0-next.0 + - @backstage/plugin-signals@0.0.20-next.0 + - @backstage/plugin-search@1.4.27-next.0 + - @backstage/plugin-home@0.8.9-next.0 + - @backstage/plugin-org@0.6.40-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/frontend-app-api@0.11.3-next.0 + - @backstage/canon@0.5.0-next.0 + - @backstage/plugin-scaffolder-react@1.16.1-next.0 + - @backstage/cli@0.32.1 + - @backstage/plugin-catalog-react@1.18.1-next.0 + - @backstage/plugin-search-react@1.9.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.26-next.0 + - @backstage/integration-react@1.2.7 + +## 0.2.109 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/canon@0.4.0 + - @backstage/cli@0.32.1 + - @backstage/plugin-user-settings@0.8.22 + - @backstage/core-components@0.17.2 + - @backstage/plugin-home@0.8.8 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-scaffolder@1.31.0 + - @backstage/frontend-app-api@0.11.2 + - @backstage/plugin-catalog-unprocessed-entities@0.2.17 + - @backstage/plugin-catalog-import@0.13.0 + - @backstage/plugin-catalog-graph@0.4.19 + - @backstage/plugin-notifications@0.5.5 + - @backstage/plugin-kubernetes@0.12.7 + - @backstage/plugin-api-docs@0.12.7 + - @backstage/plugin-devtools@0.1.27 + - @backstage/plugin-techdocs@1.12.6 + - @backstage/plugin-catalog@1.30.0 + - @backstage/plugin-signals@0.0.19 + - @backstage/plugin-search@1.4.26 + - @backstage/plugin-org@0.6.39 + - @backstage/plugin-search-react@1.9.0 + - @backstage/plugin-catalog-react@1.18.0 + - @backstage/plugin-scaffolder-react@1.16.0 + - @backstage/plugin-kubernetes-cluster@0.0.25 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/plugin-auth-react@0.1.15 + - @backstage/core-plugin-api@1.10.7 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.24 + - @backstage/app-defaults@1.6.2 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-search-common@1.2.18 + ## 0.2.109-next.3 ### Patch Changes diff --git a/packages/app/e2e-tests/HomePage.test.ts b/packages/app/e2e-tests/HomePage.test.ts index 0b1459935f..f495fb08d9 100644 --- a/packages/app/e2e-tests/HomePage.test.ts +++ b/packages/app/e2e-tests/HomePage.test.ts @@ -35,7 +35,7 @@ test('Should not throw `ResizeObserver loop completed with undelivered notificat ).not.toBeVisible(); }); -test('Should resize widgets vertically and horizontally', async ({ page }) => { +test('Should render some home page widgets', async ({ page }) => { await page.goto('/'); const enterButton = page.getByRole('button', { name: 'Enter' }); @@ -43,32 +43,6 @@ test('Should resize widgets vertically and horizontally', async ({ page }) => { await enterButton.click(); await page.goto('/home'); - await expect(page.getByText('Backstage Example App')).toBeVisible(); - - // Start editing mode - await page.getByRole('button', { name: /Edit/ }).click(); - await expect(page.getByRole('button', { name: /Save/ })).toBeVisible(); - - // Resize the last installed widget - const widgetElement = await page.locator('.react-grid-item:nth-child(3)'); - const defaultWidgetBox = { x: 1, y: 1, width: 1, height: 1 }; - const widgetBoxBefore = - (await widgetElement.boundingBox()) ?? defaultWidgetBox; - const widgetResizeHandle = await widgetElement.locator( - '.react-resizable-handle', - ); - await widgetResizeHandle.hover(); - await page.mouse.down(); - await page.mouse.move(widgetBoxBefore.width / 2, widgetBoxBefore.height / 2); - await page.mouse.up(); - const widgetBoxAfter = - (await widgetElement.boundingBox()) ?? defaultWidgetBox; - - // Ensure that both height and width was reduced - expect(widgetBoxAfter.width).toBeLessThan(widgetBoxBefore.width); - expect(widgetBoxAfter.height).toBeLessThan(widgetBoxBefore.height); - - // Exit editing mode - await page.getByRole('button', { name: 'Save' }).click(); - await expect(page.getByRole('button', { name: /Edit/ })).toBeVisible(); + await expect(page.getByText('Top Visited')).toBeVisible(); + await expect(page.getByText('Recently Visited')).toBeVisible(); }); diff --git a/packages/app/knip-report.md b/packages/app/knip-report.md index b05d232915..753f119c52 100644 --- a/packages/app/knip-report.md +++ b/packages/app/knip-report.md @@ -4,26 +4,26 @@ | Name | Location | Severity | | :------------------------------ | :----------- | :------- | -| @backstage/plugin-search-common | package.json | error | -| @backstage/plugin-auth-react | package.json | error | -| @backstage/frontend-app-api | package.json | error | -| @material-ui/lab | package.json | error | -| zen-observable | package.json | error | -| @octokit/rest | package.json | error | -| react-router | package.json | error | -| history | package.json | error | +| @backstage/plugin-search-common | packages/app/package.json | error | +| @backstage/plugin-auth-react | packages/app/package.json | error | +| @backstage/frontend-app-api | packages/app/package.json | error | +| @material-ui/lab | packages/app/package.json | error | +| zen-observable | packages/app/package.json | error | +| @octokit/rest | packages/app/package.json | error | +| react-router | packages/app/package.json | error | +| history | packages/app/package.json | error | ## Unused devDependencies (3) | Name | Location | Severity | | :-------------------------- | :----------- | :------- | -| @testing-library/user-event | package.json | error | -| @types/zen-observable | package.json | error | -| @types/jquery | package.json | error | +| @testing-library/user-event | packages/app/package.json | error | +| @types/zen-observable | packages/app/package.json | error | +| @types/jquery | packages/app/package.json | error | ## Unlisted dependencies (1) | Name | Location | Severity | | :---------- | :------------------------------------------------------- | :------- | -| @rjsf/utils | src/components/scaffolder/customScaffolderExtensions.tsx | error | +| @rjsf/utils | packages/app/src/components/scaffolder/customScaffolderExtensions.tsx | error | diff --git a/packages/app/package.json b/packages/app/package.json index 2211307884..d6875be65b 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.109-next.3", + "version": "0.2.115-next.2", "backstage": { "role": "frontend" }, @@ -36,7 +36,6 @@ }, "dependencies": { "@backstage/app-defaults": "workspace:^", - "@backstage/canon": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/config": "workspace:^", @@ -57,6 +56,7 @@ "@backstage/plugin-home": "workspace:^", "@backstage/plugin-kubernetes": "workspace:^", "@backstage/plugin-kubernetes-cluster": "workspace:^", + "@backstage/plugin-mui-to-bui": "workspace:^", "@backstage/plugin-notifications": "workspace:^", "@backstage/plugin-org": "workspace:^", "@backstage/plugin-permission-react": "workspace:^", @@ -71,6 +71,7 @@ "@backstage/plugin-techdocs-react": "workspace:^", "@backstage/plugin-user-settings": "workspace:^", "@backstage/theme": "workspace:^", + "@backstage/ui": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", @@ -94,7 +95,7 @@ "@types/react": "*", "@types/react-dom": "*", "@types/zen-observable": "^0.8.0", - "axios": "^1.7.7", + "axios": "^1.13.0", "cross-env": "^7.0.0", "msw": "^1.0.0" }, diff --git a/packages/app/public/index.html b/packages/app/public/index.html index 9a8267e98e..9b67673b2e 100644 --- a/packages/app/public/index.html +++ b/packages/app/public/index.html @@ -4,6 +4,7 @@ + } @@ -232,6 +209,7 @@ const routes = ( {customDevToolsPage} } /> + } /> ); diff --git a/packages/app/src/AuthProxyDiscoveryApi.ts b/packages/app/src/AuthProxyDiscoveryApi.ts index 761803f0de..23d6e404db 100644 --- a/packages/app/src/AuthProxyDiscoveryApi.ts +++ b/packages/app/src/AuthProxyDiscoveryApi.ts @@ -20,12 +20,16 @@ import { DiscoveryApi } from '@backstage/core-plugin-api'; export class AuthProxyDiscoveryApi implements DiscoveryApi { private urlPatternDiscovery: UrlPatternDiscovery; + private readonly isAuthProxyingEnabled?: boolean; + private readonly authProxyUrl?: string; constructor( baseUrl: string, - private readonly isAuthProxyingEnabled?: boolean, - private readonly authProxyUrl?: string, + isAuthProxyingEnabled?: boolean, + authProxyUrl?: string, ) { + this.isAuthProxyingEnabled = isAuthProxyingEnabled; + this.authProxyUrl = authProxyUrl; this.urlPatternDiscovery = UrlPatternDiscovery.compile( `${baseUrl}/api/{{ pluginId }}`, ); diff --git a/packages/app/src/apis.ts b/packages/app/src/apis.ts index e39122337f..8a05f100bc 100644 --- a/packages/app/src/apis.ts +++ b/packages/app/src/apis.ts @@ -24,11 +24,15 @@ import { configApiRef, createApiFactory, discoveryApiRef, + fetchApiRef, + identityApiRef, } from '@backstage/core-plugin-api'; import { AuthProxyDiscoveryApi } from './AuthProxyDiscoveryApi'; import { formDecoratorsApiRef } from '@backstage/plugin-scaffolder/alpha'; import { DefaultScaffolderFormDecoratorsApi } from '@backstage/plugin-scaffolder/alpha'; import { mockDecorator } from './components/scaffolder/decorators'; +import { scaffolderApiRef } from '@backstage/plugin-scaffolder-react'; +import { ScaffolderClient } from '@backstage/plugin-scaffolder'; export const apis: AnyApiFactory[] = [ createApiFactory({ @@ -42,6 +46,24 @@ export const apis: AnyApiFactory[] = [ factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), }), + createApiFactory({ + api: scaffolderApiRef, + deps: { + discoveryApi: discoveryApiRef, + fetchApi: fetchApiRef, + scmIntegrationsApi: scmIntegrationsApiRef, + identityApi: identityApiRef, + }, + factory: ({ discoveryApi, fetchApi, scmIntegrationsApi, identityApi }) => + new ScaffolderClient({ + useLongPollingLogs: true, + discoveryApi, + fetchApi, + scmIntegrationsApi, + identityApi, + }), + }), + createApiFactory({ api: formDecoratorsApiRef, deps: {}, diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx index 6f2c85c934..cbf1bcb5f8 100644 --- a/packages/app/src/components/Root/Root.tsx +++ b/packages/app/src/components/Root/Root.tsx @@ -17,14 +17,9 @@ import { PropsWithChildren } from 'react'; import { makeStyles } from '@material-ui/core/styles'; import HomeIcon from '@material-ui/icons/Home'; -import RuleIcon from '@material-ui/icons/AssignmentTurnedIn'; -import MapIcon from '@material-ui/icons/MyLocation'; -import LayersIcon from '@material-ui/icons/Layers'; -import PlaylistPlayIcon from '@material-ui/icons/PlaylistPlay'; import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; import SearchIcon from '@material-ui/icons/Search'; import MenuIcon from '@material-ui/icons/Menu'; -import MoneyIcon from '@material-ui/icons/MonetizationOn'; import LogoFull from './LogoFull'; import LogoIcon from './LogoIcon'; import { @@ -48,10 +43,11 @@ import { } from '@backstage/core-components'; import { MyGroupsSidebarItem } from '@backstage/plugin-org'; import { SearchModal } from '../search/SearchModal'; -import Score from '@material-ui/icons/Score'; import { useApp } from '@backstage/core-plugin-api'; import BuildIcon from '@material-ui/icons/Build'; import { NotificationsSidebarItem } from '@backstage/plugin-notifications'; +import UpdateIcon from '@material-ui/icons/Update'; +import CategoryIcon from '@material-ui/icons/Category'; const useSidebarLogoStyles = makeStyles({ root: { @@ -93,7 +89,8 @@ export const Root = ({ children }: PropsWithChildren<{}>) => ( }> {/* Global nav, not org-specific */} - + + ) => ( to="docs" text="Docs" /> - - {/* End global nav */} - - - - - - + + } diff --git a/packages/app/src/components/home/CustomizableHomePage.tsx b/packages/app/src/components/home/CustomizableHomePage.tsx index 8998538e54..1d3cab646b 100644 --- a/packages/app/src/components/home/CustomizableHomePage.tsx +++ b/packages/app/src/components/home/CustomizableHomePage.tsx @@ -28,6 +28,7 @@ import { HomePageSearchBar } from '@backstage/plugin-search'; import Grid from '@material-ui/core/Grid'; import { tools, useLogoStyles } from './shared'; +import { WelcomeTitle } from '@backstage/plugin-home'; const defaultConfig = [ { @@ -36,6 +37,7 @@ const defaultConfig = [ y: 0, width: 24, height: 2, + deletable: false, }, { component: 'HomePageRecentlyVisited', @@ -81,6 +83,7 @@ export const CustomizableHomePage = () => { + diff --git a/packages/app/src/identityProviders.ts b/packages/app/src/identityProviders.ts index 66f1460210..372477cd63 100644 --- a/packages/app/src/identityProviders.ts +++ b/packages/app/src/identityProviders.ts @@ -23,6 +23,7 @@ import { oneloginAuthApiRef, bitbucketAuthApiRef, bitbucketServerAuthApiRef, + openshiftAuthApiRef, } from '@backstage/core-plugin-api'; export const providers = [ @@ -74,4 +75,10 @@ export const providers = [ message: 'Sign In using Bitbucket Server', apiRef: bitbucketServerAuthApiRef, }, + { + id: 'openshift-auth-provider', + title: 'OpenShift', + message: 'Sign In using OpenShift', + apiRef: openshiftAuthApiRef, + }, ]; diff --git a/packages/app/src/index-public-experimental.tsx b/packages/app/src/index-public-experimental.tsx index fb79eb921a..972c1fd55c 100644 --- a/packages/app/src/index-public-experimental.tsx +++ b/packages/app/src/index-public-experimental.tsx @@ -30,7 +30,7 @@ import { discoveryApiRef, } from '@backstage/core-plugin-api'; import { AuthProxyDiscoveryApi } from '../src/AuthProxyDiscoveryApi'; -import '@backstage/canon/css/styles.css'; +import '@backstage/ui/css/styles.css'; const app = createApp({ apis: [ diff --git a/packages/app/src/index.tsx b/packages/app/src/index.tsx index cb6eeb3185..05dcc024bf 100644 --- a/packages/app/src/index.tsx +++ b/packages/app/src/index.tsx @@ -17,6 +17,6 @@ import '@backstage/cli/asset-types'; import ReactDOM from 'react-dom/client'; import App from './App'; -import '@backstage/canon/css/styles.css'; +import '@backstage/ui/css/styles.css'; ReactDOM.createRoot(document.getElementById('root')!).render(); diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index efb30c1d7c..8514a08cf2 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,173 @@ # @backstage/backend-app-api +## 1.3.0-next.1 + +### Minor Changes + +- a17d9df: Updates API for `instanceMetadata` service to return a list of plugins not features. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## 1.2.9-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + +## 1.2.8 + +### Patch Changes + +- dd69cf6: Moved up registration of unhandled rejections and errors listeners to be done as early as possible, avoiding flakiness in backend startups and instead always logging these failures rather than sometimes crashing the process. +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + +## 1.2.8-next.1 + +### Patch Changes + +- dd69cf6: Moved up registration of unhandled rejections and errors listeners to be done as early as possible, avoiding flakiness in backend startups and instead always logging these failures rather than sometimes crashing the process. + +## 1.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + +## 1.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3 + +## 1.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## 1.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## 1.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## 1.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/backend-plugin-api@1.4.1 + +## 1.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + +## 1.2.4 + +### Patch Changes + +- bb9a501: Fixed a bug where occasionally the initialization order of multiple modules consuming a single extension point could happen in the wrong order. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## 1.2.4-next.2 + +### Patch Changes + +- bb9a501: Fixed a bug where occasionally the initialization order of multiple modules consuming a single extension point could happen in the wrong order. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## 1.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## 1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## 1.2.3 + +### Patch Changes + +- 729a7d6: Added a configuration to permit backend plugin module failures on startup: + + ```yaml + backend: + ... + startup: + plugins: + plugin-x: + modules: + module-y: + onPluginModuleBootFailure: continue + ``` + + This configuration permits `plugin-x` with `module-y` to fail on startup. Omitting the + `onPluginModuleBootFailure` configuration matches the previous behavior, wherein any + individual plugin module failure is forwarded to the plugin and aborts backend startup. + + The default can also be changed, so that continuing on failure is the default + unless otherwise specified: + + ```yaml + backend: + startup: + default: + onPluginModuleBootFailure: continue + plugins: + catalog: + modules: + github: + onPluginModuleBootFailure: abort + ``` + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + ## 1.2.3-next.2 ### Patch Changes diff --git a/packages/backend-app-api/knip-report.md b/packages/backend-app-api/knip-report.md index 13b4ec495e..d056972992 100644 --- a/packages/backend-app-api/knip-report.md +++ b/packages/backend-app-api/knip-report.md @@ -4,5 +4,5 @@ | Name | Location | Severity | | :-------------------------- | :----------- | :------- | -| @backstage/backend-defaults | package.json | error | +| @backstage/backend-defaults | packages/backend-app-api/package.json | error | diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 296630a1f6..b55d31a8a8 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": "1.2.3-next.2", + "version": "1.3.0-next.1", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-app-api/src/lib/DependencyGraph.test.ts b/packages/backend-app-api/src/lib/DependencyGraph.test.ts index 394359e486..8aafcb21aa 100644 --- a/packages/backend-app-api/src/lib/DependencyGraph.test.ts +++ b/packages/backend-app-api/src/lib/DependencyGraph.test.ts @@ -514,5 +514,21 @@ describe('DependencyGraph', () => { }).parallelTopologicalTraversal(async id => id), ).rejects.toThrow('Circular dependency detected'); }); + + it('awaits all producers', async () => { + await expect( + DependencyGraph.fromMap({ + 1: { provides: ['a'] }, + 2: { provides: ['a'] }, + 3: { consumes: ['a'] }, + }).parallelTopologicalTraversal(async id => { + // Delaying 2 should not make 3 run, wait for 1 too first + if (id === '2') { + await new Promise(resolve => setTimeout(resolve, 100)); + } + return id; + }), + ).resolves.toEqual(['1', '2', '3']); + }); }); }); diff --git a/packages/backend-app-api/src/lib/DependencyGraph.ts b/packages/backend-app-api/src/lib/DependencyGraph.ts index 86fad3fbf2..8e36c39aec 100644 --- a/packages/backend-app-api/src/lib/DependencyGraph.ts +++ b/packages/backend-app-api/src/lib/DependencyGraph.ts @@ -30,11 +30,15 @@ class Node { ); } - private constructor( - readonly value: T, - readonly consumes: Set, - readonly provides: Set, - ) {} + readonly value: T; + readonly consumes: Set; + readonly provides: Set; + + private constructor(value: T, consumes: Set, provides: Set) { + this.value = value; + this.consumes = consumes; + this.provides = provides; + } } /** @internal */ @@ -188,12 +192,25 @@ export class DependencyGraph { fn: (value: T) => Promise, ): Promise { const allProvided = this.#allProvided; - const producedSoFar = new Set(); const waiting = new Set(this.#nodes.values()); const visited = new Set>(); const results = new Array(); let inFlight = 0; // Keep track of how many callbacks are in flight, so that we know if we got stuck + // This keeps track of a counter of how many providers there are still left + // to be visited for each dependency. This needs to be a counter instead of + // a flag for the special case where there are several providers of a given + // value, even though there may be only one consumer of it. + const producedRemaining = new Map(); + for (const node of this.#nodes) { + for (const provided of node.provides) { + producedRemaining.set( + provided, + (producedRemaining.get(provided) ?? 0) + 1, + ); + } + } + // Find all nodes that have no dependencies that have not already been produced by visited nodes async function processMoreNodes() { if (waiting.size === 0) { @@ -203,7 +220,10 @@ export class DependencyGraph { for (const node of waiting) { let ready = true; for (const consumed of node.consumes) { - if (allProvided.has(consumed) && !producedSoFar.has(consumed)) { + if ( + allProvided.has(consumed) && + producedRemaining.get(consumed) !== 0 + ) { ready = false; continue; } @@ -234,7 +254,17 @@ export class DependencyGraph { const result = await fn(node.value); results.push(result); - node.provides.forEach(produced => producedSoFar.add(produced)); + node.provides.forEach(produced => { + const remaining = producedRemaining.get(produced); + if (!remaining) { + // This should be impossible, if the code that generates the map is correct + throw new Error( + `Internal error: Node provided superfluous dependency '${produced}'`, + ); + } + producedRemaining.set(produced, remaining - 1); + }); + inFlight -= 1; await processMoreNodes(); } diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts index 3b0596cd13..965e467501 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts @@ -22,9 +22,9 @@ import { createExtensionPoint, createBackendFeatureLoader, ServiceRef, + coreServices, } from '@backstage/backend-plugin-api'; import { BackendInitializer } from './BackendInitializer'; -import { instanceMetadataServiceRef } from '@backstage/backend-plugin-api/alpha'; import { mockServices } from '@backstage/backend-test-utils'; const baseFactories = [ @@ -57,6 +57,42 @@ const testPlugin = createBackendPlugin({ }); describe('BackendInitializer', () => { + it('should only load modules if the plugin is present', async () => { + let loadedModule = false; + const backend1 = new BackendInitializer(baseFactories); + const testModule = createBackendModule({ + pluginId: 'test', + moduleId: 'producer', + register(reg) { + reg.registerInit({ + deps: {}, + async init() { + loadedModule = true; + }, + }); + }, + }); + await backend1.add(testModule); + await backend1.start(); + expect(loadedModule).toBe(false); + + const backend2 = new BackendInitializer(baseFactories); + await backend2.add(testModule); + await backend2.add( + createBackendPlugin({ + pluginId: 'test', + register(reg) { + reg.registerInit({ + deps: {}, + async init() {}, + }); + }, + }), + ); + await backend2.start(); + expect(loadedModule).toBe(true); + }); + it('should initialize root scoped services', async () => { const ref1 = createServiceRef<{ x: number }>({ id: '1', @@ -1074,7 +1110,7 @@ describe('BackendInitializer', () => { }); it('should properly add plugins + modules to the instance metadata service', async () => { - expect.assertions(2); + expect.assertions(1); const backend = new BackendInitializer(baseFactories); const plugin = createBackendPlugin({ pluginId: 'test', @@ -1090,31 +1126,25 @@ describe('BackendInitializer', () => { register(reg) { reg.registerInit({ deps: { - instanceMetadata: instanceMetadataServiceRef, + instanceMetadata: coreServices.rootInstanceMetadata, }, async init({ instanceMetadata }) { - expect(instanceMetadata.getInstalledFeatures()).toEqual([ + await expect( + instanceMetadata.getInstalledPlugins(), + ).resolves.toEqual([ { pluginId: 'test', - type: 'plugin', - }, - { - pluginId: 'test', - moduleId: 'test', - type: 'module', + modules: [ + { + moduleId: 'test', + }, + ], }, { pluginId: 'instance-metadata', - type: 'plugin', + modules: [], }, ]); - expect(instanceMetadata.getInstalledFeatures().map(String)).toEqual( - [ - 'plugin{pluginId=test}', - 'module{moduleId=test,pluginId=test}', - 'plugin{pluginId=instance-metadata}', - ], - ); }, }); }, @@ -1134,4 +1164,129 @@ describe('BackendInitializer', () => { backend.add(instanceMetadataPlugin); await backend.start(); }); + + it('should ignore modules that do not have a matching plugin', async () => { + expect.assertions(1); + const backend = new BackendInitializer(baseFactories); + const instanceMetadataPlugin = createBackendPlugin({ + pluginId: 'instance-metadata', + register(reg) { + reg.registerInit({ + deps: { + instanceMetadata: coreServices.rootInstanceMetadata, + }, + async init({ instanceMetadata }) { + await expect( + instanceMetadata.getInstalledPlugins(), + ).resolves.toEqual([ + { + pluginId: 'instance-metadata', + modules: [], + }, + ]); + }, + }); + }, + }); + const module = createBackendModule({ + pluginId: 'test', + moduleId: 'test', + register(reg) { + reg.registerInit({ + deps: {}, + async init() {}, + }); + }, + }); + backend.add(module); + backend.add(instanceMetadataPlugin); + await backend.start(); + }); + + it('should prevent writes to the instance metadata service', async () => { + expect.assertions(1); + const backend = new BackendInitializer(baseFactories); + const plugin = createBackendPlugin({ + pluginId: 'test', + register(reg) { + reg.registerInit({ + deps: { + instanceMetadata: coreServices.rootInstanceMetadata, + }, + async init({ instanceMetadata }) { + const plugins = await instanceMetadata.getInstalledPlugins(); + await expect(() => { + (plugins[0] as any).pluginId = 'foo'; + }).toThrow(/Cannot assign to read only property/); + }, + }); + }, + }); + backend.add(plugin); + await backend.start(); + }); + + it('should properly wait for all modules that consume an extension point to really finish, before starting the module that provides that extension point', async () => { + expect.assertions(3); + const backend = new BackendInitializer(baseFactories); + const ext = createExtensionPoint<{ hello: (message: string) => void }>({ + id: 'a', + }); + const plugin = createBackendPlugin({ + pluginId: 'test', + register(reg) { + reg.registerInit({ + deps: {}, + async init() {}, + }); + }, + }); + const producerModule = createBackendModule({ + pluginId: 'test', + moduleId: 'producer', + register(reg) { + const hello = jest.fn(); + reg.registerExtensionPoint(ext, { hello }); + reg.registerInit({ + deps: {}, + async init() { + // we must not have been initialized before both of the consuming modules have been initialized + expect(hello).toHaveBeenCalledTimes(2); + expect(hello).toHaveBeenNthCalledWith(1, 'fast'); + expect(hello).toHaveBeenNthCalledWith(2, 'slow'); + }, + }); + }, + }); + const fastConsumerModule = createBackendModule({ + pluginId: 'test', + moduleId: 'fast-consumer', + register(reg) { + reg.registerInit({ + deps: { x: ext }, + async init({ x }) { + x.hello('fast'); + }, + }); + }, + }); + const slowConsumerModule = createBackendModule({ + pluginId: 'test', + moduleId: 'slow-consumer', + register(reg) { + reg.registerInit({ + deps: { x: ext }, + async init({ x }) { + await new Promise(resolve => setTimeout(resolve, 100)); + x.hello('slow'); + }, + }); + }, + }); + await backend.add(plugin); + await backend.add(producerModule); + await backend.add(fastConsumerModule); + await backend.add(slowConsumerModule); + await backend.start(); + }); }); diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index 9b925adb30..e7480d3beb 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -36,14 +36,11 @@ import type { // eslint-disable-next-line @backstage/no-relative-monorepo-imports import type { InternalServiceFactory } from '../../../backend-plugin-api/src/services/system/types'; import { ForwardedError, ConflictError, assertError } from '@backstage/errors'; -import { - instanceMetadataServiceRef, - BackendFeatureMeta, -} from '@backstage/backend-plugin-api/alpha'; import { DependencyGraph } from '../lib/DependencyGraph'; import { ServiceRegistry } from './ServiceRegistry'; import { createInitializationLogger } from './createInitializationLogger'; -import { unwrapFeature } from './helpers'; +import { deepFreeze, unwrapFeature } from './helpers'; +import type { RootInstanceMetadataServicePluginInfo } from '@backstage/backend-plugin-api'; export interface BackendRegisterInit { consumes: Set; @@ -101,56 +98,52 @@ const instanceRegistry = new (class InstanceRegistry { }; })(); -function createInstanceMetadataServiceFactory( - registrations: InternalBackendRegistrations[], +function createRootInstanceMetadataServiceFactory( + rawRegistrations: InternalBackendRegistrations[], ) { - const installedFeatures = registrations - .map(registration => { - if (registration.featureType === 'registrations') { - return registration - .getRegistrations() - .map(feature => { - if (feature.type === 'plugin') { - return Object.defineProperty( - { - type: 'plugin', - pluginId: feature.pluginId, - }, - 'toString', - { - enumerable: false, - configurable: true, - value: () => `plugin{pluginId=${feature.pluginId}}`, - }, - ); - } else if (feature.type === 'module') { - return Object.defineProperty( - { - type: 'module', - pluginId: feature.pluginId, - moduleId: feature.moduleId, - }, - 'toString', - { - enumerable: false, - configurable: true, - value: () => - `module{moduleId=${feature.moduleId},pluginId=${feature.pluginId}}`, - }, - ); - } - // Ignore unknown feature types. - return undefined; - }) - .filter(Boolean) as BackendFeatureMeta[]; - } - return []; - }) - .flat(); + const installedPlugins: Map = + new Map(); + const registrations = rawRegistrations + .filter(registration => registration.featureType === 'registrations') + .flatMap(registration => registration.getRegistrations()); + const plugins = registrations.filter( + registration => registration.type === 'plugin', + ); + const modules = registrations.filter( + registration => registration.type === 'module', + ); + for (const plugin of plugins) { + const { pluginId } = plugin; + if (!installedPlugins.get(pluginId)) { + installedPlugins.set(pluginId, { + pluginId, + modules: [], + }); + } + } + for (const module of modules) { + const { pluginId, moduleId } = module; + const installedPlugin = installedPlugins.get(pluginId); + if (installedPlugin) { + (installedPlugin.modules as Array<{ moduleId: string }>).push({ + moduleId, + }); + } + } + return createServiceFactory({ - service: instanceMetadataServiceRef, + service: coreServices.rootInstanceMetadata, deps: {}, - factory: async () => ({ getInstalledFeatures: () => installedFeatures }), + factory: async () => { + const readonlyInstalledPlugins = deepFreeze([ + ...installedPlugins.values(), + ]); + const instanceMetadata = { + getInstalledPlugins: () => Promise.resolve(readonlyInstalledPlugins), + }; + + return instanceMetadata; + }, }); } @@ -255,9 +248,33 @@ export class BackendInitializer { await this.#applyBackendFeatureLoaders(this.#registeredFeatureLoaders); this.#serviceRegistry.add( - createInstanceMetadataServiceFactory(this.#registrations), + createRootInstanceMetadataServiceFactory(this.#registrations), ); + // This makes sure that any uncaught errors or unhandled rejections are + // caught and logged, rather than terminating the process. We register these + // as early as possible while still using the root logger service, the + // tradeoff that if there are any unhandled errors as part of the that + // instationation, it will cause the process to crash. If there are multiple + // backend instances, each instance will log the error, because we can't + // determine which instance the error came from. + if (process.env.NODE_ENV !== 'test') { + const rootLogger = await this.#serviceRegistry.get( + coreServices.rootLogger, + 'root', + ); + process.on('unhandledRejection', (reason: Error) => { + rootLogger + ?.child({ type: 'unhandledRejection' }) + ?.error('Unhandled rejection', reason); + }); + process.on('uncaughtException', error => { + rootLogger + ?.child({ type: 'uncaughtException' }) + ?.error('Uncaught exception', error); + }); + } + // Initialize all root scoped services await this.#serviceRegistry.initializeEagerServicesWithScope('root'); @@ -449,25 +466,6 @@ export class BackendInitializer { await lifecycleService.startup(); initLogger.onAllStarted(); - - // Once the backend is started, any uncaught errors or unhandled rejections are caught - // and logged, in order to avoid crashing the entire backend on local failures. - if (process.env.NODE_ENV !== 'test') { - const rootLogger = await this.#serviceRegistry.get( - coreServices.rootLogger, - 'root', - ); - process.on('unhandledRejection', (reason: Error) => { - rootLogger - ?.child({ type: 'unhandledRejection' }) - ?.error('Unhandled rejection', reason); - }); - process.on('uncaughtException', error => { - rootLogger - ?.child({ type: 'uncaughtException' }) - ?.error('Uncaught exception', error); - }); - } } // It's fine to call .stop() multiple times, which for example can happen with manual stop + process exit diff --git a/packages/backend-app-api/src/wiring/helpers.ts b/packages/backend-app-api/src/wiring/helpers.ts index ffb7e3b079..1be7f62da2 100644 --- a/packages/backend-app-api/src/wiring/helpers.ts +++ b/packages/backend-app-api/src/wiring/helpers.ts @@ -34,3 +34,22 @@ export function unwrapFeature( return feature; } + +/** @internal */ +export type DeepReadonly = { + readonly [K in keyof T]: T[K] extends object ? DeepReadonly : T[K]; +}; + +/** + * Deeply freezes an object by recursively freezing all of its properties. + * From https://gist.github.com/tkrotoff/e997cd6ff8d6cf6e51e6bb6146407fc3 + + * https://stackoverflow.com/a/69656011 + */ +export function deepFreeze(obj: T) { + // Can cause: "Type instantiation is excessively deep and possibly infinite." + // @ts-expect-error + Object.values(obj).forEach( + value => Object.isFrozen(value) || deepFreeze(value), + ); + return Object.freeze(obj) as DeepReadonly; +} diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 8487aa29f9..f168e43ee4 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,398 @@ # @backstage/backend-defaults +## 0.13.1-next.1 + +### Patch Changes + +- 91ab2eb: Fix a bug in the Gitlab URL reader where `search` did not handle multiple globs +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-app-api@1.3.0-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## 0.13.1-next.0 + +### Patch Changes + +- 9bcfa77: Adjusted the log line wording of task worker starting +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- b2f6a5a: Fix #31348 issue where BitbucketUrlReader ignored provided token and instead always used integration credentials +- Updated dependencies + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-app-api@1.2.9-next.0 + - @backstage/config-loader@1.10.6-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/cli-node@0.2.15-next.0 + - @backstage/integration@1.18.2-next.0 + - @backstage/integration-aws-node@0.1.19-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## 0.13.0 + +### Minor Changes + +- 2d3e2b2: implement support for direct url for AzureBlobStorageUrlReader search function +- 8b91238: Adds support for configuring server-level HTTP options through the + `app-config.yaml` file under the `backend.server` key. Supported options + include `headersTimeout`, `keepAliveTimeout`, `requestTimeout`, `timeout`, + `maxHeadersCount`, and `maxRequestsPerSocket`. + + These are passed directly to the underlying Node.js HTTP server. + If omitted, Node.js defaults are used. + +- 8495b18: Add a new `externalTokenHandlersServiceRef` to allow custom external token validations + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@1.2.8 + - @backstage/integration@1.18.1 + - @backstage/config-loader@1.10.5 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/integration-aws-node@0.1.18 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-permission-node@0.10.5 + +## 0.13.0-next.2 + +### Minor Changes + +- 8495b18: Add a new `externalTokenHandlersServiceRef` to allow custom external token validations + +## 0.13.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/integration-aws-node@0.1.18-next.0 + - @backstage/backend-app-api@1.2.8-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/cli-node@0.2.14 + +## 0.13.0-next.0 + +### Minor Changes + +- 2d3e2b2: implement support for direct url for AzureBlobStorageUrlReader search function +- 8b91238: Adds support for configuring server-level HTTP options through the + `app-config.yaml` file under the `backend.server` key. Supported options + include `headersTimeout`, `keepAliveTimeout`, `requestTimeout`, `timeout`, + `maxHeadersCount`, and `maxRequestsPerSocket`. + + These are passed directly to the underlying Node.js HTTP server. + If omitted, Node.js defaults are used. + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/backend-app-api@1.2.7 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/cli-node@0.2.14 + - @backstage/config@1.3.3 + - @backstage/config-loader@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.2 + - @backstage/plugin-events-node@0.4.15 + +## 0.12.1 + +### Patch Changes + +- 33bd4d0: Deduplicate discovered features discovered with discoveryFeatureLoader +- 4eda590: Fixed cache namespace and key prefix separator configuration to properly use configured values instead of hardcoded plugin ID. The cache manager now correctly combines the configured namespace with plugin IDs using the configured separator for Redis and Valkey. Memcache and memory store continue to use plugin ID as namespace. +- f244e61: Add `backend.logger` config options to configure the `RootLoggerService`. + + Read more about the new configuration options in the + [Root Logger Service](https://backstage.io/docs/backend-system/core-services/root-logger/) + documentation. + +- Updated dependencies + - @backstage/config-loader@1.10.3 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-node@0.4.15 + - @backstage/integration@1.18.0 + - @backstage/types@1.2.2 + - @backstage/backend-app-api@1.2.7 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-permission-node@0.10.4 + +## 0.12.1-next.1 + +### Patch Changes + +- 4eda590: Fixed cache namespace and key prefix separator configuration to properly use configured values instead of hardcoded plugin ID. The cache manager now correctly combines the configured namespace with plugin IDs using the configured separator for Redis and Valkey. Memcache and memory store continue to use plugin ID as namespace. +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/integration@1.18.0-next.0 + - @backstage/integration-aws-node@0.1.17 + +## 0.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/backend-app-api@1.2.7-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## 0.12.0 + +### Minor Changes + +- 133519b: feat: new cache manager `Infinispan Data Grid` + +### Patch Changes + +- caee2eb: Fixed WinstonLogger throwing when redactions were null or undefined +- ed74af5: Fixed bug in PackageDiscoveryService where packages with "exports" field caused ERR_PACKAGE_PATH_NOT_EXPORTED error during backend startup. +- 3a7dad9: Updated `better-sqlite3` to v12 +- Updated dependencies + - @backstage/cli-node@0.2.14 + - @backstage/backend-app-api@1.2.6 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## 0.11.2-next.0 + +### Patch Changes + +- caee2eb: Fixed WinstonLogger throwing when redactions were null or undefined +- 3a7dad9: Updated `better-sqlite3` to v12 +- Updated dependencies + - @backstage/backend-app-api@1.2.6-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.2 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/types@1.2.1 + +## 0.11.1 + +### Patch Changes + +- ead925a: Add a standard `toString` on credentials objects +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/config-loader@1.10.2 + - @backstage/config@1.3.3 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/integration@1.17.1 + - @backstage/backend-app-api@1.2.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/integration-aws-node@0.1.17 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-events-node@0.4.13 + +## 0.11.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/integration-aws-node@0.1.17-next.0 + - @backstage/backend-app-api@1.2.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## 0.11.1-next.0 + +### Patch Changes + +- ead925a: Add a standard `toString` on credentials objects +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-app-api@1.2.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## 0.11.0 + +### Minor Changes + +- 3ccb7fc: Enhanced error handling in the auditor service factory to pass errors as objects. Aligned WinstonRootAuditorService with the default service factory's error handling. + +### Patch Changes + +- 1220cf8: Added new rate limit middleware to allow rate limiting requests to the backend + + If you are using the `configure` callback of the root HTTP router service and do NOT call `applyDefaults()` inside it, please see [the relevant changes](https://github.com/backstage/backstage/pull/28708/files#diff-86ad1b6a694dd250823aee39d410428dd837c9d9a04ca8c33bd1081fbe3f22af) that were made, to see if you want to apply them as well to your custom configuration. + Rate limiting can be turned on by adding the following configuration to `app-config.yaml`: + + ```yaml + backend: + rateLimit: + window: 6s + incomingRequestLimit: 100 + ``` + + Plugin specific rate limiting can be configured by adding the following configuration to `app-config.yaml`: + + ```yaml + backend: + rateLimit: + global: false # This will disable the global rate limiting + plugin: + catalog: + window: 6s + incomingRequestLimit: 100 + ``` + +- c999c25: Added some default implementations for the experimental `ActionsService` and `ActionsRegistryService` under `/alpha` that allow registration of actions for a particular plugin. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-app-api@1.2.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-node@0.10.1 + +## 0.11.0-next.2 + +### Minor Changes + +- 3ccb7fc: Enhanced error handling in the auditor service factory to pass errors as objects. Aligned WinstonRootAuditorService with the default service factory's error handling. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@1.2.4-next.2 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## 0.10.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-app-api@1.2.4-next.1 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## 0.10.1-next.0 + +### Patch Changes + +- c999c25: Added some default implementations for the `ActionsService` and `ActionsRegistryService` that allow registration of actions for a particular plugin. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-app-api@1.2.4-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## 0.10.0 + +### Minor Changes + +- d385854: **BREAKING**: The `DefaultSchedulerService` constructor options now requires `RootLifecycleService`, `HttpRouterService`, and `PluginMetadataService` fields. + + The scheduler will register a REST API for listing and triggering tasks. Please see [the scheduler documentation](https://backstage.io/docs/backend-system/core-services/scheduler) for more details about this API. + +### Patch Changes + +- 1e06afd: `GithubUrlReader`'s search detects glob-patterns supported by `minimatch`, instead of just detecting + `*` and `?` characters. + + For example, this allows to search for patterns like `{C,c}atalog-info.yaml`. + +- acea1d4: update documentation +- 72d019d: Removed various typos +- c6bc67d: Added Valkey support alongside Redis in backend-defaults cache clients, using the new Keyv Valkey package. Also extended backend-test-utils to support Valkey in tests. +- 36f77e9: Bug fix: Pass user provided token through to gitlab url resolvers +- 0e7a640: The `GithubUrlReader` will now use the token from `options` when fetching repo details +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/backend-app-api@1.2.3 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/config-loader@1.10.1 + - @backstage/integration-aws-node@0.1.16 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + ## 0.10.0-next.3 ### Patch Changes diff --git a/packages/backend-defaults/config.d.ts b/packages/backend-defaults/config.d.ts index 14732bbccd..f0632a37bb 100644 --- a/packages/backend-defaults/config.d.ts +++ b/packages/backend-defaults/config.d.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { HumanDuration } from '@backstage/types'; +import { HumanDuration, JsonObject } from '@backstage/types'; export interface Config { app: { @@ -95,6 +95,31 @@ export interface Config { }; }; + /** + * Server-level HTTP options configuration for the backend. + * These options are passed directly to the underlying Node.js HTTP server. + * + * Timeout values support multiple formats: + * - A number in milliseconds + * - A string in the format of '1d', '2 seconds' etc. as supported by the `ms` library + * - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M' + * - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }` + */ + server?: { + /** Sets the timeout value for receiving the complete HTTP headers from the client. */ + headersTimeout?: number | string | HumanDuration; + /** Sets the timeout value for receiving the entire request (headers and body) from the client. */ + requestTimeout?: number | string | HumanDuration; + /** Sets the timeout value for inactivity on a socket during keep-alive. */ + keepAliveTimeout?: number | string | HumanDuration; + /** Sets the timeout value for sockets. */ + timeout?: number | string | HumanDuration; + /** Limits maximum incoming headers count. */ + maxHeadersCount?: number; + /** Sets the maximum number of requests socket can handle before closing keep alive connection. */ + maxRequestsPerSocket?: number; + }; + /** * Options used by the default auditor service. */ @@ -121,6 +146,16 @@ export interface Config { }; }; + /** + * Options used by the default actions service. + */ + actions?: { + /** + * List of plugin sources to load actions from. + */ + pluginSources?: string[]; + }; + /** * Options used by the default auth, httpAuth and userInfo services. */ @@ -740,6 +775,201 @@ export interface Config { connection: string; /** An optional default TTL (in milliseconds). */ defaultTtl?: number | HumanDuration | string; + } + | { + /** + * Infinispan cache store configuration. + * @see https://docs.jboss.org/infinispan/hotrod-clients/javascript/1.0/apidocs/module-infinispan.html + */ + store: 'infinispan'; + + /** + * An optional default TTL (in milliseconds). + */ + defaultTtl?: number | HumanDuration | string; + + /** + * Configuration for the Infinispan cache store. + */ + infinispan?: { + /** + * Version of client/server protocol. + * @default '2.9' is the latest version. + */ + version?: '2.9' | '2.5' | '2.2'; + + /** + * Infinispan Cache Name if not provided default is `cache` recommended to set this. + */ + cacheName?: string; + + /** + * Optional number of retries for operation. + * Defaults to 3. + */ + maxRetries?: number; + + /** + * Optional flag to controls whether the client deals with topology updates or not. + * @default true + */ + topologyUpdates?: boolean; + + /** + * Media type of the cache contents. + * @default 'text/plain' + */ + mediaType?: 'text/plain' | 'application/json'; + + /** + * Optional data format configuration. + * If not provided, defaults to text/plain for both key and value. + */ + dataFormat?: { + /** + * Type of the key in the cache. + * @default 'text/plain' + */ + keyType?: 'text/plain' | 'application/json'; + /** + * Type of the value in the cache. + * @default 'text/plain' + */ + valueType?: 'text/plain' | 'application/json'; + }; + /** + * Infinispan server host and port configuration. + * If this is an array, the client will connect to all servers in the list based on TOPOLOGY_AWARE routing. + * If this is a single object, it will be used as the default server. + */ + servers?: + | Array<{ + /** + * Infinispan server host. + */ + host: string; + /** + * Infinispan server port (Hot Rod protocol). Defaults to `11222`. + */ + port?: number; + }> + | { + /** + * Infinispan server host. Defaults to `127.0.0.1`. + */ + host?: string; + /** + * Infinispan server port (Hot Rod protocol). Defaults to `11222`. + */ + port?: number; + }; + authentication?: { + /** + * Enable authentication. Defaults to `false`. + */ + enabled?: boolean; + /** + * Select the SASL mechanism to use. Can be one of PLAIN, DIGEST-MD5, SCRAM-SHA-1, SCRAM-SHA-256, SCRAM-SHA-384, SCRAM-SHA-512, EXTERNAL, OAUTHBEARER + */ + saslMechanism?: string; + /** + * userName for authentication. + */ + userName?: string; + /** + * Password for authentication. + * @visibility secret + */ + password?: string; + /** + * The OAuth token. Required by the OAUTHBEARER mechanism. + * @visibility secret + */ + token?: string; + /** + * The SASL authorization ID. + */ + authzid?: string; + }; + + /** + * TLS/SSL configuration. + */ + ssl?: { + /** + * Enable ssl connection. Defaults to `false`. + * @default false + */ + enabled?: boolean; + + /** + * Optional field with secure protocol in use. + * @default TLSv1_2_method + */ + secureProtocol?: string; + + /** + * Optional paths of trusted SSL certificates. + */ + trustCerts?: Array; + + clientAuth?: { + /** + * Optional path to client authentication key + */ + key?: string; + /** + * Optional password for client key + */ + passphrase?: string; + /** + * Optional client certificate + */ + cert?: string; + }; + + /** + * Optional SNI host name. + */ + sniHostName?: string; + + /** + * Optional crypto store configuration. + */ + cryptoStore?: { + /** Optional crypto store path. */ + path?: string; + /** Optional password for crypto store. */ + passphrase?: string; + }; + }; + + /** + * Optional additional clusters for cross-site failovers. + * Array. + */ + clusters?: Array<{ + /** + * Optional Cluster name + */ + name?: string; + + /** + * Cluster servers details. + * Array. + */ + servers: Array<{ + /** + * Infinispan cluster server host. + */ + host: string; + /** + * Infinispan server port (Hot Rod protocol). Defaults to `11222`. + */ + port?: number; + }>; + }>; + }; }; cors?: { @@ -780,6 +1010,152 @@ export interface Config { headers?: { [name: string]: string }; }; + /** + * Options to configure the default RootLoggerService. + */ + logger?: { + /** + * Configures the global log level for messages. + * + * This can also be configured using the LOG_LEVEL environment variable, which + * takes precedence over this configuration. + * + * Defaults to 'info'. + */ + level?: 'debug' | 'info' | 'warn' | 'error'; + + /** + * Additional metadata to include with every log entry. + */ + meta?: JsonObject; + + /** + * List of logger overrides. + * + * Can be used to configure a different level for logs matching certain criterias. + * For example, it can be used to ignore 'info' logs of given plugins. + * + * @example + * + * ```yaml + * logger: + * level: info + * overrides: + * # For catalog and auth plugins, messages less important than 'warn' will be ignored. + * - matchers: + * plugin: [catalog, auth] + * level: warn + * # Ignore all messages that starts with 'Forget' + * - matchers: + * message: '/^Forget/' + * level: warn + * ``` + */ + overrides?: Array<{ + /** + * Conditions that must be met to override the log level. + * + * A matcher can be: + * + * - A string (exact match or regex pattern delimited by slashes, e.g. `/pattern/`) + * - A non-string value (compared by strict equality) + * - An array of matchers (returns true if any matcher matches) + */ + matchers: JsonObject; + + /** + * Log level to use for matched entries. + */ + level: 'debug' | 'info' | 'warn' | 'error'; + }>; + }; + + /** + * Rate limiting options. Defining this as `true` will enable rate limiting with default values. + */ + rateLimit?: + | true + | { + store?: + | { + type: 'redis'; + connection: string; + } + | { + type: 'memory'; + }; + /** + * Enable/disable global rate limiting. If this is disabled, plugin specific rate limiting must be + * used. + */ + global?: boolean; + /** + * Time frame in milliseconds or as human duration for which requests are checked/remembered. + * Defaults to one minute. + */ + window?: string | HumanDuration; + /** + * The maximum number of connections to allow during the `window` before rate limiting the client. + * Defaults to 5. + */ + incomingRequestLimit?: number; + /** + * Whether to pass requests in case of store failure. + * Defaults to false. + */ + passOnStoreError?: boolean; + /** + * List of allowed IP addresses that are not rate limited. + * Defaults to [127.0.0.1, 0:0:0:0:0:0:0:1, ::1]. + */ + ipAllowList?: string[]; + /** + * Skip rate limiting for requests that have been successful. + * Defaults to false. + */ + skipSuccessfulRequests?: boolean; + /** + * Skip rate limiting for requests that have failed. + * Defaults to false. + */ + skipFailedRequests?: boolean; + /** Plugin specific rate limiting configuration */ + plugin?: { + [pluginId: string]: { + /** + * Time frame in milliseconds or as human duration for which requests are checked/remembered. + * Defaults to one minute. + */ + window?: string | HumanDuration; + /** + * The maximum number of connections to allow during the `window` before rate limiting the client. + * Defaults to 5. + */ + incomingRequestLimit?: number; + /** + * Whether to pass requests in case of store failure. + * Defaults to false. + */ + passOnStoreError?: boolean; + /** + * List of allowed IP addresses that are not rate limited. + * Defaults to [127.0.0.1, 0:0:0:0:0:0:0:1, ::1]. + */ + ipAllowList?: string[]; + /** + * Skip rate limiting for requests that have been successful. + * Defaults to false. + */ + skipSuccessfulRequests?: boolean; + /** + * Skip rate limiting for requests that have failed. + * Defaults to false. + */ + skipFailedRequests?: boolean; + }; + }; + }; + /** * Configuration related to URL reading, used for example for reading catalog info * files, scaffolder templates, and techdocs content. diff --git a/packages/backend-defaults/knip-report.md b/packages/backend-defaults/knip-report.md index 169963316a..8951112aaa 100644 --- a/packages/backend-defaults/knip-report.md +++ b/packages/backend-defaults/knip-report.md @@ -4,12 +4,12 @@ | Name | Location | Severity | | :------------- | :----------- | :------- | -| better-sqlite3 | package.json | error | -| mysql2 | package.json | error | +| better-sqlite3 | packages/backend-defaults/package.json | error | +| mysql2 | packages/backend-defaults/package.json | error | ## Referenced optional peerDependencies (1) | Name | Location | Severity | | :-------------------------------- | :----------- | :------- | -| @google-cloud/cloud-sql-connector | package.json | error | +| @google-cloud/cloud-sql-connector | packages/backend-defaults/package.json | error | diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index b3ff563e17..a089998dee 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.10.0-next.3", + "version": "0.13.1-next.1", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" @@ -39,6 +39,7 @@ "./scheduler": "./src/entrypoints/scheduler/index.ts", "./urlReader": "./src/entrypoints/urlReader/index.ts", "./userInfo": "./src/entrypoints/userInfo/index.ts", + "./alpha": "./src/alpha/index.ts", "./package.json": "./package.json" }, "main": "src/index.ts", @@ -102,6 +103,9 @@ "userInfo": [ "src/entrypoints/userInfo/index.ts" ], + "alpha": [ + "src/alpha/index.ts" + ], "package.json": [ "package.json" ] @@ -152,7 +156,7 @@ "@types/express": "^4.17.6", "archiver": "^7.0.0", "base64-stream": "^1.0.0", - "better-sqlite3": "^11.0.0", + "better-sqlite3": "^12.0.0", "compression": "^1.7.4", "concat-stream": "^2.0.0", "cookie": "^0.7.0", @@ -160,9 +164,11 @@ "cron": "^3.0.0", "express": "^4.17.1", "express-promise-router": "^4.1.0", + "express-rate-limit": "^7.5.0", "fs-extra": "^11.2.0", "git-url-parse": "^15.0.0", "helmet": "^6.0.0", + "infinispan": "^0.12.0", "is-glob": "^4.0.3", "jose": "^5.0.0", "keyv": "^5.2.1", @@ -179,6 +185,7 @@ "pg": "^8.11.3", "pg-connection-string": "^2.3.0", "pg-format": "^1.0.4", + "rate-limit-redis": "^4.2.0", "raw-body": "^2.4.1", "selfsigned": "^2.0.0", "tar": "^6.1.12", @@ -188,7 +195,8 @@ "winston-transport": "^4.5.0", "yauzl": "^3.0.0", "yn": "^4.0.0", - "zod": "^3.22.4" + "zod": "^3.22.4", + "zod-to-json-schema": "^3.20.4" }, "devDependencies": { "@aws-sdk/util-stream-node": "^3.350.0", diff --git a/packages/backend-defaults/report-alpha.api.md b/packages/backend-defaults/report-alpha.api.md new file mode 100644 index 0000000000..2ca3525946 --- /dev/null +++ b/packages/backend-defaults/report-alpha.api.md @@ -0,0 +1,33 @@ +## 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 { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha'; +import { ActionsService } from '@backstage/backend-plugin-api/alpha'; +import { InstanceMetadataService } from '@backstage/backend-plugin-api/alpha'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @public (undocumented) +export const actionsRegistryServiceFactory: ServiceFactory< + ActionsRegistryService, + 'plugin', + 'singleton' +>; + +// @public (undocumented) +export const actionsServiceFactory: ServiceFactory< + ActionsService, + 'plugin', + 'singleton' +>; + +// @alpha @deprecated (undocumented) +export const instanceMetadataServiceFactory: ServiceFactory< + InstanceMetadataService, + 'plugin', + 'singleton' +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-defaults/report-auditor.api.md b/packages/backend-defaults/report-auditor.api.md index 353b6f241f..cc00b5c349 100644 --- a/packages/backend-defaults/report-auditor.api.md +++ b/packages/backend-defaults/report-auditor.api.md @@ -8,6 +8,7 @@ import type { AuditorServiceCreateEventOptions } from '@backstage/backend-plugin import type { AuditorServiceEvent } from '@backstage/backend-plugin-api'; import type { AuditorServiceEventSeverityLevel } from '@backstage/backend-plugin-api'; import type { AuthService } from '@backstage/backend-plugin-api'; +import { Config } from '@backstage/config'; import type { Format } from 'logform'; import type { HttpAuthService } from '@backstage/backend-plugin-api'; import type { JsonObject } from '@backstage/types'; @@ -58,7 +59,7 @@ export type AuditorEventStatus = } | { status: 'failed'; - error: string; + error: Error; }; // @public @@ -95,6 +96,7 @@ export class WinstonRootAuditorService { // (undocumented) forPlugin(deps: { auth: AuthService; + config: Config; httpAuth: HttpAuthService; plugin: PluginMetadataService; }): AuditorService; diff --git a/packages/backend-defaults/report-auth.api.md b/packages/backend-defaults/report-auth.api.md index 1883e65a6a..2fc0f16452 100644 --- a/packages/backend-defaults/report-auth.api.md +++ b/packages/backend-defaults/report-auth.api.md @@ -4,6 +4,7 @@ ```ts import { AuthService } from '@backstage/backend-plugin-api'; +import type { Config } from '@backstage/config'; import { ServiceFactory } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; @@ -14,6 +15,36 @@ export const authServiceFactory: ServiceFactory< 'singleton' >; +// @public +export function createExternalTokenHandler( + handler: ExternalTokenHandler, +): ExternalTokenHandler; + +// @public +export interface ExternalTokenHandler { + // (undocumented) + initialize(ctx: { options: Config }): TContext; + // (undocumented) + type: string; + // (undocumented) + verifyToken( + token: string, + ctx: TContext, + ): Promise< + | { + subject: string; + } + | undefined + >; +} + +// @public +export const externalTokenHandlersServiceRef: ServiceRef< + ExternalTokenHandler, + 'plugin', + 'multiton' +>; + // @public export interface PluginTokenHandler { // (undocumented) diff --git a/packages/backend-defaults/report-rootHttpRouter.api.md b/packages/backend-defaults/report-rootHttpRouter.api.md index 826d592e8b..84424be39d 100644 --- a/packages/backend-defaults/report-rootHttpRouter.api.md +++ b/packages/backend-defaults/report-rootHttpRouter.api.md @@ -93,6 +93,7 @@ export class MiddlewareFactory { helmet(): RequestHandler; logging(): RequestHandler; notFound(): RequestHandler; + rateLimit(): RequestHandler; } // @public diff --git a/packages/backend-defaults/report-rootLogger.api.md b/packages/backend-defaults/report-rootLogger.api.md index b353039c03..99dc263358 100644 --- a/packages/backend-defaults/report-rootLogger.api.md +++ b/packages/backend-defaults/report-rootLogger.api.md @@ -3,8 +3,10 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { config } from 'winston'; import { Format } from 'logform'; import { JsonObject } from '@backstage/types'; +import { JsonPrimitive } from '@backstage/types'; import { LoggerService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; @@ -31,14 +33,31 @@ export class WinstonLogger implements RootLoggerService { error(message: string, meta?: JsonObject): void; // (undocumented) info(message: string, meta?: JsonObject): void; + static logLevelFilter(defaultLogLevel: keyof config.NpmConfigSetLevels): { + format: Format; + setOverrides: (overrides: WinstonLoggerLevelOverride[]) => void; + }; static redacter(): { format: Format; add: (redactions: Iterable) => void; }; // (undocumented) + setLevelOverrides(overrides: WinstonLoggerLevelOverride[]): void; + // (undocumented) warn(message: string, meta?: JsonObject): void; } +// @public (undocumented) +export type WinstonLoggerLevelOverride = { + matchers: WinstonLoggerLevelOverrideMatchers; + level: string; +}; + +// @public (undocumented) +export type WinstonLoggerLevelOverrideMatchers = { + [key: string]: JsonPrimitive | JsonPrimitive[] | undefined; +}; + // @public (undocumented) export interface WinstonLoggerOptions { // (undocumented) diff --git a/packages/backend-defaults/report-urlReader.api.md b/packages/backend-defaults/report-urlReader.api.md index 03a112abc7..039d51808d 100644 --- a/packages/backend-defaults/report-urlReader.api.md +++ b/packages/backend-defaults/report-urlReader.api.md @@ -87,7 +87,10 @@ export class AzureBlobStorageUrlReader implements UrlReaderService { options?: UrlReaderServiceReadUrlOptions, ): Promise; // (undocumented) - search(): Promise; + search( + url: string, + options?: UrlReaderServiceSearchOptions, + ): Promise; // (undocumented) toString(): string; } diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts index d618c94138..44df59b5f1 100644 --- a/packages/backend-defaults/src/CreateBackend.ts +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -35,6 +35,11 @@ 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'; +import { + actionsRegistryServiceFactory, + actionsServiceFactory, + instanceMetadataServiceFactory, +} from '@backstage/backend-defaults/alpha'; export const defaultServiceFactories = [ auditorServiceFactory, @@ -57,6 +62,11 @@ export const defaultServiceFactories = [ userInfoServiceFactory, urlReaderServiceFactory, eventsServiceFactory, + + // alpha services + actionsRegistryServiceFactory, + actionsServiceFactory, + instanceMetadataServiceFactory, ]; /** diff --git a/packages/backend-defaults/src/PackageDiscoveryService.ts b/packages/backend-defaults/src/PackageDiscoveryService.ts index 90e8d0f59d..e4c7b3ab3b 100644 --- a/packages/backend-defaults/src/PackageDiscoveryService.ts +++ b/packages/backend-defaults/src/PackageDiscoveryService.ts @@ -23,6 +23,7 @@ import { RootLoggerService, } from '@backstage/backend-plugin-api'; import { BackstagePackageJson } from '@backstage/cli-node'; +import { isError } from '@backstage/errors'; const DETECTED_PACKAGE_ROLES = [ 'node-library', @@ -79,10 +80,13 @@ async function findClosestPackageDir( /** @internal */ export class PackageDiscoveryService { - constructor( - private readonly config: RootConfigService, - private readonly logger: RootLoggerService, - ) {} + private readonly config: RootConfigService; + private readonly logger: RootLoggerService; + + constructor(config: RootConfigService, logger: RootLoggerService) { + this.config = config; + this.logger = logger; + } getDependencyNames(path: string) { const { dependencies } = require(path) as BackstagePackageJson; @@ -125,9 +129,19 @@ export class PackageDiscoveryService { const features: BackendFeature[] = []; for (const name of dependencyNames) { - const depPkg = require(require.resolve(`${name}/package.json`, { - paths: [packageDir], - })) as BackstagePackageJson; + let depPkg: BackstagePackageJson; + try { + const packageJsonPath = require.resolve(`${name}/package.json`, { + paths: [packageDir], + }); + depPkg = require(packageJsonPath) as BackstagePackageJson; + } catch (error) { + // Handle packages with "exports" field that don't export ./package.json + if (isError(error) && error.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') { + continue; // Skip packages that don't export package.json - they can't be Backstage packages + } + throw error; + } if ( !depPkg?.backstage?.role || !DETECTED_PACKAGE_ROLES.includes(depPkg.backstage.role) @@ -164,6 +178,6 @@ export class PackageDiscoveryService { } } - return { features }; + return { features: Array.from(new Set(features)) }; } } diff --git a/packages/backend-defaults/src/alpha/entrypoints/actions/DefaultActionsService.ts b/packages/backend-defaults/src/alpha/entrypoints/actions/DefaultActionsService.ts new file mode 100644 index 0000000000..155bbf8b35 --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/actions/DefaultActionsService.ts @@ -0,0 +1,151 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + DiscoveryService, + LoggerService, + RootConfigService, +} from '@backstage/backend-plugin-api'; +import { ResponseError } from '@backstage/errors'; +import { JsonObject } from '@backstage/types'; +import { + ActionsService, + ActionsServiceAction, +} from '@backstage/backend-plugin-api/alpha'; + +export class DefaultActionsService implements ActionsService { + private readonly discovery: DiscoveryService; + private readonly config: RootConfigService; + private readonly logger: LoggerService; + private readonly auth: AuthService; + + private constructor( + discovery: DiscoveryService, + config: RootConfigService, + logger: LoggerService, + auth: AuthService, + ) { + this.discovery = discovery; + this.config = config; + this.logger = logger; + this.auth = auth; + } + + static create({ + discovery, + config, + logger, + auth, + }: { + discovery: DiscoveryService; + config: RootConfigService; + logger: LoggerService; + auth: AuthService; + }) { + return new DefaultActionsService(discovery, config, logger, auth); + } + + async list({ credentials }: { credentials: BackstageCredentials }) { + const pluginSources = + this.config.getOptionalStringArray('backend.actions.pluginSources') ?? []; + + const remoteActionsList = await Promise.all( + pluginSources.map(async source => { + try { + const response = await this.makeRequest({ + path: `/.backstage/actions/v1/actions`, + pluginId: source, + credentials, + }); + if (!response.ok) { + throw await ResponseError.fromResponse(response); + } + const { actions } = (await response.json()) as { + actions: ActionsServiceAction; + }; + + return actions; + } catch (error) { + this.logger.warn(`Failed to fetch actions from ${source}`, error); + return []; + } + }), + ); + + return { actions: remoteActionsList.flat() }; + } + + async invoke(opts: { + id: string; + input?: JsonObject; + credentials: BackstageCredentials; + }) { + const pluginId = this.pluginIdFromActionId(opts.id); + const response = await this.makeRequest({ + path: `/.backstage/actions/v1/actions/${encodeURIComponent( + opts.id, + )}/invoke`, + pluginId, + credentials: opts.credentials, + options: { + method: 'POST', + body: JSON.stringify(opts.input), + headers: { + 'Content-Type': 'application/json', + }, + }, + }); + + if (!response.ok) { + throw await ResponseError.fromResponse(response); + } + + const { output } = await response.json(); + return { output }; + } + + private async makeRequest(opts: { + path: string; + pluginId: string; + options?: RequestInit; + credentials: BackstageCredentials; + }) { + const { path, pluginId, credentials, options } = opts; + const baseUrl = await this.discovery.getBaseUrl(pluginId); + + const { token } = await this.auth.getPluginRequestToken({ + onBehalfOf: credentials, + targetPluginId: opts.pluginId, + }); + + return fetch(`${baseUrl}${path}`, { + ...options, + headers: { + ...options?.headers, + Authorization: `Bearer ${token}`, + }, + }); + } + + private pluginIdFromActionId(id: string): string { + const colonIndex = id.indexOf(':'); + if (colonIndex === -1) { + throw new Error(`Invalid action id: ${id}`); + } + return id.substring(0, colonIndex); + } +} diff --git a/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.test.ts b/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.test.ts new file mode 100644 index 0000000000..af2fcb0c12 --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.test.ts @@ -0,0 +1,346 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + mockCredentials, + mockServices, + registerMswTestHooks, + ServiceFactoryTester, + startTestBackend, +} from '@backstage/backend-test-utils'; +import { actionsRegistryServiceFactory } from '../actionsRegistry'; +import { httpRouterServiceFactory } from '../../../entrypoints/httpRouter'; +import { actionsServiceFactory } from './actionsServiceFactory'; +import { setupServer } from 'msw/node'; +import { rest } from 'msw'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { json } from 'express'; +import Router from 'express-promise-router'; +import request from 'supertest'; +import { ActionsServiceAction } from '@backstage/backend-plugin-api/alpha'; +import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha'; +import { actionsServiceRef } from '@backstage/backend-plugin-api/alpha'; + +const server = setupServer(); + +describe('actionsServiceFactory', () => { + describe('client', () => { + registerMswTestHooks(server); + const mockActionsListEndpoint = jest.fn(); + const mockNotFoundActionsListEndpoint = jest.fn(); + + const defaultServices = [ + mockServices.rootConfig.factory({ + data: { + backend: { + actions: { + pluginSources: ['my-plugin', 'not-found-plugin'], + }, + }, + }, + }), + actionsServiceFactory, + httpRouterServiceFactory, + mockServices.httpAuth.factory({ + defaultCredentials: mockCredentials.service('user:default/mock'), + }), + mockServices.discovery.factory(), + actionsRegistryServiceFactory, + ]; + + const mockActionsDefinition: ActionsServiceAction = { + description: 'my mock description', + id: 'my-plugin:test', + name: 'testy', + title: 'Test', + schema: { + input: {}, + output: {}, + }, + attributes: { + destructive: false, + idempotent: false, + readOnly: false, + }, + }; + + beforeEach(() => { + server.use( + rest.get( + 'http://localhost:0/api/my-plugin/.backstage/actions/v1/actions', + mockActionsListEndpoint.mockImplementation((_req, res, ctx) => + res( + ctx.json({ + actions: [mockActionsDefinition], + }), + ), + ), + ), + rest.get( + 'http://localhost:0/api/not-found-plugin/.backstage/actions/v1/actions', + mockNotFoundActionsListEndpoint.mockImplementation((_req, res, ctx) => + res(ctx.status(404)), + ), + ), + ); + }); + + describe('list', () => { + it('should list all plugins in config to find actions and handle failures gracefully', async () => { + const subject = await ServiceFactoryTester.from(actionsServiceFactory, { + dependencies: defaultServices, + }).getSubject(); + + const { actions } = await subject.list({ + credentials: mockCredentials.service('user:default/mock'), + }); + + expect(actions).toEqual([mockActionsDefinition]); + + expect(mockActionsListEndpoint).toHaveBeenCalledTimes(1); + expect(mockNotFoundActionsListEndpoint).toHaveBeenCalledTimes(1); + }); + }); + + describe('invoke', () => { + it('should invoke the action and return the output', async () => { + server.use( + rest.post( + 'http://localhost:0/api/my-plugin/.backstage/actions/v1/actions/my-plugin:test/invoke', + (_req, res, ctx) => res(ctx.json({ output: { ok: true } })), + ), + ); + const subject = await ServiceFactoryTester.from(actionsServiceFactory, { + dependencies: defaultServices, + }).getSubject(); + + const { output } = await subject.invoke({ + id: 'my-plugin:test', + credentials: mockCredentials.service('user:default/mock'), + }); + + expect(output).toEqual({ ok: true }); + }); + + it('should throw a 404 if the action does not exist', async () => { + server.use( + rest.post( + 'http://localhost:0/api/my-plugin/.backstage/actions/v1/actions/my-plugin:test/invoke', + (_req, res, ctx) => res(ctx.status(404)), + ), + ); + + const subject = await ServiceFactoryTester.from(actionsServiceFactory, { + dependencies: defaultServices, + }).getSubject(); + + await expect( + subject.invoke({ + id: 'my-plugin:test', + credentials: mockCredentials.service('user:default/mock'), + }), + ).rejects.toThrow('404'); + }); + + it('should throw a 400 if the action returns an invalid input', async () => { + server.use( + rest.post( + 'http://localhost:0/api/my-plugin/.backstage/actions/v1/actions/my-plugin:test/invoke', + (_req, res, ctx) => res(ctx.status(400)), + ), + ); + + const subject = await ServiceFactoryTester.from(actionsServiceFactory, { + dependencies: defaultServices, + }).getSubject(); + + await expect( + subject.invoke({ + id: 'my-plugin:test', + credentials: mockCredentials.service('user:default/mock'), + }), + ).rejects.toThrow('400'); + }); + }); + + describe('integration', () => { + beforeAll(() => { + // disable the msw server for this test. + server.close(); + }); + + const features = [ + actionsServiceFactory, + httpRouterServiceFactory, + mockServices.httpAuth.factory({ + defaultCredentials: mockCredentials.service('user:default/mock'), + }), + actionsRegistryServiceFactory, + mockServices.rootConfig.factory({ + data: { + backend: { + actions: { pluginSources: ['plugin-with-action'] }, + }, + }, + }), + + createBackendPlugin({ + pluginId: 'plugin-with-action', + register({ registerInit }) { + registerInit({ + deps: { actionsRegistry: actionsRegistryServiceRef }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'with-validation', + title: 'Test', + description: 'Test', + schema: { + input: z => + z.object({ + name: z.string(), + }), + output: z => + z.object({ + ok: z.boolean(), + string: z.string(), + }), + }, + action: async ({ input }) => { + return { + output: { + ok: true, + string: `hello ${input.name}`, + }, + }; + }, + }); + }, + }); + }, + }), + createBackendPlugin({ + pluginId: 'test-harness', + register({ registerInit }) { + registerInit({ + deps: { + actionsService: actionsServiceRef, + router: coreServices.httpRouter, + httpAuth: coreServices.httpAuth, + }, + async init({ actionsService, router, httpAuth }) { + const innerRouter = Router(); + innerRouter.use(json()); + router.use(innerRouter); + + innerRouter.post('/invoke', async (req, res) => { + const { id, input } = req.body; + const response = await actionsService.invoke({ + id, + input, + credentials: await httpAuth.credentials(req), + }); + res.json(response); + }); + + innerRouter.get('/actions', async (req, res) => { + const response = await actionsService.list({ + credentials: await httpAuth.credentials(req), + }); + + res.json(response); + }); + }, + }); + }, + }), + ]; + + it('should list the actions and return the output', async () => { + const { server: testHarnessServer } = await startTestBackend({ + features, + }); + + const { body, status } = await request(testHarnessServer).get( + '/api/test-harness/actions', + ); + + expect(status).toBe(200); + expect(body).toEqual({ + actions: [ + { + description: 'Test', + id: 'plugin-with-action:with-validation', + name: 'with-validation', + schema: { + input: { + $schema: 'http://json-schema.org/draft-07/schema#', + additionalProperties: false, + properties: { + name: { + type: 'string', + }, + }, + required: ['name'], + type: 'object', + }, + output: { + $schema: 'http://json-schema.org/draft-07/schema#', + additionalProperties: false, + properties: { + ok: { + type: 'boolean', + }, + string: { + type: 'string', + }, + }, + required: ['ok', 'string'], + type: 'object', + }, + }, + attributes: { + destructive: true, + idempotent: false, + readOnly: false, + }, + title: 'Test', + }, + ], + }); + }); + + it('should invoke the action and return the output', async () => { + const { server: testHarnessServer } = await startTestBackend({ + features, + }); + + const { body, status } = await request(testHarnessServer) + .post('/api/test-harness/invoke') + .send({ + id: 'plugin-with-action:with-validation', + input: { + name: 'world', + }, + }); + + expect(body).toEqual({ output: { ok: true, string: 'hello world' } }); + expect(status).toBe(200); + }); + }); + }); +}); diff --git a/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.ts b/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.ts new file mode 100644 index 0000000000..4325da7d13 --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 } from '@backstage/backend-plugin-api'; +import { coreServices } from '@backstage/backend-plugin-api'; +import { DefaultActionsService } from './DefaultActionsService'; +import { actionsServiceRef } from '@backstage/backend-plugin-api/alpha'; + +/** + * @public + */ +export const actionsServiceFactory = createServiceFactory({ + service: actionsServiceRef, + deps: { + discovery: coreServices.discovery, + config: coreServices.rootConfig, + logger: coreServices.logger, + auth: coreServices.auth, + }, + factory: ({ discovery, config, logger, auth }) => + DefaultActionsService.create({ + discovery, + config, + logger, + auth, + }), +}); diff --git a/packages/canon/src/components/DataTable/Table/types.ts b/packages/backend-defaults/src/alpha/entrypoints/actions/index.ts similarity index 85% rename from packages/canon/src/components/DataTable/Table/types.ts rename to packages/backend-defaults/src/alpha/entrypoints/actions/index.ts index a4ef96c732..bc34150a5f 100644 --- a/packages/canon/src/components/DataTable/Table/types.ts +++ b/packages/backend-defaults/src/alpha/entrypoints/actions/index.ts @@ -13,7 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** @public */ -export interface DataTableTableProps - extends React.HTMLAttributes {} +export { actionsServiceFactory } from './actionsServiceFactory'; diff --git a/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts new file mode 100644 index 0000000000..7348e0a185 --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts @@ -0,0 +1,176 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + HttpAuthService, + LoggerService, + PluginMetadataService, +} from '@backstage/backend-plugin-api'; +import PromiseRouter from 'express-promise-router'; +import { Router, json } from 'express'; +import { z, AnyZodObject } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; +import { + ActionsRegistryActionOptions, + ActionsRegistryService, +} from '@backstage/backend-plugin-api/alpha'; +import { + ForwardedError, + InputError, + NotAllowedError, + NotFoundError, +} from '@backstage/errors'; + +export class DefaultActionsRegistryService implements ActionsRegistryService { + private actions: Map> = + new Map(); + + private readonly logger: LoggerService; + private readonly httpAuth: HttpAuthService; + private readonly auth: AuthService; + private readonly metadata: PluginMetadataService; + + private constructor( + logger: LoggerService, + httpAuth: HttpAuthService, + auth: AuthService, + metadata: PluginMetadataService, + ) { + this.logger = logger; + this.httpAuth = httpAuth; + this.auth = auth; + this.metadata = metadata; + } + + static create({ + httpAuth, + logger, + auth, + metadata, + }: { + httpAuth: HttpAuthService; + logger: LoggerService; + auth: AuthService; + metadata: PluginMetadataService; + }): DefaultActionsRegistryService { + return new DefaultActionsRegistryService(logger, httpAuth, auth, metadata); + } + + createRouter(): Router { + const router = PromiseRouter(); + router.use(json()); + + router.get('/.backstage/actions/v1/actions', (_, res) => { + return res.json({ + actions: Array.from(this.actions.entries()).map(([id, action]) => ({ + id, + ...action, + attributes: { + // Inspired by the @modelcontextprotocol/sdk defaults for the hints. + // https://github.com/modelcontextprotocol/typescript-sdk/blob/dd69efa1de8646bb6b195ff8d5f52e13739f4550/src/types.ts#L777-L812 + destructive: action.attributes?.destructive ?? true, + idempotent: action.attributes?.idempotent ?? false, + readOnly: action.attributes?.readOnly ?? false, + }, + schema: { + input: action.schema?.input + ? zodToJsonSchema(action.schema.input(z)) + : zodToJsonSchema(z.object({})), + output: action.schema?.output + ? zodToJsonSchema(action.schema.output(z)) + : zodToJsonSchema(z.object({})), + }, + })), + }); + }); + + router.post( + '/.backstage/actions/v1/actions/:actionId/invoke', + async (req, res) => { + const credentials = await this.httpAuth.credentials(req); + if (this.auth.isPrincipal(credentials, 'user')) { + if (!credentials.principal.actor) { + throw new NotAllowedError( + `Actions must be invoked by a service, not a user`, + ); + } + } else if (this.auth.isPrincipal(credentials, 'none')) { + throw new NotAllowedError( + `Actions must be invoked by a service, not an anonymous request`, + ); + } + + const action = this.actions.get(req.params.actionId); + + if (!action) { + throw new NotFoundError(`Action "${req.params.actionId}" not found`); + } + + const input = action.schema?.input + ? action.schema.input(z).safeParse(req.body) + : ({ success: true, data: undefined } as const); + + if (!input.success) { + throw new InputError( + `Invalid input to action "${req.params.actionId}"`, + input.error, + ); + } + + try { + const result = await action.action({ + input: input.data, + credentials, + logger: this.logger, + }); + + const output = action.schema?.output + ? action.schema.output(z).safeParse(result?.output) + : ({ success: true, data: result?.output } as const); + + if (!output.success) { + throw new InputError( + `Invalid output from action "${req.params.actionId}"`, + output.error, + ); + } + + res.json({ output: output.data }); + } catch (error) { + throw new ForwardedError( + `Failed execution of action "${req.params.actionId}"`, + error, + ); + } + }, + ); + return router; + } + + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >(options: ActionsRegistryActionOptions): void { + const id = `${this.metadata.getId()}:${options.name}`; + + if (this.actions.has(id)) { + throw new Error(`Action with id "${id}" is already registered`); + } + + this.actions.set(id, options); + } +} diff --git a/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.test.ts b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.test.ts new file mode 100644 index 0000000000..79c103c284 --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.test.ts @@ -0,0 +1,538 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createBackendPlugin } from '@backstage/backend-plugin-api'; +import { + mockCredentials, + mockServices, + startTestBackend, +} from '@backstage/backend-test-utils'; +import { httpRouterServiceFactory } from '../../../entrypoints/httpRouter'; +import request from 'supertest'; +import { actionsRegistryServiceFactory } from './actionsRegistryServiceFactory'; +import { InputError } from '@backstage/errors'; +import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha'; + +describe('actionsRegistryServiceFactory', () => { + const defaultServices = [ + actionsRegistryServiceFactory, + httpRouterServiceFactory, + mockServices.httpAuth.factory({ + defaultCredentials: mockCredentials.service('user:default/mock'), + }), + ]; + + describe('typescript tests', () => { + it('should properly infer the input types', () => { + createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + schema: { + input: z => + z.object({ + test: z.string(), + }), + output: z => + z.object({ + ok: z.boolean(), + }), + }, + action: async ({ input: { test } }) => { + // @ts-expect-error - test is not a boolean + const _t: boolean = test; + return { output: { ok: true } }; + }, + }); + }, + }); + }, + }); + + expect(true).toBe(true); + }); + + it('should properly infer the output types', () => { + createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + schema: { + input: z => + z.object({ + test: z.string(), + }), + output: z => + z.object({ + ok: z.boolean(), + }), + }, + // @ts-expect-error - ok is not a boolean + action: async () => { + return { output: { ok: 'bo' } }; + }, + }); + }, + }); + }, + }); + + expect(true).toBe(true); + }); + }); + + describe('/.backstage/actions/v1/actions', () => { + it('should allow registering of actions', async () => { + const pluginSubject = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + schema: { + input: z => + z.object({ + name: z.string(), + }), + output: z => + z.object({ + ok: z.boolean(), + }), + }, + action: async () => ({ output: { ok: true } }), + }); + }, + }); + }, + }); + + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + const { body, status } = await request(server).get( + '/api/my-plugin/.backstage/actions/v1/actions', + ); + + expect(status).toBe(200); + + expect(body).toMatchObject({ + actions: [ + { + name: 'test', + title: 'Test', + description: 'Test', + schema: { + input: { + type: 'object', + properties: { + name: { + type: 'string', + }, + }, + }, + output: { + type: 'object', + properties: { + ok: { + type: 'boolean', + }, + }, + }, + }, + }, + ], + }); + }); + + it('should set default attributes', async () => { + const pluginSubject = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({}), + output: z => z.object({}), + }, + action: async () => ({ output: { ok: true } }), + }); + }, + }); + }, + }); + + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + const { body, status } = await request(server).get( + '/api/my-plugin/.backstage/actions/v1/actions', + ); + + expect(status).toBe(200); + + expect(body).toMatchObject({ + actions: [ + { + name: 'test', + attributes: { + destructive: true, + idempotent: false, + readOnly: false, + }, + }, + ], + }); + }); + + it('should allow setting attributes', async () => { + const pluginSubject = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + attributes: { + destructive: false, + idempotent: true, + readOnly: true, + }, + schema: { + input: z => z.object({}), + output: z => z.object({}), + }, + action: async () => ({ output: { ok: true } }), + }); + }, + }); + }, + }); + + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + const { body, status } = await request(server).get( + '/api/my-plugin/.backstage/actions/v1/actions', + ); + + expect(status).toBe(200); + + expect(body).toMatchObject({ + actions: [ + { + name: 'test', + title: 'Test', + description: 'Test', + attributes: { + destructive: false, + idempotent: true, + readOnly: true, + }, + }, + ], + }); + }); + + it('should forces registration of input and output schema as objects', async () => { + const pluginSubject = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + schema: { + // @ts-expect-error - z.undefined is not a valid schema + input: z => z.undefined(), + // @ts-expect-error - z.string is not a valid schema + output: z => z.string(), + }, + // @ts-expect-error - output is not a valid, needs to be an object + action: async () => ({ output: 'ok' }), + }); + }, + }); + }, + }); + + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + const { body, status } = await request(server).get( + '/api/my-plugin/.backstage/actions/v1/actions', + ); + + expect(status).toBe(200); + + expect(body).toMatchObject({ + actions: [ + { + name: 'test', + title: 'Test', + description: 'Test', + schema: { + input: {}, + output: {}, + }, + }, + ], + }); + }); + }); + + describe('/.backstage/actions/v1/actions/:actionId/invoke', () => { + const mockAction = jest.fn(); + + beforeEach(() => { + mockAction.mockResolvedValue({ output: { ok: true } }); + }); + + const pluginSubject = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + schema: { + input: z => + z.object({ + name: z.string(), + }), + output: z => + z.object({ + ok: z.boolean(), + }), + }, + action: mockAction, + }); + }, + }); + }, + }); + + it('should throw an error if the action is not found', async () => { + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + const { body, status } = await request(server).post( + '/api/my-plugin/.backstage/actions/v1/actions/test/invoke', + ); + + expect(status).toBe(404); + expect(body).toMatchObject({ + error: { + message: 'Action "test" not found', + }, + }); + }); + + it('should throw an error if the action input does not match the schema', async () => { + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + const { body, status } = await request(server) + .post( + '/api/my-plugin/.backstage/actions/v1/actions/my-plugin:test/invoke', + ) + .send({ + name: 123, + }); + + expect(status).toBe(400); + expect(body).toMatchObject({ + error: { + message: expect.stringMatching( + 'Invalid input to action "my-plugin:test"', + ), + }, + }); + }); + + it('should call the action with the input', async () => { + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + await request(server) + .post( + '/api/my-plugin/.backstage/actions/v1/actions/my-plugin:test/invoke', + ) + .send({ + name: 'test', + }); + + expect(mockAction).toHaveBeenCalledWith({ + input: { + name: 'test', + }, + credentials: { + $$type: '@backstage/BackstageCredentials', + principal: { + type: 'service', + subject: 'user:default/mock', + }, + }, + logger: expect.anything(), + }); + }); + + it('should throw an error if the action is invoked by a user', async () => { + const testServices = [ + actionsRegistryServiceFactory, + httpRouterServiceFactory, + mockServices.httpAuth.factory({ + defaultCredentials: mockCredentials.user(), + }), + ]; + + const { server } = await startTestBackend({ + features: [pluginSubject, ...testServices], + }); + + const { body, status } = await request(server) + .post( + '/api/my-plugin/.backstage/actions/v1/actions/my-plugin:test/invoke', + ) + .send({ + name: 'test', + }); + + expect(status).toBe(403); + expect(body).toMatchObject({ + error: { + message: 'Actions must be invoked by a service, not a user', + }, + }); + }); + + it('should validate the output of the action if provided', async () => { + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + mockAction.mockResolvedValue({ ok: 'blob' }); + + const { body, status } = await request(server) + .post( + '/api/my-plugin/.backstage/actions/v1/actions/my-plugin:test/invoke', + ) + .send({ + name: 'test', + }); + + expect(status).toBe(400); + expect(body).toMatchObject({ + error: { + message: expect.stringMatching( + 'Invalid output from action "my-plugin:test"', + ), + }, + }); + }); + + it('should return the output of the action', async () => { + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + const { body, status } = await request(server) + .post( + '/api/my-plugin/.backstage/actions/v1/actions/my-plugin:test/invoke', + ) + .send({ + name: 'test', + }); + + expect(status).toBe(200); + expect(body).toMatchObject({ output: { ok: true } }); + }); + + it('should return the error from the action if it throws', async () => { + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + mockAction.mockRejectedValue(new InputError('test')); + + const { body, status } = await request(server) + .post( + '/api/my-plugin/.backstage/actions/v1/actions/my-plugin:test/invoke', + ) + .send({ + name: 'test', + }); + + expect(status).toBe(400); + expect(body).toMatchObject({ + error: { + message: expect.stringContaining( + 'Failed execution of action "my-plugin:test"', + ), + }, + }); + }); + }); +}); diff --git a/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.ts b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.ts new file mode 100644 index 0000000000..8c19b8148c --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 { DefaultActionsRegistryService } from './DefaultActionsRegistryService'; +import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha'; + +/** + * @public + */ +export const actionsRegistryServiceFactory = createServiceFactory({ + service: actionsRegistryServiceRef, + deps: { + metadata: coreServices.pluginMetadata, + httpRouter: coreServices.httpRouter, + httpAuth: coreServices.httpAuth, + logger: coreServices.logger, + auth: coreServices.auth, + }, + factory: ({ metadata, httpRouter, httpAuth, logger, auth }) => { + const actionsRegistryService = DefaultActionsRegistryService.create({ + httpAuth, + logger, + auth, + metadata, + }); + + httpRouter.use(actionsRegistryService.createRouter()); + + return actionsRegistryService; + }, +}); diff --git a/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/index.ts b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/index.ts new file mode 100644 index 0000000000..ac65dd7a90 --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 { actionsRegistryServiceFactory } from './actionsRegistryServiceFactory'; diff --git a/packages/canon/src/components/DataTable/Pagination/types.ts b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/index.ts similarity index 84% rename from packages/canon/src/components/DataTable/Pagination/types.ts rename to packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/index.ts index b2a895c465..00ee75400a 100644 --- a/packages/canon/src/components/DataTable/Pagination/types.ts +++ b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/index.ts @@ -14,6 +14,4 @@ * limitations under the License. */ -/** @public */ -export interface DataTablePaginationProps - extends React.HTMLAttributes {} +export { instanceMetadataServiceFactory } from './instanceMetadataServiceFactory'; diff --git a/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/instanceMetadataServiceFactory.ts b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/instanceMetadataServiceFactory.ts new file mode 100644 index 0000000000..bd2d427a59 --- /dev/null +++ b/packages/backend-defaults/src/alpha/entrypoints/instanceMetadata/instanceMetadataServiceFactory.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 { + BackendFeatureMeta, + InstanceMetadataService, + instanceMetadataServiceRef, +} from '@backstage/backend-plugin-api/alpha'; + +/** + * @alpha + * @deprecated use {@link @backstage/backend-plugin-api#coreServices.rootInstanceMetadata} instead + */ +export const instanceMetadataServiceFactory = createServiceFactory({ + service: instanceMetadataServiceRef, + deps: { + instanceMetadata: coreServices.rootInstanceMetadata, + }, + factory: async ({ instanceMetadata }) => { + const plugins = await instanceMetadata.getInstalledPlugins(); + const features: BackendFeatureMeta[] = []; + for (const plugin of plugins) { + features.push({ + type: 'plugin' as const, + pluginId: plugin.pluginId, + }); + for (const module of plugin.modules) { + features.push({ + type: 'module' as const, + pluginId: plugin.pluginId, + moduleId: module.moduleId, + }); + } + } + const service: InstanceMetadataService = { + getInstalledFeatures: () => features, + }; + + return service; + }, +}); diff --git a/packages/backend-defaults/src/alpha/index.ts b/packages/backend-defaults/src/alpha/index.ts new file mode 100644 index 0000000000..744d5bc552 --- /dev/null +++ b/packages/backend-defaults/src/alpha/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 { actionsRegistryServiceFactory } from './entrypoints/actionsRegistry'; +export { actionsServiceFactory } from './entrypoints/actions'; +export { instanceMetadataServiceFactory } from './entrypoints/instanceMetadata'; diff --git a/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.test.ts b/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.test.ts index c960a1daa2..ac32c9e911 100644 --- a/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.test.ts +++ b/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.test.ts @@ -83,7 +83,7 @@ describe('DefaultAuditorService', () => { expect(logFn).toHaveBeenLastCalledWith({ eventId: 'test-event', status: 'failed', - error: error.toString(), + error, plugin: 'test', severityLevel: 'low', actor: {}, @@ -135,7 +135,7 @@ describe('DefaultAuditorService', () => { initiated: 'test', failed: 'test', }, - error: error.toString(), + error, plugin: 'test', severityLevel: 'low', actor: {}, diff --git a/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.ts b/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.ts index 79e206e305..b13565d841 100644 --- a/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.ts +++ b/packages/backend-defaults/src/entrypoints/auditor/DefaultAuditorService.ts @@ -48,7 +48,7 @@ export type AuditorEventStatus = | { status: 'succeeded' } | { status: 'failed'; - error: string; + error: Error; }; /** @@ -195,7 +195,7 @@ export class DefaultAuditorService implements AuditorService { await this.log({ ...options, ...params, - error: String(params.error), + error: params.error, meta: { ...options.meta, ...params?.meta }, status: 'failed', }); diff --git a/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.test.ts b/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.test.ts index 2d9a959c64..d8ffda2473 100644 --- a/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.test.ts +++ b/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.test.ts @@ -32,6 +32,7 @@ describe('WinstonRootAuditorService', () => { plugin: { getId: () => 'test-plugin', }, + config: mockServices.rootConfig.mock(), }); expect(childLogger).toBeInstanceOf(DefaultAuditorService); }); @@ -45,6 +46,7 @@ describe('WinstonRootAuditorService', () => { plugin: { getId: () => pluginId, }, + config: mockServices.rootConfig.mock(), }); // workaround to spy on private method const auditorSpy = jest.spyOn(auditor as any, 'log'); @@ -68,6 +70,7 @@ describe('WinstonRootAuditorService', () => { plugin: { getId: () => pluginId, }, + config: mockServices.rootConfig.mock(), }); // workaround to spy on private method const auditorSpy = jest.spyOn(auditor as any, 'log'); @@ -95,6 +98,7 @@ describe('WinstonRootAuditorService', () => { plugin: { getId: () => pluginId, }, + config: mockServices.rootConfig.mock(), }); // workaround to spy on private method const auditorSpy = jest.spyOn(auditor as any, 'log'); @@ -111,7 +115,7 @@ describe('WinstonRootAuditorService', () => { eventId: 'test-event', meta: {}, status: 'failed', - error: error.toString(), + error, }); }); @@ -124,6 +128,7 @@ describe('WinstonRootAuditorService', () => { plugin: { getId: () => pluginId, }, + config: mockServices.rootConfig.mock(), }); // workaround to spy on private method const auditorSpy = jest.spyOn(auditor as any, 'log'); @@ -163,7 +168,7 @@ describe('WinstonRootAuditorService', () => { initiated: 'test', failed: 'test', }, - error: error.toString(), + error, }); }); }); diff --git a/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.ts b/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.ts index 6ea5d02606..32c21e642e 100644 --- a/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.ts +++ b/packages/backend-defaults/src/entrypoints/auditor/WinstonRootAuditorService.ts @@ -20,11 +20,13 @@ import type { HttpAuthService, PluginMetadataService, } from '@backstage/backend-plugin-api'; +import { Config } from '@backstage/config'; import type { JsonObject } from '@backstage/types'; import type { Format } from 'logform'; import * as winston from 'winston'; import { WinstonLogger } from '../rootLogger'; import { DefaultAuditorService } from './DefaultAuditorService'; +import { getSeverityLogLevelMappings } from './utils'; /** @public */ export const defaultFormatter = winston.format.combine( @@ -79,7 +81,11 @@ export type WinstonRootAuditorServiceOptions = { * ``` */ export class WinstonRootAuditorService { - private constructor(private readonly winstonLogger: WinstonLogger) {} + private readonly winstonLogger: WinstonLogger; + + private constructor(winstonLogger: WinstonLogger) { + this.winstonLogger = winstonLogger; + } /** * Creates a {@link WinstonRootAuditorService} instance. @@ -108,12 +114,28 @@ export class WinstonRootAuditorService { forPlugin(deps: { auth: AuthService; + config: Config; httpAuth: HttpAuthService; plugin: PluginMetadataService; }): AuditorService { - return DefaultAuditorService.create( - e => this.winstonLogger.info(`${e.plugin}.${e.eventId}`, e), - deps, - ); + const severityLogLevelMappings = getSeverityLogLevelMappings(deps.config); + + return DefaultAuditorService.create(event => { + if ('error' in event) { + const { error, ...rest } = event; + const childAuditLogger = this.winstonLogger.child(rest); + + childAuditLogger[severityLogLevelMappings[event.severityLevel]]( + `${event.plugin}.${event.eventId}`, + error, + ); + } else { + // the else statement is required for typechecking + this.winstonLogger[severityLogLevelMappings[event.severityLevel]]( + `${event.plugin}.${event.eventId}`, + event, + ); + } + }, deps); } } diff --git a/packages/backend-defaults/src/entrypoints/auditor/auditorServiceFactory.ts b/packages/backend-defaults/src/entrypoints/auditor/auditorServiceFactory.ts index 34ea627762..3c82f95ce6 100644 --- a/packages/backend-defaults/src/entrypoints/auditor/auditorServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/auditor/auditorServiceFactory.ts @@ -19,15 +19,7 @@ import { createServiceFactory, } from '@backstage/backend-plugin-api'; import { DefaultAuditorService } from './DefaultAuditorService'; -import { z } from 'zod'; -import { InputError } from '@backstage/errors'; - -const CONFIG_ROOT_KEY = 'backend.auditor'; - -const severityLogLevelMappingsSchema = z.record( - z.enum(['low', 'medium', 'high', 'critical']), - z.enum(['debug', 'info', 'warn', 'error']), -); +import { getSeverityLogLevelMappings } from './utils'; /** * Plugin-level auditing. @@ -49,47 +41,26 @@ export const auditorServiceFactory = createServiceFactory({ }, factory({ config, logger, plugin, auth, httpAuth }) { const auditLogger = logger.child({ isAuditEvent: true }); - const auditorConfig = config.getOptionalConfig(CONFIG_ROOT_KEY); - const severityLogLevelMappings = { - low: - auditorConfig?.getOptionalString('severityLogLevelMappings.low') ?? - 'debug', - medium: - auditorConfig?.getOptionalString('severityLogLevelMappings.medium') ?? - 'info', - high: - auditorConfig?.getOptionalString('severityLogLevelMappings.high') ?? - 'info', - critical: - auditorConfig?.getOptionalString('severityLogLevelMappings.critical') ?? - 'info', - } as Required>; - - const res = severityLogLevelMappingsSchema.safeParse( - severityLogLevelMappings, - ); - if (!res.success) { - const key = res.error.issues.at(0)?.path.at(0) as string; - const value = ( - res.error.issues.at(0) as unknown as Record - ).received as string; - const validKeys = ( - res.error.issues.at(0) as unknown as Record - ).options as string[]; - throw new InputError( - `The configuration value for 'backend.auditor.severityLogLevelMappings.${key}' was given an invalid value: '${value}'. Expected one of the following valid values: '${validKeys.join( - ', ', - )}'.`, - ); - } + const severityLogLevelMappings = getSeverityLogLevelMappings(config); return DefaultAuditorService.create( event => { - auditLogger[severityLogLevelMappings[event.severityLevel]]( - `${event.plugin}.${event.eventId}`, - event, - ); + if ('error' in event) { + const { error, ...rest } = event; + const childAuditLogger = auditLogger.child(rest); + + childAuditLogger[severityLogLevelMappings[event.severityLevel]]( + `${event.plugin}.${event.eventId}`, + error, + ); + } else { + // the else statement is required for typechecking + auditLogger[severityLogLevelMappings[event.severityLevel]]( + `${event.plugin}.${event.eventId}`, + event, + ); + } }, { plugin, auth, httpAuth }, ); diff --git a/packages/backend-defaults/src/entrypoints/auditor/types.ts b/packages/backend-defaults/src/entrypoints/auditor/types.ts new file mode 100644 index 0000000000..7827a31d1f --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auditor/types.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { z } from 'zod'; + +/** @internal */ +export const severityLogLevelMappingsSchema = z.record( + z.enum(['low', 'medium', 'high', 'critical']), + z.enum(['debug', 'info', 'warn', 'error']), +); + +/** @internal */ +export const CONFIG_ROOT_KEY = 'backend.auditor'; diff --git a/packages/backend-defaults/src/entrypoints/auditor/utils.ts b/packages/backend-defaults/src/entrypoints/auditor/utils.ts new file mode 100644 index 0000000000..719a227bf9 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auditor/utils.ts @@ -0,0 +1,66 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Config } from '@backstage/config'; +import { InputError } from '@backstage/errors'; +import { z } from 'zod'; +import { CONFIG_ROOT_KEY, severityLogLevelMappingsSchema } from './types'; + +/** + * Gets the `backend.auditor.severityLogLevelMappings` configuration. + * + * @param config - The root Backstage {@link @backstage/config#Config} object. + * @returns The validated severity-to-log-level mappings. + * @throws error - {@link @backstage/errors#InputError} if the mapping configuration is invalid. + */ +export function getSeverityLogLevelMappings(config: Config) { + const auditorConfig = config.getOptionalConfig(CONFIG_ROOT_KEY); + + const severityLogLevelMappings = { + low: + auditorConfig?.getOptionalString('severityLogLevelMappings.low') ?? + 'debug', + medium: + auditorConfig?.getOptionalString('severityLogLevelMappings.medium') ?? + 'info', + high: + auditorConfig?.getOptionalString('severityLogLevelMappings.high') ?? + 'info', + critical: + auditorConfig?.getOptionalString('severityLogLevelMappings.critical') ?? + 'info', + } as Required>; + + const res = severityLogLevelMappingsSchema.safeParse( + severityLogLevelMappings, + ); + if (!res.success) { + const key = res.error.issues.at(0)?.path.at(0) as string; + const value = ( + res.error.issues.at(0) as unknown as Record + ).received as string; + const validKeys = ( + res.error.issues.at(0) as unknown as Record + ).options as string[]; + throw new InputError( + `The configuration value for 'backend.auditor.severityLogLevelMappings.${key}' was given an invalid value: '${value}'. Expected one of the following valid values: '${validKeys.join( + ', ', + )}'.`, + ); + } + + return severityLogLevelMappings; +} diff --git a/packages/backend-defaults/src/entrypoints/auth/DefaultAuthService.ts b/packages/backend-defaults/src/entrypoints/auth/DefaultAuthService.ts index d8cb60e8b5..bee40de65e 100644 --- a/packages/backend-defaults/src/entrypoints/auth/DefaultAuthService.ts +++ b/packages/backend-defaults/src/entrypoints/auth/DefaultAuthService.ts @@ -25,7 +25,7 @@ import { import { AuthenticationError } from '@backstage/errors'; import { JsonObject } from '@backstage/types'; import { decodeJwt } from 'jose'; -import { ExternalTokenHandler } from './external/ExternalTokenHandler'; +import { ExternalAuthTokenHandler } from './external/ExternalAuthTokenHandler'; import { createCredentialsWithNonePrincipal, createCredentialsWithServicePrincipal, @@ -38,14 +38,28 @@ import { UserTokenHandler } from './user/UserTokenHandler'; /** @internal */ export class DefaultAuthService implements AuthService { + private readonly userTokenHandler: UserTokenHandler; + private readonly pluginTokenHandler: PluginTokenHandler; + private readonly externalTokenHandler: ExternalAuthTokenHandler; + private readonly pluginId: string; + private readonly disableDefaultAuthPolicy: boolean; + private readonly pluginKeySource: PluginKeySource; + constructor( - private readonly userTokenHandler: UserTokenHandler, - private readonly pluginTokenHandler: PluginTokenHandler, - private readonly externalTokenHandler: ExternalTokenHandler, - private readonly pluginId: string, - private readonly disableDefaultAuthPolicy: boolean, - private readonly pluginKeySource: PluginKeySource, - ) {} + userTokenHandler: UserTokenHandler, + pluginTokenHandler: PluginTokenHandler, + externalTokenHandler: ExternalAuthTokenHandler, + pluginId: string, + disableDefaultAuthPolicy: boolean, + pluginKeySource: PluginKeySource, + ) { + this.userTokenHandler = userTokenHandler; + this.pluginTokenHandler = pluginTokenHandler; + this.externalTokenHandler = externalTokenHandler; + this.pluginId = pluginId; + this.disableDefaultAuthPolicy = disableDefaultAuthPolicy; + this.pluginKeySource = pluginKeySource; + } async authenticate( token: string, diff --git a/packages/backend-defaults/src/entrypoints/auth/JwksClient.ts b/packages/backend-defaults/src/entrypoints/auth/JwksClient.ts index f956ceb70a..cd283fe92b 100644 --- a/packages/backend-defaults/src/entrypoints/auth/JwksClient.ts +++ b/packages/backend-defaults/src/entrypoints/auth/JwksClient.ts @@ -30,7 +30,11 @@ export class JwksClient { #keyStore?: GetKeyFunction; #keyStoreUpdated: number = 0; - constructor(private readonly getEndpoint: () => Promise) {} + private readonly getEndpoint: () => Promise; + + constructor(getEndpoint: () => Promise) { + this.getEndpoint = getEndpoint; + } get getKey() { if (!this.#keyStore) { diff --git a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts index a244614135..b70aedfb9a 100644 --- a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.test.ts @@ -31,6 +31,9 @@ import { toInternalBackstageCredentials } from './helpers'; import { PluginTokenHandler } from './plugin/PluginTokenHandler'; import { createServiceFactory } from '@backstage/backend-plugin-api'; +import { externalTokenHandlersServiceRef } from './external/ExternalAuthTokenHandler'; +import { createExternalTokenHandler } from './external/helpers'; + const server = setupServer(); // TODO: Ship discovery mock service in the service factory tester @@ -450,8 +453,88 @@ describe('authServiceFactory', () => { dependencies: [...mockDeps, customPluginTokenHandler], }); const searchAuth = await tester.getSubject('search'); - searchAuth.authenticate('unlimited-static-token'); + await searchAuth.authenticate('unlimited-static-token'); expect(customLogic).toHaveBeenCalledWith('unlimited-static-token'); }); }); + describe('add custom ExternalTokenHandler', () => { + it('should allow custom logic to be injected into the plugin token handler', async () => { + const customLogic = jest.fn(); + const customConfig = jest.fn(); + const deps = [ + discoveryServiceFactory, + mockServices.rootConfig.factory({ + data: { + backend: { + baseUrl: 'http://localhost', + auth: { + keys: [{ secret: 'abc' }], + externalAccess: [ + { + type: 'static', + options: { + token: 'limited-static-token', + subject: 'limited-static-subject', + }, + accessRestrictions: [ + { plugin: 'catalog', permission: 'do.it' }, + ], + }, + { + type: 'static', + options: { + token: 'unlimited-static-token', + subject: 'unlimited-static-subject', + }, + }, + { + type: 'custom', + options: { + [`custom-config`]: 'custom-config', + foo: 'bar', + }, + }, + ], + }, + }, + }, + }), + ]; + + const customExternalTokenHandler = createExternalTokenHandler<{ + [`custom-config`]: string; + foo: string; + }>({ + type: 'custom', + initialize({ options }) { + const customConfigValue = options.getString('custom-config'); + const foo = options.getString('foo'); + customConfig(customConfigValue); + return { [`custom-config`]: customConfigValue, foo }; + }, + async verifyToken(token, ctx) { + customLogic(token); + return { + subject: ctx.foo, + }; + }, + }); + + const customPluginTokenHandler = createServiceFactory({ + service: externalTokenHandlersServiceRef, + deps: {}, + async factory() { + return customExternalTokenHandler; + }, + }); + const tester = ServiceFactoryTester.from(authServiceFactory, { + dependencies: [...deps, customPluginTokenHandler], + }); + const searchAuth = await tester.getSubject('search'); + await searchAuth.authenticate('custom-token'); + + expect(customLogic).toHaveBeenCalledWith('custom-token'); + expect(customConfig).toHaveBeenCalledWith('custom-config'); + }); + }); }); diff --git a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.ts b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.ts index 91910292e6..ee171aef25 100644 --- a/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/auth/authServiceFactory.ts @@ -20,7 +20,10 @@ import { createServiceRef, } from '@backstage/backend-plugin-api'; import { DefaultAuthService } from './DefaultAuthService'; -import { ExternalTokenHandler } from './external/ExternalTokenHandler'; +import { + ExternalAuthTokenHandler, + externalTokenHandlersServiceRef, +} from './external/ExternalAuthTokenHandler'; import { DefaultPluginTokenHandler, PluginTokenHandler, @@ -64,6 +67,7 @@ export const authServiceFactory = createServiceFactory({ plugin: coreServices.pluginMetadata, database: coreServices.database, pluginTokenHandlerDecorator: pluginTokenHandlerDecoratorServiceRef, + externalTokenHandlers: externalTokenHandlersServiceRef, }, async factory({ config, @@ -72,6 +76,7 @@ export const authServiceFactory = createServiceFactory({ logger, database, pluginTokenHandlerDecorator, + externalTokenHandlers, }) { const disableDefaultAuthPolicy = config.getOptionalBoolean( @@ -102,10 +107,11 @@ export const authServiceFactory = createServiceFactory({ }), ); - const externalTokens = ExternalTokenHandler.create({ + const externalTokens = ExternalAuthTokenHandler.create({ ownPluginId: plugin.getId(), config, logger, + externalTokenHandlers, }); return new DefaultAuthService( diff --git a/packages/backend-defaults/src/entrypoints/auth/external/ExternalAuthTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/ExternalAuthTokenHandler.test.ts new file mode 100644 index 0000000000..50cfb47b3e --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auth/external/ExternalAuthTokenHandler.test.ts @@ -0,0 +1,502 @@ +/* + * 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 { BackstagePrincipalAccessRestrictions } from '@backstage/backend-plugin-api'; +import { ExternalAuthTokenHandler } from './ExternalAuthTokenHandler'; +import { createExternalTokenHandler } from './helpers'; +import { AccessRestrictionsMap, ExternalTokenHandler } from './types'; +import { + mockServices, + registerMswTestHooks, +} from '@backstage/backend-test-utils'; +import { randomBytes } from 'crypto'; +import { SignJWT, exportJWK, generateKeyPair } from 'jose'; +import { DateTime } from 'luxon'; +import { v4 as uuid } from 'uuid'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; + +// Simplified copy of TokenFactory in @backstage/plugin-auth-backend +interface AnyJWK extends Record { + use: 'sig'; + alg: string; + kid: string; + kty: string; +} +class FakeTokenFactory { + private readonly keys = new Array(); + private readonly options: { + issuer: string; + keyDurationSeconds: number; + }; + + constructor(options: { issuer: string; keyDurationSeconds: number }) { + this.options = options; + } + + async issueToken(params: { + claims: { + sub: string; + ent?: string[]; + }; + }): Promise { + const pair = await generateKeyPair('RS256'); + const publicKey = await exportJWK(pair.publicKey); + const kid = uuid(); + publicKey.kid = kid; + this.keys.push(publicKey as AnyJWK); + + const iss = this.options.issuer; + const sub = params.claims.sub; + const ent = params.claims.ent; + const aud = 'backstage'; + const iat = Math.floor(Date.now() / 1000); + const exp = iat + this.options.keyDurationSeconds; + + return new SignJWT({ iss, sub, aud, iat, exp, ent, kid }) + .setProtectedHeader({ alg: 'RS256', ent: ent, kid: kid }) + .setIssuer(iss) + .setAudience(aud) + .setSubject(sub) + .setIssuedAt(iat) + .setExpirationTime(exp) + .sign(pair.privateKey); + } + + async listPublicKeys(): Promise<{ keys: AnyJWK[] }> { + return { keys: this.keys }; + } +} + +describe('ExternalTokenHandler', () => { + const server = setupServer(); + registerMswTestHooks(server); + + it('skips over inner handlers that do not match, and applies plugin restrictions', async () => { + const handler1: ExternalTokenHandler = createExternalTokenHandler({ + type: 'type1', + initialize: jest.fn().mockResolvedValue(undefined), + verifyToken: jest.fn().mockResolvedValue(undefined), + }); + + const handler2: ExternalTokenHandler = + createExternalTokenHandler({ + type: 'type2', + initialize: jest.fn().mockResolvedValue(undefined), + verifyToken: jest.fn().mockResolvedValue({ + subject: 'sub', + }), + }); + + const accessRestrictions: AccessRestrictionsMap = new Map( + Object.entries({ + plugin1: { + permissionNames: ['do.it'], + } satisfies BackstagePrincipalAccessRestrictions, + }), + ); + + const plugin1 = new ExternalAuthTokenHandler('plugin1', [ + { + context: undefined, + handler: handler1, + }, + { + context: undefined, + handler: handler2, + allAccessRestrictions: accessRestrictions, + }, + ]); + const plugin2 = new ExternalAuthTokenHandler('plugin2', [ + { + context: undefined, + handler: handler1, + }, + { + context: undefined, + handler: handler2, + allAccessRestrictions: accessRestrictions, + }, + ]); + + await expect(plugin1.verifyToken('token')).resolves.toEqual({ + subject: 'sub', + accessRestrictions: { permissionNames: ['do.it'] }, + }); + await expect( + plugin2.verifyToken('token'), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"This token's access is restricted to plugin(s) 'plugin1'"`, + ); + }); + + it('successfully parses known methods', async () => { + const legacyKey = randomBytes(24); + + const factory = new FakeTokenFactory({ + issuer: 'blah', + keyDurationSeconds: 100, + }); + + server.use( + rest.get( + 'https://example.com/.well-known/jwks.json', + async (_, res, ctx) => { + const keys = await factory.listPublicKeys(); + return res(ctx.json(keys)); + }, + ), + ); + + const handler = ExternalAuthTokenHandler.create({ + ownPluginId: 'catalog', + logger: mockServices.logger.mock(), + config: mockServices.rootConfig({ + data: { + backend: { + auth: { + externalAccess: [ + { + type: 'legacy', + options: { + secret: legacyKey.toString('base64'), + subject: 'legacy-subject', + }, + accessRestrictions: [ + { plugin: 'catalog', permission: 'catalog.entity.read' }, + ], + }, + { + type: 'static', + options: { + token: 'defdefdef', + subject: 'static-subject', + }, + accessRestrictions: [ + { plugin: 'catalog', permission: 'catalog.entity.read' }, + ], + }, + { + type: 'jwks', + options: { + url: 'https://example.com/.well-known/jwks.json', + algorithm: 'RS256', + issuer: 'blah', + audience: 'backstage', + subjectPrefix: 'custom-prefix', + }, + accessRestrictions: [ + { plugin: 'catalog', permission: 'catalog.entity.read' }, + ], + }, + ], + }, + }, + }, + }), + }); + + const legacyToken = await new SignJWT({ + sub: 'backstage-server', + exp: DateTime.now().plus({ minutes: 1 }).toUnixInteger(), + }) + .setProtectedHeader({ alg: 'HS256' }) + .sign(legacyKey); + + await expect(handler.verifyToken(legacyToken)).resolves.toEqual({ + subject: 'legacy-subject', + accessRestrictions: { permissionNames: ['catalog.entity.read'] }, + }); + + await expect(handler.verifyToken('defdefdef')).resolves.toEqual({ + subject: 'static-subject', + accessRestrictions: { permissionNames: ['catalog.entity.read'] }, + }); + + const jwksToken = await factory.issueToken({ + claims: { sub: 'jwks-subject' }, + }); + await expect(handler.verifyToken(jwksToken)).resolves.toEqual({ + subject: 'external:custom-prefix:jwks-subject', + accessRestrictions: { permissionNames: ['catalog.entity.read'] }, + }); + }); + it('successfully uses legacy configs', async () => { + const legacyKey = randomBytes(24); + const factory = new FakeTokenFactory({ + issuer: 'my-company', + keyDurationSeconds: 100, + }); + + server.use( + rest.get( + 'https://example.com/.well-known/jwks.json', + async (_, res, ctx) => { + const keys = await factory.listPublicKeys(); + return res(ctx.json(keys)); + }, + ), + ); + + const logger = mockServices.logger.mock(); + const handler = ExternalAuthTokenHandler.create({ + ownPluginId: 'catalog', + logger, + config: mockServices.rootConfig({ + data: { + backend: { + auth: { + keys: [ + { + secret: legacyKey.toString('base64'), + }, + ], + }, + }, + }, + }), + }); + + expect(logger.warn).toHaveBeenCalledWith( + `DEPRECATION WARNING: The backend.auth.keys config has been replaced by backend.auth.externalAccess, see https://backstage.io/docs/auth/service-to-service-auth`, + ); + + const legacyToken = await new SignJWT({ + sub: 'backstage-server', + exp: DateTime.now().plus({ minutes: 1 }).toUnixInteger(), + }) + .setProtectedHeader({ alg: 'HS256' }) + .sign(legacyKey); + + await expect(handler.verifyToken(legacyToken)).resolves.toEqual({ + subject: 'external:backstage-plugin', + }); + }); + it('successfully uses custom token handlers', async () => { + const factory = new FakeTokenFactory({ + issuer: 'my-company', + keyDurationSeconds: 100, + }); + + server.use( + rest.get( + 'https://example.com/.well-known/jwks.json', + async (_, res, ctx) => { + const keys = await factory.listPublicKeys(); + return res(ctx.json(keys)); + }, + ), + ); + + const verifyMock = jest.fn().mockResolvedValue({}); + const initializeMock = jest.fn().mockReturnValue({ context: 'a' }); + + const handler = ExternalAuthTokenHandler.create({ + ownPluginId: 'catalog', + logger: mockServices.logger.mock(), + config: mockServices.rootConfig({ + data: { + backend: { + auth: { + externalAccess: [ + { + type: 'internal-custom', + options: { + issuer: 'my-company', + subject: 'internal-subject', + audience: 'backstage', + }, + accessRestrictions: [ + { plugin: 'catalog', permission: 'catalog.entity.read' }, + ], + }, + ], + }, + }, + }, + }), + externalTokenHandlers: [ + createExternalTokenHandler({ + type: 'internal-custom', + initialize: initializeMock, + verifyToken: verifyMock, + }), + ], + }); + + expect(initializeMock).toHaveBeenCalledWith({ + options: expect.objectContaining({ + data: { + issuer: 'my-company', + subject: 'internal-subject', + audience: 'backstage', + }, + }), + }); + + const customToken = await factory.issueToken({ + claims: { sub: 'internal-subject' }, + }); + + await handler.verifyToken(customToken); + + expect(verifyMock).toHaveBeenCalledWith(customToken, { context: 'a' }); + }); + it('should fail if custom handler has same type as builtin handlers', async () => { + const logger = mockServices.logger.mock(); + const customStaticHandler: ExternalTokenHandler = + createExternalTokenHandler({ + type: 'static', + initialize: jest.fn().mockResolvedValue(undefined), + verifyToken: jest.fn().mockResolvedValue({ + subject: 'custom-static-subject', + }), + }); + + const createHandler = () => + ExternalAuthTokenHandler.create({ + ownPluginId: 'catalog', + logger, + config: mockServices.rootConfig({ + data: { + backend: { + auth: { + externalAccess: [ + { + type: 'static', + options: { + token: 'mytoken', + subject: 'static-subject', + }, + accessRestrictions: [ + { plugin: 'catalog', permission: 'catalog.entity.read' }, + ], + }, + ], + }, + }, + }, + }), + externalTokenHandlers: [customStaticHandler], + }); + + expect(createHandler).toThrowErrorMatchingInlineSnapshot( + `"Duplicate external token handler type 'static', each handler must have a unique type"`, + ); + }); + it('should fail if 2 custom handlers have the same type', async () => { + const createHandler = () => + ExternalAuthTokenHandler.create({ + ownPluginId: 'catalog', + logger: mockServices.logger.mock(), + config: mockServices.rootConfig(), + externalTokenHandlers: [ + createExternalTokenHandler({ + type: 'internal-custom', + initialize: jest.fn().mockResolvedValue(undefined), + verifyToken: jest.fn().mockResolvedValue({ + subject: 'sub', + }), + }), + createExternalTokenHandler({ + type: 'internal-custom', + initialize: jest.fn().mockResolvedValue(undefined), + verifyToken: jest.fn().mockResolvedValue({ + subject: 'sub', + }), + }), + ], + }); + + expect(createHandler).toThrowErrorMatchingInlineSnapshot( + `"Duplicate external token handler type 'internal-custom', each handler must have a unique type"`, + ); + }); + it('should fail if config contains types not declared', async () => { + const createHandler = () => + ExternalAuthTokenHandler.create({ + ownPluginId: 'catalog', + logger: mockServices.logger.mock(), + config: mockServices.rootConfig({ + data: { + backend: { + auth: { + externalAccess: [ + { + type: 'internal-custom', + options: { + issuer: 'my-company', + subject: 'internal-subject', + audience: 'backstage', + }, + accessRestrictions: [ + { plugin: 'catalog', permission: 'catalog.entity.read' }, + ], + }, + ], + }, + }, + }, + }), + }); + + expect(createHandler).toThrowErrorMatchingInlineSnapshot( + `"Unknown type 'internal-custom' in backend.auth.externalAccess, expected one of 'static', 'legacy', 'jwks'"`, + ); + }); + + it('should show valid custom types in errors', async () => { + const createHandler = () => + ExternalAuthTokenHandler.create({ + ownPluginId: 'catalog', + logger: mockServices.logger.mock(), + config: mockServices.rootConfig({ + data: { + backend: { + auth: { + externalAccess: [ + { + type: 'internal-custom-invalid', + options: { + issuer: 'my-company', + subject: 'internal-subject', + audience: 'backstage', + }, + accessRestrictions: [ + { plugin: 'catalog', permission: 'catalog.entity.read' }, + ], + }, + ], + }, + }, + }, + }), + externalTokenHandlers: [ + createExternalTokenHandler({ + type: 'internal-custom', + initialize: jest.fn().mockResolvedValue(undefined), + verifyToken: jest.fn().mockResolvedValue({ + subject: 'sub', + }), + }), + ], + }); + + expect(createHandler).toThrowErrorMatchingInlineSnapshot( + `"Unknown type 'internal-custom-invalid' in backend.auth.externalAccess, expected one of 'static', 'legacy', 'jwks', 'internal-custom'"`, + ); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/ExternalAuthTokenHandler.ts b/packages/backend-defaults/src/entrypoints/auth/external/ExternalAuthTokenHandler.ts new file mode 100644 index 0000000000..e0a7680ce5 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/auth/external/ExternalAuthTokenHandler.ts @@ -0,0 +1,197 @@ +/* + * 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 { + BackstagePrincipalAccessRestrictions, + createServiceRef, + LoggerService, + RootConfigService, +} from '@backstage/backend-plugin-api'; +import { NotAllowedError } from '@backstage/errors'; +import { legacyTokenHandler } from './legacy'; +import { staticTokenHandler } from './static'; +import { jwksTokenHandler } from './jwks'; +import { AccessRestrictionsMap, ExternalTokenHandler } from './types'; +import { readAccessRestrictionsFromConfig } from './helpers'; + +const NEW_CONFIG_KEY = 'backend.auth.externalAccess'; +const OLD_CONFIG_KEY = 'backend.auth.keys'; +let loggedDeprecationWarning = false; + +/** + * @public + * This service is used to add custom handlers for external token. + */ +export const externalTokenHandlersServiceRef = createServiceRef< + ExternalTokenHandler +>({ + id: 'core.auth.externalTokenHandlers', + multiton: true, +}); + +const defaultHandlers: Record> = { + static: staticTokenHandler, + legacy: legacyTokenHandler, + jwks: jwksTokenHandler, +}; + +type ContextMapEntry = { + context: T; + handler: ExternalTokenHandler; + allAccessRestrictions?: AccessRestrictionsMap; +}; + +/** + * Handles all types of external caller token types (i.e. not Backstage user + * tokens, nor Backstage backend plugin tokens). + * + * @internal + */ +export class ExternalAuthTokenHandler { + static create(options: { + ownPluginId: string; + config: RootConfigService; + logger: LoggerService; + externalTokenHandlers?: ExternalTokenHandler[]; + }): ExternalAuthTokenHandler { + const { + ownPluginId, + config, + externalTokenHandlers: customHandlers = [], + logger, + } = options; + + const handlersTypes = customHandlers.reduce< + Record> + >( + (acc, handler) => { + if (acc[handler.type]) { + throw new Error( + `Duplicate external token handler type '${handler.type}', each handler must have a unique type`, + ); + } + acc[handler.type] = handler; + return acc; + }, + { ...defaultHandlers }, + ); + + const handlerConfigs = config.getOptionalConfigArray(NEW_CONFIG_KEY) ?? []; + const contexts: ContextMapEntry[] = handlerConfigs.map( + handlerConfig => { + const type = handlerConfig.getString('type'); + + const handler = handlersTypes[type]; + if (!handler) { + const valid = Object.keys(handlersTypes) + .map(h => `'${h}'`) + .join(', '); + throw new Error( + `Unknown type '${type}' in ${NEW_CONFIG_KEY}, expected one of ${valid}`, + ); + } + return { + context: handler.initialize({ + options: handlerConfig.getConfig('options'), + }), + handler, + allAccessRestrictions: handlerConfig + ? readAccessRestrictionsFromConfig(handlerConfig) + : undefined, + }; + }, + ); + + // Load the old keys too + const legacyConfigs = config.getOptionalConfigArray(OLD_CONFIG_KEY) ?? []; + + if (legacyConfigs.length && !loggedDeprecationWarning) { + loggedDeprecationWarning = true; + + logger.warn( + `DEPRECATION WARNING: The ${OLD_CONFIG_KEY} config has been replaced by ${NEW_CONFIG_KEY}, see https://backstage.io/docs/auth/service-to-service-auth`, + ); + } + + for (const legacyConfig of legacyConfigs) { + contexts.push({ + context: legacyTokenHandler.initialize({ + legacy: true, + options: legacyConfig, + }), + handler: legacyTokenHandler, + allAccessRestrictions: readAccessRestrictionsFromConfig(legacyConfig), + }); + } + + return new ExternalAuthTokenHandler(ownPluginId, contexts); + } + + private readonly ownPluginId: string; + private readonly contexts: { + context: unknown; + handler: ExternalTokenHandler; + allAccessRestrictions?: AccessRestrictionsMap; + }[]; + + constructor( + ownPluginId: string, + contexts: { + context: unknown; + handler: ExternalTokenHandler; + allAccessRestrictions?: AccessRestrictionsMap; + }[], + ) { + this.ownPluginId = ownPluginId; + this.contexts = contexts; + } + + async verifyToken(token: string): Promise< + | { + subject: string; + accessRestrictions?: BackstagePrincipalAccessRestrictions; + } + | undefined + > { + for (const { handler, allAccessRestrictions, context } of this.contexts) { + const result = await handler.verifyToken(token, context); + if (result) { + if (allAccessRestrictions) { + const accessRestrictions = allAccessRestrictions.get( + this.ownPluginId, + ); + if (!accessRestrictions) { + const valid = [...allAccessRestrictions.keys()] + .map(k => `'${k}'`) + .join(', '); + throw new NotAllowedError( + `This token's access is restricted to plugin(s) ${valid}`, + ); + } + + return { + ...result, + accessRestrictions, + }; + } + + return result; + } + } + + return undefined; + } +} diff --git a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts deleted file mode 100644 index 39b01c46b6..0000000000 --- a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.test.ts +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { BackstagePrincipalAccessRestrictions } from '@backstage/backend-plugin-api'; -import { ExternalTokenHandler } from './ExternalTokenHandler'; -import { TokenHandler } from './types'; -import { - mockServices, - registerMswTestHooks, -} from '@backstage/backend-test-utils'; -import { randomBytes } from 'crypto'; -import { SignJWT, exportJWK, generateKeyPair } from 'jose'; -import { DateTime } from 'luxon'; -import { v4 as uuid } from 'uuid'; -import { rest } from 'msw'; -import { setupServer } from 'msw/node'; - -// Simplified copy of TokenFactory in @backstage/plugin-auth-backend -interface AnyJWK extends Record { - use: 'sig'; - alg: string; - kid: string; - kty: string; -} -class FakeTokenFactory { - private readonly keys = new Array(); - - constructor( - private readonly options: { - issuer: string; - keyDurationSeconds: number; - }, - ) {} - - async issueToken(params: { - claims: { - sub: string; - ent?: string[]; - }; - }): Promise { - const pair = await generateKeyPair('RS256'); - const publicKey = await exportJWK(pair.publicKey); - const kid = uuid(); - publicKey.kid = kid; - this.keys.push(publicKey as AnyJWK); - - const iss = this.options.issuer; - const sub = params.claims.sub; - const ent = params.claims.ent; - const aud = 'backstage'; - const iat = Math.floor(Date.now() / 1000); - const exp = iat + this.options.keyDurationSeconds; - - return new SignJWT({ iss, sub, aud, iat, exp, ent, kid }) - .setProtectedHeader({ alg: 'RS256', ent: ent, kid: kid }) - .setIssuer(iss) - .setAudience(aud) - .setSubject(sub) - .setIssuedAt(iat) - .setExpirationTime(exp) - .sign(pair.privateKey); - } - - async listPublicKeys(): Promise<{ keys: AnyJWK[] }> { - return { keys: this.keys }; - } -} - -describe('ExternalTokenHandler', () => { - const server = setupServer(); - registerMswTestHooks(server); - - it('skips over inner handlers that do not match, and applies plugin restrictions', async () => { - const handler1: TokenHandler = { - add: jest.fn(), - verifyToken: jest.fn().mockResolvedValue(undefined), - }; - - const handler2: TokenHandler = { - add: jest.fn(), - verifyToken: jest.fn().mockResolvedValue({ - subject: 'sub', - allAccessRestrictions: new Map( - Object.entries({ - plugin1: { - permissionNames: ['do.it'], - } satisfies BackstagePrincipalAccessRestrictions, - }), - ), - }), - }; - - const plugin1 = new ExternalTokenHandler('plugin1', [handler1, handler2]); - const plugin2 = new ExternalTokenHandler('plugin2', [handler1, handler2]); - - await expect(plugin1.verifyToken('token')).resolves.toEqual({ - subject: 'sub', - accessRestrictions: { permissionNames: ['do.it'] }, - }); - await expect( - plugin2.verifyToken('token'), - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"This token's access is restricted to plugin(s) 'plugin1'"`, - ); - }); - - it('successfully parses known methods', async () => { - const legacyKey = randomBytes(24); - - const factory = new FakeTokenFactory({ - issuer: 'blah', - keyDurationSeconds: 100, - }); - - server.use( - rest.get( - 'https://example.com/.well-known/jwks.json', - async (_, res, ctx) => { - const keys = await factory.listPublicKeys(); - return res(ctx.json(keys)); - }, - ), - ); - - const handler = ExternalTokenHandler.create({ - ownPluginId: 'catalog', - logger: mockServices.logger.mock(), - config: mockServices.rootConfig({ - data: { - backend: { - auth: { - externalAccess: [ - { - type: 'legacy', - options: { - secret: legacyKey.toString('base64'), - subject: 'legacy-subject', - }, - accessRestrictions: [ - { plugin: 'catalog', permission: 'catalog.entity.read' }, - ], - }, - { - type: 'static', - options: { - token: 'defdefdef', - subject: 'static-subject', - }, - accessRestrictions: [ - { plugin: 'catalog', permission: 'catalog.entity.read' }, - ], - }, - { - type: 'jwks', - options: { - url: 'https://example.com/.well-known/jwks.json', - algorithm: 'RS256', - issuer: 'blah', - audience: 'backstage', - subjectPrefix: 'custom-prefix', - }, - accessRestrictions: [ - { plugin: 'catalog', permission: 'catalog.entity.read' }, - ], - }, - ], - }, - }, - }, - }), - }); - - const legacyToken = await new SignJWT({ - sub: 'backstage-server', - exp: DateTime.now().plus({ minutes: 1 }).toUnixInteger(), - }) - .setProtectedHeader({ alg: 'HS256' }) - .sign(legacyKey); - - await expect(handler.verifyToken(legacyToken)).resolves.toEqual({ - subject: 'legacy-subject', - accessRestrictions: { permissionNames: ['catalog.entity.read'] }, - }); - - await expect(handler.verifyToken('defdefdef')).resolves.toEqual({ - subject: 'static-subject', - accessRestrictions: { permissionNames: ['catalog.entity.read'] }, - }); - - const jwksToken = await factory.issueToken({ - claims: { sub: 'jwks-subject' }, - }); - await expect(handler.verifyToken(jwksToken)).resolves.toEqual({ - subject: 'external:custom-prefix:jwks-subject', - accessRestrictions: { permissionNames: ['catalog.entity.read'] }, - }); - }); -}); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.ts b/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.ts deleted file mode 100644 index 72eeae6fcf..0000000000 --- a/packages/backend-defaults/src/entrypoints/auth/external/ExternalTokenHandler.ts +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - BackstagePrincipalAccessRestrictions, - LoggerService, - RootConfigService, -} from '@backstage/backend-plugin-api'; -import { NotAllowedError } from '@backstage/errors'; -import { LegacyTokenHandler } from './legacy'; -import { StaticTokenHandler } from './static'; -import { JWKSHandler } from './jwks'; -import { TokenHandler } from './types'; - -const NEW_CONFIG_KEY = 'backend.auth.externalAccess'; -const OLD_CONFIG_KEY = 'backend.auth.keys'; -let loggedDeprecationWarning = false; - -/** - * Handles all types of external caller token types (i.e. not Backstage user - * tokens, nor Backstage backend plugin tokens). - * - * @internal - */ -export class ExternalTokenHandler { - static create(options: { - ownPluginId: string; - config: RootConfigService; - logger: LoggerService; - }): ExternalTokenHandler { - const { ownPluginId, config, logger } = options; - - const staticHandler = new StaticTokenHandler(); - const legacyHandler = new LegacyTokenHandler(); - const jwksHandler = new JWKSHandler(); - const handlers: Record = { - static: staticHandler, - legacy: legacyHandler, - jwks: jwksHandler, - }; - - // Load the new-style handlers - const handlerConfigs = config.getOptionalConfigArray(NEW_CONFIG_KEY) ?? []; - for (const handlerConfig of handlerConfigs) { - const type = handlerConfig.getString('type'); - const handler = handlers[type]; - if (!handler) { - const valid = Object.keys(handlers) - .map(k => `'${k}'`) - .join(', '); - throw new Error( - `Unknown type '${type}' in ${NEW_CONFIG_KEY}, expected one of ${valid}`, - ); - } - handler.add(handlerConfig); - } - - // Load the old keys too - const legacyConfigs = config.getOptionalConfigArray(OLD_CONFIG_KEY) ?? []; - if (legacyConfigs.length && !loggedDeprecationWarning) { - loggedDeprecationWarning = true; - logger.warn( - `DEPRECATION WARNING: The ${OLD_CONFIG_KEY} config has been replaced by ${NEW_CONFIG_KEY}, see https://backstage.io/docs/auth/service-to-service-auth`, - ); - } - for (const handlerConfig of legacyConfigs) { - legacyHandler.addOld(handlerConfig); - } - - return new ExternalTokenHandler(ownPluginId, Object.values(handlers)); - } - - constructor( - private readonly ownPluginId: string, - private readonly handlers: TokenHandler[], - ) {} - - async verifyToken(token: string): Promise< - | { - subject: string; - accessRestrictions?: BackstagePrincipalAccessRestrictions; - } - | undefined - > { - for (const handler of this.handlers) { - const result = await handler.verifyToken(token); - if (result) { - const { allAccessRestrictions, ...rest } = result; - if (allAccessRestrictions) { - const accessRestrictions = allAccessRestrictions.get( - this.ownPluginId, - ); - if (!accessRestrictions) { - const valid = [...allAccessRestrictions.keys()] - .map(k => `'${k}'`) - .join(', '); - throw new NotAllowedError( - `This token's access is restricted to plugin(s) ${valid}`, - ); - } - - return { - ...rest, - accessRestrictions, - }; - } - - return rest; - } - } - - return undefined; - } -} diff --git a/packages/backend-defaults/src/entrypoints/auth/external/helpers.ts b/packages/backend-defaults/src/entrypoints/auth/external/helpers.ts index d6aa0a01ff..94d289bd7c 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/helpers.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/helpers.ts @@ -15,7 +15,7 @@ */ import { Config } from '@backstage/config'; -import { AccessRestriptionsMap } from './types'; +import { AccessRestrictionsMap, ExternalTokenHandler } from './types'; /** * Parses and returns the `accessRestrictions` configuration from an @@ -25,12 +25,12 @@ import { AccessRestriptionsMap } from './types'; */ export function readAccessRestrictionsFromConfig( externalAccessEntryConfig: Config, -): AccessRestriptionsMap | undefined { +): AccessRestrictionsMap | undefined { const configs = externalAccessEntryConfig.getOptionalConfigArray('accessRestrictions') ?? []; - const result: AccessRestriptionsMap = new Map(); + const result: AccessRestrictionsMap = new Map(); for (const config of configs) { const validKeys = ['plugin', 'permission', 'permissionAttribute']; for (const key of config.keys()) { @@ -147,3 +147,37 @@ function readPermissionAttributes(externalAccessEntryConfig: Config) { return Object.keys(result).length ? result : undefined; } + +/** + * Creates an external token handler with the provided implementation. + * + * This helper function simplifies the creation of external token handlers by + * providing type safety and a consistent API. External token handlers are used + * to validate tokens from external systems that need to authenticate with Backstage. + * + * See {@link https://backstage.io/docs/auth/service-to-service-auth#adding-custom-externaltokenhandler | the service-to-service auth docs} + * for more information about implementing custom external token handlers. + * + * @public + * @param handler - The external token handler implementation with type, initialize, and verifyToken methods + * @returns The same handler instance, typed as ExternalTokenHandler + * + * @example + * ```ts + * const customHandler = createExternalTokenHandler({ + * type: 'custom', + * initialize({ options }) { + * return { apiKey: options.getString('apiKey') }; + * }, + * async verifyToken(token, context) { + * // Custom validation logic here + * return { subject: 'custom:user' }; + * }, + * }); + * ``` + */ +export function createExternalTokenHandler( + handler: ExternalTokenHandler, +): ExternalTokenHandler { + return handler; +} diff --git a/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts index 321e1823aa..327173fdee 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/jwks.test.ts @@ -20,7 +20,7 @@ import { SignJWT, exportJWK, generateKeyPair } from 'jose'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { v4 as uuid } from 'uuid'; -import { JWKSHandler } from './jwks'; +import { jwksTokenHandler } from './jwks'; // Simplified copy of TokenFactory in @backstage/plugin-auth-backend interface AnyJWK extends Record { @@ -31,13 +31,14 @@ interface AnyJWK extends Record { } class FakeTokenFactory { private readonly keys = new Array(); + private readonly options: { + issuer: string; + keyDurationSeconds: number; + }; - constructor( - private readonly options: { - issuer: string; - keyDurationSeconds: number; - }, - ) {} + constructor(options: { issuer: string; keyDurationSeconds: number }) { + this.options = options; + } async issueToken(params: { claims: { @@ -101,114 +102,45 @@ describe('JWKSHandler', () => { it('verifies token with valid entry', async () => { const validEntry = { - options: { - url: `${mockBaseUrl}/.well-known/jwks.json`, - algorithm: 'RS256', - issuer: mockBaseUrl, - audience: 'backstage', - }, + url: `${mockBaseUrl}/.well-known/jwks.json`, + algorithm: 'RS256', + issuer: mockBaseUrl, + audience: 'backstage', }; - const jwksHandler = new JWKSHandler(); - - jwksHandler.add(new ConfigReader(validEntry)); + const context = jwksTokenHandler.initialize({ + options: new ConfigReader(validEntry), + }); const token = await factory.issueToken({ claims: { sub: mockSubject }, }); - const result = await jwksHandler.verifyToken(token); + const result = await jwksTokenHandler.verifyToken(token, context); expect(result).toEqual({ subject: `external:${mockSubject}` }); }); - it('skips invalid entry and continues verification', async () => { - const invalidEntry = { - options: { - url: `${mockBaseUrl}/.well-known/jwks.json`, - algorithm: 'RS256', - issuer: ['fakeIssuer'], - audience: ['fakeAud'], - }, - }; - - const validEntry = { - options: { - url: `${mockBaseUrl}/.well-known/jwks.json`, - algorithm: 'RS256', - issuer: ['multiple-issuers', mockBaseUrl], - audience: ['multiple-audiences', 'backstage'], - }, - }; - const jwksHandler = new JWKSHandler(); - - jwksHandler.add(new ConfigReader(invalidEntry)); - jwksHandler.add(new ConfigReader(validEntry)); - - const token = await factory.issueToken({ - claims: { sub: mockSubject }, - }); - - const result = await jwksHandler.verifyToken(token); - - expect(result).toEqual({ subject: `external:${mockSubject}` }); - }); - - it('returns undefined if no valid entry found', async () => { - const invalidEntry1 = { - options: { - url: `${mockBaseUrl}/.well-known/jwks.json`, - algorithm: 'RS256', - issuer: 'wrong', - }, - }; - - const invalidEntry2 = { - options: { - url: `${mockBaseUrl}/.well-known/jwks.json`, - algorithm: ['HS256'], - audience: 'wrong', - }, - }; - const jwksHandler = new JWKSHandler(); - - jwksHandler.add(new ConfigReader(invalidEntry1)); - jwksHandler.add(new ConfigReader(invalidEntry2)); - - const token = await factory.issueToken({ - claims: { sub: mockSubject }, - }); - - const result = await jwksHandler.verifyToken(token); - - expect(result).toBeUndefined(); - }); - it('rejects bad config', () => { - const jwksHandler = new JWKSHandler(); - expect(() => { - jwksHandler.add( - new ConfigReader({ - options: { - url: 'https://exampl e.com/jwks', - }, + return jwksTokenHandler.initialize({ + options: new ConfigReader({ + url: 'https://exampl e.com/jwks', }), - ); + }); }).toThrow('Illegal JWKS URL, must be a set of non-space characters'); expect(() => { - jwksHandler.add( - new ConfigReader({ - options: { - url: 'https://example.com/jwks\n', - }, + return jwksTokenHandler.initialize({ + options: new ConfigReader({ + url: 'https://example.com/jwks\n', }), - ); + }); }).toThrow('Illegal JWKS URL, must be a set of non-space characters'); }); it('gracefully handles no added tokens', async () => { - const handler = new JWKSHandler(); - await expect(handler.verifyToken('ghi')).resolves.toBeUndefined(); + await expect( + jwksTokenHandler.verifyToken('ghi', {} as any), + ).resolves.toBeUndefined(); }); it('uses custom subject prefix if provided', async () => { @@ -221,41 +153,18 @@ describe('JWKSHandler', () => { subjectPrefix: 'custom-prefix', }, }; - const jwksHandler = new JWKSHandler(); - - jwksHandler.add(new ConfigReader(validEntry)); + const context = jwksTokenHandler.initialize({ + options: new ConfigReader(validEntry.options), + }); const token = await factory.issueToken({ claims: { sub: mockSubject }, }); - const result = await jwksHandler.verifyToken(token); + const result = await jwksTokenHandler.verifyToken(token, context); expect(result).toEqual({ subject: `external:${validEntry.options.subjectPrefix}:${mockSubject}`, }); }); - - it('carries over access restrictions', async () => { - const jwksHandler = new JWKSHandler(); - jwksHandler.add( - new ConfigReader({ - options: { - url: `${mockBaseUrl}/.well-known/jwks.json`, - }, - accessRestrictions: [{ plugin: 'scaffolder', permission: 'do.it' }], - }), - ); - - const token = await factory.issueToken({ claims: { sub: mockSubject } }); - - await expect(jwksHandler.verifyToken(token)).resolves.toEqual({ - subject: `external:${mockSubject}`, - allAccessRestrictions: new Map( - Object.entries({ - scaffolder: { permissionNames: ['do.it'] }, - }), - ), - }); - }); }); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/jwks.ts b/packages/backend-defaults/src/entrypoints/auth/external/jwks.ts index d88dc62a47..33b55df775 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/jwks.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/jwks.ts @@ -15,51 +15,40 @@ */ import { jwtVerify, createRemoteJWKSet, JWTVerifyGetKey } from 'jose'; -import { Config } from '@backstage/config'; import { + createExternalTokenHandler, readAccessRestrictionsFromConfig, readStringOrStringArrayFromConfig, } from './helpers'; -import { AccessRestriptionsMap, TokenHandler } from './types'; +import { AccessRestrictionsMap } from './types'; -/** - * Handles `type: jwks` access. - * - * @internal - */ -export class JWKSHandler implements TokenHandler { - #entries: Array<{ - algorithms?: string[]; - audiences?: string[]; - issuers?: string[]; - subjectPrefix?: string; - url: URL; - jwks: JWTVerifyGetKey; - allAccessRestrictions?: AccessRestriptionsMap; - }> = []; +type JWKSTokenContext = { + algorithms?: string[]; + audiences?: string[]; + issuers?: string[]; + subjectPrefix?: string; + url: URL; + jwks: JWTVerifyGetKey; + allAccessRestrictions?: AccessRestrictionsMap; +}; - add(config: Config) { - if (!config.getString('options.url').match(/^\S+$/)) { +export const jwksTokenHandler = createExternalTokenHandler({ + type: 'jwks', + initialize({ options }): JWKSTokenContext { + if (!options.getString('url').match(/^\S+$/)) { throw new Error( 'Illegal JWKS URL, must be a set of non-space characters', ); } - const algorithms = readStringOrStringArrayFromConfig( - config, - 'options.algorithm', - ); - const issuers = readStringOrStringArrayFromConfig(config, 'options.issuer'); - const audiences = readStringOrStringArrayFromConfig( - config, - 'options.audience', - ); - const subjectPrefix = config.getOptionalString('options.subjectPrefix'); - const url = new URL(config.getString('options.url')); + const algorithms = readStringOrStringArrayFromConfig(options, 'algorithm'); + const issuers = readStringOrStringArrayFromConfig(options, 'issuer'); + const audiences = readStringOrStringArrayFromConfig(options, 'audience'); + const subjectPrefix = options.getOptionalString('subjectPrefix'); + const url = new URL(options.getString('url')); const jwks = createRemoteJWKSet(url); - const allAccessRestrictions = readAccessRestrictionsFromConfig(config); - - this.#entries.push({ + const allAccessRestrictions = readAccessRestrictionsFromConfig(options); + return { algorithms, audiences, issuers, @@ -67,33 +56,30 @@ export class JWKSHandler implements TokenHandler { subjectPrefix, url, allAccessRestrictions, - }); - } + }; + }, - async verifyToken(token: string) { - for (const entry of this.#entries) { - try { - const { - payload: { sub }, - } = await jwtVerify(token, entry.jwks, { - algorithms: entry.algorithms, - issuer: entry.issuers, - audience: entry.audiences, - }); + async verifyToken(token: string, context: JWKSTokenContext) { + try { + const { + payload: { sub }, + } = await jwtVerify(token, context.jwks, { + algorithms: context.algorithms, + issuer: context.issuers, + audience: context.audiences, + }); - if (sub) { - const prefix = entry.subjectPrefix - ? `external:${entry.subjectPrefix}:` - : 'external:'; - return { - subject: `${prefix}${sub}`, - allAccessRestrictions: entry.allAccessRestrictions, - }; - } - } catch { - continue; + if (sub) { + const prefix = context.subjectPrefix + ? `external:${context.subjectPrefix}:` + : 'external:'; + return { + subject: `${prefix}${sub}`, + }; } + } catch { + return undefined; } return undefined; - } -} + }, +}); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/legacy.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/legacy.test.ts index c674e46ec9..48dbcc2418 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/legacy.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/legacy.test.ts @@ -18,49 +18,35 @@ import { ConfigReader } from '@backstage/config'; import { randomBytes } from 'crypto'; import { SignJWT, importJWK } from 'jose'; import { DateTime } from 'luxon'; -import { LegacyTokenHandler } from './legacy'; +import { legacyTokenHandler } from './legacy'; describe('LegacyTokenHandler', () => { - const tokenHandler = new LegacyTokenHandler(); const key1 = randomBytes(24); const key2 = randomBytes(24); const key3 = randomBytes(24); - const accessRestrictions1 = new Map( - Object.entries({ - scaffolder: {}, - }), - ); - const accessRestrictions2 = new Map( - Object.entries({ - catalog: { permissionNames: ['catalog.entity.read'] }, - }), - ); - tokenHandler.add( - new ConfigReader({ - options: { - secret: key1.toString('base64'), - subject: 'key1', - }, - accessRestrictions: [{ plugin: 'scaffolder' }], + const tokenHandler = legacyTokenHandler; + + const context1 = tokenHandler.initialize({ + options: new ConfigReader({ + secret: key1.toString('base64'), + subject: 'key1', }), - ); - tokenHandler.add( - new ConfigReader({ - options: { - secret: key2.toString('base64'), - subject: 'key2', - }, - accessRestrictions: [ - { plugin: 'catalog', permission: 'catalog.entity.read' }, - ], + }); + + const context2 = tokenHandler.initialize({ + options: new ConfigReader({ + secret: key2.toString('base64'), + subject: 'key2', }), - ); - tokenHandler.addOld( - new ConfigReader({ + }); + + const contextWithLegacy = tokenHandler.initialize({ + options: new ConfigReader({ secret: key3.toString('base64'), }), - ); + legacy: true, + }); it('should verify valid tokens', async () => { const token1 = await new SignJWT({ @@ -70,9 +56,8 @@ describe('LegacyTokenHandler', () => { .setProtectedHeader({ alg: 'HS256' }) .sign(key1); - await expect(tokenHandler.verifyToken(token1)).resolves.toEqual({ + await expect(tokenHandler.verifyToken(token1, context1)).resolves.toEqual({ subject: 'key1', - allAccessRestrictions: accessRestrictions1, }); const token2 = await new SignJWT({ @@ -82,9 +67,8 @@ describe('LegacyTokenHandler', () => { .setProtectedHeader({ alg: 'HS256' }) .sign(key2); - await expect(tokenHandler.verifyToken(token2)).resolves.toEqual({ + await expect(tokenHandler.verifyToken(token2, context2)).resolves.toEqual({ subject: 'key2', - allAccessRestrictions: accessRestrictions2, }); const token3 = await new SignJWT({ @@ -94,7 +78,9 @@ describe('LegacyTokenHandler', () => { .setProtectedHeader({ alg: 'HS256' }) .sign(key3); - await expect(tokenHandler.verifyToken(token3)).resolves.toEqual({ + await expect( + tokenHandler.verifyToken(token3, contextWithLegacy), + ).resolves.toEqual({ subject: 'external:backstage-plugin', }); }); @@ -107,10 +93,18 @@ describe('LegacyTokenHandler', () => { .setProtectedHeader({ alg: 'HS256' }) .sign(key1); - await expect(tokenHandler.verifyToken(validToken)).resolves.toBeUndefined(); + await expect( + tokenHandler.verifyToken(validToken, context1), + ).resolves.toBeUndefined(); + await expect( + tokenHandler.verifyToken(validToken, context2), + ).resolves.toBeUndefined(); await expect( - tokenHandler.verifyToken('statickeyblaaa'), + tokenHandler.verifyToken('statickeyblaaa', context1), + ).resolves.toBeUndefined(); + await expect( + tokenHandler.verifyToken('statickeyblaaa', context2), ).resolves.toBeUndefined(); const randomToken = await new SignJWT({ @@ -120,7 +114,10 @@ describe('LegacyTokenHandler', () => { .setProtectedHeader({ alg: 'HS256' }) .sign(randomBytes(24)); await expect( - tokenHandler.verifyToken(randomToken), + tokenHandler.verifyToken(randomToken, context1), + ).resolves.toBeUndefined(); + await expect( + tokenHandler.verifyToken(randomToken, context2), ).resolves.toBeUndefined(); const mockPublicKey = { @@ -144,7 +141,10 @@ describe('LegacyTokenHandler', () => { .sign(await importJWK(mockPrivateKey)); await expect( - tokenHandler.verifyToken(keyWithWrongAlg), + tokenHandler.verifyToken(keyWithWrongAlg, context1), + ).resolves.toBeUndefined(); + await expect( + tokenHandler.verifyToken(keyWithWrongAlg, context2), ).resolves.toBeUndefined(); }); @@ -157,130 +157,151 @@ describe('LegacyTokenHandler', () => { .setProtectedHeader({ alg: 'HS256' }) .sign(key1); - await expect(tokenHandler.verifyToken(keyWithWrongExp)).rejects.toThrow( - /\"exp\" claim must be a number/, - ); + await expect( + tokenHandler.verifyToken(keyWithWrongExp, context1), + ).rejects.toThrow(/\"exp\" claim must be a number/); }); it('rejects bad config', () => { - const handler = new LegacyTokenHandler(); + const handler = legacyTokenHandler; // new style add, bad secrets expect(() => - handler.add( - new ConfigReader({ options: { _missingsecret: true, subject: 'ok' } }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Missing required config value at 'options.secret' in 'mock-config'"`, - ); - expect(() => - handler.add(new ConfigReader({ options: { secret: '', subject: 'ok' } })), - ).toThrowErrorMatchingInlineSnapshot( - `"Invalid type in config for key 'options.secret' in 'mock-config', got empty-string, wanted string"`, - ); - expect(() => - handler.add( - new ConfigReader({ options: { secret: 'has spaces', subject: 'ok' } }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Illegal secret, must be a valid base64 string"`, - ); - expect(() => - handler.add( - new ConfigReader({ - options: { secret: 'hasnewline\n', subject: 'ok' }, + handler.initialize({ + options: new ConfigReader({ + _missingsecret: true, + subject: 'ok', }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Illegal secret, must be a valid base64 string"`, - ); - expect(() => - handler.add(new ConfigReader({ options: { secret: 3, subject: 'ok' } })), - ).toThrowErrorMatchingInlineSnapshot( - `"Invalid type in config for key 'options.secret' in 'mock-config', got number, wanted string"`, - ); - - // new style add, bad subjects - expect(() => - handler.add( - new ConfigReader({ - options: { secret: 'b2s=', _missingsubject: true }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Missing required config value at 'options.subject' in 'mock-config'"`, - ); - expect(() => - handler.add( - new ConfigReader({ options: { secret: 'b2s=', subject: '' } }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Invalid type in config for key 'options.subject' in 'mock-config', got empty-string, wanted string"`, - ); - expect(() => - handler.add( - new ConfigReader({ - options: { secret: 'b2s=', subject: 'has spaces' }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Illegal subject, must be a set of non-space characters"`, - ); - expect(() => - handler.add( - new ConfigReader({ - options: { secret: 'b2s=', subject: 'hasnewline\n' }, - }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Illegal subject, must be a set of non-space characters"`, - ); - expect(() => - handler.add( - new ConfigReader({ options: { secret: 'b2s=', subject: 3 } }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Invalid type in config for key 'options.subject' in 'mock-config', got number, wanted string"`, - ); - - // new style add, bad access restrictions - expect(() => - handler.add( - new ConfigReader({ - options: { secret: 'b2s=', subject: 'subject' }, - accessRestrictions: [{ plugin: ['a'] }], - }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Invalid type in config for key 'accessRestrictions[0].plugin' in 'mock-config', got array, wanted string"`, - ); - - // old style add - expect(() => - handler.addOld(new ConfigReader({ secret: 'b2s=' })), - ).not.toThrow(); - expect(() => - handler.addOld(new ConfigReader({ _missingsecret: true })), + }), ).toThrowErrorMatchingInlineSnapshot( `"Missing required config value at 'secret' in 'mock-config'"`, ); expect(() => - handler.addOld(new ConfigReader({ secret: '' })), + handler.initialize({ + options: new ConfigReader({ secret: '', subject: 'ok' }), + }), ).toThrowErrorMatchingInlineSnapshot( `"Invalid type in config for key 'secret' in 'mock-config', got empty-string, wanted string"`, ); expect(() => - handler.addOld(new ConfigReader({ secret: 'has spaces' })), + handler.initialize({ + options: new ConfigReader({ + secret: 'has spaces', + subject: 'ok', + }), + }), ).toThrowErrorMatchingInlineSnapshot( `"Illegal secret, must be a valid base64 string"`, ); expect(() => - handler.addOld(new ConfigReader({ secret: 'hasnewline\n' })), + handler.initialize({ + options: new ConfigReader({ + secret: 'hasnewline\n', + subject: 'ok', + }), + }), ).toThrowErrorMatchingInlineSnapshot( `"Illegal secret, must be a valid base64 string"`, ); expect(() => - handler.addOld(new ConfigReader({ secret: 3 })), + handler.initialize({ + options: new ConfigReader({ secret: 3, subject: 'ok' }), + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid type in config for key 'secret' in 'mock-config', got number, wanted string"`, + ); + + // new style add, bad subjects + expect(() => + handler.initialize({ + options: new ConfigReader({ + secret: 'b2s=', + _missingsubject: true, + }), + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Missing required config value at 'subject' in 'mock-config'"`, + ); + expect(() => + handler.initialize({ + options: new ConfigReader({ secret: 'b2s=', subject: '' }), + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid type in config for key 'subject' in 'mock-config', got empty-string, wanted string"`, + ); + expect(() => + handler.initialize({ + options: new ConfigReader({ + secret: 'b2s=', + subject: 'has spaces', + }), + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Illegal subject, must be a set of non-space characters"`, + ); + expect(() => + handler.initialize({ + options: new ConfigReader({ + secret: 'b2s=', + subject: 'hasnewline\n', + }), + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Illegal subject, must be a set of non-space characters"`, + ); + expect(() => + handler.initialize({ + options: new ConfigReader({ secret: 'b2s=', subject: 3 }), + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid type in config for key 'subject' in 'mock-config', got number, wanted string"`, + ); + + // old style add + expect(() => + handler.initialize({ + options: new ConfigReader({ secret: 'b2s=' }), + legacy: true, + }), + ).not.toThrow(); + + expect(() => + handler.initialize({ + options: new ConfigReader({ _missingsecret: true }), + legacy: true, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Missing required config value at 'secret' in 'mock-config'"`, + ); + expect(() => + handler.initialize({ + options: new ConfigReader({ secret: '' }), + legacy: true, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Invalid type in config for key 'secret' in 'mock-config', got empty-string, wanted string"`, + ); + expect(() => + handler.initialize({ + options: new ConfigReader({ secret: 'has spaces' }), + legacy: true, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Illegal secret, must be a valid base64 string"`, + ); + expect(() => + handler.initialize({ + options: new ConfigReader({ secret: 'hasnewline\n' }), + legacy: true, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Illegal secret, must be a valid base64 string"`, + ); + expect(() => + handler.initialize({ + options: new ConfigReader({ secret: 3 }), + legacy: true, + }), ).toThrowErrorMatchingInlineSnapshot( `"Invalid type in config for key 'secret' in 'mock-config', got number, wanted string"`, ); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/legacy.ts b/packages/backend-defaults/src/entrypoints/auth/external/legacy.ts index 9c60e70707..2ab8c3a5ea 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/legacy.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/legacy.ts @@ -16,72 +16,56 @@ import { Config } from '@backstage/config'; import { base64url, decodeJwt, decodeProtectedHeader, jwtVerify } from 'jose'; -import { readAccessRestrictionsFromConfig } from './helpers'; -import { AccessRestriptionsMap, TokenHandler } from './types'; -/** - * Handles `type: legacy` access. - * - * @internal - */ -export class LegacyTokenHandler implements TokenHandler { - #entries = new Array<{ - key: Uint8Array; - result: { - subject: string; - allAccessRestrictions?: AccessRestriptionsMap; - }; - }>(); +import { ExternalTokenHandler } from './types'; - add(config: Config) { - const allAccessRestrictions = readAccessRestrictionsFromConfig(config); - this.#doAdd( - config.getString('options.secret'), - config.getString('options.subject'), - allAccessRestrictions, - ); - } +export type LegacyConfigWrapper = { + legacy: boolean; + config: Config; +}; - // used only for the old backend.auth.keys array - addOld(config: Config) { - // This choice of subject is for compatibility reasons - this.#doAdd(config.getString('secret'), 'external:backstage-plugin'); - } +type LegacyTokenHandlerContext = { + key: Uint8Array; + + subject: string; +}; + +type LegacyTokenHandlerOverloaded = + ExternalTokenHandler & { + initialize(ctx: { + options: Config; + legacy: true; + }): LegacyTokenHandlerContext; + }; + +export const legacyTokenHandler: LegacyTokenHandlerOverloaded = { + type: 'legacy', + initialize(ctx: { + options: Config; + legacy?: true; + }): LegacyTokenHandlerContext { + const secret = ctx.options.getString('secret'); + const subject = ctx.legacy + ? 'external:backstage-plugin' + : ctx.options.getString('subject'); - #doAdd( - secret: string, - subject: string, - allAccessRestrictions?: AccessRestriptionsMap, - ) { if (!secret.match(/^\S+$/)) { throw new Error('Illegal secret, must be a valid base64 string'); } else if (!subject.match(/^\S+$/)) { throw new Error('Illegal subject, must be a set of non-space characters'); } - let key: Uint8Array; try { - key = base64url.decode(secret); + return { + key: base64url.decode(secret), + subject, + }; } catch { throw new Error('Illegal secret, must be a valid base64 string'); } + }, - if (this.#entries.some(e => e.key === key)) { - throw new Error( - 'Legacy externalAccess token was declared more than once', - ); - } - - this.#entries.push({ - key, - result: { - subject, - allAccessRestrictions, - }, - }); - } - - async verifyToken(token: string) { + async verifyToken(token: string, context: LegacyTokenHandlerContext) { // First do a duck typing check to see if it remotely looks like a legacy token try { // We do a fair amount of checking upfront here. Since we aren't certain @@ -102,19 +86,18 @@ export class LegacyTokenHandler implements TokenHandler { return undefined; } - for (const { key, result } of this.#entries) { - try { - await jwtVerify(token, key); - return result; - } catch (e) { - if (e.code !== 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') { - throw e; - } - // Otherwise continue to try the next key + try { + await jwtVerify(token, context.key); + return { + subject: context.subject, + }; + } catch (error) { + if (error.code !== 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED') { + throw error; } } // None of the signing keys matched return undefined; - } -} + }, +}; diff --git a/packages/backend-defaults/src/entrypoints/auth/external/static.test.ts b/packages/backend-defaults/src/entrypoints/auth/external/static.test.ts index a5945daba9..10e78d2dbf 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/static.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/static.test.ts @@ -15,137 +15,146 @@ */ import { ConfigReader } from '@backstage/config'; -import { StaticTokenHandler } from './static'; +import { staticTokenHandler } from './static'; describe('StaticTokenHandler', () => { it('accepts any of the added list of tokens', async () => { - const handler = new StaticTokenHandler(); - handler.add( - new ConfigReader({ - options: { token: 'abcabcabc', subject: 'one' }, - accessRestrictions: [{ plugin: 'scaffolder' }], + const context1 = staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'abcabcabc', + subject: 'one', }), - ); - handler.add( - new ConfigReader({ - options: { token: 'defdefdef', subject: 'two' }, - accessRestrictions: [ - { plugin: 'catalog', permission: 'catalog.entity.read' }, - ], + }); + const context2 = staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'defdefdef', + subject: 'two', }), - ); - const accessRestrictionsOne = new Map(Object.entries({ scaffolder: {} })); - const accessRestrictionsTwo = new Map( - Object.entries({ - catalog: { - permissionNames: ['catalog.entity.read'], - }, - }), - ); + }); - await expect(handler.verifyToken('abcabcabc')).resolves.toEqual({ + await expect( + staticTokenHandler.verifyToken('abcabcabc', context1), + ).resolves.toEqual({ subject: 'one', - allAccessRestrictions: accessRestrictionsOne, }); - await expect(handler.verifyToken('defdefdef')).resolves.toEqual({ + await expect( + staticTokenHandler.verifyToken('defdefdef', context2), + ).resolves.toEqual({ subject: 'two', - allAccessRestrictions: accessRestrictionsTwo, }); - await expect(handler.verifyToken('ghighighi')).resolves.toBeUndefined(); + await expect( + staticTokenHandler.verifyToken('ghighighi', context1), + ).resolves.toBeUndefined(); }); it('gracefully handles no added tokens', async () => { - const handler = new StaticTokenHandler(); - await expect(handler.verifyToken('ghi')).resolves.toBeUndefined(); + await expect( + staticTokenHandler.verifyToken('ghi', {} as any), + ).resolves.toBeUndefined(); }); it('rejects bad config', () => { - const handler = new StaticTokenHandler(); - expect(() => - handler.add( - new ConfigReader({ options: { _missingtoken: true, subject: 'ok' } }), - ), + staticTokenHandler.initialize({ + options: new ConfigReader({ _missingtoken: true, subject: 'ok' }), + }), ).toThrowErrorMatchingInlineSnapshot( - `"Missing required config value at 'options.token' in 'mock-config'"`, + `"Missing required config value at 'token' in 'mock-config'"`, ); expect(() => - handler.add(new ConfigReader({ options: { token: '', subject: 'ok' } })), + staticTokenHandler.initialize({ + options: new ConfigReader({ token: '', subject: 'ok' }), + }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid type in config for key 'options.token' in 'mock-config', got empty-string, wanted string"`, + `"Invalid type in config for key 'token' in 'mock-config', got empty-string, wanted string"`, ); expect(() => - handler.add( - new ConfigReader({ options: { token: 'has spaces', subject: 'ok' } }), - ), - ).toThrowErrorMatchingInlineSnapshot( - `"Illegal token, must be a set of non-space characters"`, - ); - expect(() => - handler.add( - new ConfigReader({ - options: { - token: 'hasnewlinebutislongenough\n', - subject: 'ok', - }, + staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'has spaces', + subject: 'ok', }), - ), + }), ).toThrowErrorMatchingInlineSnapshot( `"Illegal token, must be a set of non-space characters"`, ); expect(() => - handler.add( - new ConfigReader({ options: { token: 'short', subject: 'ok' } }), - ), + staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'hasnewlinebutislongenough\n', + subject: 'ok', + }), + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Illegal token, must be a set of non-space characters"`, + ); + expect(() => + staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'short', + subject: 'ok', + }), + }), ).toThrowErrorMatchingInlineSnapshot( `"Illegal token, must be at least 8 characters length"`, ); expect(() => - handler.add(new ConfigReader({ options: { token: 3, subject: 'ok' } })), + staticTokenHandler.initialize({ + options: new ConfigReader({ token: 3, subject: 'ok' }), + }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid type in config for key 'options.token' in 'mock-config', got number, wanted string"`, + `"Invalid type in config for key 'token' in 'mock-config', got number, wanted string"`, ); expect(() => - handler.add( - new ConfigReader({ - options: { token: 'validtoken', _missingsubject: true }, + staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'validtoken', + _missingsubject: true, }), - ), + }), ).toThrowErrorMatchingInlineSnapshot( - `"Missing required config value at 'options.subject' in 'mock-config'"`, + `"Missing required config value at 'subject' in 'mock-config'"`, ); expect(() => - handler.add( - new ConfigReader({ options: { token: 'validtoken', subject: '' } }), - ), + staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'validtoken', + subject: '', + }), + }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid type in config for key 'options.subject' in 'mock-config', got empty-string, wanted string"`, + `"Invalid type in config for key 'subject' in 'mock-config', got empty-string, wanted string"`, ); expect(() => - handler.add( - new ConfigReader({ - options: { token: 'validtoken', subject: 'has spaces' }, + staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'validtoken', + subject: 'has spaces', }), - ), + }), ).toThrowErrorMatchingInlineSnapshot( `"Illegal subject, must be a set of non-space characters"`, ); expect(() => - handler.add( - new ConfigReader({ - options: { token: 'validtoken', subject: 'hasnewline\n' }, + staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'validtoken', + subject: 'hasnewline\n', }), - ), + }), ).toThrowErrorMatchingInlineSnapshot( `"Illegal subject, must be a set of non-space characters"`, ); expect(() => - handler.add( - new ConfigReader({ options: { token: 'validtoken', subject: 3 } }), - ), + staticTokenHandler.initialize({ + options: new ConfigReader({ + token: 'validtoken', + subject: 3, + }), + }), ).toThrowErrorMatchingInlineSnapshot( - `"Invalid type in config for key 'options.subject' in 'mock-config', got number, wanted string"`, + `"Invalid type in config for key 'subject' in 'mock-config', got number, wanted string"`, ); }); }); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/static.ts b/packages/backend-defaults/src/entrypoints/auth/external/static.ts index 1e89d8c6a1..502150d5a8 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/static.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/static.ts @@ -15,29 +15,18 @@ */ import { Config } from '@backstage/config'; -import { readAccessRestrictionsFromConfig } from './helpers'; -import { AccessRestriptionsMap, TokenHandler } from './types'; +import { createExternalTokenHandler } from './helpers'; const MIN_TOKEN_LENGTH = 8; -/** - * Handles `type: static` access. - * - * @internal - */ -export class StaticTokenHandler implements TokenHandler { - #entries = new Map< - string, - { - subject: string; - allAccessRestrictions?: AccessRestriptionsMap; - } - >(); - - add(config: Config) { - const token = config.getString('options.token'); - const subject = config.getString('options.subject'); - const allAccessRestrictions = readAccessRestrictionsFromConfig(config); +export const staticTokenHandler = createExternalTokenHandler<{ + token: string; + subject: string; +}>({ + type: 'static', + initialize(ctx: { options: Config }): { token: string; subject: string } { + const token = ctx.options.getString('token'); + const subject = ctx.options.getString('subject'); if (!token.match(/^\S+$/)) { throw new Error('Illegal token, must be a set of non-space characters'); @@ -47,16 +36,17 @@ export class StaticTokenHandler implements TokenHandler { ); } else if (!subject.match(/^\S+$/)) { throw new Error('Illegal subject, must be a set of non-space characters'); - } else if (this.#entries.has(token)) { - throw new Error( - 'Static externalAccess token was declared more than once', - ); } - this.#entries.set(token, { subject, allAccessRestrictions }); - } - - async verifyToken(token: string) { - return this.#entries.get(token); - } -} + return { token, subject }; + }, + async verifyToken( + token: string, + context: { token: string; subject: string }, + ) { + if (token === context.token) { + return { subject: context.subject }; + } + return undefined; + }, +}); diff --git a/packages/backend-defaults/src/entrypoints/auth/external/types.ts b/packages/backend-defaults/src/entrypoints/auth/external/types.ts index 6a1fd084ed..01d5a26149 100644 --- a/packages/backend-defaults/src/entrypoints/auth/external/types.ts +++ b/packages/backend-defaults/src/entrypoints/auth/external/types.ts @@ -15,20 +15,23 @@ */ import { BackstagePrincipalAccessRestrictions } from '@backstage/backend-plugin-api'; -import { Config } from '@backstage/config'; +import type { Config } from '@backstage/config'; -export type AccessRestriptionsMap = Map< +export type AccessRestrictionsMap = Map< string, // plugin ID BackstagePrincipalAccessRestrictions >; -export interface TokenHandler { - add(options: Config): void; - verifyToken(token: string): Promise< - | { - subject: string; - allAccessRestrictions?: AccessRestriptionsMap; - } - | undefined - >; +/** + * @public + * This interface is used to handle external tokens. + * It is used by the auth service to verify tokens and extract the subject. + */ +export interface ExternalTokenHandler { + type: string; + initialize(ctx: { options: Config }): TContext; + verifyToken( + token: string, + ctx: TContext, + ): Promise<{ subject: string } | undefined>; } diff --git a/packages/backend-defaults/src/entrypoints/auth/helpers.test.ts b/packages/backend-defaults/src/entrypoints/auth/helpers.test.ts index 8454aa3ecc..fdc6e26c3a 100644 --- a/packages/backend-defaults/src/entrypoints/auth/helpers.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/helpers.test.ts @@ -42,6 +42,23 @@ describe('credentials', () => { }, }); + expect( + createCredentialsWithUserPrincipal( + 'user:default/mock', + 'my-token', + undefined, + 'my-actor', + ), + ).toEqual({ + $$type: '@backstage/BackstageCredentials', + version: 'v1', + principal: { + type: 'user', + userEntityRef: 'user:default/mock', + actor: { type: 'service', subject: 'my-actor' }, + }, + }); + expect(createCredentialsWithNonePrincipal()).toEqual({ $$type: '@backstage/BackstageCredentials', version: 'v1', @@ -64,4 +81,63 @@ describe('credentials', () => { ), ).not.toMatch(/my-token/); }); + + it('should have a serializable form both as strings and as JSON', () => { + const simpleService = createCredentialsWithServicePrincipal('my-service'); + expect(String(simpleService)).toMatchInlineSnapshot( + `"backstageCredentials{servicePrincipal{my-service}}"`, + ); + expect(JSON.stringify(simpleService)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"service","subject":"my-service"}}"`, + ); + + const serviceWithAccessRestrictions = createCredentialsWithServicePrincipal( + 'my-service', + undefined, + { + permissionNames: ['perm'], + permissionAttributes: { + action: ['read'], + }, + }, + ); + expect(String(serviceWithAccessRestrictions)).toMatchInlineSnapshot( + `"backstageCredentials{servicePrincipal{my-service,accessRestrictions=cXWOJgUirHkHNZIowUi/YO5nwEwhTicC38iXi2XTYCk}}"`, + ); + expect(JSON.stringify(serviceWithAccessRestrictions)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"service","subject":"my-service","accessRestrictions":{"permissionNames":["perm"],"permissionAttributes":{"action":["read"]}}}}"`, + ); + + const simpleUser = createCredentialsWithUserPrincipal( + 'user:default/mock', + 'my-token', + ); + expect(String(simpleUser)).toMatchInlineSnapshot( + `"backstageCredentials{userPrincipal{user:default/mock}}"`, + ); + expect(JSON.stringify(simpleUser)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"user","userEntityRef":"user:default/mock"}}"`, + ); + + const userWithActor = createCredentialsWithUserPrincipal( + 'user:default/mock', + 'my-token', + undefined, + 'my-actor', + ); + expect(String(userWithActor)).toMatchInlineSnapshot( + `"backstageCredentials{userPrincipal{user:default/mock,actor={servicePrincipal{my-actor}}}}"`, + ); + expect(JSON.stringify(userWithActor)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"user","userEntityRef":"user:default/mock","actor":{"type":"service","subject":"my-actor"}}}"`, + ); + + const none = createCredentialsWithNonePrincipal(); + expect(String(none)).toMatchInlineSnapshot( + `"backstageCredentials{nonePrincipal}"`, + ); + expect(JSON.stringify(none)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"none"}}"`, + ); + }); }); diff --git a/packages/backend-defaults/src/entrypoints/auth/helpers.ts b/packages/backend-defaults/src/entrypoints/auth/helpers.ts index 58e2bcff74..02840112a9 100644 --- a/packages/backend-defaults/src/entrypoints/auth/helpers.ts +++ b/packages/backend-defaults/src/entrypoints/auth/helpers.ts @@ -22,29 +22,34 @@ import { BackstageUserPrincipal, } from '@backstage/backend-plugin-api'; import { InternalBackstageCredentials } from './types'; +import { createHash } from 'crypto'; export function createCredentialsWithServicePrincipal( sub: string, token?: string, accessRestrictions?: BackstagePrincipalAccessRestrictions, ): InternalBackstageCredentials { - return Object.defineProperty( - { - $$type: '@backstage/BackstageCredentials', - version: 'v1', - principal: { - type: 'service', - subject: sub, - accessRestrictions, - }, - }, - 'token', - { + const principal = createServicePrincipal(sub, accessRestrictions); + const result = { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + principal, + } as const; + Object.defineProperties(result, { + token: { enumerable: false, configurable: true, + writable: true, value: token, }, - ); + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => `backstageCredentials{${principal}}`, + }, + }); + return result; } export function createCredentialsWithUserPrincipal( @@ -53,36 +58,49 @@ export function createCredentialsWithUserPrincipal( expiresAt?: Date, actor?: string, ): InternalBackstageCredentials { - return Object.defineProperty( - { - $$type: '@backstage/BackstageCredentials', - version: 'v1', - expiresAt, - principal: { - type: 'user', - userEntityRef: sub, - ...(actor && { - actor: { type: 'service', subject: actor }, - }), - }, - }, - 'token', - { + const principal = createUserPrincipal( + sub, + actor ? createServicePrincipal(actor) : undefined, + ); + const result = { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + expiresAt, + principal, + } as const; + Object.defineProperties(result, { + token: { enumerable: false, configurable: true, + writable: true, value: token, }, - ); + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => `backstageCredentials{${principal}}`, + }, + }); + return result; } export function createCredentialsWithNonePrincipal(): InternalBackstageCredentials { - return { + const principal = createNonePrincipal(); + const result = { $$type: '@backstage/BackstageCredentials', version: 'v1', - principal: { - type: 'none', + principal, + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => `backstageCredentials{${principal}}`, }, - }; + }); + return result; } export function toInternalBackstageCredentials( @@ -106,3 +124,74 @@ export function toInternalBackstageCredentials( return internalCredentials; } + +function createServicePrincipal( + sub: string, + accessRestrictions?: BackstagePrincipalAccessRestrictions, +): BackstageServicePrincipal { + const result = { + type: 'service', + subject: sub, + accessRestrictions, + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => { + let parts = sub; + if (accessRestrictions) { + const hash = createHash('sha256') + .update(JSON.stringify(accessRestrictions)) + .digest('base64') + .replace(/=+$/, ''); + parts += `,accessRestrictions=${hash}`; + } + return `servicePrincipal{${parts}}`; + }, + }, + }); + return result; +} + +function createUserPrincipal( + userEntityRef: string, + actor?: BackstageServicePrincipal, +): BackstageUserPrincipal { + const result = { + type: 'user', + userEntityRef, + actor, + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => { + let parts = userEntityRef; + if (actor) { + parts += `,actor={${actor}}`; + } + return `userPrincipal{${parts}}`; + }, + }, + }); + return result; +} + +function createNonePrincipal(): BackstageNonePrincipal { + const result = { + type: 'none', + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => 'nonePrincipal', + }, + }); + return result; +} diff --git a/packages/backend-defaults/src/entrypoints/auth/index.ts b/packages/backend-defaults/src/entrypoints/auth/index.ts index e48926f0ce..69d41b0310 100644 --- a/packages/backend-defaults/src/entrypoints/auth/index.ts +++ b/packages/backend-defaults/src/entrypoints/auth/index.ts @@ -19,4 +19,10 @@ export { pluginTokenHandlerDecoratorServiceRef, } from './authServiceFactory'; +export { createExternalTokenHandler } from './external/helpers'; + +export { externalTokenHandlersServiceRef } from './external/ExternalAuthTokenHandler'; + +export type { ExternalTokenHandler } from './external/types'; + export type { PluginTokenHandler } from './plugin/PluginTokenHandler'; diff --git a/packages/backend-defaults/src/entrypoints/auth/plugin/PluginTokenHandler.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/PluginTokenHandler.ts index 9aec52bc08..2bd797c929 100644 --- a/packages/backend-defaults/src/entrypoints/auth/plugin/PluginTokenHandler.ts +++ b/packages/backend-defaults/src/entrypoints/auth/plugin/PluginTokenHandler.ts @@ -46,7 +46,7 @@ type Options = { /** * @public - * Issues and verifies {@link https://backstage.iceio/docs/auth/service-to-service-auth | service-to-service tokens}. + * Issues and verifies {@link https://backstage.io/docs/auth/service-to-service-auth | service-to-service tokens}. */ export interface PluginTokenHandler { verifyToken( @@ -77,14 +77,28 @@ export class DefaultPluginTokenHandler implements PluginTokenHandler { ); } + private readonly logger: LoggerService; + private readonly ownPluginId: string; + private readonly keySource: PluginKeySource; + private readonly algorithm: string; + private readonly keyDurationSeconds: number; + private readonly discovery: DiscoveryService; + private constructor( - private readonly logger: LoggerService, - private readonly ownPluginId: string, - private readonly keySource: PluginKeySource, - private readonly algorithm: string, - private readonly keyDurationSeconds: number, - private readonly discovery: DiscoveryService, - ) {} + logger: LoggerService, + ownPluginId: string, + keySource: PluginKeySource, + algorithm: string, + keyDurationSeconds: number, + discovery: DiscoveryService, + ) { + this.logger = logger; + this.ownPluginId = ownPluginId; + this.keySource = keySource; + this.algorithm = algorithm; + this.keyDurationSeconds = keyDurationSeconds; + this.discovery = discovery; + } async verifyToken( token: string, diff --git a/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabaseKeyStore.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabaseKeyStore.ts index 9f5c278a9c..c34da745d1 100644 --- a/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabaseKeyStore.ts +++ b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabaseKeyStore.ts @@ -62,10 +62,13 @@ export class DatabaseKeyStore implements KeyStore { return new DatabaseKeyStore(client, logger); } - private constructor( - private readonly client: Knex, - private readonly logger: LoggerService, - ) {} + private readonly client: Knex; + private readonly logger: LoggerService; + + private constructor(client: Knex, logger: LoggerService) { + this.client = client; + this.logger = logger; + } async addKey(options: { id: string; diff --git a/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabasePluginKeySource.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabasePluginKeySource.ts index 37cb1aeb5c..e6a7bbcfc6 100644 --- a/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabasePluginKeySource.ts +++ b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/DatabasePluginKeySource.ts @@ -33,13 +33,22 @@ const KEY_EXPIRATION_MARGIN_FACTOR = 3; export class DatabasePluginKeySource implements PluginKeySource { private privateKeyPromise?: Promise; private keyExpiry?: Date; + private readonly keyStore: KeyStore; + private readonly logger: LoggerService; + private readonly keyDurationSeconds: number; + private readonly algorithm: string; constructor( - private readonly keyStore: KeyStore, - private readonly logger: LoggerService, - private readonly keyDurationSeconds: number, - private readonly algorithm: string, - ) {} + keyStore: KeyStore, + logger: LoggerService, + keyDurationSeconds: number, + algorithm: string, + ) { + this.keyStore = keyStore; + this.logger = logger; + this.keyDurationSeconds = keyDurationSeconds; + this.algorithm = algorithm; + } public static async create(options: { logger: LoggerService; diff --git a/packages/backend-defaults/src/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.ts b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.ts index eb863a807a..504f608d8d 100644 --- a/packages/backend-defaults/src/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.ts +++ b/packages/backend-defaults/src/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.ts @@ -67,10 +67,13 @@ const SECONDS_IN_MS = 1000; * private and public key paths in the `create` method. */ export class StaticConfigPluginKeySource implements PluginKeySource { - private constructor( - private readonly keyPairs: KeyPair[], - private readonly keyDurationSeconds: number, - ) {} + private readonly keyPairs: KeyPair[]; + private readonly keyDurationSeconds: number; + + private constructor(keyPairs: KeyPair[], keyDurationSeconds: number) { + this.keyPairs = keyPairs; + this.keyDurationSeconds = keyDurationSeconds; + } public static async create(options: { sourceConfig: Config; diff --git a/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.ts b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.ts index d205fa6b82..a1b8654527 100644 --- a/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.ts +++ b/packages/backend-defaults/src/entrypoints/auth/user/UserTokenHandler.ts @@ -44,10 +44,13 @@ export class UserTokenHandler { return new UserTokenHandler(jwksClient, options.logger); } - constructor( - private readonly jwksClient: JwksClient, - private readonly logger: LoggerService, - ) {} + private readonly jwksClient: JwksClient; + private readonly logger: LoggerService; + + constructor(jwksClient: JwksClient, logger: LoggerService) { + this.jwksClient = jwksClient; + this.logger = logger; + } async verifyToken(token: string) { const verifyOpts = this.#getTokenVerificationOptions(token); diff --git a/packages/backend-defaults/src/entrypoints/cache/CacheManager.test.ts b/packages/backend-defaults/src/entrypoints/cache/CacheManager.test.ts index 4e9475b66e..a308caa222 100644 --- a/packages/backend-defaults/src/entrypoints/cache/CacheManager.test.ts +++ b/packages/backend-defaults/src/entrypoints/cache/CacheManager.test.ts @@ -333,4 +333,147 @@ describe('CacheManager store options', () => { keyPrefixSeparator: '!', }); }); + + it('correctly applies namespace configuration to redis and valkey stores', () => { + const testCases = [ + { store: 'redis', namespace: 'test1', separator: ':' }, + { store: 'valkey', namespace: 'test2', separator: '!' }, + ]; + + testCases.forEach(({ store, namespace, separator }) => { + const manager = CacheManager.fromConfig( + mockServices.rootConfig({ + data: { + backend: { + cache: { + store, + connection: 'redis://localhost:6379', + [store]: { + client: { + namespace, + keyPrefixSeparator: separator, + }, + }, + }, + }, + }, + }), + ); + + manager.forPlugin('testPlugin'); + + if (store === 'redis') { + // eslint-disable-next-line jest/no-conditional-expect + expect(KeyvRedis).toHaveBeenCalledWith('redis://localhost:6379', { + namespace, + keyPrefixSeparator: separator, + }); + } else if (store === 'valkey') { + // eslint-disable-next-line jest/no-conditional-expect + expect(KeyvValkey).toHaveBeenCalledWith('redis://localhost:6379', { + namespace, + keyPrefixSeparator: separator, + }); + } + }); + }); + + it('falls back to pluginId when no namespace is configured', () => { + const manager = CacheManager.fromConfig( + mockServices.rootConfig({ + data: { + backend: { + cache: { + store: 'redis', + connection: 'redis://localhost:6379', + }, + }, + }, + }), + ); + + manager.forPlugin('testPlugin'); + + expect(KeyvRedis).toHaveBeenCalledWith('redis://localhost:6379', { + keyPrefixSeparator: ':', + }); + }); + + describe('Namespace construction', () => { + it('returns pluginId when no store options are provided', () => { + const result = (CacheManager as any).constructNamespace( + 'testPlugin', + undefined, + ); + expect(result).toBe('testPlugin'); + }); + + it('returns pluginId when store options have no namespace', () => { + const storeOptions = { + client: { + keyPrefixSeparator: ':', + }, + }; + const result = (CacheManager as any).constructNamespace( + 'testPlugin', + storeOptions, + ); + expect(result).toBe('testPlugin'); + }); + + it('combines namespace and pluginId with default separator', () => { + const storeOptions = { + client: { + namespace: 'my-app', + keyPrefixSeparator: ':', + }, + }; + const result = (CacheManager as any).constructNamespace( + 'testPlugin', + storeOptions, + ); + expect(result).toBe('my-app:testPlugin'); + }); + + it('combines namespace and pluginId with custom separator', () => { + const storeOptions = { + client: { + namespace: 'my-app', + keyPrefixSeparator: '-', + }, + }; + const result = (CacheManager as any).constructNamespace( + 'testPlugin', + storeOptions, + ); + expect(result).toBe('my-app-testPlugin'); + }); + + it('uses default separator when keyPrefixSeparator is not provided', () => { + const storeOptions = { + client: { + namespace: 'my-app', + }, + }; + const result = (CacheManager as any).constructNamespace( + 'testPlugin', + storeOptions, + ); + expect(result).toBe('my-app:testPlugin'); + }); + + it('handles empty namespace by falling back to pluginId', () => { + const storeOptions = { + client: { + namespace: '', + keyPrefixSeparator: ':', + }, + }; + const result = (CacheManager as any).constructNamespace( + 'testPlugin', + storeOptions, + ); + expect(result).toBe('testPlugin'); + }); + }); }); diff --git a/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts b/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts index 9a691bdb21..06b2b0c57b 100644 --- a/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts +++ b/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts @@ -27,9 +27,16 @@ import { ttlToMilliseconds, CacheStoreOptions, RedisCacheStoreOptions, + InfinispanClientBehaviorOptions, + InfinispanServerConfig, } from './types'; +import { InfinispanOptionsMapper } from './providers/infinispan/InfinispanOptionsMapper'; import { durationToMilliseconds } from '@backstage/types'; -import { readDurationFromConfig } from '@backstage/config'; +import { ConfigReader, readDurationFromConfig } from '@backstage/config'; +import { + InfinispanClientCacheInterface, + InfinispanKeyvStore, +} from './providers/infinispan/InfinispanKeyvStore'; type StoreFactory = (pluginId: string, defaultTtl: number | undefined) => Keyv; @@ -50,6 +57,7 @@ export class CacheManager { valkey: this.createValkeyStoreFactory(), memcache: this.createMemcacheStoreFactory(), memory: this.createMemoryStoreFactory(), + infinispan: this.createInfinispanStoreFactory(), }; private readonly logger?: LoggerService; @@ -64,6 +72,8 @@ export class CacheManager { * config section, specifically the `.cache` key. * * @param config - The loaded application configuration. + * @param options - Optional configuration for the CacheManager. + * @returns A new CacheManager instance. */ static fromConfig( config: RootConfigService, @@ -112,7 +122,7 @@ export class CacheManager { /** * Parse store-specific options from configuration. * - * @param store - The cache store type ('redis', 'valkey', 'memcache', or 'memory') + * @param store - The cache store type ('redis', 'valkey', 'memcache', 'infinispan', or 'memory') * @param config - The configuration service * @param logger - Optional logger for warnings * @returns The parsed store options @@ -124,11 +134,27 @@ export class CacheManager { ): CacheStoreOptions | undefined { const storeConfigPath = `backend.cache.${store}`; - if ( - (store === 'redis' || store === 'valkey') && - config.has(storeConfigPath) - ) { - return CacheManager.parseRedisOptions(storeConfigPath, config, logger); + if (!config.has(storeConfigPath)) { + logger?.warn( + `No configuration found for cache store '${store}' at '${storeConfigPath}'.`, + ); + } + + if (store === 'redis' || store === 'valkey') { + return CacheManager.parseRedisOptions( + store, + storeConfigPath, + config, + logger, + ); + } + + if (store === 'infinispan') { + return InfinispanOptionsMapper.parseInfinispanOptions( + storeConfigPath, + config, + logger, + ); } return undefined; @@ -138,12 +164,17 @@ export class CacheManager { * Parse Redis-specific options from configuration. */ private static parseRedisOptions( + store: string, storeConfigPath: string, config: RootConfigService, logger?: LoggerService, ): RedisCacheStoreOptions { - const redisOptions: RedisCacheStoreOptions = {}; - const redisConfig = config.getConfig(storeConfigPath); + const redisOptions: RedisCacheStoreOptions = { + type: store as 'redis' | 'valkey', + }; + + const redisConfig = + config.getOptionalConfig(storeConfigPath) ?? new ConfigReader({}); redisOptions.client = { namespace: redisConfig.getOptionalString('client.namespace'), @@ -182,6 +213,26 @@ export class CacheManager { return redisOptions; } + /** + * Construct the full namespace based on the options and pluginId. + * + * @param pluginId - The plugin ID to namespace + * @param storeOptions - Optional cache store configuration options + * @returns The constructed namespace string combining the configured namespace with pluginId + */ + private static constructNamespace( + pluginId: string, + storeOptions: RedisCacheStoreOptions | undefined, + ): string { + const prefix = storeOptions?.client?.namespace + ? `${storeOptions.client.namespace}${ + storeOptions.client.keyPrefixSeparator ?? ':' + }` + : ''; + + return `${prefix}${pluginId}`; + } + /** @internal */ constructor( store: string, @@ -230,6 +281,11 @@ export class CacheManager { const stores: Record = {}; return (pluginId, defaultTtl) => { + if (this.storeOptions?.type !== 'redis') { + throw new Error( + `Internal error: Wrong config type passed to redis factory: ${this.storeOptions?.type}`, + ); + } if (!stores[pluginId]) { const redisOptions = this.storeOptions?.client || { keyPrefixSeparator: ':', @@ -250,7 +306,7 @@ export class CacheManager { }); } return new Keyv({ - namespace: pluginId, + namespace: CacheManager.constructNamespace(pluginId, this.storeOptions), ttl: defaultTtl, store: stores[pluginId], emitErrors: false, @@ -265,6 +321,11 @@ export class CacheManager { const stores: Record = {}; return (pluginId, defaultTtl) => { + if (this.storeOptions?.type !== 'valkey') { + throw new Error( + `Internal error: Wrong config type passed to valkey factory: ${this.storeOptions?.type}`, + ); + } if (!stores[pluginId]) { const valkeyOptions = this.storeOptions?.client || { keyPrefixSeparator: ':', @@ -285,7 +346,7 @@ export class CacheManager { }); } return new Keyv({ - namespace: pluginId, + namespace: CacheManager.constructNamespace(pluginId, this.storeOptions), ttl: defaultTtl, store: stores[pluginId], emitErrors: false, @@ -326,4 +387,100 @@ export class CacheManager { store, }); } + + private createInfinispanStoreFactory(): StoreFactory { + const stores: Record = {}; + + return (pluginId, defaultTtl) => { + if (this.storeOptions?.type !== 'infinispan') { + throw new Error( + `Internal error: Wrong config type passed to infinispan factory: ${this.storeOptions?.type}`, + ); + } + + if (!stores[pluginId]) { + // Use sync version for testing environments + const isTest = + process.env.NODE_ENV === 'test' || typeof jest !== 'undefined'; + + // Create the client promise ONCE and reuse it + const clientPromise: Promise = isTest + ? this.createInfinispanClientSync() + : this.createInfinispanClientAsync(); + + this.logger?.info( + `Creating Infinispan cache client for plugin ${pluginId} isTest = ${isTest}`, + ); + const storeInstance = new InfinispanKeyvStore({ + clientPromise, + logger: this.logger!, + }); + + stores[pluginId] = storeInstance; + + // Always provide an error handler to avoid stopping the process + storeInstance.on('error', (err: Error) => { + this.logger?.error('Failed to create infinispan cache client', err); + this.errorHandler?.(err); + }); + } + + return new Keyv({ + namespace: pluginId, + ttl: defaultTtl, + store: stores[pluginId], + emitErrors: false, + }); + }; + } + + /** + * Creates an Infinispan client using dynamic import (production use). + * @returns Promise that resolves to an Infinispan client + */ + private async createInfinispanClientAsync(): Promise { + return this.createInfinispanClient(false); + } + + /** + * Creates an Infinispan client using synchronous import (testing purposes). + * @returns Promise that resolves to an Infinispan client + */ + private createInfinispanClientSync(): Promise { + return this.createInfinispanClient(true); + } + + /** + * Creates an Infinispan client based on the provided configuration. + * @param useSync - Whether to use synchronous import (for testing) or dynamic import + * @returns Promise that resolves to an Infinispan client + */ + private async createInfinispanClient( + useSync: boolean = false, + ): Promise { + try { + this.logger?.info('Creating Infinispan client'); + + if (this.storeOptions?.type === 'infinispan') { + // Import infinispan based on the useSync parameter + const infinispan = useSync + ? require('infinispan') + : await import('infinispan'); + + const client = await infinispan.client( + this.storeOptions.servers as InfinispanServerConfig[], + this.storeOptions.options as InfinispanClientBehaviorOptions, + ); + + this.logger?.info('Infinispan client created successfully'); + return client; + } + throw new Error('Infinispan store options are not defined'); + } catch (error: any) { + this.logger?.error('Failed to create Infinispan client', { + error: error.message, + }); + throw error; + } + } } diff --git a/packages/backend-defaults/src/entrypoints/cache/providers/infinispan/InfinispanKeyvStore.test.ts b/packages/backend-defaults/src/entrypoints/cache/providers/infinispan/InfinispanKeyvStore.test.ts new file mode 100644 index 0000000000..4f6b2b1ba0 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/cache/providers/infinispan/InfinispanKeyvStore.test.ts @@ -0,0 +1,177 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { InfinispanKeyvStore } from './InfinispanKeyvStore'; +import { mockServices } from '@backstage/backend-test-utils'; + +describe('InfinispanKeyvStore', () => { + const logger = mockServices.logger.mock(); + let store: InfinispanKeyvStore; + let mockClient: any; + + beforeEach(() => { + mockClient = { + get: jest.fn(), + put: jest.fn(), + remove: jest.fn(), + clear: jest.fn(), + disconnect: jest.fn(), + on: jest.fn(), + }; + + store = new InfinispanKeyvStore({ + clientPromise: Promise.resolve(mockClient), + logger, + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('get', () => { + it('returns undefined when key is not found', async () => { + mockClient.get.mockResolvedValueOnce(null); + const result = await store.get('test-key'); + expect(result).toBeUndefined(); + expect(mockClient.get).toHaveBeenCalledWith('test-key'); + }); + + it('returns value when key is found', async () => { + const value = 'test-value'; + mockClient.get.mockResolvedValueOnce(value); + const result = await store.get('test-key'); + expect(result).toBe(value); + expect(mockClient.get).toHaveBeenCalledWith('test-key'); + }); + + it('handles client errors', async () => { + const error = new Error('Connection error'); + mockClient.get.mockRejectedValueOnce(error); + await expect(store.get('test-key')).rejects.toThrow('Connection error'); + }); + }); + + describe('set', () => { + it('sets value with default options', async () => { + await store.set('test-key', 'test-value'); + expect(mockClient.put).toHaveBeenCalledWith('test-key', 'test-value', {}); + }); + + it('sets value with TTL', async () => { + await store.set('test-key', 'test-value', 1000); + expect(mockClient.put).toHaveBeenCalledWith('test-key', 'test-value', { + lifespan: '1000ms', + }); + }); + + it('handles client errors', async () => { + const error = new Error('Connection error'); + mockClient.put.mockRejectedValueOnce(error); + await expect(store.set('test-key', 'test-value')).rejects.toThrow( + 'Connection error', + ); + }); + }); + + describe('delete', () => { + it('deletes key', async () => { + mockClient.remove.mockResolvedValueOnce(true); + const result = await store.delete('test-key'); + expect(result).toBe(true); + expect(mockClient.remove).toHaveBeenCalledWith('test-key'); + }); + + it('handles client errors', async () => { + const error = new Error('Connection error'); + mockClient.remove.mockRejectedValueOnce(error); + await expect(store.delete('test-key')).rejects.toThrow( + 'Connection error', + ); + }); + }); + + describe('clear', () => { + it('clears all entries', async () => { + await store.clear(); + expect(mockClient.clear).toHaveBeenCalled(); + }); + + it('handles client errors', async () => { + const error = new Error('Connection error'); + mockClient.clear.mockRejectedValueOnce(error); + await expect(store.clear()).rejects.toThrow('Connection error'); + }); + }); + + describe('disconnect', () => { + it('is a no-op as client is managed by CacheManager', async () => { + const disconnectMockClient = { + disconnect: jest.fn().mockResolvedValue(undefined), + get: jest.fn().mockResolvedValue(null), + put: jest.fn().mockResolvedValue(undefined), + remove: jest.fn().mockResolvedValue(undefined), + clear: jest.fn().mockResolvedValue(undefined), + }; + const disconnectStore = new InfinispanKeyvStore({ + clientPromise: Promise.resolve(disconnectMockClient), + logger: mockServices.logger.mock(), + }); + await disconnectStore.disconnect(); + expect(disconnectMockClient.disconnect).not.toHaveBeenCalled(); + }); + + it('handles client errors', async () => { + const error = new Error('Connection error'); + const errorMockClient = { + disconnect: jest.fn().mockRejectedValue(error), + get: jest.fn().mockResolvedValue(null), + put: jest.fn().mockResolvedValue(undefined), + remove: jest.fn().mockResolvedValue(undefined), + clear: jest.fn().mockResolvedValue(undefined), + }; + const errorStore = new InfinispanKeyvStore({ + clientPromise: Promise.resolve(errorMockClient), + logger: mockServices.logger.mock(), + }); + await expect(errorStore.disconnect()).resolves.not.toThrow(); + }); + }); + + describe('error handling', () => { + it('emits error events from client', async () => { + const error = new Error('Client error'); + const errorHandler = jest.fn(); + store.on('error', errorHandler); + + // Simulate client error + const clientPromise = Promise.resolve(mockClient); + store = new InfinispanKeyvStore({ + clientPromise, + logger, + }); + + // Wait for client to be resolved + await clientPromise; + + // Trigger error event + const errorCallback = mockClient.on.mock.calls[0][1]; + errorCallback(error); + + expect(errorHandler).toHaveBeenCalledWith(error); + }); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/cache/providers/infinispan/InfinispanKeyvStore.ts b/packages/backend-defaults/src/entrypoints/cache/providers/infinispan/InfinispanKeyvStore.ts new file mode 100644 index 0000000000..b6efca718f --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/cache/providers/infinispan/InfinispanKeyvStore.ts @@ -0,0 +1,206 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EventEmitter } from 'events'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { InfinispanPutOptions } from '../../types'; + +/** + * Interface defining the required methods for an Infinispan client. + * @public + */ +export interface InfinispanClientCacheInterface { + get(key: string): Promise; + put(key: string, value: string, options?: InfinispanPutOptions): Promise; + remove(key: string): Promise; + clear(): Promise; + disconnect(): Promise; + on?(event: 'error' | string, listener: (...args: any[]) => void): this; + connect?(): Promise; + query?(query: string): Promise; + containsKey?(key: string): Promise; +} + +/** + * Options for creating an InfinispanKeyvStore instance. + */ +export interface InfinispanKeyvStoreOptions { + clientPromise: Promise; + logger: LoggerService; + defaultTtl?: number; // TTL in milliseconds +} + +/** + * A Keyv store implementation that uses Infinispan as the backend. + * This store implements the Keyv store interface and provides caching functionality + * using Infinispan's distributed cache capabilities. + */ +export class InfinispanKeyvStore extends EventEmitter { + private readonly clientPromise: Promise; + private readonly logger: LoggerService; + private readonly defaultTtl?: number; + private resolvedClient: InfinispanClientCacheInterface | null = null; + + public readonly namespace?: string; // Keyv expects this + + constructor(options: InfinispanKeyvStoreOptions) { + super(); + this.clientPromise = options.clientPromise; + this.logger = options.logger.child({ class: InfinispanKeyvStore.name }); + this.defaultTtl = options.defaultTtl; + + // Eagerly try to resolve the client to attach error listeners early + // and to have it ready for disconnect if resolved. + this.clientPromise + .then(client => { + this.resolvedClient = client; + if (typeof client.on === 'function') { + client.on('error', (error: Error) => { + this.logger.error('Native Infinispan client reported an error.', { + error: error.message, + }); + this.emit('error', error); + }); + } else { + this.logger.warn( + 'Native Infinispan client does not appear to support .on("error") event listening.', + ); + } + }) + .catch(err => { + this.logger.error( + 'Failed to resolve Infinispan client promise in constructor.', + { error: err.message }, + ); + // Errors from operations will also be emitted when clientPromise is awaited and rejects. + this.emit('error', err); + }); + } + + private async getClient(): Promise { + if (this.resolvedClient) { + return this.resolvedClient; + } + // If not yet resolved (e.g. called very quickly or promise rejected and retrying implicitly) + // Await the promise. This will throw if the promise is rejected. + this.resolvedClient = await this.clientPromise; + return this.resolvedClient; + } + + async get(key: string): Promise { + this.logger.debug(`Getting key: ${key}`); + try { + const client = await this.getClient(); + const value = await client.get(key); + if (value === null || value === undefined) { + this.logger.debug(`Key not found or value is null/undefined: ${key}`); + return undefined; + } + this.logger.debug(`Successfully retrieved key: ${key}`); + return value; + } catch (error: any) { + this.logger.error(`Error getting key '${key}' from Infinispan.`, { + error: error.message, + }); + this.emit( + 'error', + error instanceof Error ? error : new Error(String(error)), + ); + throw error; + } + } + + async set(key: string, value: string, ttl?: number): Promise { + this.logger.debug(`Setting key: ${key}`, { ttl }); + this.logger.debug(`Setting key: ${key}`, { ttlInput: ttl }); + const currentTtl = ttl ?? this.defaultTtl; + this.logger.debug(`Calculated currentTtl for key ${key}: ${currentTtl}ms`); // Log do TTL calculado + const storeOptions: InfinispanPutOptions = {}; + + if (typeof currentTtl === 'number' && currentTtl > 0) { + storeOptions.lifespan = `${currentTtl}ms`; // Ensure time unit is passed as string + // Ensure this matches client expectations. If client expects string '10s', convert here. + // For now, assuming number in ms is fine or string like '10000ms'. + // The PutOptions defines lifespan as string | number | null. + } else if (typeof currentTtl === 'string') { + storeOptions.lifespan = currentTtl; + } + + try { + const client = await this.getClient(); + await client.put(key, value, storeOptions); + this.logger.debug(`Successfully set key: ${key}`); + } catch (error: any) { + this.logger.error(`Error setting key '${key}' in Infinispan.`, { + error: error.message, + }); + this.emit( + 'error', + error instanceof Error ? error : new Error(String(error)), + ); + throw error; + } + } + + async delete(key: string): Promise { + this.logger.debug(`Deleting key: ${key}`); + try { + const client = await this.getClient(); + const deleted = await client.remove(key); + this.logger.debug(`Key deletion status for '${key}': ${deleted}`); + return deleted; + } catch (error: any) { + this.logger.error(`Error deleting key '${key}' from Infinispan.`, { + error: error.message, + }); + this.emit( + 'error', + error instanceof Error ? error : new Error(String(error)), + ); + throw error; + } + } + + async clear(): Promise { + this.logger.info('Clearing all entries from Infinispan cache.'); + try { + const client = await this.getClient(); + await client.clear(); + this.logger.info('Infinispan cache cleared successfully.'); + } catch (error: any) { + this.logger.error('Error clearing Infinispan cache.', { + error: error.message, + }); + this.emit( + 'error', + error instanceof Error ? error : new Error(String(error)), + ); + throw error; + } + } + + // This disconnect is for the Keyv store instance, but the actual client is shared. + // The CacheManager should handle the shared client's disconnection. + // However, if Keyv calls this, we shouldn't error. + async disconnect(): Promise { + this.logger.info( + 'InfinispanKeyvStore disconnect called. Shared client managed by CacheManager.', + ); + // No-op for this store instance as the actual client is managed externally by CacheManager. + // The CacheManager's stop() method will disconnect the shared native client. + return Promise.resolve(); + } +} diff --git a/packages/backend-defaults/src/entrypoints/cache/providers/infinispan/InfinispanOptionsMapper.ts b/packages/backend-defaults/src/entrypoints/cache/providers/infinispan/InfinispanOptionsMapper.ts new file mode 100644 index 0000000000..59fd4fb28e --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/cache/providers/infinispan/InfinispanOptionsMapper.ts @@ -0,0 +1,203 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + RootConfigService, +} from '@backstage/backend-plugin-api'; +import { + DataFormatOptions, + InfinispanAuthOptions, + InfinispanCacheStoreOptions, + InfinispanClientAuthOptions, + InfinispanClientBehaviorOptions, + InfinispanClusterConfig, + InfinispanServerConfig, + InfinispanSslOptions, +} from '../../types'; + +export class InfinispanOptionsMapper { + /** + * Parses Infinispan options from the provided configuration path. + * + * @param storeConfigPath - The configuration path for the Infinispan store. + * @param config - The root configuration service to retrieve the Infinispan configuration. + * @param logger - An optional logger service for logging errors and warnings. + * @returns Parsed Infinispan cache store options. + */ + public static parseInfinispanOptions( + storeConfigPath: string, + config: RootConfigService, + logger?: LoggerService, + ): InfinispanCacheStoreOptions { + const infinispanConfig = config.getConfig(storeConfigPath); + const parsedOptions: Partial = { + type: 'infinispan', + }; + + // Parse Servers & Clusters Configurations + if (infinispanConfig.has('servers')) { + const serversConfig = infinispanConfig.get('servers'); + if (Array.isArray(serversConfig)) { + parsedOptions.servers = infinispanConfig.getConfigArray('servers').map( + serverConf => + ({ + host: serverConf.getString('host'), + port: serverConf.getOptionalNumber('port') ?? 11222, + } as InfinispanServerConfig), + ); + } else if (typeof serversConfig === 'object' && serversConfig !== null) { + const serverConf = infinispanConfig.getConfig('servers'); + parsedOptions.servers = { + host: serverConf.getOptionalString('host') ?? '127.0.0.1', + port: serverConf.getOptionalString('port') ?? 11222, + } as InfinispanServerConfig; + } else { + throw new Error( + `Infinispan 'servers' configuration at ${storeConfigPath} is invalid, must be an object or an array.`, + ); + } + } else { + logger?.warn( + `Infinispan configuration at ${storeConfigPath} is missing the 'servers' definition, will use client defaults.`, + ); + } + + // The parsed options block to send to the Infinispan client + // This will be used to configure the Infinispan client behavior. + const behaviorOptions: Partial = {}; + + behaviorOptions.clusters = infinispanConfig + .getOptionalConfigArray('clusters') + ?.map(clusterConf => { + const name = clusterConf.getOptionalString('name'); + return { + ...(name && { name }), + servers: clusterConf.getConfigArray('servers').map(serverConf => ({ + host: serverConf.getString('host'), + port: serverConf.getOptionalNumber('port') ?? 11222, + })), + } as InfinispanClusterConfig; + }); + + // Parse Default Options Start... + const clientVersion = + infinispanConfig.getOptionalString('version') ?? '2.9'; + if ( + clientVersion === '2.9' || + clientVersion === '2.5' || + clientVersion === '2.2' + ) { + behaviorOptions.version = clientVersion; + } else if (clientVersion !== null && clientVersion !== undefined) { + logger?.warn( + `Invalid Infinispan client version "${clientVersion}" in config at ${storeConfigPath}.version. Must be "2.9", "2.5", or "2.2". It will be ignored, and the client may use a default or fail.`, + ); + } + + behaviorOptions.cacheName = + infinispanConfig.getOptionalString('cacheName') ?? 'cache'; + + const mediaType = infinispanConfig.getOptionalString('mediaType'); + if (mediaType === 'text/plain' || mediaType === 'application/json') { + behaviorOptions.mediaType = mediaType; + } else if (mediaType !== null && mediaType !== undefined) { + logger?.warn( + `Invalid Infinispan mediaType "${mediaType}" in config at ${storeConfigPath}.mediaType. Must be "text/plain" | "application/json". It will be ignored, and the client may use a default or fail.`, + ); + } + + behaviorOptions.maxRetries = + infinispanConfig.getOptionalNumber('maxRetries'); + + behaviorOptions.topologyUpdates = + infinispanConfig.getOptionalBoolean('topologyUpdates') ?? true; + + // Default Options End... + + // Parse Authentication and SSL Options + const authConfig = infinispanConfig.getOptionalConfig('authentication'); + const auth: Partial = {}; + + auth.enabled = authConfig?.getOptionalBoolean('enabled'); + auth.saslMechanism = authConfig?.getOptionalString('saslMechanism'); + auth.userName = authConfig?.getOptionalString('userName'); + auth.password = authConfig?.getOptionalString('password'); + auth.token = authConfig?.getOptionalString('token'); + auth.authzid = authConfig?.getOptionalString('authzid'); + + behaviorOptions.authentication = auth as InfinispanAuthOptions; + + const sslConfig = infinispanConfig.getOptionalConfig('ssl'); + const ssl: Partial = {}; + + ssl.enabled = sslConfig?.getOptionalBoolean('enabled'); + ssl.secureProtocol = sslConfig?.getOptionalString('secureProtocol'); + ssl.trustCerts = sslConfig?.getOptionalStringArray('trustCerts'); + ssl.sniHostName = sslConfig?.getOptionalString('sniHostname'); + + const clientAuth = infinispanConfig.getOptionalConfig('clientAuth'); + const clientAuthOpts: Partial = {}; + + clientAuthOpts.key = clientAuth?.getOptionalString('key'); + clientAuthOpts.passphrase = clientAuth?.getOptionalString('passphrase'); + clientAuthOpts.cert = clientAuth?.getOptionalString('cert'); + + ssl.clientAuth = clientAuthOpts as InfinispanClientAuthOptions; + + const cryptoStore = infinispanConfig.getOptionalConfig('cryptoStore'); + const cryptoStoreOpts: Partial = {}; + + cryptoStoreOpts.key = cryptoStore?.getOptionalString('path'); + cryptoStoreOpts.passphrase = cryptoStore?.getOptionalString('passphrase'); + + ssl.cryptoStore = cryptoStoreOpts as InfinispanClientAuthOptions; + + behaviorOptions.ssl = ssl as InfinispanSslOptions; + + const dataFormat = infinispanConfig.getOptionalConfig('dataFormat'); + const dataFormatOpts: Partial = {}; + + const keyType = dataFormat?.getOptionalString('keyType') ?? 'text/plain'; + const valueType = + dataFormat?.getOptionalString('valueType') ?? 'text/plain'; + + if (keyType === 'text/plain' || keyType === 'application/json') { + dataFormatOpts.keyType = keyType; + } else if (keyType !== null && keyType !== undefined) { + logger?.warn( + `Invalid Infinispan dataFormat.keyType "${keyType}" in config at ${storeConfigPath}.dataFormat.keyType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`, + ); + } + + if (valueType === 'text/plain' || valueType === 'application/json') { + dataFormatOpts.valueType = valueType; + } else if (valueType !== null && valueType !== undefined) { + logger?.warn( + `Invalid Infinispan dataFormat.valueType "${valueType}" in config at ${storeConfigPath}.dataFormat.valueType. Must be "text/plain" | "application/json". Not mapped, client will use default 'text/plain'.`, + ); + } + behaviorOptions.dataFormat = dataFormatOpts as DataFormatOptions; + parsedOptions.options = behaviorOptions as InfinispanClientBehaviorOptions; + + logger?.debug( + `Parsed Infinispan options from config at ${storeConfigPath}: ${JSON.stringify( + parsedOptions, + )}`, + ); + return parsedOptions as InfinispanCacheStoreOptions; + } +} diff --git a/packages/backend-defaults/src/entrypoints/cache/types.ts b/packages/backend-defaults/src/entrypoints/cache/types.ts index d21fb5d44b..522ab2ac3e 100644 --- a/packages/backend-defaults/src/entrypoints/cache/types.ts +++ b/packages/backend-defaults/src/entrypoints/cache/types.ts @@ -24,6 +24,7 @@ import { RedisClusterOptions, KeyvRedisOptions } from '@keyv/redis'; * @public */ export type RedisCacheStoreOptions = { + type: 'redis' | 'valkey'; client?: KeyvRedisOptions; cluster?: RedisClusterOptions; }; @@ -33,7 +34,9 @@ export type RedisCacheStoreOptions = { * * @public */ -export type CacheStoreOptions = RedisCacheStoreOptions; +export type CacheStoreOptions = + | RedisCacheStoreOptions + | InfinispanCacheStoreOptions; /** * Options given when constructing a {@link CacheManager}. @@ -56,3 +59,101 @@ export type CacheManagerOptions = { export function ttlToMilliseconds(ttl: number | HumanDuration): number { return typeof ttl === 'number' ? ttl : durationToMilliseconds(ttl); } + +/** + * Configuration for a single Infinispan server. + */ +export type InfinispanServerConfig = { + host: string; + port: number; +}; + +/** + * Options for putting values into Infinispan cache. + */ +export type InfinispanPutOptions = { + lifespan?: string; + maxIdle?: string; + previous?: boolean; + flags?: string[]; +}; +/** + * SSL/TLS options for the Infinispan client. + */ +export type InfinispanSslOptions = { + enabled: boolean; + secureProtocol?: string; + trustCerts?: string[]; // Array of trusted CA certificates + clientAuth?: InfinispanClientAuthOptions; + cryptoStore?: InfinispanCryptoStoreOptions; + sniHostName?: string; +}; + +/** + * Authentication options for the Infinispan client. + * This is used for client-side authentication with the Infinispan server. + */ +export type InfinispanClientAuthOptions = { + key?: string; + passphrase?: string; + cert?: string; +}; + +/** + * Options for the Infinispan client crypto store. + * This is used for storing keys and certificates securely. + */ +export type InfinispanCryptoStoreOptions = { + path?: string; + passphrase?: string; +}; + +/** + * Authentication options for the Infinispan client. + */ +export type InfinispanAuthOptions = { + enabled: boolean; + saslMechanism?: string; + userName?: string; + password?: string; + token?: string; + authzid?: string; +}; + +/** + * Options for the Infinispan cache store, designed to be configured + * in app-config.yaml under `backend.cache.infinispan`. + */ +export type InfinispanCacheStoreOptions = { + type: 'infinispan'; + servers: InfinispanServerConfig | InfinispanServerConfig[]; + options?: InfinispanClientBehaviorOptions; +}; + +export type InfinispanClusterConfig = { + name?: string; + servers: InfinispanServerConfig[]; +}; + +export type DataFormatOptions = { + keyType: 'text/plain' | 'application/json'; + valueType: 'text/plain' | 'application/json'; +}; + +/** + * Detailed client behavior options for the Infinispan client. + * @public + */ +export type InfinispanClientBehaviorOptions = { + version?: '2.9' | '2.5' | '2.2'; + cacheName?: string; + maxRetries?: number; + connectionTimeout?: number; + socketTimeout?: number; + authentication?: InfinispanAuthOptions; + ssl?: InfinispanSslOptions; + mediaType?: 'text/plain' | 'application/json'; + topologyUpdates?: boolean; + clusters?: InfinispanClusterConfig[]; + dataFormat: DataFormatOptions; +}; diff --git a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts index 5ca70cab86..96313e50af 100644 --- a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts +++ b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts @@ -52,16 +52,24 @@ export type DatabaseManagerOptions = { * Testable implementation class for {@link DatabaseManager} below. */ export class DatabaseManagerImpl { + private readonly config: Config; + private readonly connectors: Record; + private readonly options?: DatabaseManagerOptions; + private readonly databaseCache: Map>; + private readonly keepaliveIntervals: Map; + constructor( - private readonly config: Config, - private readonly connectors: Record, - private readonly options?: DatabaseManagerOptions, - private readonly databaseCache: Map> = new Map(), - private readonly keepaliveIntervals: Map< - string, - NodeJS.Timeout - > = new Map(), + config: Config, + connectors: Record, + options?: DatabaseManagerOptions, + databaseCache: Map> = new Map(), + keepaliveIntervals: Map = new Map(), ) { + this.config = config; + this.connectors = connectors; + this.options = options; + this.databaseCache = databaseCache; + this.keepaliveIntervals = keepaliveIntervals; // If a rootLifecycle service was provided, register a shutdown hook to // clean up any database connections. if (options?.rootLifecycle !== undefined) { @@ -262,7 +270,11 @@ export class DatabaseManager { ); } - private constructor(private readonly impl: DatabaseManagerImpl) {} + private readonly impl: DatabaseManagerImpl; + + private constructor(impl: DatabaseManagerImpl) { + this.impl = impl; + } /** * Generates a DatabaseService for consumption by plugins. diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/mysql.ts b/packages/backend-defaults/src/entrypoints/database/connectors/mysql.ts index d5bd88deef..e44feed361 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/mysql.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/mysql.ts @@ -243,10 +243,13 @@ function normalizeConnection( } export class MysqlConnector implements Connector { - constructor( - private readonly config: Config, - private readonly prefix: string, - ) {} + private readonly config: Config; + private readonly prefix: string; + + constructor(config: Config, prefix: string) { + this.config = config; + this.prefix = prefix; + } async getClient( pluginId: string, diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts index 4adf77a2f6..4a6893e9c1 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts @@ -294,10 +294,13 @@ function normalizeConnection( } export class PgConnector implements Connector { - constructor( - private readonly config: Config, - private readonly prefix: string, - ) {} + private readonly config: Config; + private readonly prefix: string; + + constructor(config: Config, prefix: string) { + this.config = config; + this.prefix = prefix; + } async getClient( pluginId: string, diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.ts b/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.ts index 67dd9d975f..081169c700 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.ts @@ -174,7 +174,11 @@ function normalizeConnection( } export class Sqlite3Connector implements Connector { - constructor(private readonly config: Config) {} + private readonly config: Config; + + constructor(config: Config) { + this.config = config; + } async getClient( pluginId: string, diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.test.ts deleted file mode 100644 index 31eecf14bb..0000000000 --- a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createLifecycleMiddleware } from './createLifecycleMiddleware'; -import { BackendLifecycleImpl } from '../rootLifecycle/rootLifecycleServiceFactory'; -import { mockServices } from '@backstage/backend-test-utils'; -import { ServiceUnavailableError } from '@backstage/errors'; - -describe('createLifecycleMiddleware', () => { - it('should pause requests when plugin is not ready', async () => { - const lifecycle = new BackendLifecycleImpl(mockServices.rootLogger()); - - const middleware = createLifecycleMiddleware({ lifecycle }); - - const next = jest.fn(); - middleware({} as any, {} as any, next); - expect(next).not.toHaveBeenCalled(); - await lifecycle.startup(); - - // pending call - expect(next).toHaveBeenCalledWith(); - - // new call - const next2 = jest.fn(); - middleware({} as any, {} as any, next2); - expect(next2).toHaveBeenCalledWith(); - }); - - it('should throw ServiceUnavailableError after shutdown', async () => { - const lifecycle = new BackendLifecycleImpl(mockServices.rootLogger()); - const middleware = createLifecycleMiddleware({ lifecycle }); - - const next = jest.fn(); - middleware({} as any, {} as any, next); - expect(next).not.toHaveBeenCalled(); - await lifecycle.shutdown(); - - // pending call - expect(next).toHaveBeenCalledWith( - new ServiceUnavailableError('Service is shutting down'), - ); - - // new call - const next2 = jest.fn(); - middleware({} as any, {} as any, next2); - expect(next2).toHaveBeenCalledWith( - new ServiceUnavailableError('Service is shutting down'), - ); - }); - - it('should throw ServiceUnavailableError after timeout', async () => { - const lifecycle = new BackendLifecycleImpl(mockServices.rootLogger()); - const middleware = createLifecycleMiddleware({ - lifecycle, - startupRequestPauseTimeout: { milliseconds: 1 }, - }); - - const next = jest.fn(); - middleware({} as any, {} as any, next); - expect(next).not.toHaveBeenCalled(); - - await new Promise(r => setTimeout(r, 2)); - - expect(next).toHaveBeenCalledWith( - new ServiceUnavailableError('Service has not started up yet'), - ); - }); -}); diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts deleted file mode 100644 index 99fb82a41e..0000000000 --- a/packages/backend-defaults/src/entrypoints/httpRouter/createLifecycleMiddleware.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { RootLifecycleService } from '@backstage/backend-plugin-api'; -import { ServiceUnavailableError } from '@backstage/errors'; -import { HumanDuration, durationToMilliseconds } from '@backstage/types'; -import { RequestHandler } from 'express'; - -export const DEFAULT_STARTUP_REQUEST_PAUSE_TIMEOUT = { seconds: 5 }; -export const DEFAULT_SERVER_SHUTDOWN_TIMEOUT = { seconds: 0 }; - -/** - * Options for {@link createLifecycleMiddleware}. - * @public - */ -export interface LifecycleMiddlewareOptions { - lifecycle: RootLifecycleService; - /** - * 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 } = 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(); - }); - - return (_req, _res, next) => { - if (state === 'up') { - next(); - return; - } else if (state === 'down') { - next(new ServiceUnavailableError('Service is shutting down')); - return; - } - - const timeoutMs = durationToMilliseconds( - startupRequestPauseTimeout ?? DEFAULT_STARTUP_REQUEST_PAUSE_TIMEOUT, - ); - - 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-defaults/src/entrypoints/httpRouter/http/createRateLimitMiddleware.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/createRateLimitMiddleware.ts new file mode 100644 index 0000000000..b139b212d2 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/httpRouter/http/createRateLimitMiddleware.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { NextFunction, Request, Response } from 'express'; +import { RateLimitStoreFactory } from '../../../lib/RateLimitStoreFactory.ts'; +import { Config } from '@backstage/config'; +import { rateLimitMiddleware } from '../../../lib/rateLimitMiddleware.ts'; + +export const createRateLimitMiddleware = (options: { + pluginId: string; + config: Config; +}) => { + const { pluginId, config } = options; + const configKey = `backend.rateLimit.plugin.${pluginId}`; + const enabled = config.has(configKey); + if (!enabled) { + return (_req: Request, _res: Response, next: NextFunction) => { + next(); + }; + } + + const rateLimitOptions = config.getConfig(configKey); + + return rateLimitMiddleware({ + store: RateLimitStoreFactory.create({ config, prefix: pluginId }), + config: rateLimitOptions, + }); +}; diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts index 1f2b989018..0fc70a07f0 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts @@ -22,12 +22,13 @@ import { HttpRouterServiceAuthPolicy, } from '@backstage/backend-plugin-api'; import { - createLifecycleMiddleware, + createAuthIntegrationRouter, createCookieAuthRefreshMiddleware, createCredentialsBarrier, - createAuthIntegrationRouter, + createLifecycleMiddleware, } from './http'; import { MiddlewareFactory } from '../rootHttpRouter'; +import { createRateLimitMiddleware } from './http/createRateLimitMiddleware.ts'; /** * HTTP route registration for plugins. @@ -61,6 +62,8 @@ export const httpRouterServiceFactory = createServiceFactory({ }) { const router = PromiseRouter(); + router.use(createRateLimitMiddleware({ pluginId: plugin.getId(), config })); + rootHttpRouter.use(`/api/${plugin.getId()}`, router); const credentialsBarrier = createCredentialsBarrier({ diff --git a/packages/backend-defaults/src/entrypoints/lifecycle/lifecycleServiceFactory.ts b/packages/backend-defaults/src/entrypoints/lifecycle/lifecycleServiceFactory.ts index 0ba812f5b4..92c4f599a4 100644 --- a/packages/backend-defaults/src/entrypoints/lifecycle/lifecycleServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/lifecycle/lifecycleServiceFactory.ts @@ -28,10 +28,13 @@ import { /** @internal */ export class BackendPluginLifecycleImpl implements LifecycleService { - constructor( - private readonly logger: LoggerService, - private readonly pluginMetadata: PluginMetadataService, - ) {} + private readonly logger: LoggerService; + private readonly pluginMetadata: PluginMetadataService; + + constructor(logger: LoggerService, pluginMetadata: PluginMetadataService) { + this.logger = logger; + this.pluginMetadata = pluginMetadata; + } #hasStarted = false; #hasShutdown = false; diff --git a/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.ts index b201079b4f..e7255610bc 100644 --- a/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHealth/rootHealthServiceFactory.ts @@ -24,8 +24,10 @@ import { /** @internal */ export class DefaultRootHealthService implements RootHealthService { #state: 'init' | 'up' | 'down' = 'init'; + readonly options: { lifecycle: RootLifecycleService }; - constructor(readonly options: { lifecycle: RootLifecycleService }) { + constructor(options: { lifecycle: RootLifecycleService }) { + this.options = options; options.lifecycle.addStartupHook(() => { this.#state = 'up'; }); diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts index 1ff9bd15d1..80a10fe0eb 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts @@ -15,15 +15,15 @@ */ import { - RootConfigService, LoggerService, + RootConfigService, } from '@backstage/backend-plugin-api'; import { - Request, - Response, ErrorRequestHandler, NextFunction, + Request, RequestHandler, + Response, } from 'express'; import cors from 'cors'; import helmet from 'helmet'; @@ -37,12 +37,14 @@ import { InputError, NotAllowedError, NotFoundError, + NotImplementedError, NotModifiedError, - ServiceUnavailableError, serializeError, + ServiceUnavailableError, } from '@backstage/errors'; -import { NotImplementedError } from '@backstage/errors'; import { applyInternalErrorFilter } from './applyInternalErrorFilter'; +import { RateLimitStoreFactory } from '../../../lib/RateLimitStoreFactory.ts'; +import { rateLimitMiddleware } from '../../../lib/rateLimitMiddleware.ts'; type LogMeta = { date: string; @@ -227,6 +229,47 @@ export class MiddlewareFactory { return cors(readCorsOptions(this.#config.getOptionalConfig('backend'))); } + /** + * Returns a middleware that implements rate limiting. + * + * @remarks + * + * Rate limiting is a common technique to prevent abuse of APIs. This middleware is + * configured using the config key `backend.rateLimit`. + * + * @returns An Express request handler + */ + rateLimit(): RequestHandler { + const enabled = this.#config.has('backend.rateLimit'); + if (!enabled) { + return (_req: Request, _res: Response, next: NextFunction) => { + next(); + }; + } + + const useDefaults = this.#config.getOptional('backend.rateLimit') === true; + const rateLimitOptions = useDefaults + ? undefined + : this.#config.getOptionalConfig('backend.rateLimit'); + + // Global rate limiting disabled + if ( + rateLimitOptions && + rateLimitOptions.getOptionalBoolean('global') === false + ) { + return (_req: Request, _res: Response, next: NextFunction) => { + next(); + }; + } + + return rateLimitMiddleware({ + store: useDefaults + ? undefined + : RateLimitStoreFactory.create({ config: this.#config }), + config: rateLimitOptions, + }); + } + /** * Express middleware to handle errors during request processing. * diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts index 0f2b6463e4..8f8d1b7656 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.test.ts @@ -323,4 +323,65 @@ describe('rootHttpRouterServiceFactory', () => { }), ).resolves.toBeUndefined(); }); + + it('should start successfully with server configuration options', async () => { + const { app } = await createExpressApp( + mockServices.rootConfig.factory({ + data: { + backend: { + listen: { port: 0 }, + server: { + headersTimeout: 30000, + requestTimeout: '45s', + keepAliveTimeout: 'PT1M', + timeout: { seconds: 120 }, + maxHeadersCount: 2000, + maxRequestsPerSocket: 100, + }, + }, + }, + }), + ); + + // Verify the server starts and responds to health checks + await request(app) + .get('/.backstage/health/v1/liveness') + .expect(200, { status: 'ok' }); + }); + + it('should start successfully with partial server configuration', async () => { + const { app } = await createExpressApp( + mockServices.rootConfig.factory({ + data: { + backend: { + listen: { port: 0 }, + server: { + headersTimeout: 60000, + maxHeadersCount: 1500, + }, + }, + }, + }), + ); + + await request(app) + .get('/.backstage/health/v1/liveness') + .expect(200, { status: 'ok' }); + }); + + it('should start successfully with no server configuration', async () => { + const { app } = await createExpressApp( + mockServices.rootConfig.factory({ + data: { + backend: { + listen: { port: 0 }, + }, + }, + }), + ); + + await request(app) + .get('/.backstage/health/v1/liveness') + .expect(200, { status: 'ok' }); + }); }); diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts index da7fcfe3f9..b0cc9d160e 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts @@ -15,13 +15,13 @@ */ import { - RootConfigService, coreServices, createServiceFactory, LifecycleService, LoggerService, + RootConfigService, } from '@backstage/backend-plugin-api'; -import express, { RequestHandler, Express } from 'express'; +import express, { Express, RequestHandler } from 'express'; import type { Server } from 'node:http'; import { createHttpServer, @@ -117,10 +117,80 @@ const rootHttpRouterServiceFactoryWithOptions = ( if (trustProxy !== undefined) { app.set('trust proxy', trustProxy); } + + // Apply server-level HTTP options from config + const backendConfig = config.getOptionalConfig('backend'); + const serverConfig = backendConfig?.getOptionalConfig('server'); + + if (serverConfig) { + // Helper function to read duration values (supporting number, string, or HumanDuration) + const readDurationValue = (key: string): number | undefined => { + if (!serverConfig.has(key)) { + return undefined; + } + + const value = serverConfig.getOptional(key); + if (typeof value === 'number') { + return value; + } + + // If it's not a number, try to read it as a duration + try { + const duration = readDurationFromConfig(serverConfig, { key }); + return durationToMilliseconds(duration); + } catch (error) { + // Log warning for parsing failures + logger.warn( + `Failed to parse backend.server.${key} as duration: ${error}. ` + + `Expected a number (milliseconds), duration string (e.g., '30s'), ` + + `ISO duration (e.g., 'PT30S'), or duration object (e.g., {seconds: 30}). ` + + `Falling back to number parsing.`, + ); + return undefined; + } + }; + + // Apply timeout settings + const headersTimeout = readDurationValue('headersTimeout'); + if (headersTimeout !== undefined) { + server.headersTimeout = headersTimeout; + } + + const requestTimeout = readDurationValue('requestTimeout'); + if (requestTimeout !== undefined) { + server.requestTimeout = requestTimeout; + } + + const keepAliveTimeout = readDurationValue('keepAliveTimeout'); + if (keepAliveTimeout !== undefined) { + server.keepAliveTimeout = keepAliveTimeout; + } + + const timeout = readDurationValue('timeout'); + if (timeout !== undefined) { + server.timeout = timeout; + } + + // Apply numeric settings + const maxHeadersCount = + serverConfig.getOptionalNumber('maxHeadersCount'); + if (maxHeadersCount !== undefined) { + server.maxHeadersCount = maxHeadersCount; + } + + const maxRequestsPerSocket = serverConfig.getOptionalNumber( + 'maxRequestsPerSocket', + ); + if (maxRequestsPerSocket !== undefined) { + server.maxRequestsPerSocket = maxRequestsPerSocket; + } + } + app.use(middleware.helmet()); app.use(middleware.cors()); app.use(middleware.compression()); app.use(middleware.logging()); + app.use(middleware.rateLimit()); app.use(healthRouter); app.use(routes); app.use(middleware.notFound()); diff --git a/packages/backend-defaults/src/entrypoints/rootLifecycle/rootLifecycleServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootLifecycle/rootLifecycleServiceFactory.ts index abba4beece..a77a2e1308 100644 --- a/packages/backend-defaults/src/entrypoints/rootLifecycle/rootLifecycleServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootLifecycle/rootLifecycleServiceFactory.ts @@ -27,7 +27,11 @@ import { /** @internal */ export class BackendLifecycleImpl implements RootLifecycleService { - constructor(private readonly logger: LoggerService) {} + private readonly logger: LoggerService; + + constructor(logger: LoggerService) { + this.logger = logger; + } #hasStarted = false; #startupTasks: Array<{ diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.test.ts b/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.test.ts index 39293dcc55..7dba10cccf 100644 --- a/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.test.ts +++ b/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.test.ts @@ -110,4 +110,90 @@ describe('WinstonLogger', () => { `={"foo":{"bar":{"baz":"qux"}}}`, ); }); + + it('should handle null and undefined values in redactions without crashing', () => { + const { add } = WinstonLogger.redacter(); + + expect(() => { + add([null as any, undefined as any, 'valid-secret']); + }).not.toThrow(); + }); + + it('should filter logs below the default log level', () => { + const mockTransport = new Transport({ + log: jest.fn(), + logv: jest.fn(), + }); + + const logger = WinstonLogger.create({ + level: 'warn', + format: format.json(), + transports: [mockTransport], + }); + + logger.debug('debug log'); + + expect(mockTransport.log).not.toHaveBeenCalled(); + }); + + it('should not filter logs below the default log level with an override', () => { + const mockTransport = new Transport({ + log: jest.fn(), + logv: jest.fn(), + }); + + const logger = WinstonLogger.create({ + level: 'warn', + format: format.json(), + transports: [mockTransport], + }); + + logger.setLevelOverrides([ + { + matchers: { + plugin: 'catalog', + }, + level: 'debug', + }, + ]); + + logger.debug('debug log', { plugin: 'catalog' }); + + expect(mockTransport.log).toHaveBeenCalledWith( + expect.objectContaining({ + [MESSAGE]: JSON.stringify({ + level: 'debug', + message: 'debug log', + plugin: 'catalog', + }), + }), + expect.any(Function), + ); + }); + + it('should filter logs above the default log level with an override', () => { + const mockTransport = new Transport({ + log: jest.fn(), + logv: jest.fn(), + }); + + const logger = WinstonLogger.create({ + level: 'debug', + format: format.json(), + transports: [mockTransport], + }); + + logger.setLevelOverrides([ + { + matchers: { + plugin: 'catalog', + }, + level: 'error', + }, + ]); + + logger.info('info log', { plugin: 'catalog' }); + + expect(mockTransport.log).not.toHaveBeenCalled(); + }); }); diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.ts b/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.ts index 545c9377b2..c48cef2f1f 100644 --- a/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.ts +++ b/packages/backend-defaults/src/entrypoints/rootLogger/WinstonLogger.ts @@ -26,9 +26,12 @@ import { createLogger, transports, transport as Transport, + config as winstonConfig, } from 'winston'; import { MESSAGE } from 'triple-beam'; import { escapeRegExp } from '../../lib/escapeRegExp'; +import { winstonLevels, WinstonLoggerLevelOverride } from './types'; +import { createLogMatcher } from './utils'; /** * @public @@ -48,20 +51,27 @@ export interface WinstonLoggerOptions { export class WinstonLogger implements RootLoggerService { #winston: Logger; #addRedactions?: (redactions: Iterable) => void; + #setLevelOverrides?: (overrides: WinstonLoggerLevelOverride[]) => void; /** * Creates a {@link WinstonLogger} instance. */ static create(options: WinstonLoggerOptions): WinstonLogger { + const defaultLogLevel = process.env.LOG_LEVEL || options.level || 'info'; + const redacter = WinstonLogger.redacter(); + const logLevelFilter = WinstonLogger.logLevelFilter(defaultLogLevel); + const defaultFormatter = process.env.NODE_ENV === 'production' ? format.json() : WinstonLogger.colorFormat(); let logger = createLogger({ - level: process.env.LOG_LEVEL || options.level || 'info', + // Lowest level possible as we let the logLevelFilter do the filtering + level: 'silly', format: format.combine( + logLevelFilter.format, options.format ?? defaultFormatter, redacter.format, ), @@ -72,7 +82,7 @@ export class WinstonLogger implements RootLoggerService { logger = logger.child(options.meta); } - return new WinstonLogger(logger, redacter.add); + return new WinstonLogger(logger, redacter.add, logLevelFilter.setOverrides); } /** @@ -99,6 +109,10 @@ export class WinstonLogger implements RootLoggerService { add(newRedactions) { let added = 0; for (const redactionToTrim of newRedactions) { + // Skip null or undefined values + if (redactionToTrim === null || redactionToTrim === undefined) { + continue; + } // 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 @@ -165,12 +179,61 @@ export class WinstonLogger implements RootLoggerService { ); } + /** + * Formatter that filters log levels using overrides, falling back to the default level when no criteria match. + */ + static logLevelFilter( + defaultLogLevel: keyof winstonConfig.NpmConfigSetLevels, + ): { + format: Format; + setOverrides: (overrides: WinstonLoggerLevelOverride[]) => void; + } { + const overrides: { + predicate: (log: TransformableInfo) => boolean; + level: string; + }[] = []; + + return { + format: format(log => { + for (const override of overrides) { + if (override.predicate(log)) { + // Discard the log if the log level is below the override + // eg, if the override level is 'warn' (1) and the log is 'debug' (5) + if (winstonLevels[log.level] > winstonLevels[override.level]) { + return false; + } + + return log; + } + } + + // Ignore logs that are below the global level + // eg, if the global level is 'warn' (1) and the log level is 'debug' (5) + if (winstonLevels[log.level] > winstonLevels[defaultLogLevel]) { + return false; + } + + return log; + })(), + setOverrides: newOverrides => { + const newOverridesPredicates = newOverrides.map(o => ({ + predicate: createLogMatcher(o.matchers), + level: o.level, + })); + // Replace the content while preserving the reference to support live config updates + overrides.splice(0, overrides.length, ...newOverridesPredicates); + }, + }; + } + private constructor( winston: Logger, addRedactions?: (redactions: Iterable) => void, + setLevelOverrides?: (overrides: WinstonLoggerLevelOverride[]) => void, ) { this.#winston = winston; this.#addRedactions = addRedactions; + this.#setLevelOverrides = setLevelOverrides; } error(message: string, meta?: JsonObject): void { @@ -196,4 +259,8 @@ export class WinstonLogger implements RootLoggerService { addRedactions(redactions: Iterable) { this.#addRedactions?.(redactions); } + + setLevelOverrides(overrides: WinstonLoggerLevelOverride[]) { + this.#setLevelOverrides?.(overrides); + } } diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/config.test.ts b/packages/backend-defaults/src/entrypoints/rootLogger/config.test.ts new file mode 100644 index 0000000000..e32cc13247 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootLogger/config.test.ts @@ -0,0 +1,75 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 { getRootLoggerConfig } from './config'; + +describe('getRootLoggerConfig', () => { + it('should load the configuration without throwing', () => { + const config = { + backend: { + logger: { + level: 'info', + meta: { + env: 'prod', + }, + overrides: [ + { + matchers: { + plugin: 'catalog', + }, + level: 'warn', + }, + ], + }, + }, + }; + + expect(() => + getRootLoggerConfig( + mockServices.rootConfig({ + data: config, + }), + ), + ).not.toThrow(); + }); + + it('should throw if an override is using an invalid level', () => { + const config = { + backend: { + logger: { + level: 'info', + meta: { + env: 'prod', + }, + overrides: [ + { + matchers: { + plugin: 'catalog', + }, + level: 'invalid', + }, + ], + }, + }, + }; + + expect(() => + getRootLoggerConfig(mockServices.rootConfig({ data: config })), + ).toThrow( + "Invalid config at backend.logger.overrides[0].level, 'invalid' is not a valid logging level, must be one of 'error', 'warn', 'info' or 'debug'.", + ); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/config.ts b/packages/backend-defaults/src/entrypoints/rootLogger/config.ts new file mode 100644 index 0000000000..11687d72f4 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootLogger/config.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 } from '@backstage/backend-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { + RootLoggerConfig, + winstonLevels, + WinstonLoggerLevelOverrideMatchers, +} from './types'; + +export const getRootLoggerConfig = ( + config: RootConfigService, +): RootLoggerConfig => { + const level = config.getOptionalString('backend.logger.level'); + const meta = config + .getOptionalConfig('backend.logger.meta') + ?.get(); + + const overridesConfig = config.getOptionalConfigArray( + 'backend.logger.overrides', + ); + const overrides = overridesConfig?.map((override, i) => { + const overrideLevel = override.getString('level'); + if (winstonLevels[overrideLevel] === undefined) { + throw new Error( + `Invalid config at backend.logger.overrides[${i}].level, '${overrideLevel}' is not a valid logging level, must be one of 'error', 'warn', 'info' or 'debug'.`, + ); + } + + const matchers = override + .getConfig('matchers') + .get(); + + return { + matchers, + level: overrideLevel, + }; + }); + + return { + meta, + level, + overrides, + }; +}; diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/index.ts b/packages/backend-defaults/src/entrypoints/rootLogger/index.ts index 96ed402520..676c1f5398 100644 --- a/packages/backend-defaults/src/entrypoints/rootLogger/index.ts +++ b/packages/backend-defaults/src/entrypoints/rootLogger/index.ts @@ -16,3 +16,7 @@ export { rootLoggerServiceFactory } from './rootLoggerServiceFactory'; export { WinstonLogger, type WinstonLoggerOptions } from './WinstonLogger'; +export { + type WinstonLoggerLevelOverride, + type WinstonLoggerLevelOverrideMatchers, +} from './types'; diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.test.ts b/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.test.ts new file mode 100644 index 0000000000..4b807aafc8 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.test.ts @@ -0,0 +1,72 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + ServiceFactoryTester, +} from '@backstage/backend-test-utils'; +import { rootLoggerServiceFactory } from './rootLoggerServiceFactory'; + +import { WinstonLogger } from './WinstonLogger'; + +describe('rootLoggerServiceFactory', () => { + beforeEach(() => { + jest.spyOn(WinstonLogger, 'create'); + }); + + it('should create WinstonLogger with defaults', async () => { + await ServiceFactoryTester.from(rootLoggerServiceFactory, { + dependencies: [mockServices.rootConfig.factory()], + }).getSubject(); + + expect(WinstonLogger.create).toHaveBeenCalledWith({ + level: 'info', + meta: { + service: 'backstage', + }, + format: expect.anything(), + transports: expect.anything(), + }); + }); + + it('should create WinstonLogger from config', async () => { + await ServiceFactoryTester.from(rootLoggerServiceFactory, { + dependencies: [ + mockServices.rootConfig.factory({ + data: { + backend: { + logger: { + meta: { + env: 'test', + }, + level: 'warn', + }, + }, + }, + }), + ], + }).getSubject(); + + expect(WinstonLogger.create).toHaveBeenCalledWith({ + level: 'warn', + meta: { + service: 'backstage', + env: 'test', + }, + format: expect.anything(), + transports: expect.anything(), + }); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.ts index 5a4427cf5f..abd81e575b 100644 --- a/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootLogger/rootLoggerServiceFactory.ts @@ -15,12 +15,13 @@ */ import { - createServiceFactory, coreServices, + createServiceFactory, } from '@backstage/backend-plugin-api'; -import { transports, format } from 'winston'; -import { WinstonLogger } from '../rootLogger/WinstonLogger'; +import { format, transports } from 'winston'; import { createConfigSecretEnumerator } from '../rootConfig/createConfigSecretEnumerator'; +import { WinstonLogger } from '../rootLogger/WinstonLogger'; +import { getRootLoggerConfig } from './config'; /** * Root-level logging. @@ -37,11 +38,14 @@ export const rootLoggerServiceFactory = createServiceFactory({ config: coreServices.rootConfig, }, async factory({ config }) { + const rootLoggerConfig = getRootLoggerConfig(config); + const logger = WinstonLogger.create({ meta: { service: 'backstage', + ...rootLoggerConfig.meta, }, - level: process.env.LOG_LEVEL || 'info', + level: process.env.LOG_LEVEL || rootLoggerConfig.level || 'info', format: process.env.NODE_ENV === 'production' ? format.json() @@ -53,6 +57,11 @@ export const rootLoggerServiceFactory = createServiceFactory({ logger.addRedactions(secretEnumerator(config)); config.subscribe?.(() => logger.addRedactions(secretEnumerator(config))); + logger.setLevelOverrides(rootLoggerConfig.overrides ?? []); + config.subscribe?.(() => + logger.setLevelOverrides(getRootLoggerConfig(config).overrides ?? []), + ); + return logger; }, }); diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/types.ts b/packages/backend-defaults/src/entrypoints/rootLogger/types.ts new file mode 100644 index 0000000000..f8277d8075 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootLogger/types.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JsonObject, JsonPrimitive } from '@backstage/types'; +import { config as winstonConfig } from 'winston'; + +/** + * @public + */ +export type WinstonLoggerLevelOverrideMatchers = { + [key: string]: JsonPrimitive | JsonPrimitive[] | undefined; +}; + +/** + * @public + */ +export type WinstonLoggerLevelOverride = { + matchers: WinstonLoggerLevelOverrideMatchers; + level: string; +}; + +export type RootLoggerConfig = { + level?: string; + meta?: JsonObject; + overrides?: WinstonLoggerLevelOverride[]; +}; + +export const winstonLevels = winstonConfig.npm.levels; diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/utils.test.ts b/packages/backend-defaults/src/entrypoints/rootLogger/utils.test.ts new file mode 100644 index 0000000000..ede3de600b --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootLogger/utils.test.ts @@ -0,0 +1,80 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createLogMatcher } from './utils'; + +describe('createLogMatcher', () => { + const log = { + level: 'info', + message: 'This is a simple log from the catalog plugin', + plugin: 'catalog', + status: 200, + action: 'read', + }; + + it('should match with a simple matcher', () => { + const matcher = createLogMatcher({ plugin: 'catalog' }); + expect(matcher(log)).toEqual(true); + }); + + it('should not match with a simple matcher', () => { + const matcher = createLogMatcher({ plugin: 'search' }); + expect(matcher(log)).toEqual(false); + }); + + it('should match with an AND matcher', () => { + const matcher = createLogMatcher({ + plugin: 'catalog', + action: 'read', + }); + expect(matcher(log)).toEqual(true); + }); + + it('should not match log with an AND matcher', () => { + const matcher = createLogMatcher({ + plugin: 'catalog', + action: 'write', + }); + expect(matcher(log)).toEqual(false); + }); + + it('should match with an OR matcher', () => { + const matcher = createLogMatcher({ + plugin: ['auth', 'catalog'], + }); + expect(matcher(log)).toEqual(true); + }); + + it('should not match log with an OR matcher', () => { + const matcher = createLogMatcher({ + plugin: ['auth', 'search'], + }); + expect(matcher(log)).toEqual(false); + }); + + it('should match log with a regex matcher', () => { + const matcher = createLogMatcher({ + message: '/This is a simple log/', + }); + expect(matcher(log)).toEqual(true); + }); + + it('should not match log with a regex matcher', () => { + const matcher = createLogMatcher({ + message: '/^simple log/', + }); + expect(matcher(log)).toEqual(false); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/rootLogger/utils.ts b/packages/backend-defaults/src/entrypoints/rootLogger/utils.ts new file mode 100644 index 0000000000..adf38fc4da --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/rootLogger/utils.ts @@ -0,0 +1,94 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TransformableInfo } from 'logform'; +import { WinstonLoggerLevelOverrideMatchers } from './types'; + +/** Parse a slash-delimited regex like `/pattern/flags` into a RegExp, or null if not a regex-string */ +const parseRegex = (s: string): RegExp | null => { + if (!s.startsWith('/')) return null; + const lastSlash = s.lastIndexOf('/'); + if (lastSlash <= 0) return null; + + const pattern = s.slice(1, lastSlash); + const flags = s.slice(lastSlash + 1); + + try { + return new RegExp(pattern, flags); + } catch { + return null; // fall back to treating it as a plain string + } +}; + +/** + * Create a predicate function that determines whether a log field matches a given matcher. + * + * The matcher can be: + * - A string (exact match or regex pattern delimited by slashes, e.g. `/pattern/`) + * - A non-string value (compared by strict equality) + * - An array of matchers (returns true if any matcher matches) + * + * @param matcher - The matcher or array of matchers to compare against the log field. + * @returns A function that takes a log field and returns `true` if it matches the matcher, otherwise `false`. + */ +const createLogFieldMatcher = ( + matcher: WinstonLoggerLevelOverrideMatchers[0], +): ((logField: unknown) => boolean) => { + // Array of matchers: create predicates for each element and OR them together + if (Array.isArray(matcher)) { + const fns = matcher.map(m => createLogFieldMatcher(m)); + return (logField: unknown) => fns.some(fn => fn(logField)); + } + + // Non-string matcher: strict equality + if (typeof matcher !== 'string') { + return (logField: unknown) => logField === matcher; + } + + // String matcher: maybe a slash-delimited regex (/pattern/flags) + const regex = parseRegex(matcher); + if (regex) { + return (logField: unknown) => + typeof logField === 'string' && regex.test(logField); + } + + // Plain string matcher: strict equality + return (logField: unknown) => logField === matcher; +}; + +/** + * Create a predicate function that determines whether a log entry matches + * all specified override matchers. + * + * Iterates over each key-matcher pair in the provided `matchers` object, + * retrieves the corresponding field from the `log` object, and checks if + * the field matches the matcher using `isLogFieldMatching`. Returns `true` + * only if all matchers are satisfied. + * + * @param matchers - An object where each key corresponds to a log field and each value is a matcher to test against that field. + * @returns A function that takes a log entry and returns `true` if it matches all specified matchers, otherwise `false`. + */ +export const createLogMatcher = ( + matchers: WinstonLoggerLevelOverrideMatchers, +): ((log: TransformableInfo) => boolean) => { + const logFieldMatchers = Object.entries(matchers).map(([key, m]) => { + const fn = createLogFieldMatcher(m); + return [key, fn] as const; + }); + + return (log: TransformableInfo) => + logFieldMatchers.every(([key, fn]) => fn(log[key])); +}; diff --git a/packages/backend-defaults/src/entrypoints/scheduler/lib/LocalTaskWorker.ts b/packages/backend-defaults/src/entrypoints/scheduler/lib/LocalTaskWorker.ts index a063f4145e..efecb1c0ed 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/lib/LocalTaskWorker.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/lib/LocalTaskWorker.ts @@ -36,15 +36,23 @@ export class LocalTaskWorker { status: 'idle', }; + private readonly taskId: string; + private readonly fn: SchedulerServiceTaskFunction; + private readonly logger: LoggerService; + constructor( - private readonly taskId: string, - private readonly fn: SchedulerServiceTaskFunction, - private readonly logger: LoggerService, - ) {} + taskId: string, + fn: SchedulerServiceTaskFunction, + logger: LoggerService, + ) { + this.taskId = taskId; + this.fn = fn; + this.logger = logger; + } start(settings: TaskSettingsV2, options: { signal: AbortSignal }) { this.logger.info( - `Task worker starting: ${this.taskId}, ${JSON.stringify(settings)}`, + `Registered scheduled task: ${this.taskId}, ${JSON.stringify(settings)}`, ); (async () => { diff --git a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.test.ts b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.test.ts index c0339a7a2d..5872ae793e 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.test.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.test.ts @@ -33,7 +33,7 @@ jest.setTimeout(60_000); describe('PluginTaskManagerImpl', () => { const addShutdownHook = jest.fn(); const databases = TestDatabases.create({ - ids: ['POSTGRES_17', 'POSTGRES_13', 'SQLITE_3'], + ids: ['POSTGRES_18', 'POSTGRES_14', 'SQLITE_3'], }); beforeAll(async () => { diff --git a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts index b7a946ab80..90f5d08e4a 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts @@ -50,12 +50,19 @@ export class PluginTaskSchedulerImpl implements SchedulerService { private readonly lastStarted: Gauge; private readonly lastCompleted: Gauge; + private readonly pluginId: string; + private readonly databaseFactory: () => Promise; + private readonly logger: LoggerService; + constructor( - private readonly pluginId: string, - private readonly databaseFactory: () => Promise, - private readonly logger: LoggerService, + pluginId: string, + databaseFactory: () => Promise, + logger: LoggerService, rootLifecycle: RootLifecycleService, ) { + this.pluginId = pluginId; + this.databaseFactory = databaseFactory; + this.logger = logger; const meter = metrics.getMeter('default'); this.counter = meter.createCounter('backend_tasks.task.runs.count', { description: 'Total number of times a task has been run', diff --git a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.test.ts b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.test.ts index bfba35ac30..8c2b54f69f 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.test.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.test.ts @@ -39,8 +39,8 @@ describe('PluginTaskSchedulerJanitor', () => { const databases = TestDatabases.create({ ids: [ /* 'MYSQL_8' not supported yet */ - 'POSTGRES_17', - 'POSTGRES_13', + 'POSTGRES_18', + 'POSTGRES_14', 'SQLITE_3', 'MYSQL_8', ], diff --git a/packages/backend-defaults/src/entrypoints/scheduler/lib/TaskWorker.ts b/packages/backend-defaults/src/entrypoints/scheduler/lib/TaskWorker.ts index 32e7a5ab4e..eb040ef415 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/lib/TaskWorker.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/lib/TaskWorker.ts @@ -46,14 +46,25 @@ export class TaskWorker { #workerState: TaskApiTasksResponse['workerState'] = { status: 'idle', }; + private readonly taskId: string; + private readonly fn: SchedulerServiceTaskFunction; + private readonly knex: Knex; + private readonly logger: LoggerService; + private readonly workCheckFrequency: Duration; constructor( - private readonly taskId: string, - private readonly fn: SchedulerServiceTaskFunction, - private readonly knex: Knex, - private readonly logger: LoggerService, - private readonly workCheckFrequency: Duration = DEFAULT_WORK_CHECK_FREQUENCY, - ) {} + taskId: string, + fn: SchedulerServiceTaskFunction, + knex: Knex, + logger: LoggerService, + workCheckFrequency: Duration = DEFAULT_WORK_CHECK_FREQUENCY, + ) { + this.taskId = taskId; + this.fn = fn; + this.knex = knex; + this.logger = logger; + this.workCheckFrequency = workCheckFrequency; + } async start(settings: TaskSettingsV2, options: { signal: AbortSignal }) { try { @@ -63,7 +74,7 @@ export class TaskWorker { } this.logger.info( - `Task worker starting: ${this.taskId}, ${JSON.stringify(settings)}`, + `Registered scheduled task: ${this.taskId}, ${JSON.stringify(settings)}`, ); let workCheckFrequency = this.workCheckFrequency; diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.ts index 7cffe6a28b..06af036891 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.ts @@ -142,13 +142,23 @@ export class AwsCodeCommitUrlReader implements UrlReaderService { }); }; + private readonly credsManager: AwsCredentialsManager; + private readonly integration: AwsCodeCommitIntegration; + private readonly deps: { + treeResponseFactory: ReadTreeResponseFactory; + }; + constructor( - private readonly credsManager: AwsCredentialsManager, - private readonly integration: AwsCodeCommitIntegration, - private readonly deps: { + credsManager: AwsCredentialsManager, + integration: AwsCodeCommitIntegration, + deps: { treeResponseFactory: ReadTreeResponseFactory; }, - ) {} + ) { + this.credsManager = credsManager; + this.integration = integration; + this.deps = deps; + } /** * If accessKeyId and secretAccessKey are missing, the standard credentials provider chain will be used: diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader.ts index 5060f6c632..87563a86ba 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader.ts @@ -151,13 +151,23 @@ export class AwsS3UrlReader implements UrlReaderService { }); }; + private readonly credsManager: AwsCredentialsManager; + private readonly integration: AwsS3Integration; + private readonly deps: { + treeResponseFactory: ReadTreeResponseFactory; + }; + constructor( - private readonly credsManager: AwsCredentialsManager, - private readonly integration: AwsS3Integration, - private readonly deps: { + credsManager: AwsCredentialsManager, + integration: AwsS3Integration, + deps: { treeResponseFactory: ReadTreeResponseFactory; }, - ) {} + ) { + this.credsManager = credsManager; + this.integration = integration; + this.deps = deps; + } /** * If accessKeyId and secretAccessKey are missing, the standard credentials provider chain will be used: diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureBlobStorageUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureBlobStorageUrlReader.test.ts new file mode 100644 index 0000000000..93f0d81441 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureBlobStorageUrlReader.test.ts @@ -0,0 +1,359 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as AzureStorage from '@azure/storage-blob'; +import { ConfigReader } from '@backstage/config'; +import { JsonObject } from '@backstage/types'; +import { DefaultReadTreeResponseFactory } from './tree'; +import { + AzureBlobStorageUrlReader, + parseUrl, +} from './AzureBlobStorageUrlReader'; +import { + DefaultAzureCredentialsManager, + ScmIntegrations, +} from '@backstage/integration'; +import { UrlReaderPredicateTuple } from './types'; +import { mockServices } from '@backstage/backend-test-utils'; +import { Readable } from 'stream'; + +// Mock Azure Blob Storage SDK +const mockBlobDownload = jest.fn(); +const mockGetBlobClient = jest.fn(() => ({ + download: mockBlobDownload, +})); +const mockListBlobsFlat = jest.fn(); + +class MockContainerClient { + getBlobClient = mockGetBlobClient; + listBlobsFlat = mockListBlobsFlat; +} + +class MockBlobServiceClient { + getContainerClient = jest.fn(() => new MockContainerClient()); +} + +jest + .spyOn(AzureStorage, 'BlobServiceClient') + .mockReturnValue(new MockBlobServiceClient() as any); +jest + .spyOn(AzureStorage, 'StorageSharedKeyCredential') + .mockReturnValue({} as any); + +const treeResponseFactory = DefaultReadTreeResponseFactory.create({ + config: new ConfigReader({}), +}); + +describe('parseUrl', () => { + it('parses Azure Blob Storage URLs correctly', () => { + expect( + parseUrl( + 'https://test-account.blob.core.windows.net/mycontainer/path/to/file.yaml', + ), + ).toEqual({ + path: 'path/to/file.yaml', + container: 'mycontainer', + }); + + expect( + parseUrl( + 'https://test-account.blob.core.windows.net/mycontainer/file.yaml', + ), + ).toEqual({ + path: 'file.yaml', + container: 'mycontainer', + }); + }); + + it('handles URLs with no path correctly', () => { + expect( + parseUrl('https://test-account.blob.core.windows.net/mycontainer/'), + ).toEqual({ + path: '', + container: 'mycontainer', + }); + }); + + it('throws error for invalid URLs', () => { + expect(() => + parseUrl('https://test-account.blob.core.windows.net/'), + ).toThrow('Invalid Azure Blob Storage URL format'); + }); +}); + +describe('AzureBlobStorageUrlReader', () => { + const createReader = (config: JsonObject): UrlReaderPredicateTuple[] => { + return AzureBlobStorageUrlReader.factory({ + config: new ConfigReader(config), + logger: mockServices.logger.mock(), + treeResponseFactory, + }); + }; + + it('creates a reader with minimal config', () => { + const entries = createReader({ + integrations: { + azureBlobStorage: [ + { + accountName: 'test-account', + }, + ], + }, + }); + + expect(entries).toHaveLength(1); + }); + + describe('predicates', () => { + const readers = createReader({ + integrations: { + azureBlobStorage: [ + { + accountName: 'test-account', + }, + ], + }, + }); + const predicate = readers[0].predicate; + + it('returns true for the correct azure blob storage host', () => { + expect( + predicate(new URL('https://test-account.blob.core.windows.net')), + ).toBe(true); + }); + + it('returns false for an incorrect host', () => { + expect( + predicate(new URL('https://wrongaccount.blob.core.windows.net')), + ).toBe(false); + }); + }); + + describe('toString', () => { + it('returns a string representation with account name and auth status', () => { + const config = new ConfigReader({ + integrations: { + azureBlobStorage: [ + { + accountName: 'test-account', + accountKey: 'test-key', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const credsManager = + DefaultAzureCredentialsManager.fromIntegrations(integrations); + const reader = new AzureBlobStorageUrlReader( + credsManager, + integrations.azureBlobStorage.list()[0], + { treeResponseFactory }, + ); + + expect(reader.toString()).toBe( + 'azureBlobStorage{accountName=test-account,authed=true}', + ); + }); + + it('shows authed=false when no account key provided', () => { + const config = new ConfigReader({ + integrations: { + azureBlobStorage: [ + { + accountName: 'test-account', + }, + ], + }, + }); + + const integrations = ScmIntegrations.fromConfig(config); + const credsManager = + DefaultAzureCredentialsManager.fromIntegrations(integrations); + const reader = new AzureBlobStorageUrlReader( + credsManager, + integrations.azureBlobStorage.list()[0], + { treeResponseFactory }, + ); + + expect(reader.toString()).toBe( + 'azureBlobStorage{accountName=test-account,authed=false}', + ); + }); + }); + + describe('readUrl', () => { + const [{ reader }] = createReader({ + integrations: { + azureBlobStorage: [ + { + accountName: 'test-account', + accountKey: 'test-key', + }, + ], + }, + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('returns contents of a blob via buffer', async () => { + mockBlobDownload.mockResolvedValue({ + readableStreamBody: Readable.from( + Buffer.from('site_name: Test Azure Blob'), + ), + etag: '"etag"', + lastModified: new Date('2025-01-01T00:00:00Z'), + }); + + const { buffer, etag, lastModifiedAt } = await reader.readUrl( + 'https://test-account.blob.core.windows.net/test-container/test-file.yaml', + ); + + expect(etag).toBe('"etag"'); + expect(lastModifiedAt).toEqual(new Date('2025-01-01T00:00:00Z')); + const response = await buffer(); + expect(response.toString()).toBe('site_name: Test Azure Blob'); + }); + + it('handles Azure SDK errors', async () => { + mockBlobDownload.mockRejectedValue(new Error('Blob not found')); + + await expect( + reader.readUrl( + 'https://test-account.blob.core.windows.net/test-container/nonexistent.yaml', + ), + ).rejects.toThrow('Could not retrieve file from Azure Blob Storage'); + }); + }); + + describe('readTree', () => { + const [{ reader }] = createReader({ + integrations: { + azureBlobStorage: [ + { + accountName: 'test-account', + accountKey: 'test-key', + }, + ], + }, + }); + + beforeEach(() => { + jest.clearAllMocks(); + const mockBlobs = [ + { + name: 'prefix/file1.yaml', + properties: { + lastModified: new Date('2025-01-01T00:00:00Z'), + }, + }, + { + name: 'prefix/subdir/file2.yaml', + properties: { + lastModified: new Date('2024-01-01T00:00:00Z'), + }, + }, + ]; + + mockBlobDownload.mockResolvedValue({ + readableStreamBody: Readable.from( + Buffer.from('site_name: Test Azure Blob'), + ), + }); + + mockListBlobsFlat.mockReturnValue({ + [Symbol.asyncIterator]: async function* generateBlobs() { + for (const blob of mockBlobs) { + yield blob; + } + }, + }); + }); + + it('returns contents of blobs in a container', async () => { + const response = await reader.readTree( + 'https://test-account.blob.core.windows.net/test-container/prefix', + ); + const files = await response.files(); + + expect(files).toHaveLength(2); + const file1Content = await files[0].content(); + expect(file1Content.toString()).toBe('site_name: Test Azure Blob'); + }); + }); + + describe('search', () => { + const [{ reader }] = createReader({ + integrations: { + azureBlobStorage: [ + { + accountName: 'test-account', + accountKey: 'test-key', + }, + ], + }, + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should return a file when given an exact valid url', async () => { + mockBlobDownload.mockResolvedValue({ + readableStreamBody: Readable.from( + Buffer.from('site_name: Test Azure Blob'), + ), + etag: '"etag"', + lastModified: new Date('2025-01-01T00:00:00Z'), + }); + + const data = await reader.search( + 'https://test-account.blob.core.windows.net/test-container/test-file.yaml', + ); + + expect(data.etag).toBe('"etag"'); + expect(data.files.length).toBe(1); + expect(data.files[0].url).toBe( + 'https://test-account.blob.core.windows.net/test-container/test-file.yaml', + ); + expect((await data.files[0].content()).toString()).toEqual( + 'site_name: Test Azure Blob', + ); + }); + + it('should handle Azure SDK errors from readUrl', async () => { + mockBlobDownload.mockRejectedValue(new Error('Blob not found')); + + await expect( + reader.search( + 'https://test-account.blob.core.windows.net/test-container/missing.yaml', + ), + ).rejects.toThrow('Could not retrieve file from Azure Blob Storage'); + }); + + it('throws if given URL with wildcard', async () => { + await expect( + reader.search( + 'https://test-account.blob.core.windows.net/test-container/test-*.yaml', + ), + ).rejects.toThrow( + 'Glob search pattern not implemented for AzureBlobStorageUrlReader', + ); + }); + }); +}); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureBlobStorageUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureBlobStorageUrlReader.ts index e04e2c5b47..ca5f49405f 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureBlobStorageUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureBlobStorageUrlReader.ts @@ -21,7 +21,11 @@ import { StorageSharedKeyCredential, } from '@azure/storage-blob'; import { ReaderFactory, ReadTreeResponseFactory } from './types'; -import { ForwardedError, NotModifiedError } from '@backstage/errors'; +import { + assertError, + ForwardedError, + NotModifiedError, +} from '@backstage/errors'; import { Readable } from 'stream'; import { relative } from 'path/posix'; import { ReadUrlResponseFactory } from './ReadUrlResponseFactory'; @@ -37,6 +41,7 @@ import { UrlReaderServiceReadTreeResponse, UrlReaderServiceReadUrlOptions, UrlReaderServiceReadUrlResponse, + UrlReaderServiceSearchOptions, UrlReaderServiceSearchResponse, } from '@backstage/backend-plugin-api'; @@ -86,13 +91,23 @@ export class AzureBlobStorageUrlReader implements UrlReaderService { // private readonly blobServiceClient: BlobServiceClient; + private readonly credsManager: AzureCredentialsManager; + private readonly integration: AzureBlobStorageIntergation; + private readonly deps: { + treeResponseFactory: ReadTreeResponseFactory; + }; + constructor( - private readonly credsManager: AzureCredentialsManager, - private readonly integration: AzureBlobStorageIntergation, - private readonly deps: { + credsManager: AzureCredentialsManager, + integration: AzureBlobStorageIntergation, + deps: { treeResponseFactory: ReadTreeResponseFactory; }, - ) {} + ) { + this.credsManager = credsManager; + this.integration = integration; + this.deps = deps; + } private async createContainerClient( containerName: string, @@ -190,13 +205,13 @@ export class AzureBlobStorageUrlReader implements UrlReaderService { const { path, container } = parseUrl(url); const containerClient = await this.createContainerClient(container); - const blobs = containerClient.listBlobsFlat({ prefix: path }); const responses = []; for await (const blob of blobs) { const blobClient = containerClient.getBlobClient(blob.name); + const downloadBlockBlobResponse = await blobClient.download( undefined, undefined, @@ -221,8 +236,35 @@ export class AzureBlobStorageUrlReader implements UrlReaderService { } } - async search(): Promise { - throw new Error('AzureBlobStorageUrlReader does not implement search'); + async search( + url: string, + options?: UrlReaderServiceSearchOptions, + ): Promise { + const { path } = parseUrl(url); + + if (path.match(/[*?]/)) { + throw new Error( + 'Glob search pattern not implemented for AzureBlobStorageUrlReader', + ); + } + + try { + const data = await this.readUrl(url, options); + + return { + files: [ + { + url: url, + content: data.buffer, + lastModifiedAt: data.lastModifiedAt, + }, + ], + etag: data.etag ?? '', + }; + } catch (error) { + assertError(error); + throw error; + } } toString() { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts index 12a7ae8093..ee0eac6b4e 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.test.ts @@ -214,7 +214,7 @@ describe('AzureUrlReader', () => { res( ctx.status(200), ctx.set('Content-Type', 'application/zip'), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( @@ -324,7 +324,7 @@ describe('AzureUrlReader', () => { res( ctx.status(200), ctx.set('Content-Type', 'application/zip'), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.ts index 465ec2326c..66fd1cc95a 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.ts @@ -62,13 +62,22 @@ export class AzureUrlReader implements UrlReaderService { }); }; + private readonly integration: AzureIntegration; + private readonly deps: { + treeResponseFactory: ReadTreeResponseFactory; + credentialsProvider: AzureDevOpsCredentialsProvider; + }; + constructor( - private readonly integration: AzureIntegration, - private readonly deps: { + integration: AzureIntegration, + deps: { treeResponseFactory: ReadTreeResponseFactory; credentialsProvider: AzureDevOpsCredentialsProvider; }, - ) {} + ) { + this.integration = integration; + this.deps = deps; + } async read(url: string): Promise { const response = await this.readUrl(url); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts index d2d0d28d76..89ff98ba27 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.test.ts @@ -271,7 +271,7 @@ describe('BitbucketCloudUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-12ab34cd56ef.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( @@ -399,7 +399,7 @@ describe('BitbucketCloudUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-12ab34cd56ef.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.ts index c968420a5e..3a228f1e9c 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader.ts @@ -59,10 +59,15 @@ export class BitbucketCloudUrlReader implements UrlReaderService { }); }; + private readonly integration: BitbucketCloudIntegration; + private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }; + constructor( - private readonly integration: BitbucketCloudIntegration, - private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }, + integration: BitbucketCloudIntegration, + deps: { treeResponseFactory: ReadTreeResponseFactory }, ) { + this.integration = integration; + this.deps = deps; const { host, username, appPassword } = integration.config; if (username && !appPassword) { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts index 5e82246298..1ab6342225 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.test.ts @@ -71,7 +71,7 @@ describe('BitbucketServerUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock.tgz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( @@ -157,7 +157,7 @@ describe('BitbucketServerUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock.tgz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( @@ -216,7 +216,7 @@ describe('BitbucketServerUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock.tgz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.ts index 3482bdf4bd..aba28b4fd7 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader.ts @@ -58,10 +58,16 @@ export class BitbucketServerUrlReader implements UrlReaderService { }); }; + private readonly integration: BitbucketServerIntegration; + private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }; + constructor( - private readonly integration: BitbucketServerIntegration, - private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }, - ) {} + integration: BitbucketServerIntegration, + deps: { treeResponseFactory: ReadTreeResponseFactory }, + ) { + this.integration = integration; + this.deps = deps; + } async read(url: string): Promise { const response = await this.readUrl(url); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts index 29217ea1f5..bd1a2d5912 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.test.ts @@ -130,6 +130,27 @@ describe('BitbucketUrlReader', () => { expect(buffer.toString()).toBe('foo'); }); + it('should be able to readUrl using provided token', async () => { + worker.use( + rest.get( + 'https://api.bitbucket.org/2.0/repositories/backstage-verification/test-template/src/master/template.yaml', + (req, res, ctx) => { + expect(req.headers.get('authorization')).toBe( + 'Bearer manual-token', + ); + return res(ctx.status(200), ctx.body('foo')); + }, + ), + ); + + const result = await bitbucketProcessor.readUrl( + 'https://bitbucket.org/backstage-verification/test-template/src/master/template.yaml', + { token: 'manual-token' }, + ); + const buffer = await result.buffer(); + expect(buffer.toString()).toBe('foo'); + }); + it('should be able to readUrl via stream without ETag', async () => { worker.use( rest.get( @@ -324,7 +345,7 @@ describe('BitbucketUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-12ab34cd56ef.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( @@ -347,7 +368,7 @@ describe('BitbucketUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock.tgz', ), - ctx.body(privateBitbucketRepoBuffer), + ctx.body(new Uint8Array(privateBitbucketRepoBuffer)), ), ), rest.get( @@ -491,7 +512,7 @@ describe('BitbucketUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-12ab34cd56ef.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( @@ -562,7 +583,7 @@ describe('BitbucketUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock.tgz', ), - ctx.body(privateBitbucketRepoBuffer), + ctx.body(new Uint8Array(privateBitbucketRepoBuffer)), ), ), rest.get( diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.ts index 4c6de31aa4..8c8843d7e9 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader.ts @@ -69,11 +69,16 @@ export class BitbucketUrlReader implements UrlReaderService { }); }; + private readonly integration: BitbucketIntegration; + private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }; + constructor( - private readonly integration: BitbucketIntegration, + integration: BitbucketIntegration, logger: LoggerService, - private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }, + deps: { treeResponseFactory: ReadTreeResponseFactory }, ) { + this.integration = integration; + this.deps = deps; const { host, token, username, appPassword } = integration.config; const replacement = host === 'bitbucket.org' ? 'bitbucketCloud' : 'bitbucketServer'; @@ -93,13 +98,27 @@ export class BitbucketUrlReader implements UrlReaderService { return response.buffer(); } + private getCredentials = async (options?: { + token?: string; + }): Promise<{ headers: Record }> => { + if (options?.token) { + return { + headers: { + Authorization: `Bearer ${options.token}`, + }, + }; + } + + return await getBitbucketRequestOptions(this.integration.config); + }; + async readUrl( url: string, options?: UrlReaderServiceReadUrlOptions, ): Promise { const { etag, lastModifiedAfter, signal } = options ?? {}; const bitbucketUrl = getBitbucketFileFetchUrl(url, this.integration.config); - const requestOptions = getBitbucketRequestOptions(this.integration.config); + const requestOptions = await this.getCredentials(options); let response: Response; try { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts index 246c07631b..69c834201c 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.test.ts @@ -291,7 +291,7 @@ describe.skip('GerritUrlReader', () => { 'content-disposition', 'attachment; filename=web-refs/heads/master.tar.gz', ), - ctx.body(repoArchiveBuffer), + ctx.body(new Uint8Array(repoArchiveBuffer)), ), ), rest.get( @@ -304,7 +304,7 @@ describe.skip('GerritUrlReader', () => { 'content-disposition', 'attachment; filename=web-refs/heads/master-docs.tar.gz', ), - ctx.body(repoArchiveDocsBuffer), + ctx.body(new Uint8Array(repoArchiveDocsBuffer)), ), ), rest.get( @@ -317,7 +317,7 @@ describe.skip('GerritUrlReader', () => { 'content-disposition', 'attachment; filename=web-refs/heads/master.tar.gz', ), - ctx.body(repoArchiveBuffer), + ctx.body(new Uint8Array(repoArchiveBuffer)), ), ), ); @@ -330,7 +330,10 @@ describe.skip('GerritUrlReader', () => { it('reads the wanted files correctly using gitiles.', async () => { worker.use( rest.get(branchAPIUrl, (_, res, ctx) => { - return res(ctx.status(200), ctx.body(branchAPIresponse)); + return res( + ctx.status(200), + ctx.body(new Uint8Array(branchAPIresponse)), + ); }), ); @@ -353,7 +356,10 @@ describe.skip('GerritUrlReader', () => { it('throws NotModifiedError for matching etags.', async () => { worker.use( rest.get(branchAPIUrl, (_, res, ctx) => { - return res(ctx.status(200), ctx.body(branchAPIresponse)); + return res( + ctx.status(200), + ctx.body(new Uint8Array(branchAPIresponse)), + ); }), ); @@ -389,7 +395,10 @@ describe.skip('GerritUrlReader', () => { it('should returns wanted files with a subpath using gitiles', async () => { worker.use( rest.get(branchAPIUrl, (_, res, ctx) => { - return res(ctx.status(200), ctx.body(branchAPIresponse)); + return res( + ctx.status(200), + ctx.body(new Uint8Array(branchAPIresponse)), + ); }), ); @@ -462,7 +471,7 @@ describe.skip('GerritUrlReader', () => { ctx.status(200), ctx.set('Content-Type', 'application/json'), ctx.set('content-disposition', 'attachment'), - ctx.body(treeRecursiveResponse), + ctx.body(new Uint8Array(treeRecursiveResponse)), ); } @@ -522,7 +531,10 @@ describe.skip('GerritUrlReader', () => { it('reads the wanted files correctly using gitiles.', async () => { worker.use( rest.get(branchAPIUrl, (_, res, ctx) => { - return res(ctx.status(200), ctx.body(branchAPIresponse)); + return res( + ctx.status(200), + ctx.body(new Uint8Array(branchAPIresponse)), + ); }), ); @@ -549,7 +561,10 @@ describe.skip('GerritUrlReader', () => { it('throws NotModifiedError for matching etags.', async () => { worker.use( rest.get(branchAPIUrl, (_, res, ctx) => { - return res(ctx.status(200), ctx.body(branchAPIresponse)); + return res( + ctx.status(200), + ctx.body(new Uint8Array(branchAPIresponse)), + ); }), ); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.ts index bec062ee8b..9facb613d4 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader.ts @@ -84,10 +84,16 @@ export class GerritUrlReader implements UrlReaderService { }); }; + private readonly integration: GerritIntegration; + private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }; + constructor( - private readonly integration: GerritIntegration, - private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }, - ) {} + integration: GerritIntegration, + deps: { treeResponseFactory: ReadTreeResponseFactory }, + ) { + this.integration = integration; + this.deps = deps; + } async read(url: string): Promise { const response = await this.readUrl(url); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts index 0adbc3381f..9242cd2f9b 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.test.ts @@ -279,7 +279,7 @@ describe('GiteaUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ); }, ), diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.ts index bce033c2ae..b1b4b79c34 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader.ts @@ -62,12 +62,20 @@ export class GiteaUrlReader implements UrlReaderService { }); }; + private readonly integration: GiteaIntegration; + private readonly deps: { + treeResponseFactory: ReadTreeResponseFactory; + }; + constructor( - private readonly integration: GiteaIntegration, - private readonly deps: { + integration: GiteaIntegration, + deps: { treeResponseFactory: ReadTreeResponseFactory; }, - ) {} + ) { + this.integration = integration; + this.deps = deps; + } async read(url: string): Promise { const response = await this.readUrl(url); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts index 861b3ad7cb..fe832e124f 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.test.ts @@ -373,7 +373,7 @@ describe('GithubUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-etag123.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( @@ -390,7 +390,7 @@ describe('GithubUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-etag123.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( @@ -480,7 +480,7 @@ describe('GithubUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-etag123.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ); }, ), @@ -531,7 +531,7 @@ describe('GithubUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-etag123.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ); }, ), @@ -720,7 +720,7 @@ describe('GithubUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-etag123.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), rest.get( @@ -733,7 +733,7 @@ describe('GithubUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock-etag123.tar.gz', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ), ), ); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts index fe0bd08fec..7846262da3 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader.ts @@ -77,13 +77,21 @@ export class GithubUrlReader implements UrlReaderService { }); }; + private readonly integration: GithubIntegration; + private readonly deps: { + treeResponseFactory: ReadTreeResponseFactory; + credentialsProvider: GithubCredentialsProvider; + }; + constructor( - private readonly integration: GithubIntegration, - private readonly deps: { + integration: GithubIntegration, + deps: { treeResponseFactory: ReadTreeResponseFactory; credentialsProvider: GithubCredentialsProvider; }, ) { + this.integration = integration; + this.deps = deps; if (!integration.config.apiBaseUrl && !integration.config.rawBaseUrl) { throw new Error( `GitHub integration '${integration.title}' must configure an explicit apiBaseUrl or rawBaseUrl`, diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts index b7ccf165ad..c5ce323c54 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts @@ -108,9 +108,6 @@ describe('GitlabUrlReader', () => { config: createConfig(), response: expect.objectContaining({ url: 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', - headers: expect.objectContaining({ - 'private-token': '', - }), }), }, { @@ -119,7 +116,7 @@ describe('GitlabUrlReader', () => { response: expect.objectContaining({ url: 'https://gitlab.example.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', headers: expect.objectContaining({ - 'private-token': '0123456789', + authorization: 'Bearer 0123456789', }), }), }, @@ -252,10 +249,10 @@ describe('GitlabUrlReader', () => { it('should return the file when using a user token', async () => { worker.use( rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); @@ -313,7 +310,7 @@ describe('GitlabUrlReader', () => { 'content-disposition', 'attachment; filename="mock-main-sha123abc.zip"', ), - ctx.body(archiveBuffer), + ctx.body(new Uint8Array(archiveBuffer)), ), ), rest.get( @@ -391,7 +388,7 @@ describe('GitlabUrlReader', () => { 'content-disposition', 'attachment; filename="mock-main-sha123abc.zip"', ), - ctx.body(archiveBuffer), + ctx.body(new Uint8Array(archiveBuffer)), ), ), ); @@ -440,7 +437,7 @@ describe('GitlabUrlReader', () => { 'content-disposition', 'attachment; filename="mock-main-sha123abc.zip"', ), - ctx.body(archiveBuffer), + ctx.body(new Uint8Array(archiveBuffer)), ), ), ); @@ -571,10 +568,10 @@ describe('GitlabUrlReader', () => { it('should return the file when using a user token', async () => { worker.use( rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); @@ -635,7 +632,7 @@ describe('GitlabUrlReader', () => { 'content-disposition', `attachment; filename="${filename}"`, ), - ctx.body(body), + ctx.body(new Uint8Array(body)), ); }, ), @@ -673,6 +670,17 @@ describe('GitlabUrlReader', () => { ); }); + it('works when there are multiple globs', async () => { + const result = await gitlabProcessor.search( + 'https://gitlab.com/backstage/mock/tree/main/**/docs/**/index.*', + ); + expect(result.etag).toBe('sha123abc'); + expect(result.files.length).toBe(1); + expect(result.files[0].url).toBe( + 'https://gitlab.com/backstage/mock/tree/main/docs/index.md', + ); + }); + it('works for the naive case', async () => { const result = await gitlabProcessor.search( 'https://gitlab.com/backstage/mock/tree/main/**/index.*', @@ -737,10 +745,10 @@ describe('GitlabUrlReader', () => { (_, res, ctx) => res(ctx.status(200), ctx.json({ id: 12345 })), ), rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); @@ -798,10 +806,10 @@ describe('GitlabUrlReader', () => { (_, res, ctx) => res(ctx.status(404)), ), rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); @@ -857,21 +865,19 @@ describe('GitlabUrlReader', () => { beforeEach(() => { worker.use( rest.get('*/api/v4/projects/group%2Fproject', (req, res, ctx) => { - // the private-token header must be included on API calls - if (req.headers.get('private-token') !== 'gl-dummy-token') { + if (req.headers.get('authorization') !== 'Bearer gl-dummy-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); }), rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - // the private-token header must be included on API calls - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts index 3e5497a307..ee290e31e6 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts @@ -63,10 +63,16 @@ export class GitlabUrlReader implements UrlReaderService { }); }; + private readonly integration: GitLabIntegration; + private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }; + constructor( - private readonly integration: GitLabIntegration, - private readonly deps: { treeResponseFactory: ReadTreeResponseFactory }, - ) {} + integration: GitLabIntegration, + deps: { treeResponseFactory: ReadTreeResponseFactory }, + ) { + this.integration = integration; + this.deps = deps; + } async read(url: string): Promise { const response = await this.readUrl(url); @@ -313,14 +319,10 @@ export class GitlabUrlReader implements UrlReaderService { */ private getStaticPart(globPattern: string) { const segments = globPattern.split('/'); - let i = segments.length; - while ( - i > 0 && - new Minimatch(segments.slice(0, i).join('/')).match(globPattern) - ) { - i--; - } - return segments.slice(0, i).join('/'); + const globIndex = segments.findIndex(segment => segment.match(/[*?]/)); + return globIndex === -1 + ? globPattern + : segments.slice(0, globIndex).join('/'); } toString() { @@ -340,10 +342,7 @@ export class GitlabUrlReader implements UrlReaderService { ); } // Default to the old behavior of assuming the url is for a file - return getGitLabFileFetchUrl(target, { - ...this.integration.config, - ...(token && { token }), - }); + return getGitLabFileFetchUrl(target, this.integration.config, token); } // convert urls of the form: @@ -398,6 +397,12 @@ export class GitlabUrlReader implements UrlReaderService { ); const data = await result.json(); if (!result.ok) { + if (result.status === 401) { + throw new Error( + 'GitLab Error: 401 - Unauthorized. The access token used is either expired, or does not have permission to read the project', + ); + } + throw new Error(`Gitlab error: ${data.error}, ${data.error_description}`); } return Number(data.id); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GoogleGcsUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GoogleGcsUrlReader.ts index 36f2e183c7..0bc5add43f 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GoogleGcsUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GoogleGcsUrlReader.ts @@ -88,10 +88,16 @@ export class GoogleGcsUrlReader implements UrlReaderService { return [{ reader, predicate }]; }; + private readonly integration: GoogleGcsIntegrationConfig; + private readonly storage: GoogleCloud.Storage; + constructor( - private readonly integration: GoogleGcsIntegrationConfig, - private readonly storage: GoogleCloud.Storage, - ) {} + integration: GoogleGcsIntegrationConfig, + storage: GoogleCloud.Storage, + ) { + this.integration = integration; + this.storage = storage; + } private readStreamFromUrl(url: string): Readable { const { bucket, key } = parseURL(url); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts index 37dab25883..33a0e1a088 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.test.ts @@ -215,7 +215,7 @@ describe('HarnessUrlReader', () => { 'content-disposition', 'attachment; filename=backstage-mock.zip', ), - ctx.body(repoBuffer), + ctx.body(new Uint8Array(repoBuffer)), ); }, ), diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.ts index bc2e0dab11..ebc9b7be83 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader.ts @@ -64,12 +64,20 @@ export class HarnessUrlReader implements UrlReaderService { }); }; + private readonly integration: HarnessIntegration; + private readonly deps: { + treeResponseFactory: ReadTreeResponseFactory; + }; + constructor( - private readonly integration: HarnessIntegration, - private readonly deps: { + integration: HarnessIntegration, + deps: { treeResponseFactory: ReadTreeResponseFactory; }, - ) {} + ) { + this.integration = integration; + this.deps = deps; + } async read(url: string): Promise { const response = await this.readUrl(url); return response.buffer(); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.ts index a8f187d7b8..816b734b28 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.ts @@ -36,7 +36,11 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory { ); } - constructor(private readonly workDir: string) {} + private readonly workDir: string; + + constructor(workDir: string) { + this.workDir = workDir; + } async fromTarArchive( options: ReadTreeResponseFactoryOptions & { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadableArrayResponse.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadableArrayResponse.ts index 6b39672ddd..095b58edb1 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadableArrayResponse.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ReadableArrayResponse.ts @@ -35,12 +35,13 @@ const pipeline = promisify(pipelineCb); */ export class ReadableArrayResponse implements UrlReaderServiceReadTreeResponse { private read = false; + private readonly stream: FromReadableArrayOptions; + private readonly workDir: string; + public readonly etag: string; - constructor( - private readonly stream: FromReadableArrayOptions, - private readonly workDir: string, - public readonly etag: string, - ) { + constructor(stream: FromReadableArrayOptions, workDir: string, etag: string) { + this.stream = stream; + this.workDir = workDir; this.etag = etag; } diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/TarArchiveResponse.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/TarArchiveResponse.ts index 9fb1d3fe7e..3102137f64 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/TarArchiveResponse.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/TarArchiveResponse.ts @@ -37,15 +37,27 @@ const pipeline = promisify(pipelineCb); */ export class TarArchiveResponse implements UrlReaderServiceReadTreeResponse { private read = false; + private readonly stream: Readable; + private readonly subPath: string; + private readonly workDir: string; + public readonly etag: string; + private readonly filter?: (path: string, info: { size: number }) => boolean; + private readonly stripFirstDirectory: boolean; constructor( - private readonly stream: Readable, - private readonly subPath: string, - private readonly workDir: string, - public readonly etag: string, - private readonly filter?: (path: string, info: { size: number }) => boolean, - private readonly stripFirstDirectory: boolean = true, + stream: Readable, + subPath: string, + workDir: string, + etag: string, + filter?: (path: string, info: { size: number }) => boolean, + stripFirstDirectory: boolean = true, ) { + this.stream = stream; + this.subPath = subPath; + this.workDir = workDir; + this.etag = etag; + this.filter = filter; + this.stripFirstDirectory = stripFirstDirectory; if (subPath) { if (!subPath.endsWith('/')) { this.subPath += '/'; diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ZipArchiveResponse.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ZipArchiveResponse.ts index 5c0b6f77bc..2d5a743172 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ZipArchiveResponse.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/tree/ZipArchiveResponse.ts @@ -32,14 +32,24 @@ import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; */ export class ZipArchiveResponse implements UrlReaderServiceReadTreeResponse { private read = false; + private readonly stream: Readable; + private readonly subPath: string; + private readonly workDir: string; + public readonly etag: string; + private readonly filter?: (path: string, info: { size: number }) => boolean; constructor( - private readonly stream: Readable, - private readonly subPath: string, - private readonly workDir: string, - public readonly etag: string, - private readonly filter?: (path: string, info: { size: number }) => boolean, + stream: Readable, + subPath: string, + workDir: string, + etag: string, + filter?: (path: string, info: { size: number }) => boolean, ) { + this.stream = stream; + this.subPath = subPath; + this.workDir = workDir; + this.etag = etag; + this.filter = filter; if (subPath) { if (!subPath.endsWith('/')) { this.subPath += '/'; diff --git a/packages/backend-defaults/src/lib/RateLimitStoreFactory.test.ts b/packages/backend-defaults/src/lib/RateLimitStoreFactory.test.ts new file mode 100644 index 0000000000..684c204cb8 --- /dev/null +++ b/packages/backend-defaults/src/lib/RateLimitStoreFactory.test.ts @@ -0,0 +1,68 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { mockServices } from '@backstage/backend-test-utils'; +import { RateLimitStoreFactory } from './RateLimitStoreFactory.ts'; +import { RedisStore } from 'rate-limit-redis'; + +jest.mock('@keyv/redis', () => { + const Actual = jest.requireActual('@keyv/redis'); + return { + ...Actual, + __esModule: true, + default: jest.fn(() => { + return { + getClient: jest.fn(() => ({ + sendCommand: jest.fn().mockReturnValue('mock'), + })), + }; + }), + }; +}); + +describe('CacheRateLimitStoreFactory', () => { + afterEach(jest.clearAllMocks); + + it('should return undefined store with auto configuration if redis is not available', () => { + const config = mockServices.rootConfig({ + data: { + backend: { + rateLimit: { + store: undefined, + }, + }, + }, + }); + const store = RateLimitStoreFactory.create({ config }); + expect(store).toBeUndefined(); + }); + + it('should return redis store if configured explicitly', async () => { + const config = mockServices.rootConfig({ + data: { + backend: { + rateLimit: { + store: { + type: 'redis', + connection: 'redis://localhost:6379', + }, + }, + }, + }, + }); + const store = RateLimitStoreFactory.create({ config }); + expect(store).toBeInstanceOf(RedisStore); + }); +}); diff --git a/packages/backend-defaults/src/lib/RateLimitStoreFactory.ts b/packages/backend-defaults/src/lib/RateLimitStoreFactory.ts new file mode 100644 index 0000000000..9df6f03225 --- /dev/null +++ b/packages/backend-defaults/src/lib/RateLimitStoreFactory.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Config } from '@backstage/config'; +import type { Store } from 'express-rate-limit'; +import { RedisStore } from 'rate-limit-redis'; + +/** + * Creates a store for `express-rate-limit` based on the configuration. + * + * @internal + */ +export class RateLimitStoreFactory { + static create(options: { + config: Config; + prefix?: string; + }): Store | undefined { + const { config, prefix } = options; + const store = config.getOptionalConfig('backend.rateLimit.store'); + if (!store) { + return undefined; + } + const type = store.getString('type'); + switch (type) { + case 'redis': + return this.redis({ store, prefix }); + case 'memory': + default: + return undefined; + } + } + + private static redis(options: { store: Config; prefix?: string }): Store { + const { store, prefix } = options; + const connectionString = store.getString('connection'); + const KeyvRedis = require('@keyv/redis').default; + const keyv = new KeyvRedis(connectionString); + return new RedisStore({ + prefix, + sendCommand: async (...args: string[]) => { + const client = await keyv.getClient(); + return client.sendCommand(args); + }, + }); + } +} diff --git a/packages/backend-defaults/src/lib/rateLimitMiddleware.ts b/packages/backend-defaults/src/lib/rateLimitMiddleware.ts new file mode 100644 index 0000000000..57163b5908 --- /dev/null +++ b/packages/backend-defaults/src/lib/rateLimitMiddleware.ts @@ -0,0 +1,81 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { RequestHandler } from 'express'; +import { rateLimit, Store } from 'express-rate-limit'; +import { Config, readDurationFromConfig } from '@backstage/config'; +import { durationToMilliseconds } from '@backstage/types'; + +export const rateLimitMiddleware = (options: { + store?: Store; + config?: Config; +}): RequestHandler => { + const { store, config } = options; + let windowMs: number = 60000; + if (config && config.has('window')) { + const windowDuration = readDurationFromConfig(config, { + key: 'window', + }); + windowMs = durationToMilliseconds(windowDuration); + } + const limit = config?.getOptionalNumber('incomingRequestLimit'); + const ipAllowList = config?.getOptionalStringArray('ipAllowList') ?? [ + '127.0.0.1', + '0:0:0:0:0:0:0:1', + '::1', + ]; + const skipSuccessfulRequests = config?.getOptionalBoolean( + 'skipSuccessfulRequests', + ); + const skipFailedRequests = config?.getOptionalBoolean('skipFailedRequests'); + const passOnStoreError = config?.getOptionalBoolean('passOnStoreError'); + + return rateLimit({ + windowMs, + limit, + skipSuccessfulRequests, + message: { + error: { + name: 'Error', + message: `Too many requests, please try again later`, + }, + response: { + statusCode: 429, + }, + }, + statusCode: 429, + skipFailedRequests, + passOnStoreError: passOnStoreError, + keyGenerator(req, _res): string { + if (!req.ip) { + return req.socket.remoteAddress!; + } + return req.ip; + }, + skip: (req, _res) => { + return ( + Boolean(req.ip && ipAllowList.includes(req.ip)) || + Boolean( + req.socket.remoteAddress && + ipAllowList.includes(req.socket.remoteAddress), + ) + ); + }, + validate: { + trustProxy: false, + }, + store, + }); +}; diff --git a/packages/backend-defaults/src/setupTests.ts b/packages/backend-defaults/src/setupTests.ts index c9745b280d..7d47eea453 100644 --- a/packages/backend-defaults/src/setupTests.ts +++ b/packages/backend-defaults/src/setupTests.ts @@ -21,5 +21,5 @@ import { Settings } from 'luxon'; Settings.throwOnInvalid = true; TestDatabases.setDefaults({ - ids: ['MYSQL_8', 'POSTGRES_17', 'POSTGRES_13', 'SQLITE_3'], + ids: ['MYSQL_8', 'POSTGRES_18', 'POSTGRES_14', 'SQLITE_3'], }); diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index bf49582494..6e5ff62fd1 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,411 @@ # @backstage/backend-dynamic-feature-service +## 0.7.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/backend-openapi-utils@0.6.3-next.1 + - @backstage/plugin-app-node@0.1.39-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-scaffolder-node@0.12.1-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## 0.7.6-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-catalog-backend@3.1.3-next.0 + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/plugin-events-backend@0.5.8-next.0 + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config-loader@1.10.6-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/cli-node@0.2.15-next.0 + - @backstage/plugin-scaffolder-node@0.12.1-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/backend-openapi-utils@0.6.3-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-app-node@0.1.39-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-search-common@1.2.21-next.0 + +## 0.7.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.2 + - @backstage/backend-defaults@0.13.0 + - @backstage/plugin-scaffolder-node@0.12.0 + - @backstage/config-loader@1.10.5 + - @backstage/config@1.3.5 + - @backstage/backend-openapi-utils@0.6.2 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-app-node@0.1.38 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-events-backend@0.5.7 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-search-common@1.2.20 + +## 0.7.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/plugin-app-node@0.1.38-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-catalog-backend@3.1.1-next.1 + - @backstage/plugin-events-backend@0.5.7-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.1 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/backend-openapi-utils@0.6.2-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + - @backstage/cli-node@0.2.14 + - @backstage/plugin-search-common@1.2.20-next.0 + +## 0.7.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.1-next.0 + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-scaffolder-node@0.12.0-next.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-backend@0.5.6 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.14 + - @backstage/config@1.3.3 + - @backstage/config-loader@1.10.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-app-node@0.1.37 + - @backstage/plugin-events-node@0.4.15 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## 0.7.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/config-loader@1.10.3 + - @backstage/plugin-catalog-backend@3.1.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-backend@0.5.6 + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-openapi-utils@0.6.1 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-app-node@0.1.37 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-scaffolder-node@0.11.1 + - @backstage/plugin-search-backend-node@1.3.15 + +## 0.7.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + - @backstage/backend-defaults@0.12.1-next.1 + - @backstage/plugin-auth-node@0.6.7-next.1 + - @backstage/plugin-catalog-backend@3.0.2-next.1 + - @backstage/plugin-app-node@0.1.37-next.1 + +## 0.7.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.2-next.0 + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-scaffolder-node@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/plugin-events-backend@0.5.6-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + - @backstage/backend-openapi-utils@0.6.1-next.0 + - @backstage/plugin-app-node@0.1.37-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## 0.7.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.6.0 + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-scaffolder-node@0.11.0 + - @backstage/plugin-catalog-backend@3.0.1 + - @backstage/cli-node@0.2.14 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-events-backend@0.5.5 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-app-node@0.1.36 + - @backstage/plugin-events-node@0.4.14 + +## 0.7.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/backend-openapi-utils@0.6.0-next.0 + - @backstage/plugin-scaffolder-node@0.11.0-next.0 + - @backstage/plugin-catalog-backend@3.0.1-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-events-backend@0.5.5-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.2 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.36-next.0 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-common@1.2.19 + +## 0.7.2 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- 3d61c36: Fix wrong imports which lead to module initialization failures when enabling dynamic plugins. +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0 + - @backstage/config-loader@1.10.2 + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-scaffolder-node@0.10.0 + - @backstage/backend-openapi-utils@0.5.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-app-node@0.1.35 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-events-backend@0.5.4 + - @backstage/plugin-events-node@0.4.13 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-search-common@1.2.19 + +## 0.7.2-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.10.0-next.2 + +## 0.7.2-next.1 + +### Patch Changes + +- 3507fcd: Just some more circular dep cleanup +- 3d61c36: Fix wrong imports which lead to module initialization failures when enabling dynamic plugins. +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/plugin-app-node@0.1.35-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-catalog-backend@3.0.0-next.1 + - @backstage/plugin-events-backend@0.5.4-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.1 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-search-common@1.2.19-next.0 + - @backstage/backend-openapi-utils@0.5.5-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## 0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## 0.7.1 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## 0.7.1-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/plugin-catalog-backend@2.0.1-next.2 + - @backstage/plugin-scaffolder-node@0.9.0-next.2 + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34-next.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-events-backend@0.5.3-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## 0.7.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-backend@2.0.1-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-openapi-utils@0.5.4-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34-next.1 + - @backstage/plugin-events-backend@0.5.3-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-search-common@1.2.18 + +## 0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.8.3-next.0 + - @backstage/plugin-catalog-backend@2.0.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-events-backend@0.5.3-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + - @backstage/backend-openapi-utils@0.5.4-next.0 + - @backstage/plugin-app-node@0.1.34-next.0 + +## 0.7.0 + +### Minor Changes + +- 10f693c: **BREAKING** Removed support for the legacy backend, please migrate to the new backend system + +### Patch Changes + +- 72d019d: Fixed various typos. + `FrontendRemoteResolver`'s misspelled `getAdditionaRemoteInfo` has been deprecated. Use the correct spelling `getAdditionalRemoteInfo` instead. +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.0 + - @backstage/backend-defaults@0.10.0 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/plugin-scaffolder-node@0.8.2 + - @backstage/config-loader@1.10.1 + - @backstage/backend-openapi-utils@0.5.3 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.33 + - @backstage/plugin-events-backend@0.5.2 + - @backstage/plugin-events-node@0.4.11 + - @backstage/plugin-search-backend-node@1.3.11 + - @backstage/plugin-search-common@1.2.18 + ## 0.7.0-next.3 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/knip-report.md b/packages/backend-dynamic-feature-service/knip-report.md index 79f2435433..01af03f52e 100644 --- a/packages/backend-dynamic-feature-service/knip-report.md +++ b/packages/backend-dynamic-feature-service/knip-report.md @@ -1,8 +1,17 @@ # Knip report -## Unused dependencies (1) +## Unused dependencies (10) -| Name | Location | Severity | -| :------------------------------ | :----------- | :------- | -| @backstage/plugin-search-common | package.json | error | +| Name | Location | Severity | +| :------------------------------------ | :----------- | :------- | +| @backstage/plugin-search-backend-node | packages/backend-dynamic-feature-service/package.json | error | +| @backstage/plugin-permission-common | packages/backend-dynamic-feature-service/package.json | error | +| @backstage/plugin-catalog-backend | packages/backend-dynamic-feature-service/package.json | error | +| @backstage/plugin-permission-node | packages/backend-dynamic-feature-service/package.json | error | +| @backstage/plugin-scaffolder-node | packages/backend-dynamic-feature-service/package.json | error | +| @backstage/plugin-events-backend | packages/backend-dynamic-feature-service/package.json | error | +| @backstage/plugin-search-common | packages/backend-dynamic-feature-service/package.json | error | +| @backstage/plugin-events-node | packages/backend-dynamic-feature-service/package.json | error | +| @backstage/plugin-auth-node | packages/backend-dynamic-feature-service/package.json | error | +| express-promise-router | packages/backend-dynamic-feature-service/package.json | error | diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index aec40551a4..c96ad18d94 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-dynamic-feature-service", - "version": "0.7.0-next.3", + "version": "0.7.6-next.1", "description": "Backstage dynamic feature service", "backstage": { "role": "node-library" diff --git a/packages/backend-dynamic-feature-service/src/loader/CommonJSModuleLoader.ts b/packages/backend-dynamic-feature-service/src/loader/CommonJSModuleLoader.ts index 28203a2019..b960e5bd38 100644 --- a/packages/backend-dynamic-feature-service/src/loader/CommonJSModuleLoader.ts +++ b/packages/backend-dynamic-feature-service/src/loader/CommonJSModuleLoader.ts @@ -36,8 +36,10 @@ export type CommonJSModuleLoaderOptions = { */ export class CommonJSModuleLoader implements ModuleLoader { private module: any; + public readonly options: CommonJSModuleLoaderOptions; - constructor(public readonly options: CommonJSModuleLoaderOptions) { + constructor(options: CommonJSModuleLoaderOptions) { + this.options = options; this.module = require('node:module'); } diff --git a/packages/backend-dynamic-feature-service/src/manager/plugin-manager.ts b/packages/backend-dynamic-feature-service/src/manager/plugin-manager.ts index 0162cbef2d..02ddd6168b 100644 --- a/packages/backend-dynamic-feature-service/src/manager/plugin-manager.ts +++ b/packages/backend-dynamic-feature-service/src/manager/plugin-manager.ts @@ -99,11 +99,18 @@ export class DynamicPluginManager implements DynamicPluginProvider { private readonly _plugins: DynamicPlugin[]; private _availablePackages: ScannedPluginPackage[]; + private readonly logger: LoggerService; + private readonly packages: ScannedPluginPackage[]; + private readonly moduleLoader: ModuleLoader; + private constructor( - private readonly logger: LoggerService, - private readonly packages: ScannedPluginPackage[], - private readonly moduleLoader: ModuleLoader, + logger: LoggerService, + packages: ScannedPluginPackage[], + moduleLoader: ModuleLoader, ) { + this.logger = logger; + this.packages = packages; + this.moduleLoader = moduleLoader; this._plugins = []; this._availablePackages = packages; } @@ -304,7 +311,11 @@ export const dynamicPluginsServiceFactory = Object.assign( ); class DynamicPluginsEnabledFeatureDiscoveryService { - constructor(private readonly dynamicPlugins: DynamicPluginProvider) {} + private readonly dynamicPlugins: DynamicPluginProvider; + + constructor(dynamicPlugins: DynamicPluginProvider) { + this.dynamicPlugins = dynamicPlugins; + } async getBackendFeatures(): Promise<{ features: Array }> { return { diff --git a/packages/backend-dynamic-feature-service/src/scanner/plugin-scanner.ts b/packages/backend-dynamic-feature-service/src/scanner/plugin-scanner.ts index 5b254908b2..a468a382d5 100644 --- a/packages/backend-dynamic-feature-service/src/scanner/plugin-scanner.ts +++ b/packages/backend-dynamic-feature-service/src/scanner/plugin-scanner.ts @@ -42,13 +42,22 @@ export class PluginScanner { private configUnsubscribe?: () => void; private rootDirectoryWatcher?: chokidar.FSWatcher; private subscribers: (() => void)[] = []; + private readonly config: Config; + private readonly logger: LoggerService; + private readonly backstageRoot: string; + private readonly preferAlpha: boolean; private constructor( - private readonly config: Config, - private readonly logger: LoggerService, - private readonly backstageRoot: string, - private readonly preferAlpha: boolean, - ) {} + config: Config, + logger: LoggerService, + backstageRoot: string, + preferAlpha: boolean, + ) { + this.config = config; + this.logger = logger; + this.backstageRoot = backstageRoot; + this.preferAlpha = preferAlpha; + } static create(options: DynamicPluginScannerOptions): PluginScanner { const scanner = new PluginScanner( diff --git a/packages/backend-dynamic-feature-service/src/schema/openapi/generated/router.ts b/packages/backend-dynamic-feature-service/src/schema/openapi/generated/router.ts index 9f1ef68a77..cf48bcfc95 100644 --- a/packages/backend-dynamic-feature-service/src/schema/openapi/generated/router.ts +++ b/packages/backend-dynamic-feature-service/src/schema/openapi/generated/router.ts @@ -18,7 +18,7 @@ // * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * // ****************************************************************** import { createValidatedOpenApiRouterFromGeneratedEndpointMap } from '@backstage/backend-openapi-utils'; -import { EndpointMap } from './'; +import { EndpointMap } from './apis'; export const spec = { openapi: '3.0.3', diff --git a/packages/backend-dynamic-feature-service/src/server/frontendRemotesServer.ts b/packages/backend-dynamic-feature-service/src/server/frontendRemotesServer.ts index f1a245b1ac..a12804ba48 100644 --- a/packages/backend-dynamic-feature-service/src/server/frontendRemotesServer.ts +++ b/packages/backend-dynamic-feature-service/src/server/frontendRemotesServer.ts @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { coreServices, createServiceFactory, createServiceRef, } from '@backstage/backend-plugin-api'; import { createRouter } from './router'; -import { dynamicPluginsServiceRef } from '@backstage/backend-dynamic-feature-service'; -import { spec } from '../schema/openapi'; +import { dynamicPluginsServiceRef } from '../manager/plugin-manager'; +import { spec } from '../schema/openapi/generated'; import { ManifestFileName } from '@module-federation/sdk'; import { RemoteInfo } from '../schema/openapi/generated/models'; import { JsonObject } from '@backstage/types'; diff --git a/packages/backend-dynamic-feature-service/src/server/router.ts b/packages/backend-dynamic-feature-service/src/server/router.ts index 61c97797e7..9e2fb59c59 100644 --- a/packages/backend-dynamic-feature-service/src/server/router.ts +++ b/packages/backend-dynamic-feature-service/src/server/router.ts @@ -19,8 +19,8 @@ import { RootConfigService, } from '@backstage/backend-plugin-api'; import express from 'express'; -import { createOpenApiRouter, spec } from '../schema/openapi'; -import { DynamicPluginProvider } from '@backstage/backend-dynamic-feature-service'; +import { createOpenApiRouter, spec } from '../schema/openapi/generated'; +import { DynamicPluginProvider } from '../manager/types'; import * as fs from 'fs'; import * as path from 'path'; import * as url from 'url'; diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index 31b3497a33..109df60032 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,129 @@ # @backstage/backend-openapi-utils +## 0.6.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## 0.6.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + +## 0.6.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4 + +## 0.6.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.4-next.0 + +## 0.6.1 + +### Patch Changes + +- Updated dependencies + - @backstage/types@1.2.2 + - @backstage/backend-plugin-api@1.4.3 + +## 0.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## 0.6.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- 3760352: Update `express-openapi-validator` to 5.5.8 to fix security vulnerability in transitive dependency `multer` +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2 + +## 0.6.0-next.1 + +### Patch Changes + +- 3760352: Update `express-openapi-validator` to 5.5.8 to fix security vulnerability in transitive dependency `multer` + +## 0.6.0-next.0 + +### Minor Changes + +- c08cbc4: Move Scaffolder API to OpenAPI + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## 0.5.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1 + +## 0.5.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.1-next.0 + +## 0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## 0.5.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## 0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + +## 0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.3.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + ## 0.5.3-next.2 ### Patch Changes diff --git a/packages/backend-openapi-utils/knip-report.md b/packages/backend-openapi-utils/knip-report.md index cf540a8d1d..d2f286fde1 100644 --- a/packages/backend-openapi-utils/knip-report.md +++ b/packages/backend-openapi-utils/knip-report.md @@ -4,5 +4,5 @@ | Name | Location | Severity | | :---------------------------- | :----------- | :------- | -| @backstage/backend-plugin-api | package.json | error | +| @backstage/backend-plugin-api | packages/backend-openapi-utils/package.json | error | diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index 6dc909925a..d88bfb2a91 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-openapi-utils", - "version": "0.5.3-next.2", + "version": "0.6.3-next.1", "description": "OpenAPI typescript support.", "backstage": { "role": "node-library" @@ -53,7 +53,7 @@ "@types/express-serve-static-core": "^4.17.5", "ajv": "^8.16.0", "express": "^4.17.1", - "express-openapi-validator": "^5.0.4", + "express-openapi-validator": "^5.5.8", "express-promise-router": "^4.1.0", "get-port": "^5.1.1", "json-schema-to-ts": "^3.0.0", diff --git a/packages/backend-openapi-utils/report.api.md b/packages/backend-openapi-utils/report.api.md index 6606f88b4a..75bf53cdf1 100644 --- a/packages/backend-openapi-utils/report.api.md +++ b/packages/backend-openapi-utils/report.api.md @@ -274,7 +274,7 @@ type EndpointMap = Record< { query?: object; body?: object; - response?: object | void; + response?: object | string | void; path?: object; } >; diff --git a/packages/backend-openapi-utils/src/types/generated.ts b/packages/backend-openapi-utils/src/types/generated.ts index e4d5dada72..ffbabb6f92 100644 --- a/packages/backend-openapi-utils/src/types/generated.ts +++ b/packages/backend-openapi-utils/src/types/generated.ts @@ -21,7 +21,12 @@ import { PathTemplate, ValueOf } from './common'; */ export type EndpointMap = Record< string, - { query?: object; body?: object; response?: object | void; path?: object } + { + query?: object; + body?: object; + response?: object | string | void; + path?: object; + } >; // OpenAPI generator doesn't emit regular lowercase 'delete'. diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index d627deabf6..0b820e221c 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,193 @@ # @backstage/backend-plugin-api +## 1.5.0-next.1 + +### Minor Changes + +- a17d9df: Promote `instanceMetadata` service to main entrypoint. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + +## 1.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## 1.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + +## 1.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + +## 1.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-node@0.10.4 + +## 1.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + +## 1.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-permission-node@0.10.3 + +## 1.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + +## 1.4.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/plugin-auth-node@0.6.5 + +## 1.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + +## 1.4.0 + +### Minor Changes + +- 664c07a: Added `actionsRegistry` and `actions` experimental services to `/alpha` to allow registration of distributed actions from plugins, and the ability to invoke these actions. You can use these services by including them like the following: + + ```ts + import { + actionsRegistryServiceRef, + actionsServiceRef, + } from '@backstage/backend-plugin-api/alpha'; + + createBackendPlugin({ + pluginId: 'test-plugin', + register({ registerInit }) { + registerInit({ + deps: { + actions: actionsServiceRef, + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actions, actionsRegistry }) { + actionsRegistry.register({ + ..., + }); + + await actions.invoke(...); + }, + }); + }, + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## 1.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + +## 1.4.0-next.0 + +### Minor Changes + +- 664c07a: Added `coreServices.actionsRegistry` and `coreServices.actions` to allow registration of distributed actions from plugins, and the ability to invoke these actions + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + +## 1.3.1 + +### Patch Changes + +- acea1d4: update documentation +- 72d019d: Removed various typos +- d385854: Minor doc comment update +- Updated dependencies + - @backstage/plugin-auth-node@0.6.3 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + ## 1.3.1-next.2 ### Patch Changes diff --git a/packages/backend-plugin-api/knip-report.md b/packages/backend-plugin-api/knip-report.md index 89988530e6..869066c9f6 100644 --- a/packages/backend-plugin-api/knip-report.md +++ b/packages/backend-plugin-api/knip-report.md @@ -4,5 +4,5 @@ | Name | Location | Severity | | :-------------------------- | :----------- | :------- | -| @backstage/plugin-auth-node | package.json | error | +| @backstage/plugin-auth-node | packages/backend-plugin-api/package.json | error | diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 2c56ac85bf..2c47843444 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": "1.3.1-next.2", + "version": "1.5.0-next.1", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" @@ -20,7 +20,7 @@ "license": "Apache-2.0", "exports": { ".": "./src/index.ts", - "./alpha": "./src/alpha.ts", + "./alpha": "./src/alpha/index.ts", "./testUtils": "./src/testUtils.ts", "./package.json": "./package.json" }, @@ -29,7 +29,7 @@ "typesVersions": { "*": { "alpha": [ - "src/alpha.ts" + "src/alpha/index.ts" ], "testUtils": [ "src/testUtils.ts" @@ -61,9 +61,12 @@ "@backstage/plugin-permission-node": "workspace:^", "@backstage/types": "workspace:^", "@types/express": "^4.17.6", + "@types/json-schema": "^7.0.6", "@types/luxon": "^3.0.0", + "json-schema": "^0.4.0", "knex": "^3.0.0", - "luxon": "^3.0.0" + "luxon": "^3.0.0", + "zod": "^3.22.4" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", diff --git a/packages/backend-plugin-api/report-alpha.api.md b/packages/backend-plugin-api/report-alpha.api.md index d485e2132e..9be7a29ed5 100644 --- a/packages/backend-plugin-api/report-alpha.api.md +++ b/packages/backend-plugin-api/report-alpha.api.md @@ -3,7 +3,105 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AnyZodObject } from 'zod'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { JSONSchema7 } from 'json-schema'; +import { JsonValue } from '@backstage/types'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; +import { z } from 'zod'; + +// @alpha (undocumented) +export type ActionsRegistryActionContext = { + input: z.infer; + logger: LoggerService; + credentials: BackstageCredentials; +}; + +// @alpha (undocumented) +export type ActionsRegistryActionOptions< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, +> = { + name: string; + title: string; + description: string; + schema: { + input: (zod: typeof z) => TInputSchema; + output: (zod: typeof z) => TOutputSchema; + }; + attributes?: { + destructive?: boolean; + idempotent?: boolean; + readOnly?: boolean; + }; + action: (context: ActionsRegistryActionContext) => Promise< + z.infer extends void + ? void + : { + output: z.infer; + } + >; +}; + +// @alpha (undocumented) +export interface ActionsRegistryService { + // (undocumented) + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >( + options: ActionsRegistryActionOptions, + ): void; +} + +// @alpha +export const actionsRegistryServiceRef: ServiceRef< + ActionsRegistryService, + 'plugin', + 'singleton' +>; + +// @alpha (undocumented) +export interface ActionsService { + // (undocumented) + invoke(opts: { + id: string; + input?: JsonObject; + credentials: BackstageCredentials; + }): Promise<{ + output: JsonValue; + }>; + // (undocumented) + list: (opts: { credentials: BackstageCredentials }) => Promise<{ + actions: ActionsServiceAction[]; + }>; +} + +// @alpha (undocumented) +export type ActionsServiceAction = { + id: string; + name: string; + title: string; + description: string; + schema: { + input: JSONSchema7; + output: JSONSchema7; + }; + attributes: { + readOnly: boolean; + destructive: boolean; + idempotent: boolean; + }; +}; + +// @alpha +export const actionsServiceRef: ServiceRef< + ActionsService, + 'plugin', + 'singleton' +>; // @alpha (undocumented) export type BackendFeatureMeta = @@ -23,7 +121,7 @@ export interface InstanceMetadataService { getInstalledFeatures: () => BackendFeatureMeta[]; } -// @alpha +// @alpha (undocumented) export const instanceMetadataServiceRef: ServiceRef< InstanceMetadataService, 'plugin', diff --git a/packages/backend-plugin-api/report.api.md b/packages/backend-plugin-api/report.api.md index 52843dec96..cce3221c80 100644 --- a/packages/backend-plugin-api/report.api.md +++ b/packages/backend-plugin-api/report.api.md @@ -232,6 +232,11 @@ export namespace coreServices { const rootLogger: ServiceRef; const scheduler: ServiceRef; const urlReader: ServiceRef; + const rootInstanceMetadata: ServiceRef< + RootInstanceMetadataService, + 'plugin', + 'singleton' + >; } // @public @@ -578,6 +583,24 @@ export interface RootHttpRouterService { use(path: string, handler: Handler): void; } +// @public (undocumented) +export interface RootInstanceMetadataService { + // (undocumented) + getInstalledPlugins: () => Promise< + ReadonlyArray + >; +} + +// @public (undocumented) +export interface RootInstanceMetadataServicePluginInfo { + // (undocumented) + readonly modules: ReadonlyArray<{ + moduleId: string; + }>; + // (undocumented) + readonly pluginId: string; +} + // @public export interface RootLifecycleService extends LifecycleService { // (undocumented) diff --git a/packages/backend-plugin-api/src/alpha/ActionsRegistryService.ts b/packages/backend-plugin-api/src/alpha/ActionsRegistryService.ts new file mode 100644 index 0000000000..9a7820e354 --- /dev/null +++ b/packages/backend-plugin-api/src/alpha/ActionsRegistryService.ts @@ -0,0 +1,69 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { z, AnyZodObject } from 'zod'; +import { + LoggerService, + BackstageCredentials, +} from '@backstage/backend-plugin-api'; + +/** + * @alpha + */ +export type ActionsRegistryActionContext = { + input: z.infer; + logger: LoggerService; + credentials: BackstageCredentials; +}; + +/** + * @alpha + */ +export type ActionsRegistryActionOptions< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, +> = { + name: string; + title: string; + description: string; + schema: { + input: (zod: typeof z) => TInputSchema; + output: (zod: typeof z) => TOutputSchema; + }; + attributes?: { + destructive?: boolean; + idempotent?: boolean; + readOnly?: boolean; + }; + action: ( + context: ActionsRegistryActionContext, + ) => Promise< + z.infer extends void + ? void + : { output: z.infer } + >; +}; + +/** + * @alpha + */ +export interface ActionsRegistryService { + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >( + options: ActionsRegistryActionOptions, + ): void; +} diff --git a/packages/backend-plugin-api/src/alpha/ActionsService.ts b/packages/backend-plugin-api/src/alpha/ActionsService.ts new file mode 100644 index 0000000000..528b6cea67 --- /dev/null +++ b/packages/backend-plugin-api/src/alpha/ActionsService.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JsonObject, JsonValue } from '@backstage/types'; +import { JSONSchema7 } from 'json-schema'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; + +/** + * @alpha + */ +export type ActionsServiceAction = { + id: string; + name: string; + title: string; + description: string; + schema: { + input: JSONSchema7; + output: JSONSchema7; + }; + attributes: { + readOnly: boolean; + destructive: boolean; + idempotent: boolean; + }; +}; + +/** + * @alpha + */ +export interface ActionsService { + list: (opts: { + credentials: BackstageCredentials; + }) => Promise<{ actions: ActionsServiceAction[] }>; + invoke(opts: { + id: string; + input?: JsonObject; + credentials: BackstageCredentials; + }): Promise<{ output: JsonValue }>; +} diff --git a/packages/backend-plugin-api/src/services/definitions/InstanceMetadataService.ts b/packages/backend-plugin-api/src/alpha/InstanceMetadataService.ts similarity index 95% rename from packages/backend-plugin-api/src/services/definitions/InstanceMetadataService.ts rename to packages/backend-plugin-api/src/alpha/InstanceMetadataService.ts index 869d361343..a82a261d9d 100644 --- a/packages/backend-plugin-api/src/services/definitions/InstanceMetadataService.ts +++ b/packages/backend-plugin-api/src/alpha/InstanceMetadataService.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/packages/backend-plugin-api/src/alpha.ts b/packages/backend-plugin-api/src/alpha/index.ts similarity index 60% rename from packages/backend-plugin-api/src/alpha.ts rename to packages/backend-plugin-api/src/alpha/index.ts index 6e91e10671..5bb69eb4e2 100644 --- a/packages/backend-plugin-api/src/alpha.ts +++ b/packages/backend-plugin-api/src/alpha/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2023 The Backstage Authors + * Copyright 2025 The 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,20 +14,21 @@ * limitations under the License. */ -import { createServiceRef } from '@backstage/backend-plugin-api'; - -/** - * EXPERIMENTAL: Instance metadata service. - * - * @alpha - */ -export const instanceMetadataServiceRef = createServiceRef< - import('./services/definitions/InstanceMetadataService').InstanceMetadataService ->({ - id: 'core.instanceMetadata', -}); - export type { BackendFeatureMeta, InstanceMetadataService, -} from './services/definitions/InstanceMetadataService'; +} from './InstanceMetadataService'; + +export type { + ActionsRegistryService, + ActionsRegistryActionOptions, + ActionsRegistryActionContext, +} from './ActionsRegistryService'; + +export type { ActionsService, ActionsServiceAction } from './ActionsService'; + +export { + actionsRegistryServiceRef, + actionsServiceRef, + instanceMetadataServiceRef, +} from './refs'; diff --git a/packages/backend-plugin-api/src/alpha/refs.ts b/packages/backend-plugin-api/src/alpha/refs.ts new file mode 100644 index 0000000000..81996679f7 --- /dev/null +++ b/packages/backend-plugin-api/src/alpha/refs.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createServiceRef } from '@backstage/backend-plugin-api'; + +/** + * @alpha + */ +export const instanceMetadataServiceRef = createServiceRef< + import('./InstanceMetadataService').InstanceMetadataService +>({ + id: 'core.instanceMetadata', +}); + +/** + * Service for calling distributed actions + * + * See {@link ActionsService} + * and {@link https://backstage.io/docs/backend-system/core-services/actions | the service docs} + * for more information. + * + * @alpha + */ +export const actionsServiceRef = createServiceRef< + import('./ActionsService').ActionsService +>({ + id: 'alpha.core.actions', +}); + +/** + * Service for registering and managing distributed actions. + * + * See {@link ActionsRegistryService} + * and {@link https://backstage.io/docs/backend-system/core-services/actions-registry | the service docs} + * for more information. + * + * @alpha + */ +export const actionsRegistryServiceRef = createServiceRef< + import('./ActionsRegistryService').ActionsRegistryService +>({ + id: 'alpha.core.actionsRegistry', +}); diff --git a/packages/backend-plugin-api/src/services/definitions/ActionsRegistryService.ts b/packages/backend-plugin-api/src/services/definitions/ActionsRegistryService.ts new file mode 100644 index 0000000000..6c0936f85c --- /dev/null +++ b/packages/backend-plugin-api/src/services/definitions/ActionsRegistryService.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { z, AnyZodObject } from 'zod'; +import { LoggerService } from './LoggerService'; +import { BackstageCredentials } from './AuthService'; + +/** + * @public + */ +export type ActionsRegistryActionContext = { + input: z.infer; + logger: LoggerService; + credentials: BackstageCredentials; +}; + +/** + * @public + */ +export type ActionsRegistryActionOptions< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, +> = { + name: string; + title: string; + description: string; + schema: { + input: (zod: typeof z) => TInputSchema; + output: (zod: typeof z) => TOutputSchema; + }; + attributes?: { + destructive?: boolean; + idempotent?: boolean; + readOnly?: boolean; + }; + action: ( + context: ActionsRegistryActionContext, + ) => Promise< + z.infer extends void + ? void + : { output: z.infer } + >; +}; + +/** + * @public + */ +export interface ActionsRegistryService { + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >( + options: ActionsRegistryActionOptions, + ): void; +} diff --git a/packages/backend-plugin-api/src/services/definitions/ActionsService.ts b/packages/backend-plugin-api/src/services/definitions/ActionsService.ts new file mode 100644 index 0000000000..d595008a42 --- /dev/null +++ b/packages/backend-plugin-api/src/services/definitions/ActionsService.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JsonObject, JsonValue } from '@backstage/types'; +import { JSONSchema7 } from 'json-schema'; +import { BackstageCredentials } from './AuthService'; + +/** + * @public + */ +export type ActionsServiceAction = { + id: string; + name: string; + title: string; + description: string; + schema: { + input: JSONSchema7; + output: JSONSchema7; + }; + attributes: { + readOnly: boolean; + destructive: boolean; + idempotent: boolean; + }; +}; + +/** + * @public + */ +export interface ActionsService { + list: (opts: { + credentials: BackstageCredentials; + }) => Promise<{ actions: ActionsServiceAction[] }>; + invoke(opts: { + id: string; + input?: JsonObject; + credentials: BackstageCredentials; + }): Promise<{ output: JsonValue }>; +} diff --git a/packages/canon/src/components/Icon/context.tsx b/packages/backend-plugin-api/src/services/definitions/RootInstanceMetadataService.ts similarity index 67% rename from packages/canon/src/components/Icon/context.tsx rename to packages/backend-plugin-api/src/services/definitions/RootInstanceMetadataService.ts index 4d1974d081..c324fed331 100644 --- a/packages/canon/src/components/Icon/context.tsx +++ b/packages/backend-plugin-api/src/services/definitions/RootInstanceMetadataService.ts @@ -14,14 +14,17 @@ * limitations under the License. */ -import { createContext, useContext } from 'react'; -import { icons } from './icons'; -import type { IconContextProps } from './types'; +/** @public */ +export interface RootInstanceMetadataServicePluginInfo { + readonly pluginId: string; + readonly modules: ReadonlyArray<{ + moduleId: string; + }>; +} /** @public */ -export const IconContext = createContext({ - icons, -}); - -/** @public */ -export const useIcons = () => useContext(IconContext); +export interface RootInstanceMetadataService { + getInstalledPlugins: () => Promise< + ReadonlyArray + >; +} diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index 8c8c6c0f82..62f2f848fc 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -277,4 +277,15 @@ export namespace coreServices { export const urlReader = createServiceRef< import('./UrlReaderService').UrlReaderService >({ id: 'core.urlReader' }); + + /** + * Information about the current Backstage instance. + * + * @public + */ + export const rootInstanceMetadata = createServiceRef< + import('./RootInstanceMetadataService').RootInstanceMetadataService + >({ + id: 'core.rootInstanceMetadata', + }); } diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index d6346cbe4e..6bcee4b043 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - export type { AuditorService, AuditorServiceCreateEventOptions, @@ -86,4 +85,8 @@ export type { UrlReaderServiceSearchResponseFile, } from './UrlReaderService'; export type { BackstageUserInfo, UserInfoService } from './UserInfoService'; +export type { + RootInstanceMetadataService, + RootInstanceMetadataServicePluginInfo, +} from './RootInstanceMetadataService'; export { coreServices } from './coreServices'; diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 33e7ce200e..8ce8e92fda 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,326 @@ # @backstage/backend-test-utils +## 1.10.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/backend-app-api@1.3.0-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-events-node@0.4.17-next.1 + +## 1.10.0-next.0 + +### Minor Changes + +- d57b13b: Added support for Postgres 18 to the available `TestDatabases`. + + Note that the set of _default_ databases to test against for users of the `TestDatabases` class was also updated to include Postgres 14 and 18, instead of 13 and 17. If you need to override this, you can pass in an explicit `ids` argument, for example `ids: ['POSTGRES_17', 'POSTGRES_13', 'SQLITE_3']`. + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-events-node@0.4.17-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/backend-app-api@1.2.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## 1.9.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/backend-app-api@1.2.8 + - @backstage/config@1.3.5 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-events-node@0.4.16 + - @backstage/plugin-permission-common@0.9.2 + +## 1.9.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/backend-app-api@1.2.8-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-events-node@0.4.16-next.0 + +## 1.9.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/backend-app-api@1.2.7 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.2 + - @backstage/plugin-events-node@0.4.15 + - @backstage/plugin-permission-common@0.9.1 + +## 1.9.0 + +### Minor Changes + +- 4e2c237: The `mockServices.rootConfig()` instance now has an `update` method that can be used to test configuration subscriptions and updates. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-events-node@0.4.15 + - @backstage/types@1.2.2 + - @backstage/backend-app-api@1.2.7 + - @backstage/backend-plugin-api@1.4.3 + +## 1.9.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/backend-app-api@1.2.7-next.0 + - @backstage/plugin-events-node@0.4.15-next.0 + +## 1.9.0-next.0 + +### Minor Changes + +- 4e2c237: The `mockServices.rootConfig()` instance now has an `update` method that can be used to test configuration subscriptions and updates. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@1.2.6 + - @backstage/backend-defaults@0.12.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-events-node@0.4.14 + - @backstage/plugin-permission-common@0.9.1 + +## 1.8.0 + +### Minor Changes + +- dffaf70: Switched out `mockServices.scheduler` to use a mocked implementation instead of the default scheduler implementation. This implementation runs any scheduled tasks immediately on startup, as long as they don't have an initial delay or a manual trigger. After the initial run, the tasks are never run again unless manually triggered. + +### Patch Changes + +- 279e1f7: Updated the type definition of `mockErrorHandler` to ensure that it is used correctly. + + ```ts + // This is wrong and will now result in a type error + app.use(mockErrorHandler); + + // This is the correct usage + app.use(mockErrorHandler()); + ``` + +- 3a7dad9: Updated `better-sqlite3` to v12 +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/backend-app-api@1.2.6 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-events-node@0.4.14 + +## 1.7.1-next.0 + +### Patch Changes + +- 3a7dad9: Updated `better-sqlite3` to v12 +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/backend-app-api@1.2.6-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-events-node@0.4.14-next.0 + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + +## 1.7.0 + +### Minor Changes + +- ead925a: Add a standard `toString` on credentials objects + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/backend-defaults@0.11.1 + - @backstage/backend-app-api@1.2.5 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-events-node@0.4.13 + +## 1.7.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/backend-app-api@1.2.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-events-node@0.4.13-next.0 + +## 1.7.0-next.0 + +### Minor Changes + +- ead925a: Add a standard `toString` on credentials objects + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/backend-app-api@1.2.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + +## 1.6.0 + +### Minor Changes + +- 6dfb7be: Added `mockServices.permissions()` that can return actual results. +- c999c25: Added an `actionsRegistryServiceMock` and `actionsServiceMock` to `/alpha` export for the experimental services. + + This allows you to write tests for your actions by doing something similar to the following: + + ```ts + import { actionsRegistryServiceMock } from '@backstage/backend-test-utils/alpha'; + + const mockActionsRegistry = actionsRegistryServiceMock(); + const mockCatalog = catalogServiceMock({ + entities: [ + ... + ], + }); + + createGetCatalogEntityAction({ + catalog: mockCatalog, + actionsRegistry: mockActionsRegistry, + }); + + await expect( + mockActionsRegistry.invoke({ + id: 'test:get-catalog-entity', + input: { name: 'test' }, + }), + ).resolves.toEqual(...) + ``` + +### Patch Changes + +- 12c1fd4: Make the `user` credentials mock behave more like production +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-app-api@1.2.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + +## 1.6.0-next.2 + +### Patch Changes + +- 12c1fd4: Make the `user` credentials mock behave more like production +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/backend-app-api@1.2.4-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## 1.6.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/backend-app-api@1.2.4-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12-next.1 + +## 1.6.0-next.0 + +### Minor Changes + +- c999c25: Added mock implementations for `ActionsService` and `ActionsRegistryService` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/backend-app-api@1.2.4-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-events-node@0.4.12-next.0 + +## 1.5.0 + +### Minor Changes + +- b3832d1: Add a functional `mockServices.events()` +- c6bc67d: Added Valkey support alongside Redis in backend-defaults cache clients, using the new Keyv Valkey package. Also extended backend-test-utils to support Valkey in tests. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0 + - @backstage/backend-app-api@1.2.3 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.11 + ## 1.5.0-next.3 ### Patch Changes diff --git a/packages/backend-test-utils/knip-report.md b/packages/backend-test-utils/knip-report.md index 6ba3e32cd6..860e474541 100644 --- a/packages/backend-test-utils/knip-report.md +++ b/packages/backend-test-utils/knip-report.md @@ -1,13 +1,20 @@ # Knip report -## Unused dependencies (6) +## Unused dependencies (7) | Name | Location | Severity | | :------------------------------- | :----------- | :------- | -| @types/express-serve-static-core | package.json | error | -| @backstage/plugin-auth-node | package.json | error | -| better-sqlite3 | package.json | error | -| @types/qs | package.json | error | -| mysql2 | package.json | error | -| pg | package.json | error | +| @types/express-serve-static-core | packages/backend-test-utils/package.json | error | +| @backstage/plugin-auth-node | packages/backend-test-utils/package.json | error | +| better-sqlite3 | packages/backend-test-utils/package.json | error | +| @types/qs | packages/backend-test-utils/package.json | error | +| lodash | packages/backend-test-utils/package.json | error | +| mysql2 | packages/backend-test-utils/package.json | error | +| pg | packages/backend-test-utils/package.json | error | + +## Unused devDependencies (1) + +| Name | Location | Severity | +| :------------ | :----------- | :------- | +| @types/lodash | packages/backend-test-utils/package.json | error | diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 89fa65b09c..8da6bb6640 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": "1.5.0-next.3", + "version": "1.10.0-next.1", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" @@ -21,7 +21,8 @@ "license": "Apache-2.0", "exports": { ".": "./src/index.ts", - "./package.json": "./package.json" + "./package.json": "./package.json", + "./alpha": "./src/alpha/index.ts" }, "main": "src/index.ts", "types": "src/index.ts", @@ -29,6 +30,9 @@ "*": { "package.json": [ "package.json" + ], + "alpha": [ + "src/alpha/index.ts" ] } }, @@ -52,6 +56,7 @@ "@backstage/errors": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-events-node": "workspace:^", + "@backstage/plugin-permission-common": "workspace:^", "@backstage/types": "workspace:^", "@keyv/memcache": "^2.0.1", "@keyv/redis": "^4.0.1", @@ -60,23 +65,27 @@ "@types/express-serve-static-core": "^4.17.5", "@types/keyv": "^4.2.0", "@types/qs": "^6.9.6", - "better-sqlite3": "^11.0.0", + "better-sqlite3": "^12.0.0", "cookie": "^0.7.0", "express": "^4.17.1", "fs-extra": "^11.0.0", "keyv": "^5.2.1", "knex": "^3.0.0", + "lodash": "^4.17.21", "mysql2": "^3.0.0", "pg": "^8.11.3", "pg-connection-string": "^2.3.0", "testcontainers": "^10.0.0", "textextensions": "^5.16.0", "uuid": "^11.0.0", - "yn": "^4.0.0" + "yn": "^4.0.0", + "zod": "^3.22.4", + "zod-to-json-schema": "^3.20.4" }, "devDependencies": { "@backstage/cli": "workspace:^", "@types/jest": "*", + "@types/lodash": "^4.14.151", "@types/supertest": "^2.0.8", "supertest": "^7.0.0" } diff --git a/packages/backend-test-utils/report-alpha.api.md b/packages/backend-test-utils/report-alpha.api.md new file mode 100644 index 0000000000..ccbf96c0c7 --- /dev/null +++ b/packages/backend-test-utils/report-alpha.api.md @@ -0,0 +1,85 @@ +## API Report File for "@backstage/backend-test-utils" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ActionsRegistryActionOptions } from '@backstage/backend-plugin-api/alpha'; +import { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha'; +import { ActionsService } from '@backstage/backend-plugin-api/alpha'; +import { ActionsServiceAction } from '@backstage/backend-plugin-api/alpha'; +import { AnyZodObject } from 'zod'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { JsonValue } from '@backstage/types'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @alpha (undocumented) +export function actionsRegistryServiceMock(options?: { + logger: LoggerService; +}): MockActionsRegistry; + +// @alpha (undocumented) +export namespace actionsRegistryServiceMock { + const // (undocumented) + factory: () => ServiceFactory< + ActionsRegistryService, + 'plugin', + 'singleton' + >; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; +} + +// @alpha (undocumented) +export namespace actionsServiceMock { + const // (undocumented) + factory: () => ServiceFactory; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; +} + +// @alpha +export class MockActionsRegistry + implements ActionsRegistryService, ActionsService +{ + // (undocumented) + readonly actions: Map>; + // (undocumented) + static create(opts: { logger: LoggerService }): MockActionsRegistry; + // (undocumented) + invoke(opts: { + id: string; + input?: JsonObject; + credentials?: BackstageCredentials; + }): Promise<{ + output: JsonValue; + }>; + // (undocumented) + list(): Promise<{ + actions: ActionsServiceAction[]; + }>; + // (undocumented) + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >(options: ActionsRegistryActionOptions): void; +} + +// @alpha (undocumented) +export type ServiceMock = { + factory: ServiceFactory; +} & { + [Key in keyof TService]: TService[Key] extends ( + ...args: infer Args + ) => infer Return + ? TService[Key] & jest.MockInstance + : TService[Key]; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-test-utils/report.api.md b/packages/backend-test-utils/report.api.md index 7edcf6e1b7..915162e9ab 100644 --- a/packages/backend-test-utils/report.api.md +++ b/packages/backend-test-utils/report.api.md @@ -4,6 +4,7 @@ ```ts import { AuditorService } from '@backstage/backend-plugin-api'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { AuthService } from '@backstage/backend-plugin-api'; import { Backend } from '@backstage/backend-app-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; @@ -34,6 +35,7 @@ import { PermissionsService } from '@backstage/backend-plugin-api'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { RootHealthService } from '@backstage/backend-plugin-api'; import { RootHttpRouterService } from '@backstage/backend-plugin-api'; +import { RootInstanceMetadataService } from '@backstage/backend-plugin-api'; import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; import { SchedulerService } from '@backstage/backend-plugin-api'; @@ -151,7 +153,10 @@ export interface MockDirectoryContentOptions { } // @public -export function mockErrorHandler(): ErrorRequestHandler< +export function mockErrorHandler( + _options?: {}, + ..._args: never[] +): ErrorRequestHandler< ParamsDictionary, any, any, @@ -275,14 +280,17 @@ export namespace mockServices { partialImpl?: Partial | undefined, ) => ServiceMock; } + export function permissions(options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }): PermissionsService; // (undocumented) export namespace permissions { - const // (undocumented) - factory: () => ServiceFactory; - const // (undocumented) - mock: ( - partialImpl?: Partial | undefined, - ) => ServiceMock; + const factory: (options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }) => ServiceFactory; + const mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace permissionsRegistry { @@ -298,7 +306,11 @@ export namespace mockServices { ) => ServiceMock; } // (undocumented) - export function rootConfig(options?: rootConfig.Options): RootConfigService; + export function rootConfig( + options?: rootConfig.Options, + ): RootConfigService & { + update(options: { data: JsonObject }): void; + }; // (undocumented) export namespace rootConfig { // (undocumented) @@ -333,6 +345,21 @@ export namespace mockServices { ) => ServiceMock; } // (undocumented) + export function rootInstanceMetadata(): RootInstanceMetadataService; + // (undocumented) + export namespace rootInstanceMetadata { + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; + const // (undocumented) + factory: () => ServiceFactory< + RootInstanceMetadataService, + 'plugin', + 'singleton' | 'multiton' + >; + } + // (undocumented) export namespace rootLifecycle { const // (undocumented) factory: () => ServiceFactory; @@ -359,9 +386,15 @@ export namespace mockServices { ) => ServiceMock; } // (undocumented) + export function scheduler(): SchedulerService; + // (undocumented) export namespace scheduler { const // (undocumented) - factory: () => ServiceFactory; + factory: (options?: { + skipTaskRunOnStartup?: boolean; + includeManualTasksOnStartup?: boolean; + includeInitialDelayedTasksOnStartup?: boolean; + }) => ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, @@ -493,6 +526,7 @@ export class TestCaches { // @public export type TestDatabaseId = + | 'POSTGRES_18' | 'POSTGRES_17' | 'POSTGRES_16' | 'POSTGRES_15' diff --git a/packages/backend-test-utils/src/next/index.ts b/packages/backend-test-utils/src/alpha/index.ts similarity index 96% rename from packages/backend-test-utils/src/next/index.ts rename to packages/backend-test-utils/src/alpha/index.ts index 572fb3a9e7..d891744260 100644 --- a/packages/backend-test-utils/src/next/index.ts +++ b/packages/backend-test-utils/src/alpha/index.ts @@ -14,5 +14,4 @@ * limitations under the License. */ -export * from './wiring'; export * from './services'; diff --git a/packages/backend-test-utils/src/alpha/services/ActionsRegistryServiceMock.ts b/packages/backend-test-utils/src/alpha/services/ActionsRegistryServiceMock.ts new file mode 100644 index 0000000000..faf89b393a --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/ActionsRegistryServiceMock.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 '../../services'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { MockActionsRegistry } from './MockActionsRegistry'; +import { simpleMock } from './simpleMock'; +import { + ActionsRegistryService, + actionsRegistryServiceRef, +} from '@backstage/backend-plugin-api/alpha'; +import { actionsRegistryServiceFactory } from '@backstage/backend-defaults/alpha'; + +/** + * @alpha + */ +export function actionsRegistryServiceMock(options?: { + logger: LoggerService; +}): MockActionsRegistry { + return MockActionsRegistry.create({ + logger: options?.logger ?? mockServices.logger.mock(), + }); +} + +/** + * @alpha + */ +export namespace actionsRegistryServiceMock { + export const factory = () => actionsRegistryServiceFactory; + + export const mock = simpleMock( + actionsRegistryServiceRef, + () => ({ + register: jest.fn(), + }), + ); +} diff --git a/packages/backend-test-utils/src/alpha/services/ActionsServiceMock.ts b/packages/backend-test-utils/src/alpha/services/ActionsServiceMock.ts new file mode 100644 index 0000000000..63abff4c37 --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/ActionsServiceMock.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { simpleMock } from './simpleMock'; +import { + ActionsService, + actionsServiceRef, +} from '@backstage/backend-plugin-api/alpha'; +import { actionsServiceFactory } from '@backstage/backend-defaults/alpha'; + +/** + * @alpha + */ +export namespace actionsServiceMock { + export const factory = () => actionsServiceFactory; + + export const mock = simpleMock(actionsServiceRef, () => ({ + invoke: jest.fn(), + list: jest.fn(), + })); +} diff --git a/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.test.ts b/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.test.ts new file mode 100644 index 0000000000..f604689c63 --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.test.ts @@ -0,0 +1,236 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { startTestBackend } from '../../wiring'; +import { actionsRegistryServiceMock } from './ActionsRegistryServiceMock'; +import { mockCredentials } from '../../services'; +import { Router } from 'express'; +import supertest from 'supertest'; +import { + actionsRegistryServiceRef, + actionsServiceRef, +} from '@backstage/backend-plugin-api/alpha'; + +describe('MockActionsRegistry', () => { + it('should be able to register and invoke actions', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => + z.object({ + name: z.string(), + }), + output: z => + z.object({ + name: z.string(), + }), + }, + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + const result = await registry.invoke({ + id: 'test:my-demo-action', + input: { name: 'test' }, + }); + + expect(result).toEqual({ output: { name: 'test' } }); + }); + + it('should throw an error when the input is invalid to the action', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.string() }), + output: z => z.object({ name: z.string() }), + }, + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + await expect( + registry.invoke({ id: 'test:my-demo-action', input: { name: 1 } }), + ).rejects.toThrow('Invalid input to action "test:my-demo-action"'); + }); + + it('should throw an error when the action is not found', async () => { + const registry = actionsRegistryServiceMock(); + + await expect(registry.invoke({ id: 'test' })).rejects.toThrow( + 'Action "test" not found, available actions: none', + ); + }); + + it('should throw an error when the action is not found with recommended actions', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.string() }), + output: z => z.object({ name: z.string() }), + }, + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + await expect(registry.invoke({ id: 'test' })).rejects.toThrow( + 'Action "test" not found, available actions: "test:my-demo-action"', + ); + }); + + it('should throw an error when the output is invalid', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.number() }), + output: z => z.object({ name: z.string() }), + }, + // @ts-expect-error - we want to test the error case + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + await expect( + registry.invoke({ id: 'test:my-demo-action', input: { name: 1 } }), + ).rejects.toThrow('Invalid output from action "test:my-demo-action"'); + }); + + it('should list the actions correctly', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.string() }), + output: z => z.object({ name: z.string() }), + }, + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + const result = await registry.list(); + + expect(result).toMatchObject({ + actions: [ + { + id: 'test:my-demo-action', + name: 'my-demo-action', + title: 'Test', + description: 'Test', + attributes: { + destructive: true, + idempotent: false, + readOnly: false, + }, + schema: { + input: { + type: 'object', + properties: { + name: { type: 'string' }, + }, + }, + output: { + type: 'object', + properties: { + name: { type: 'string' }, + }, + }, + }, + }, + ], + }); + }); + + describe('actionsRegistryServiceMock + mockService.actionsRegistry', () => { + it('should be able to register and invoke actions', async () => { + const pluginWithAction = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { actionsRegistry: actionsRegistryServiceRef }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.string() }), + output: z => z.object({ name: z.string() }), + }, + action: async ({ input }) => { + expect(input).toEqual({ name: 'test' }); + return { output: { name: input.name } }; + }, + }); + }, + }); + }, + }); + + const pluginToCallAction = createBackendPlugin({ + pluginId: 'my-plugin-to-call-action', + register(reg) { + reg.registerInit({ + deps: { + actions: actionsServiceRef, + router: coreServices.httpRouter, + }, + async init({ actions, router }) { + const testRouter = Router(); + router.use(testRouter); + + testRouter.post('/test', async (_, res) => { + const { output } = await actions.invoke({ + id: 'my-plugin:test', + input: { name: 'test' }, + credentials: mockCredentials.service(), + }); + + res.json(output); + }); + }, + }); + }, + }); + + const { server } = await startTestBackend({ + features: [pluginWithAction, pluginToCallAction], + }); + + const { body, status } = await supertest(server).post( + '/api/my-plugin-to-call-action/test', + ); + + expect(status).toBe(200); + expect(body).toEqual({ name: 'test' }); + }); + }); +}); diff --git a/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.ts b/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.ts new file mode 100644 index 0000000000..94e5987afd --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.ts @@ -0,0 +1,172 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + BackstageCredentials, + LoggerService, +} from '@backstage/backend-plugin-api'; +import { ForwardedError, InputError, NotFoundError } from '@backstage/errors'; +import { JsonObject, JsonValue } from '@backstage/types'; +import { z, AnyZodObject } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; +import { mockCredentials } from '../../services'; +import { + ActionsRegistryActionOptions, + ActionsRegistryService, + ActionsService, + ActionsServiceAction, +} from '@backstage/backend-plugin-api/alpha'; + +/** + * A mock implementation of the ActionsRegistryService and ActionsService that can be used in tests. + * + * This is useful for testing actions that are registered with the ActionsRegistryService and ActionsService. + * + * The plugin ID is hardcoded to `testing` in the mock implementation. + * + * @example + * ```ts + * const actionsRegistry = mockServices.actionsRegistry(); + * + * actionsRegistry.register({ + * name: 'test', + * title: 'Test', + * description: 'Test', + * schema: { + * input: z.object({ name: z.string() }), + * output: z.object({ name: z.string() }), + * }, + * action: async ({ input }) => ({ output: { name: input.name } }), + * }); + * + * + * const result = await actionsRegistry.invoke({ + * id: 'testing:test', + * input: { name: 'test' }, + * }); + * + * expect(result).toEqual({ output: { name: 'test' } }); + * ``` + * + * @alpha + */ +export class MockActionsRegistry + implements ActionsRegistryService, ActionsService +{ + private readonly logger: LoggerService; + + private constructor(logger: LoggerService) { + this.logger = logger; + } + + static create(opts: { logger: LoggerService }) { + return new MockActionsRegistry(opts.logger); + } + + readonly actions: Map> = + new Map(); + + async list(): Promise<{ actions: ActionsServiceAction[] }> { + return { + actions: Array.from(this.actions.entries()).map(([id, action]) => ({ + id, + name: action.name, + title: action.title, + description: action.description, + attributes: { + destructive: action.attributes?.destructive ?? true, + idempotent: action.attributes?.idempotent ?? false, + readOnly: action.attributes?.readOnly ?? false, + }, + schema: { + input: action.schema?.input + ? zodToJsonSchema(action.schema.input(z)) + : zodToJsonSchema(z.object({})), + output: action.schema?.output + ? zodToJsonSchema(action.schema.output(z)) + : zodToJsonSchema(z.object({})), + } as ActionsServiceAction['schema'], + })), + }; + } + + async invoke(opts: { + id: string; + input?: JsonObject; + credentials?: BackstageCredentials; + }): Promise<{ output: JsonValue }> { + const action = this.actions.get(opts.id); + + if (!action) { + const availableActionIds = Array.from(this.actions.keys()).join(', '); + throw new NotFoundError( + `Action "${opts.id}" not found, available actions: ${ + availableActionIds ? `"${availableActionIds}"` : 'none' + }`, + ); + } + + const input = action.schema?.input + ? action.schema.input(z).safeParse(opts.input) + : ({ success: true, data: undefined } as const); + + if (!input.success) { + throw new InputError(`Invalid input to action "${opts.id}"`, input.error); + } + + try { + const result = await action.action({ + input: input.data, + credentials: opts.credentials ?? mockCredentials.none(), + logger: this.logger, + }); + + const output = action.schema?.output + ? action.schema.output(z).safeParse(result?.output) + : ({ success: true, data: result?.output } as const); + + if (!output.success) { + throw new InputError( + `Invalid output from action "${opts.id}"`, + output.error, + ); + } + + return { output: output.data }; + } catch (error) { + throw new ForwardedError( + `Failed execution of action "${opts.id}"`, + error, + ); + } + } + + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >(options: ActionsRegistryActionOptions): void { + // hardcode test: prefix similar to how the default actions registry does it + // and other places around the testing ecosystem: + // https://github.com/backstage/backstage/blob/a9219496d5c073aaa0b8caf32ece10455cf65e61/packages/backend-test-utils/src/next/services/mockServices.ts#L321 + // https://github.com/backstage/backstage/blob/861f162b4a39117b824669d67a951ed1db142e3d/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts#L99 + const id = `test:${options.name}`; + + if (this.actions.has(id)) { + throw new Error(`Action with id "${id}" is already registered`); + } + + this.actions.set(id, options); + } +} diff --git a/packages/backend-test-utils/src/alpha/services/index.ts b/packages/backend-test-utils/src/alpha/services/index.ts new file mode 100644 index 0000000000..ca9b3f23a0 --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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 { actionsRegistryServiceMock } from './ActionsRegistryServiceMock'; +export { MockActionsRegistry } from './MockActionsRegistry'; +export { actionsServiceMock } from './ActionsServiceMock'; +export { type ServiceMock } from './simpleMock'; diff --git a/packages/backend-test-utils/src/alpha/services/simpleMock.ts b/packages/backend-test-utils/src/alpha/services/simpleMock.ts new file mode 100644 index 0000000000..d07b143f7a --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/simpleMock.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + ServiceFactory, + ServiceRef, +} from '@backstage/backend-plugin-api'; + +/** @alpha */ +export type ServiceMock = { + factory: ServiceFactory; +} & { + [Key in keyof TService]: TService[Key] extends ( + ...args: infer Args + ) => infer Return + ? TService[Key] & jest.MockInstance + : TService[Key]; +}; + +/** @internal */ +export function simpleMock( + ref: ServiceRef, + mockFactory: () => jest.Mocked, +): (partialImpl?: Partial) => ServiceMock { + return partialImpl => { + const mock = mockFactory(); + if (partialImpl) { + for (const [key, impl] of Object.entries(partialImpl)) { + if (typeof impl === 'function') { + (mock as any)[key].mockImplementation(impl); + } else { + (mock as any)[key] = impl; + } + } + } + return Object.assign(mock, { + factory: createServiceFactory({ + service: ref, + deps: {}, + factory: () => mock, + }), + }) as ServiceMock; + }; +} diff --git a/packages/backend-test-utils/src/database/TestDatabases.ts b/packages/backend-test-utils/src/database/TestDatabases.ts index cd20e2997b..8baac04193 100644 --- a/packages/backend-test-utils/src/database/TestDatabases.ts +++ b/packages/backend-test-utils/src/database/TestDatabases.ts @@ -131,7 +131,7 @@ export class TestDatabases { * Returns a fresh, unique, empty logical database on an instance of the * given database ID platform. * - * @param id - The ID of the database platform to use, e.g. 'POSTGRES_13' + * @param id - The ID of the database platform to use, e.g. 'POSTGRES_14' * @returns A `Knex` connection object */ async init(id: TestDatabaseId): Promise { diff --git a/packages/backend-test-utils/src/database/types.ts b/packages/backend-test-utils/src/database/types.ts index e1ef61a93b..30e7e2f905 100644 --- a/packages/backend-test-utils/src/database/types.ts +++ b/packages/backend-test-utils/src/database/types.ts @@ -28,6 +28,7 @@ export interface Engine { * @public */ export type TestDatabaseId = + | 'POSTGRES_18' | 'POSTGRES_17' | 'POSTGRES_16' | 'POSTGRES_15' @@ -48,6 +49,13 @@ export type TestDatabaseProperties = { export const allDatabases: Record = Object.freeze({ + POSTGRES_18: { + name: 'Postgres 18.x', + driver: 'pg', + dockerImageName: getDockerImageForName('postgres:18'), + connectionStringEnvironmentVariableName: + 'BACKSTAGE_TEST_DATABASE_POSTGRES18_CONNECTION_STRING', + }, POSTGRES_17: { name: 'Postgres 17.x', driver: 'pg', diff --git a/packages/backend-test-utils/src/index.ts b/packages/backend-test-utils/src/index.ts index d8e0e2c4a6..7cc4546415 100644 --- a/packages/backend-test-utils/src/index.ts +++ b/packages/backend-test-utils/src/index.ts @@ -24,5 +24,6 @@ export * from './cache'; export * from './database'; export * from './msw'; export * from './filesystem'; -export * from './next'; +export * from './services'; +export * from './wiring'; export { mockErrorHandler } from './util'; diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts b/packages/backend-test-utils/src/services/MockAuthService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockAuthService.test.ts rename to packages/backend-test-utils/src/services/MockAuthService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/services/MockAuthService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockAuthService.ts rename to packages/backend-test-utils/src/services/MockAuthService.ts diff --git a/packages/backend-test-utils/src/next/services/MockEventsService.test.ts b/packages/backend-test-utils/src/services/MockEventsService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockEventsService.test.ts rename to packages/backend-test-utils/src/services/MockEventsService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockEventsService.ts b/packages/backend-test-utils/src/services/MockEventsService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockEventsService.ts rename to packages/backend-test-utils/src/services/MockEventsService.ts diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts b/packages/backend-test-utils/src/services/MockHttpAuthService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts rename to packages/backend-test-utils/src/services/MockHttpAuthService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts b/packages/backend-test-utils/src/services/MockHttpAuthService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockHttpAuthService.ts rename to packages/backend-test-utils/src/services/MockHttpAuthService.ts diff --git a/packages/backend-test-utils/src/services/MockPermissionsService.test.ts b/packages/backend-test-utils/src/services/MockPermissionsService.test.ts new file mode 100644 index 0000000000..eb98fe9457 --- /dev/null +++ b/packages/backend-test-utils/src/services/MockPermissionsService.test.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { MockPermissionsService } from './MockPermissionsService'; + +describe('MockPermissionsService', () => { + it('should return the correct result', async () => { + const permission = { + permission: { + name: 'test', + type: 'basic', + attributes: {}, + }, + } as const; + + const defaultService = new MockPermissionsService(); + const allowService = new MockPermissionsService({ + result: AuthorizeResult.ALLOW, + }); + const denyService = new MockPermissionsService({ + result: AuthorizeResult.DENY, + }); + + await expect(defaultService.authorize([permission])).resolves.toEqual([ + { + ...permission, + result: AuthorizeResult.ALLOW, + }, + ]); + await expect(allowService.authorize([permission])).resolves.toEqual([ + { + ...permission, + result: AuthorizeResult.ALLOW, + }, + ]); + await expect(denyService.authorize([permission])).resolves.toEqual([ + { + ...permission, + result: AuthorizeResult.DENY, + }, + ]); + }); +}); diff --git a/packages/backend-test-utils/src/services/MockPermissionsService.ts b/packages/backend-test-utils/src/services/MockPermissionsService.ts new file mode 100644 index 0000000000..3637c34554 --- /dev/null +++ b/packages/backend-test-utils/src/services/MockPermissionsService.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PermissionsService } from '@backstage/backend-plugin-api'; +import { + AuthorizePermissionRequest, + AuthorizePermissionResponse, + AuthorizeResult, + QueryPermissionRequest, + QueryPermissionResponse, +} from '@backstage/plugin-permission-common'; + +export class MockPermissionsService implements PermissionsService { + readonly #result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + + constructor(options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }) { + this.#result = options?.result ?? AuthorizeResult.ALLOW; + } + + async authorize( + requests: AuthorizePermissionRequest[], + ): Promise { + return requests.map(request => ({ + ...request, + result: this.#result, + })); + } + + async authorizeConditional( + requests: QueryPermissionRequest[], + ): Promise { + return requests.map(request => ({ + ...request, + result: this.#result, + })); + } +} diff --git a/packages/backend-test-utils/src/next/services/MockRootLoggerService.test.ts b/packages/backend-test-utils/src/services/MockRootLoggerService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockRootLoggerService.test.ts rename to packages/backend-test-utils/src/services/MockRootLoggerService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockRootLoggerService.ts b/packages/backend-test-utils/src/services/MockRootLoggerService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockRootLoggerService.ts rename to packages/backend-test-utils/src/services/MockRootLoggerService.ts diff --git a/packages/backend-test-utils/src/services/MockSchedulerService.test.ts b/packages/backend-test-utils/src/services/MockSchedulerService.test.ts new file mode 100644 index 0000000000..87390520b0 --- /dev/null +++ b/packages/backend-test-utils/src/services/MockSchedulerService.test.ts @@ -0,0 +1,243 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { startTestBackend } from '../wiring'; +import { MockSchedulerService } from './MockSchedulerService'; +import { mockServices } from './mockServices'; +import { setTimeout } from 'timers/promises'; + +const baseOpts = { + frequency: { seconds: 10 }, + timeout: { seconds: 10 }, +}; + +describe('MockSchedulerService', () => { + it('should run a task', async () => { + const scheduler = new MockSchedulerService(); + expect(scheduler).toBeDefined(); + + const taskFn = jest.fn(); + scheduler.scheduleTask({ + ...baseOpts, + id: 'test', + fn: taskFn, + }); + + expect(taskFn).not.toHaveBeenCalled(); + + await scheduler.triggerTask('test'); + + expect(taskFn).toHaveBeenCalled(); + }); + + it('should run tasks on startup', async () => { + const testFnPlain = jest.fn(); + const testFnInitialDelay = jest.fn(); + const testFnManual = jest.fn(); + const testFnLocal = jest.fn(); + + // Relying on the fact that the mock scheduler service is used by default + await startTestBackend({ + features: [ + createBackendPlugin({ + pluginId: 'tester', + register(reg) { + reg.registerInit({ + deps: { scheduler: coreServices.scheduler }, + async init({ scheduler }) { + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-plain', + fn: testFnPlain, + }); + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-local', + scope: 'local', + fn: testFnLocal, + }); + + // Should not run by default + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-with-initial-delay', + initialDelay: { seconds: 1 }, + fn: testFnInitialDelay, + }); + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-manual', + frequency: { trigger: 'manual' }, + fn: testFnManual, + }); + }, + }); + }, + }), + ], + }); + + expect(testFnPlain).toHaveBeenCalled(); + expect(testFnLocal).toHaveBeenCalled(); + expect(testFnInitialDelay).not.toHaveBeenCalled(); + expect(testFnManual).not.toHaveBeenCalled(); + }); + + it('should not run tasks on startup if skipped', async () => { + const testFnPlain = jest.fn(); + + await startTestBackend({ + features: [ + new MockSchedulerService().factory({ skipTaskRunOnStartup: true }), + createBackendPlugin({ + pluginId: 'tester', + register(reg) { + reg.registerInit({ + deps: { scheduler: coreServices.scheduler }, + async init({ scheduler }) { + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-plain', + fn: testFnPlain, + }); + }, + }); + }, + }), + ], + }); + + expect(testFnPlain).not.toHaveBeenCalled(); + }); + + it('should run all tasks on startup if configured', async () => { + const testFnPlain = jest.fn(); + const testFnInitialDelay = jest.fn(); + const testFnManual = jest.fn(); + const testFnLocal = jest.fn(); + + await startTestBackend({ + features: [ + mockServices.scheduler.factory({ + includeManualTasksOnStartup: true, + includeInitialDelayedTasksOnStartup: true, + }), + createBackendPlugin({ + pluginId: 'tester', + register(reg) { + reg.registerInit({ + deps: { scheduler: coreServices.scheduler }, + async init({ scheduler }) { + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-plain', + fn: testFnPlain, + }); + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-local', + scope: 'local', + fn: testFnLocal, + }); + + // Should not run by default + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-with-initial-delay', + initialDelay: { seconds: 1 }, + fn: testFnInitialDelay, + }); + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-manual', + frequency: { trigger: 'manual' }, + fn: testFnManual, + }); + }, + }); + }, + }), + ], + }); + + expect(testFnPlain).toHaveBeenCalled(); + expect(testFnLocal).toHaveBeenCalled(); + expect(testFnInitialDelay).toHaveBeenCalled(); + expect(testFnManual).toHaveBeenCalled(); + }); + + it('should wait for a specific task to complete', async () => { + const scheduler = new MockSchedulerService(); + const taskFn = jest.fn(); + scheduler.scheduleTask({ + ...baseOpts, + id: 'test', + fn: taskFn, + }); + + const wait = scheduler.waitForTask('test'); + + const isDone = () => + Promise.race([wait.then(() => true), setTimeout(1, false)]); + + expect(taskFn).not.toHaveBeenCalled(); + await expect(isDone()).resolves.toBe(false); + + await scheduler.triggerTask('test'); + + expect(taskFn).toHaveBeenCalled(); + await expect(isDone()).resolves.toBe(true); + }); + + it('should abort tasks when shutting down', async () => { + let taskSignal: AbortSignal | undefined; + + const backend = await startTestBackend({ + features: [ + mockServices.scheduler.factory({ + includeManualTasksOnStartup: true, + includeInitialDelayedTasksOnStartup: true, + }), + createBackendPlugin({ + pluginId: 'tester', + register(reg) { + reg.registerInit({ + deps: { scheduler: coreServices.scheduler }, + async init({ scheduler }) { + scheduler.scheduleTask({ + ...baseOpts, + id: 'test-plain', + fn: async signal => { + taskSignal = signal; + }, + }); + }, + }); + }, + }), + ], + }); + + expect(taskSignal).toBeDefined(); + expect(taskSignal?.aborted).toBe(false); + await backend.stop(); + expect(taskSignal?.aborted).toBe(true); + }); +}); diff --git a/packages/backend-test-utils/src/services/MockSchedulerService.ts b/packages/backend-test-utils/src/services/MockSchedulerService.ts new file mode 100644 index 0000000000..aafd6d98ec --- /dev/null +++ b/packages/backend-test-utils/src/services/MockSchedulerService.ts @@ -0,0 +1,177 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + SchedulerService, + SchedulerServiceTaskDescriptor, + SchedulerServiceTaskInvocationDefinition, + SchedulerServiceTaskRunner, + SchedulerServiceTaskScheduleDefinition, +} from '@backstage/backend-plugin-api'; +import { createDeferred, DeferredPromise } from '@backstage/types'; + +export class MockSchedulerService implements SchedulerService { + readonly #tasks = new Map< + string, + SchedulerServiceTaskInvocationDefinition & + SchedulerServiceTaskScheduleDefinition & { + descriptor: SchedulerServiceTaskDescriptor; + abortControllers: AbortController; + } + >(); + readonly #runningTasks = new Set(); + readonly #deferredTaskCompletions = new Map>(); + + /** + * Creates a service factory for this mock scheduler instance, which can be installed in a test backend + */ + factory(options?: { + skipTaskRunOnStartup?: boolean; + includeManualTasksOnStartup?: boolean; + includeInitialDelayedTasksOnStartup?: boolean; + }) { + return createServiceFactory({ + service: coreServices.scheduler, + deps: { lifecycle: coreServices.lifecycle }, + factory: async ({ lifecycle }) => { + if (!options?.skipTaskRunOnStartup) { + lifecycle.addStartupHook(async () => { + await this.#triggerAllTasks({ + includeManualTasks: options?.includeManualTasksOnStartup, + includeInitialDelayedTasks: + options?.includeInitialDelayedTasksOnStartup, + }); + }); + } + lifecycle.addShutdownHook(async () => { + await this.#shutdownAllTasks(); + }); + return this; + }, + }); + } + + createScheduledTaskRunner( + schedule: SchedulerServiceTaskScheduleDefinition, + ): SchedulerServiceTaskRunner { + return { + run: async task => { + await this.scheduleTask({ ...task, ...schedule }); + }, + }; + } + + async getScheduledTasks(): Promise { + return Array.from(this.#tasks.values()).map(({ descriptor }) => descriptor); + } + + async scheduleTask( + task: SchedulerServiceTaskScheduleDefinition & + SchedulerServiceTaskInvocationDefinition, + ): Promise { + this.#tasks.set(task.id, { + ...task, + descriptor: { + id: task.id, + scope: task.scope ?? 'global', + settings: { version: 1 }, + }, + abortControllers: new AbortController(), + }); + } + + async triggerTask(id: string): Promise { + const task = this.#tasks.get(id); + if (!task) { + throw new Error(`Task ${id} not found`); + } + if (this.#runningTasks.has(id)) { + return; + } + this.#runningTasks.add(id); + try { + await task.fn(task.abortControllers.signal); + this.#deferredTaskCompletions.get(id)?.resolve(); + } catch (error) { + this.#deferredTaskCompletions.get(id)?.reject(error); + } finally { + this.#deferredTaskCompletions.delete(id); + this.#runningTasks.delete(id); + } + } + + /** + * Trigger all tasks that match the given options, and wait for them to complete. + * + * @param options - The options to filter the tasks to trigger + */ + async #triggerAllTasks(options?: { + scope?: 'all' | 'global' | 'local'; + includeInitialDelayedTasks?: boolean; + includeManualTasks?: boolean; + }): Promise { + const { + scope = 'all', + includeManualTasks = false, + includeInitialDelayedTasks = false, + } = options ?? {}; + + const selectedTaskIds = new Array(); + for (const task of this.#tasks.values()) { + if (task.initialDelay && !includeInitialDelayedTasks) { + continue; + } + if ( + 'trigger' in task.frequency && + task.frequency.trigger === 'manual' && + !includeManualTasks + ) { + continue; + } + if (scope === 'all' || scope === task.scope) { + selectedTaskIds.push(task.id); + } + } + + await Promise.all(selectedTaskIds.map(id => this.triggerTask(id))); + } + + async #shutdownAllTasks() { + for (const task of this.#tasks.values()) { + task.abortControllers.abort(); + } + } + + /** + * Wait for the task with the given ID to complete. + * + * If the task has not yet been scheduled or started, this will wait for it to be scheduled, started, and completed + * + * @param id - The task ID to wait for + * @returns A promise that resolves when the task is completed + */ + async waitForTask(id: string): Promise { + const existing = this.#deferredTaskCompletions.get(id); + if (existing) { + return existing; + } + const deferred = createDeferred(); + this.#deferredTaskCompletions.set(id, deferred); + return deferred; + } +} diff --git a/packages/backend-test-utils/src/next/services/MockUserInfoService.test.ts b/packages/backend-test-utils/src/services/MockUserInfoService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockUserInfoService.test.ts rename to packages/backend-test-utils/src/services/MockUserInfoService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockUserInfoService.ts b/packages/backend-test-utils/src/services/MockUserInfoService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockUserInfoService.ts rename to packages/backend-test-utils/src/services/MockUserInfoService.ts diff --git a/packages/backend-test-utils/src/next/services/index.ts b/packages/backend-test-utils/src/services/index.ts similarity index 87% rename from packages/backend-test-utils/src/next/services/index.ts rename to packages/backend-test-utils/src/services/index.ts index 7c3949e207..73f179ca41 100644 --- a/packages/backend-test-utils/src/next/services/index.ts +++ b/packages/backend-test-utils/src/services/index.ts @@ -13,5 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { mockServices, type ServiceMock } from './mockServices'; +export { mockServices } from './mockServices'; export { mockCredentials } from './mockCredentials'; +export { type ServiceMock } from './simpleMock'; diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts b/packages/backend-test-utils/src/services/mockCredentials.test.ts similarity index 89% rename from packages/backend-test-utils/src/next/services/mockCredentials.test.ts rename to packages/backend-test-utils/src/services/mockCredentials.test.ts index 343d6d6d20..9248e3bde0 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts +++ b/packages/backend-test-utils/src/services/mockCredentials.test.ts @@ -170,4 +170,27 @@ describe('mockCredentials', () => { "Invalid user entity reference 'wrong', expected :/", ); }); + + it('should have a serializable form', () => { + expect(String(mockCredentials.service('my-service'))).toMatchInlineSnapshot( + `"mockCredentials{servicePrincipal{my-service}}"`, + ); + expect( + String(mockCredentials.user('user:default/mock')), + ).toMatchInlineSnapshot( + `"mockCredentials{userPrincipal{user:default/mock}}"`, + ); + expect( + String( + mockCredentials.user('user:default/mock', { + actor: { subject: 'my-actor' }, + }), + ), + ).toMatchInlineSnapshot( + `"mockCredentials{userPrincipal{user:default/mock,actor={my-actor}}}"`, + ); + expect(String(mockCredentials.none())).toMatchInlineSnapshot( + `"mockCredentials{nonePrincipal}"`, + ); + }); }); diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.ts b/packages/backend-test-utils/src/services/mockCredentials.ts similarity index 88% rename from packages/backend-test-utils/src/next/services/mockCredentials.ts rename to packages/backend-test-utils/src/services/mockCredentials.ts index 231c108ac4..d749f7edb1 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.ts +++ b/packages/backend-test-utils/src/services/mockCredentials.ts @@ -76,10 +76,19 @@ export namespace mockCredentials { * Creates a mocked credentials object for a unauthenticated principal. */ export function none(): BackstageCredentials { - return { + const result = { $$type: '@backstage/BackstageCredentials', principal: { type: 'none' }, - }; + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => `mockCredentials{nonePrincipal}`, + }, + }); + return result; } /** @@ -111,16 +120,32 @@ export namespace mockCredentials { options?: { actor?: { subject: string } }, ): BackstageCredentials { validateUserEntityRef(userEntityRef); - return { + const result = { $$type: '@backstage/BackstageCredentials', principal: { type: 'user', userEntityRef, ...(options?.actor && { - actor: { type: 'service', subject: options.actor.subject }, + actor: { type: 'service', subject: options.actor.subject } as const, }), }, - }; + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + value: () => + `mockCredentials{userPrincipal{${userEntityRef}${ + options?.actor ? `,actor={${options.actor.subject}}` : '' + }}}`, + }, + token: { + enumerable: false, + configurable: true, + value: user.token(), + }, + }); + return result; } /** @@ -223,14 +248,27 @@ export namespace mockCredentials { subject: string = DEFAULT_MOCK_SERVICE_SUBJECT, accessRestrictions?: BackstagePrincipalAccessRestrictions, ): BackstageCredentials { - return { + const result = { $$type: '@backstage/BackstageCredentials', principal: { type: 'service', subject, ...(accessRestrictions ? { accessRestrictions } : {}), }, - }; + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + value: () => + `mockCredentials{servicePrincipal{${subject}${ + accessRestrictions + ? `,accessRestrictions=${JSON.stringify(accessRestrictions)}` + : '' + }}}`, + }, + }); + return result; } /** diff --git a/packages/backend-test-utils/src/next/services/mockServices.test.ts b/packages/backend-test-utils/src/services/mockServices.test.ts similarity index 55% rename from packages/backend-test-utils/src/next/services/mockServices.test.ts rename to packages/backend-test-utils/src/services/mockServices.test.ts index 80d6e4c6f1..f5ba684608 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.test.ts +++ b/packages/backend-test-utils/src/services/mockServices.test.ts @@ -30,3 +30,37 @@ describe('mockServices', () => { expect(mockServices[key].factory()).toEqual(expect.any(Object)); }); }); + +describe('mockServices.rootConfig()', () => { + it('should notify about updates', async () => { + const config = mockServices.rootConfig(); + + const fooConfig = config.getConfig('foo'); + + const rootListener = jest.fn(); + const fooListener = jest.fn(); + + config.subscribe?.(rootListener); + fooConfig.subscribe?.(fooListener); + + expect(rootListener).toHaveBeenCalledTimes(0); + expect(fooListener).toHaveBeenCalledTimes(0); + + config.update({ data: { foo: { bar: 1, baz: 2 } } }); + + expect(rootListener).toHaveBeenCalledTimes(1); + expect(fooListener).toHaveBeenCalledTimes(1); + + config.update({ data: { foo: { baz: 2, bar: 1 } } }); + + // Doesn't notify, no changes + expect(rootListener).toHaveBeenCalledTimes(1); + expect(fooListener).toHaveBeenCalledTimes(1); + + config.update({ data: { foo: { bar: 1, baz: 2 }, unrelated: 'key' } }); + + // Notifies all listeners, even if an unrelated key was changed + expect(rootListener).toHaveBeenCalledTimes(2); + expect(fooListener).toHaveBeenCalledTimes(2); + }); +}); diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/services/mockServices.ts similarity index 85% rename from packages/backend-test-utils/src/next/services/mockServices.ts rename to packages/backend-test-utils/src/services/mockServices.ts index f68f1337b9..9ecb59a35b 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/services/mockServices.ts @@ -26,7 +26,6 @@ import { permissionsRegistryServiceFactory } from '@backstage/backend-defaults/p 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, @@ -35,8 +34,11 @@ import { DatabaseService, DiscoveryService, HttpAuthService, + RootInstanceMetadataService, LoggerService, + PermissionsService, RootConfigService, + SchedulerService, ServiceFactory, ServiceRef, UserInfoService, @@ -45,6 +47,7 @@ import { } from '@backstage/backend-plugin-api'; import { ConfigReader } from '@backstage/config'; import { EventsService, eventsServiceRef } from '@backstage/plugin-events-node'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { JsonObject } from '@backstage/types'; import { Knex } from 'knex'; import { MockAuthService } from './MockAuthService'; @@ -53,6 +56,11 @@ import { MockRootLoggerService } from './MockRootLoggerService'; import { MockUserInfoService } from './MockUserInfoService'; import { mockCredentials } from './mockCredentials'; import { MockEventsService } from './MockEventsService'; +import { MockPermissionsService } from './MockPermissionsService'; +import { simpleMock } from './simpleMock'; +import { MockSchedulerService } from './MockSchedulerService'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { ObservableConfigProxy } from '../../../config-loader/src/sources/ObservableConfigProxy'; /** @internal */ function createLoggerMock() { @@ -89,43 +97,6 @@ function simpleFactoryWithOptions< ((...options: TOptions) => ServiceFactory); } -/** @public */ -export type ServiceMock = { - factory: ServiceFactory; -} & { - [Key in keyof TService]: TService[Key] extends ( - ...args: infer Args - ) => infer Return - ? TService[Key] & jest.MockInstance - : TService[Key]; -}; - -/** @internal */ -function simpleMock( - ref: ServiceRef, - mockFactory: () => jest.Mocked, -): (partialImpl?: Partial) => ServiceMock { - return partialImpl => { - const mock = mockFactory(); - if (partialImpl) { - for (const [key, impl] of Object.entries(partialImpl)) { - if (typeof impl === 'function') { - (mock as any)[key].mockImplementation(impl); - } else { - (mock as any)[key] = impl; - } - } - } - return Object.assign(mock, { - factory: createServiceFactory({ - service: ref, - deps: {}, - factory: () => mock, - }), - }) as ServiceMock; - }; -} - /** * Mock implementations of the core services, to be used in tests. * @@ -169,8 +140,16 @@ function simpleMock( * ``` */ export namespace mockServices { - export function rootConfig(options?: rootConfig.Options): RootConfigService { - return new ConfigReader(options?.data, 'mock-config'); + export function rootConfig( + options?: rootConfig.Options, + ): RootConfigService & { update(options: { data: JsonObject }): void } { + const config = ObservableConfigProxy.create(new AbortController()); + config.setConfig(new ConfigReader(options?.data ?? {}, 'mock-config')); + return Object.assign(config, { + update({ data }: { data: JsonObject }): void { + config.setConfig(new ConfigReader(data, 'mock-config')); + }, + }); } export namespace rootConfig { export type Options = { data?: JsonObject }; @@ -473,8 +452,37 @@ export namespace mockServices { ); } + /** + * Creates a functional mock implementation of the + * {@link @backstage/backend-plugin-api#PermissionsService}. + */ + export function permissions(options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }): PermissionsService { + return new MockPermissionsService(options); + } export namespace permissions { - export const factory = () => permissionsServiceFactory; + /** + * Creates a mock factory for the + * {@link @backstage/backend-plugin-api#coreServices.permissions}. Just + * returns the given `result` if you supply one. Otherwise, it returns the + * regular default permissions factory. + */ + export const factory = (options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }) => + options?.result + ? createServiceFactory({ + service: coreServices.permissions, + deps: {}, + factory: () => new MockPermissionsService(options), + }) + : permissionsServiceFactory; + /** + * Creates a mock of the + * {@link @backstage/backend-plugin-api#coreServices.permissions}, + * optionally with some given method implementations. + */ export const mock = simpleMock(coreServices.permissions, () => ({ authorize: jest.fn(), authorizeConditional: jest.fn(), @@ -500,8 +508,15 @@ export namespace mockServices { })); } + export function scheduler(): SchedulerService { + return new MockSchedulerService(); + } export namespace scheduler { - export const factory = () => schedulerServiceFactory; + export const factory = (options?: { + skipTaskRunOnStartup?: boolean; + includeManualTasksOnStartup?: boolean; + includeInitialDelayedTasksOnStartup?: boolean; + }) => new MockSchedulerService().factory(options); export const mock = simpleMock(coreServices.scheduler, () => ({ createScheduledTaskRunner: jest.fn(), getScheduledTasks: jest.fn(), @@ -542,4 +557,19 @@ export namespace mockServices { subscribe: jest.fn(), })); } + + export function rootInstanceMetadata(): RootInstanceMetadataService { + return { + getInstalledPlugins: () => Promise.resolve([]), + }; + } + export namespace rootInstanceMetadata { + export const mock = simpleMock(coreServices.rootInstanceMetadata, () => ({ + getInstalledPlugins: jest.fn(), + })); + export const factory = simpleFactoryWithOptions( + coreServices.rootInstanceMetadata, + rootInstanceMetadata, + ); + } } diff --git a/packages/backend-test-utils/src/services/simpleMock.ts b/packages/backend-test-utils/src/services/simpleMock.ts new file mode 100644 index 0000000000..484969f235 --- /dev/null +++ b/packages/backend-test-utils/src/services/simpleMock.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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, + ServiceFactory, + ServiceRef, +} from '@backstage/backend-plugin-api'; + +/** @public */ +export type ServiceMock = { + factory: ServiceFactory; +} & { + [Key in keyof TService]: TService[Key] extends ( + ...args: infer Args + ) => infer Return + ? TService[Key] & jest.MockInstance + : TService[Key]; +}; + +/** @internal */ +export function simpleMock( + ref: ServiceRef, + mockFactory: () => jest.Mocked, +): (partialImpl?: Partial) => ServiceMock { + return partialImpl => { + const mock = mockFactory(); + if (partialImpl) { + for (const [key, impl] of Object.entries(partialImpl)) { + if (typeof impl === 'function') { + (mock as any)[key].mockImplementation(impl); + } else { + (mock as any)[key] = impl; + } + } + } + return Object.assign(mock, { + factory: createServiceFactory({ + service: ref, + deps: {}, + factory: () => mock, + }), + }) as ServiceMock; + }; +} diff --git a/packages/backend-test-utils/src/util/errorHandler.test.ts b/packages/backend-test-utils/src/util/errorHandler.test.ts new file mode 100644 index 0000000000..a5ed9c1a53 --- /dev/null +++ b/packages/backend-test-utils/src/util/errorHandler.test.ts @@ -0,0 +1,71 @@ +/* + * 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 { InputError } from '@backstage/errors'; +import express from 'express'; +import request from 'supertest'; +import { mockErrorHandler } from './errorHandler'; + +describe('mockErrorHandler', () => { + it('should return a function', () => { + const errorHandler = mockErrorHandler(); + expect(errorHandler).toBeInstanceOf(Function); + }); + + it('should hint that it must be called', () => { + const app = express(); + + // @ts-expect-error - passing the function directly should result in a type error + app.use(mockErrorHandler); + + app.use(mockErrorHandler()); + + expect('test').toBe('test'); + }); + + it('should convert errors in an express app', async () => { + const errorHandler = mockErrorHandler(); + + const app = express(); + app.get('/plain', () => { + throw new Error('test'); + }); + app.get('/input', () => { + throw new InputError('bad'); + }); + app.use(errorHandler); + + await expect(request(app).get('/plain')).resolves.toMatchObject({ + status: 500, + body: { + error: { + name: 'Error', + message: 'test', + }, + }, + }); + + await expect(request(app).get('/input')).resolves.toMatchObject({ + status: 400, + body: { + error: { + name: 'InputError', + message: 'bad', + }, + }, + }); + }); +}); diff --git a/packages/backend-test-utils/src/util/errorHandler.ts b/packages/backend-test-utils/src/util/errorHandler.ts index f534823f50..611fef8747 100644 --- a/packages/backend-test-utils/src/util/errorHandler.ts +++ b/packages/backend-test-utils/src/util/errorHandler.ts @@ -15,13 +15,19 @@ */ import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter'; -import { mockServices } from '../next'; +import { mockServices } from '../services'; /** * A mock for error handler middleware that can be used in router tests. * @public + * + * @example + * ```ts + * const app = express(); + * app.use(mockErrorHandler()); + * ``` */ -export function mockErrorHandler() { +export function mockErrorHandler(_options?: {}, ..._args: never[]) { return MiddlewareFactory.create({ config: mockServices.rootConfig(), logger: mockServices.rootLogger(), diff --git a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.test.ts b/packages/backend-test-utils/src/wiring/ServiceFactoryTester.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.test.ts rename to packages/backend-test-utils/src/wiring/ServiceFactoryTester.test.ts diff --git a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts b/packages/backend-test-utils/src/wiring/ServiceFactoryTester.ts similarity index 97% rename from packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts rename to packages/backend-test-utils/src/wiring/ServiceFactoryTester.ts index 83a6a42307..2b49abc88f 100644 --- a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts +++ b/packages/backend-test-utils/src/wiring/ServiceFactoryTester.ts @@ -20,7 +20,7 @@ import { defaultServiceFactories } from './TestBackend'; // This is a relative import in order to make sure that the implementation is duplicated // rather than leading to an import from @backstage/backend-app-api. // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { ServiceRegistry } from '../../../../backend-app-api/src/wiring/ServiceRegistry'; +import { ServiceRegistry } from '../../../backend-app-api/src/wiring/ServiceRegistry'; /** * Options for {@link ServiceFactoryTester}. diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/wiring/TestBackend.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/wiring/TestBackend.test.ts rename to packages/backend-test-utils/src/wiring/TestBackend.test.ts diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/wiring/TestBackend.ts similarity index 97% rename from packages/backend-test-utils/src/next/wiring/TestBackend.ts rename to packages/backend-test-utils/src/wiring/TestBackend.ts index 20d02cf880..cdfa1fc695 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/wiring/TestBackend.ts @@ -31,7 +31,7 @@ import express from 'express'; import { InternalBackendFeature, InternalBackendRegistrations, -} from '../../../../backend-plugin-api/src/wiring/types'; +} from '../../../backend-plugin-api/src/wiring/types'; import { DefaultRootHttpRouter, ExtendedHttpServer, @@ -40,6 +40,10 @@ import { createHttpServer, } from '@backstage/backend-defaults/rootHttpRouter'; import { HostDiscovery } from '@backstage/backend-defaults/discovery'; +import { + actionsRegistryServiceMock, + actionsServiceMock, +} from '../alpha/services'; /** @public */ export interface TestBackendOptions { @@ -84,6 +88,10 @@ export const defaultServiceFactories = [ mockServices.userInfo.factory(), mockServices.urlReader.factory(), mockServices.events.factory(), + + // Alpha services + actionsRegistryServiceMock.factory(), + actionsServiceMock.factory(), ]; /** diff --git a/packages/backend-test-utils/src/next/wiring/index.ts b/packages/backend-test-utils/src/wiring/index.ts similarity index 100% rename from packages/backend-test-utils/src/next/wiring/index.ts rename to packages/backend-test-utils/src/wiring/index.ts diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index cc5809695e..f59395af02 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,740 @@ # example-backend +## 0.0.44-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.2.0-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.7.8-next.1 + - @backstage/plugin-kubernetes-backend@0.20.4-next.1 + - @backstage/plugin-techdocs-backend@2.1.2-next.1 + - @backstage/plugin-signals-backend@0.3.10-next.1 + - @backstage/backend-defaults@0.13.1-next.1 + - @backstage/plugin-notifications-backend@0.5.12-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.16-next.1 + - @backstage/backend-plugin-api@1.5.0-next.1 + - @backstage/plugin-permission-backend@0.7.6-next.1 + - @backstage/plugin-permission-common@0.9.3-next.1 + - @backstage/plugin-search-backend@2.0.8-next.1 + - @backstage/plugin-auth-backend@0.25.6-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.8-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.6-next.1 + - @backstage/plugin-mcp-actions-backend@0.1.5-next.1 + - @backstage/plugin-scaffolder-backend@3.0.1-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.10-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.8-next.1 + - @backstage/plugin-app-backend@0.5.8-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.9-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.14-next.1 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.2-next.1 + - @backstage/plugin-auth-node@0.6.9-next.1 + - @backstage/plugin-devtools-backend@0.5.11-next.1 + - @backstage/plugin-events-backend@0.5.8-next.1 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.6-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.14-next.1 + - @backstage/plugin-permission-node@0.10.6-next.1 + - @backstage/plugin-proxy-backend@0.6.8-next.1 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.1 + - @backstage/plugin-search-backend-module-explore@0.3.9-next.1 + - @backstage/plugin-search-backend-node@1.3.17-next.1 + +## 0.0.44-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-catalog-backend@3.1.3-next.0 + - @backstage/plugin-notifications-backend@0.5.12-next.0 + - @backstage/plugin-scaffolder-backend@3.0.1-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.7.8-next.0 + - @backstage/plugin-search-backend@2.0.8-next.0 + - @backstage/plugin-search-backend-node@1.3.17-next.0 + - @backstage/plugin-kubernetes-backend@0.20.4-next.0 + - @backstage/plugin-events-backend@0.5.8-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.8-next.0 + - @backstage/plugin-auth-backend@0.25.6-next.0 + - @backstage/plugin-devtools-backend@0.5.11-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.6-next.0 + - @backstage/plugin-auth-node@0.6.9-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.5-next.0 + - @backstage/plugin-app-backend@0.5.8-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.9-next.0 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.2-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.6-next.0 + - @backstage/plugin-permission-backend@0.7.6-next.0 + - @backstage/plugin-permission-node@0.10.6-next.0 + - @backstage/plugin-proxy-backend@0.6.8-next.0 + - @backstage/plugin-signals-backend@0.3.10-next.0 + - @backstage/plugin-techdocs-backend@2.1.2-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.14-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.16-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.14-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.14-next.0 + - @backstage/plugin-permission-common@0.9.3-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.9.2-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.16-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.10-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.9-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.8-next.0 + +## 0.0.43 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.2 + - @backstage/backend-defaults@0.13.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.15 + - @backstage/plugin-scaffolder-backend-module-github@0.9.1 + - @backstage/plugin-scaffolder-backend@3.0.0 + - @backstage/plugin-notifications-backend@0.5.11 + - @backstage/backend-plugin-api@1.4.4 + - @backstage/plugin-app-backend@0.5.7 + - @backstage/plugin-auth-backend@0.25.5 + - @backstage/plugin-auth-backend-module-github-provider@0.3.8 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.13 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.1 + - @backstage/plugin-auth-node@0.6.8 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.7 + - @backstage/plugin-catalog-backend-module-openapi@0.2.15 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.5 + - @backstage/plugin-devtools-backend@0.5.10 + - @backstage/plugin-events-backend@0.5.7 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.5 + - @backstage/plugin-kubernetes-backend@0.20.3 + - @backstage/plugin-mcp-actions-backend@0.1.4 + - @backstage/plugin-permission-backend@0.7.5 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.13 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-node@0.10.5 + - @backstage/plugin-proxy-backend@0.6.7 + - @backstage/plugin-search-backend@2.0.7 + - @backstage/plugin-search-backend-module-catalog@0.3.9 + - @backstage/plugin-search-backend-module-explore@0.3.8 + - @backstage/plugin-search-backend-module-techdocs@0.4.7 + - @backstage/plugin-search-backend-node@1.3.16 + - @backstage/plugin-signals-backend@0.3.9 + - @backstage/plugin-techdocs-backend@2.1.1 + +## 0.0.43-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/plugin-app-backend@0.5.7-next.0 + - @backstage/plugin-devtools-backend@0.5.10-next.1 + - @backstage/plugin-proxy-backend@0.6.7-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/plugin-auth-backend@0.25.5-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.13-next.0 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.1-next.0 + - @backstage/plugin-auth-node@0.6.8-next.0 + - @backstage/plugin-catalog-backend@3.1.1-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.7-next.0 + - @backstage/plugin-events-backend@0.5.7-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.5-next.0 + - @backstage/plugin-kubernetes-backend@0.20.3-next.1 + - @backstage/plugin-notifications-backend@0.5.11-next.0 + - @backstage/plugin-permission-backend@0.7.5-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-node@0.10.5-next.0 + - @backstage/plugin-scaffolder-backend@3.0.0-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.1-next.1 + - @backstage/plugin-search-backend@2.0.7-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.9-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.8-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.7-next.1 + - @backstage/plugin-search-backend-node@1.3.16-next.0 + - @backstage/plugin-signals-backend@0.3.9-next.0 + - @backstage/plugin-techdocs-backend@2.1.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.8-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.15-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.5-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.4-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.13-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.15-next.1 + +## 0.0.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.1.1-next.0 + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.15-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.9.1-next.0 + - @backstage/plugin-scaffolder-backend@3.0.0-next.0 + - @backstage/plugin-app-backend@0.5.6 + - @backstage/plugin-auth-backend@0.25.4 + - @backstage/plugin-auth-backend-module-github-provider@0.3.7 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-devtools-backend@0.5.10-next.0 + - @backstage/plugin-events-backend@0.5.6 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.4 + - @backstage/plugin-kubernetes-backend@0.20.3-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.4-next.0 + - @backstage/plugin-notifications-backend@0.5.10 + - @backstage/plugin-permission-backend@0.7.4 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-proxy-backend@0.6.6 + - @backstage/plugin-search-backend@2.0.7-next.0 + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/plugin-signals-backend@0.3.8 + - @backstage/plugin-techdocs-backend@2.1.1-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.15-next.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.12 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.6 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.13-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.4 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.12 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-search-backend-module-catalog@0.3.8 + - @backstage/plugin-search-backend-module-explore@0.3.7 + - @backstage/plugin-search-backend-module-techdocs@0.4.7-next.0 + +## 0.0.42 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-scaffolder-backend-module-github@0.9.0 + - @backstage/plugin-scaffolder-backend@2.2.1 + - @backstage/plugin-catalog-backend@3.1.0 + - @backstage/plugin-mcp-actions-backend@0.1.3 + - @backstage/plugin-auth-backend@0.25.4 + - @backstage/plugin-techdocs-backend@2.1.0 + - @backstage/plugin-auth-node@0.6.7 + - @backstage/plugin-app-backend@0.5.6 + - @backstage/plugin-kubernetes-backend@0.20.2 + - @backstage/plugin-events-backend@0.5.6 + - @backstage/plugin-search-backend@2.0.6 + - @backstage/plugin-search-backend-module-explore@0.3.7 + - @backstage/plugin-notifications-backend@0.5.10 + - @backstage/plugin-auth-backend-module-openshift-provider@0.1.0 + - @backstage/backend-plugin-api@1.4.3 + - @backstage/plugin-auth-backend-module-github-provider@0.3.7 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.12 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.6 + - @backstage/plugin-catalog-backend-module-openapi@0.2.14 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.4 + - @backstage/plugin-devtools-backend@0.5.9 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.4 + - @backstage/plugin-permission-backend@0.7.4 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.12 + - @backstage/plugin-permission-node@0.10.4 + - @backstage/plugin-proxy-backend@0.6.6 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.14 + - @backstage/plugin-search-backend-module-catalog@0.3.8 + - @backstage/plugin-search-backend-module-techdocs@0.4.6 + - @backstage/plugin-search-backend-node@1.3.15 + - @backstage/plugin-signals-backend@0.3.8 + +## 0.0.42-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.2-next.0 + - @backstage/plugin-techdocs-backend@2.1.0-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.3-next.0 + - @backstage/plugin-auth-node@0.6.7-next.0 + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.14-next.0 + - @backstage/plugin-scaffolder-backend@2.2.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.3-next.0 + - @backstage/backend-plugin-api@1.4.3-next.0 + - @backstage/plugin-app-backend@0.5.6-next.0 + - @backstage/plugin-auth-backend@0.25.4-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.7-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.12-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.4-next.0 + - @backstage/plugin-kubernetes-backend@0.20.2-next.1 + - @backstage/plugin-notifications-backend@0.5.10-next.0 + - @backstage/plugin-permission-backend@0.7.4-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.12-next.0 + - @backstage/plugin-permission-node@0.10.4-next.0 + - @backstage/plugin-signals-backend@0.3.8-next.0 + - @backstage/plugin-devtools-backend@0.5.9-next.0 + - @backstage/plugin-events-backend@0.5.6-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.4-next.0 + - @backstage/plugin-proxy-backend@0.6.6-next.0 + - @backstage/plugin-search-backend@2.0.6-next.0 + - @backstage/plugin-search-backend-node@1.3.15-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.12-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.14-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.6-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.6-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.8-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.7-next.1 + +## 0.0.42-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-module-explore@0.3.6-next.0 + - @backstage/plugin-kubernetes-backend@0.20.2-next.0 + - @backstage/backend-defaults@0.12.0 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-app-backend@0.5.5 + - @backstage/plugin-auth-backend@0.25.3 + - @backstage/plugin-auth-backend-module-github-provider@0.3.6 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.11 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-catalog-backend@3.0.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.5 + - @backstage/plugin-catalog-backend-module-openapi@0.2.13 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.3 + - @backstage/plugin-devtools-backend@0.5.8 + - @backstage/plugin-events-backend@0.5.5 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.3 + - @backstage/plugin-mcp-actions-backend@0.1.2 + - @backstage/plugin-notifications-backend@0.5.9 + - @backstage/plugin-permission-backend@0.7.3 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.11 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/plugin-proxy-backend@0.6.5 + - @backstage/plugin-scaffolder-backend@2.2.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.13 + - @backstage/plugin-search-backend@2.0.5 + - @backstage/plugin-search-backend-module-catalog@0.3.7 + - @backstage/plugin-search-backend-module-techdocs@0.4.5 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/plugin-signals-backend@0.3.7 + - @backstage/plugin-techdocs-backend@2.0.5 + +## 0.0.41 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-backend@0.20.0 + - @backstage/plugin-scaffolder-backend@2.2.0 + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-catalog-backend@3.0.1 + - @backstage/plugin-proxy-backend@0.6.5 + - @backstage/plugin-search-backend-module-explore@0.3.5 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2 + - @backstage/plugin-techdocs-backend@2.0.5 + - @backstage/plugin-search-backend-module-catalog@0.3.7 + - @backstage/plugin-notifications-backend@0.5.9 + - @backstage/plugin-app-backend@0.5.5 + - @backstage/plugin-auth-backend@0.25.3 + - @backstage/plugin-auth-backend-module-github-provider@0.3.6 + - @backstage/plugin-auth-node@0.6.6 + - @backstage/plugin-devtools-backend@0.5.8 + - @backstage/plugin-events-backend@0.5.5 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.3 + - @backstage/plugin-mcp-actions-backend@0.1.2 + - @backstage/plugin-permission-backend@0.7.3 + - @backstage/plugin-permission-node@0.10.3 + - @backstage/plugin-search-backend@2.0.5 + - @backstage/plugin-search-backend-node@1.3.14 + - @backstage/plugin-signals-backend@0.3.7 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.13 + - @backstage/backend-plugin-api@1.4.2 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.11 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.5 + - @backstage/plugin-catalog-backend-module-openapi@0.2.13 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.3 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.11 + - @backstage/plugin-search-backend-module-techdocs@0.4.5 + +## 0.0.41-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.1-next.1 + - @backstage/plugin-kubernetes-backend@0.20.0-next.1 + - @backstage/plugin-scaffolder-backend@2.2.0-next.1 + - @backstage/plugin-proxy-backend@0.6.5-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2-next.1 + +## 0.0.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes-backend@0.19.9-next.0 + - @backstage/plugin-scaffolder-backend@2.2.0-next.0 + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-catalog-backend@3.0.1-next.0 + - @backstage/plugin-app-backend@0.5.5-next.0 + - @backstage/plugin-auth-backend@0.25.3-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.6-next.0 + - @backstage/plugin-auth-node@0.6.6-next.0 + - @backstage/plugin-devtools-backend@0.5.8-next.0 + - @backstage/plugin-events-backend@0.5.5-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.3-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.2-next.0 + - @backstage/plugin-notifications-backend@0.5.9-next.0 + - @backstage/plugin-permission-backend@0.7.3-next.0 + - @backstage/plugin-permission-node@0.10.3-next.0 + - @backstage/plugin-proxy-backend@0.6.5-next.0 + - @backstage/plugin-search-backend@2.0.5-next.0 + - @backstage/plugin-search-backend-node@1.3.14-next.0 + - @backstage/plugin-signals-backend@0.3.7-next.0 + - @backstage/plugin-techdocs-backend@2.0.5-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.5-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.2-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.13-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.7-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.5-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.13-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.3-next.0 + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.11-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.11-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/plugin-permission-common@0.9.1 + +## 0.0.40 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0 + - @backstage/plugin-scaffolder-backend@2.1.0 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-node@0.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-notifications-backend@0.5.8 + - @backstage/plugin-mcp-actions-backend@0.1.1 + - @backstage/plugin-auth-backend@0.25.2 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1 + - @backstage/plugin-search-backend@2.0.4 + - @backstage/backend-plugin-api@1.4.1 + - @backstage/plugin-app-backend@0.5.4 + - @backstage/plugin-auth-backend-module-github-provider@0.3.5 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.10 + - @backstage/plugin-auth-node@0.6.5 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.4 + - @backstage/plugin-catalog-backend-module-openapi@0.2.12 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.2 + - @backstage/plugin-devtools-backend@0.5.7 + - @backstage/plugin-events-backend@0.5.4 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.2 + - @backstage/plugin-kubernetes-backend@0.19.8 + - @backstage/plugin-permission-backend@0.7.2 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.10 + - @backstage/plugin-proxy-backend@0.6.4 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12 + - @backstage/plugin-search-backend-module-catalog@0.3.6 + - @backstage/plugin-search-backend-module-explore@0.3.4 + - @backstage/plugin-search-backend-module-techdocs@0.4.4 + - @backstage/plugin-search-backend-node@1.3.13 + - @backstage/plugin-signals-backend@0.3.6 + - @backstage/plugin-techdocs-backend@2.0.4 + +## 0.0.40-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.2-next.1 + - @backstage/plugin-scaffolder-backend@2.1.0-next.2 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.2 + +## 0.0.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/plugin-permission-node@0.10.2-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/plugin-app-backend@0.5.4-next.0 + - @backstage/plugin-devtools-backend@0.5.7-next.1 + - @backstage/plugin-proxy-backend@0.6.4-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + - @backstage/plugin-auth-backend@0.25.2-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.10-next.0 + - @backstage/plugin-auth-node@0.6.5-next.0 + - @backstage/plugin-catalog-backend@3.0.0-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.4-next.0 + - @backstage/plugin-events-backend@0.5.4-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.2-next.0 + - @backstage/plugin-kubernetes-backend@0.19.8-next.0 + - @backstage/plugin-notifications-backend@0.5.8-next.1 + - @backstage/plugin-permission-backend@0.7.2-next.0 + - @backstage/plugin-scaffolder-backend@2.0.1-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.1 + - @backstage/plugin-search-backend@2.0.4-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.6-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.4-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.4-next.1 + - @backstage/plugin-search-backend-node@1.3.13-next.0 + - @backstage/plugin-signals-backend@0.3.6-next.0 + - @backstage/plugin-techdocs-backend@2.0.4-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.2-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.10-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.12-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.10-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.5-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.1 + +## 0.0.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-backend@2.0.1-next.0 + - @backstage/plugin-notifications-backend@0.5.8-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.0 + - @backstage/plugin-search-backend@2.0.4-next.0 + - @backstage/plugin-app-backend@0.5.3 + - @backstage/plugin-auth-backend@0.25.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-devtools-backend@0.5.7-next.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + - @backstage/plugin-kubernetes-backend@0.19.7 + - @backstage/plugin-permission-backend@0.7.1 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-proxy-backend@0.6.3 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-signals-backend@0.3.5 + - @backstage/plugin-techdocs-backend@2.0.4-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + - @backstage/plugin-catalog-backend-module-openapi@0.2.12-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + - @backstage/plugin-search-backend-module-catalog@0.3.5 + - @backstage/plugin-search-backend-module-explore@0.3.3 + - @backstage/plugin-search-backend-module-techdocs@0.4.4-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + - @backstage/plugin-permission-common@0.9.0 + +## 0.0.39 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-backend@0.5.7 + - @backstage/plugin-scaffolder-backend-module-github@0.8.0 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-backend@2.0.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-devtools-backend@0.5.6 + - @backstage/plugin-mcp-actions-backend@0.1.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-search-backend@2.0.3 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-search-backend-module-techdocs@0.4.3 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-kubernetes-backend@0.19.7 + - @backstage/plugin-search-backend-module-catalog@0.3.5 + - @backstage/plugin-techdocs-backend@2.0.3 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-app-backend@0.5.3 + - @backstage/plugin-auth-backend@0.25.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + - @backstage/plugin-permission-backend@0.7.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-proxy-backend@0.6.3 + - @backstage/plugin-search-backend-module-explore@0.3.3 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-signals-backend@0.3.5 + +## 0.0.39-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-github@0.8.0-next.2 + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/plugin-scaffolder-backend@2.0.0-next.2 + - @backstage/plugin-notifications-backend@0.5.7-next.2 + - @backstage/plugin-catalog-backend@2.0.1-next.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11-next.2 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-app-backend@0.5.3-next.1 + - @backstage/plugin-auth-backend@0.25.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9-next.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1-next.1 + - @backstage/plugin-devtools-backend@0.5.6-next.2 + - @backstage/plugin-events-backend@0.5.3-next.1 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1-next.1 + - @backstage/plugin-kubernetes-backend@0.19.7-next.1 + - @backstage/plugin-permission-backend@0.7.1-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-proxy-backend@0.6.3-next.1 + - @backstage/plugin-search-backend@2.0.3-next.2 + - @backstage/plugin-search-backend-module-catalog@0.3.5-next.1 + - @backstage/plugin-search-backend-module-explore@0.3.3-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.3-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-signals-backend@0.3.5-next.1 + - @backstage/plugin-techdocs-backend@2.0.3-next.2 + +## 0.0.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11-next.1 + - @backstage/plugin-notifications-backend@0.5.7-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.3-next.1 + - @backstage/plugin-scaffolder-backend@2.0.0-next.1 + - @backstage/plugin-auth-node@0.6.4-next.1 + - @backstage/plugin-catalog-backend@2.0.1-next.1 + - @backstage/plugin-kubernetes-backend@0.19.7-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.7.2-next.1 + - @backstage/plugin-search-backend-module-catalog@0.3.5-next.1 + - @backstage/plugin-techdocs-backend@2.0.3-next.1 + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-app-backend@0.5.3-next.1 + - @backstage/plugin-auth-backend@0.25.1-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1-next.1 + - @backstage/plugin-devtools-backend@0.5.6-next.1 + - @backstage/plugin-events-backend@0.5.3-next.1 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1-next.1 + - @backstage/plugin-permission-backend@0.7.1-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9-next.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1-next.1 + - @backstage/plugin-proxy-backend@0.6.3-next.1 + - @backstage/plugin-search-backend@2.0.3-next.1 + - @backstage/plugin-search-backend-module-explore@0.3.3-next.1 + - @backstage/plugin-search-backend-node@1.3.12-next.1 + - @backstage/plugin-signals-backend@0.3.5-next.1 + +## 0.0.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.0.1-next.0 + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-events-backend@0.5.3-next.0 + - @backstage/plugin-search-backend@2.0.3-next.0 + - @backstage/plugin-scaffolder-backend@1.33.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.7.2-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11-next.0 + - @backstage/plugin-techdocs-backend@2.0.3-next.0 + - @backstage/plugin-app-backend@0.5.3-next.0 + - @backstage/plugin-auth-backend@0.25.1-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9-next.0 + - @backstage/plugin-auth-node@0.6.4-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9-next.0 + - @backstage/plugin-devtools-backend@0.5.6-next.0 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1-next.0 + - @backstage/plugin-kubernetes-backend@0.19.7-next.0 + - @backstage/plugin-notifications-backend@0.5.7-next.0 + - @backstage/plugin-permission-backend@0.7.1-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9-next.0 + - @backstage/plugin-permission-node@0.10.1-next.0 + - @backstage/plugin-proxy-backend@0.6.3-next.0 + - @backstage/plugin-search-backend-module-catalog@0.3.5-next.0 + - @backstage/plugin-search-backend-module-explore@0.3.3-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.4.3-next.0 + - @backstage/plugin-search-backend-node@1.3.12-next.0 + - @backstage/plugin-signals-backend@0.3.5-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1-next.0 + +## 0.0.38 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-backend@0.25.0 + - @backstage/plugin-catalog-backend@2.0.0 + - @backstage/plugin-scaffolder-backend-module-github@0.7.1 + - @backstage/backend-defaults@0.10.0 + - @backstage/plugin-auth-backend-module-github-provider@0.3.3 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.2 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-kubernetes-backend@0.19.6 + - @backstage/plugin-auth-node@0.6.3 + - @backstage/plugin-scaffolder-backend@1.33.0 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/plugin-permission-backend@0.7.0 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.0 + - @backstage/plugin-techdocs-backend@2.0.2 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.10 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.0 + - @backstage/plugin-notifications-backend@0.5.6 + - @backstage/plugin-signals-backend@0.3.4 + - @backstage/plugin-catalog-backend-module-openapi@0.2.10 + - @backstage/plugin-app-backend@0.5.2 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.8 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.8 + - @backstage/plugin-devtools-backend@0.5.5 + - @backstage/plugin-events-backend@0.5.2 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.8 + - @backstage/plugin-proxy-backend@0.6.2 + - @backstage/plugin-search-backend@2.0.2 + - @backstage/plugin-search-backend-module-catalog@0.3.4 + - @backstage/plugin-search-backend-module-explore@0.3.2 + - @backstage/plugin-search-backend-module-techdocs@0.4.2 + - @backstage/plugin-search-backend-node@1.3.11 + ## 0.0.38-next.3 ### Patch Changes diff --git a/packages/backend/knip-report.md b/packages/backend/knip-report.md index d24322fd2b..2410758b6d 100644 --- a/packages/backend/knip-report.md +++ b/packages/backend/knip-report.md @@ -4,12 +4,12 @@ | Name | Location | Severity | | :----------------------------------------------- | :----------- | :------- | -| @backstage/plugin-catalog-backend-module-openapi | package.json | error | -| @opentelemetry/auto-instrumentations-node | package.json | error | -| @backstage/plugin-search-backend-node | package.json | error | -| @backstage/plugin-permission-common | package.json | error | -| @opentelemetry/exporter-prometheus | package.json | error | -| @backstage/plugin-permission-node | package.json | error | -| @opentelemetry/sdk-node | package.json | error | -| example-app | package.json | error | +| @backstage/plugin-catalog-backend-module-openapi | packages/backend/package.json | error | +| @opentelemetry/auto-instrumentations-node | packages/backend/package.json | error | +| @backstage/plugin-search-backend-node | packages/backend/package.json | error | +| @backstage/plugin-permission-common | packages/backend/package.json | error | +| @opentelemetry/exporter-prometheus | packages/backend/package.json | error | +| @backstage/plugin-permission-node | packages/backend/package.json | error | +| @opentelemetry/sdk-node | packages/backend/package.json | error | +| example-app | packages/backend/package.json | error | diff --git a/packages/backend/package.json b/packages/backend/package.json index c6675f7e38..3f2d388318 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.38-next.3", + "version": "0.0.44-next.1", "backstage": { "role": "backend" }, @@ -37,6 +37,7 @@ "@backstage/plugin-auth-backend": "workspace:^", "@backstage/plugin-auth-backend-module-github-provider": "workspace:^", "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^", + "@backstage/plugin-auth-backend-module-openshift-provider": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-catalog-backend": "workspace:^", "@backstage/plugin-catalog-backend-module-backstage-openapi": "workspace:^", @@ -47,6 +48,7 @@ "@backstage/plugin-events-backend": "workspace:^", "@backstage/plugin-events-backend-module-google-pubsub": "workspace:^", "@backstage/plugin-kubernetes-backend": "workspace:^", + "@backstage/plugin-mcp-actions-backend": "workspace:^", "@backstage/plugin-notifications-backend": "workspace:^", "@backstage/plugin-permission-backend": "workspace:^", "@backstage/plugin-permission-backend-module-allow-all-policy": "workspace:^", @@ -58,12 +60,13 @@ "@backstage/plugin-scaffolder-backend-module-notifications": "workspace:^", "@backstage/plugin-search-backend": "workspace:^", "@backstage/plugin-search-backend-module-catalog": "workspace:^", + "@backstage/plugin-search-backend-module-elasticsearch": "workspace:^", "@backstage/plugin-search-backend-module-explore": "workspace:^", "@backstage/plugin-search-backend-module-techdocs": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", "@backstage/plugin-signals-backend": "workspace:^", "@backstage/plugin-techdocs-backend": "workspace:^", - "@opentelemetry/auto-instrumentations-node": "^0.54.0", + "@opentelemetry/auto-instrumentations-node": "^0.61.0", "@opentelemetry/exporter-prometheus": "^0.54.0", "@opentelemetry/sdk-node": "^0.54.0", "example-app": "link:../app" diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 23d814f1ae..541c3bd791 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -15,24 +15,34 @@ */ import { createBackend } from '@backstage/backend-defaults'; -import { createBackendFeatureLoader } from '@backstage/backend-plugin-api'; +import { + coreServices, + createBackendFeatureLoader, +} from '@backstage/backend-plugin-api'; const backend = createBackend(); // An example of how to group together and load multiple features. You can also // access root-scoped services by adding `deps`. const searchLoader = createBackendFeatureLoader({ - *loader() { + deps: { + config: coreServices.rootConfig, + }, + *loader({ config }) { yield import('@backstage/plugin-search-backend'); yield import('@backstage/plugin-search-backend-module-catalog'); yield import('@backstage/plugin-search-backend-module-explore'); yield import('@backstage/plugin-search-backend-module-techdocs'); + if (config.has('search.elasticsearch')) { + yield import('@backstage/plugin-search-backend-module-elasticsearch'); + } }, }); 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-auth-backend-module-openshift-provider')); backend.add(import('@backstage/plugin-app-backend')); backend.add(import('@backstage/plugin-catalog-backend-module-unprocessed')); backend.add( @@ -62,4 +72,5 @@ backend.add(import('@backstage/plugin-notifications-backend')); backend.add(import('./instanceMetadata')); backend.add(import('@backstage/plugin-events-backend-module-google-pubsub')); +backend.add(import('@backstage/plugin-mcp-actions-backend')); backend.start(); diff --git a/packages/backend/src/instanceMetadata.ts b/packages/backend/src/instanceMetadata.ts index 5f835f3117..026fc6fd02 100644 --- a/packages/backend/src/instanceMetadata.ts +++ b/packages/backend/src/instanceMetadata.ts @@ -17,21 +17,21 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { instanceMetadataServiceRef } from '@backstage/backend-plugin-api/alpha'; -// Example usage of the instance metadata service to log the installed features. +// Example usage of the instance metadata service to log the installed plugins. export default createBackendPlugin({ pluginId: 'instance-metadata-logging', register(env) { env.registerInit({ deps: { - instanceMetadata: instanceMetadataServiceRef, + instanceMetadata: coreServices.rootInstanceMetadata, logger: coreServices.logger, }, async init({ instanceMetadata, logger }) { + const plugins = await instanceMetadata.getInstalledPlugins(); logger.info( - `Installed features on this instance: ${instanceMetadata - .getInstalledFeatures() + `Installed plugins on this instance: ${plugins + .map(e => e.pluginId) .join(', ')}`, ); }, diff --git a/packages/canon/.storybook/main.ts b/packages/canon/.storybook/main.ts deleted file mode 100644 index e58c0f182f..0000000000 --- a/packages/canon/.storybook/main.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { StorybookConfig } from '@storybook/react-webpack5'; -import { join, dirname } from 'path'; - -/** - * This function is used to resolve the absolute path of a package. - * It is needed in projects that use Yarn PnP or are set up within a monorepo. - */ -function getAbsolutePath(value: string): string { - return dirname(require.resolve(join(value, 'package.json'))); -} -const config: StorybookConfig = { - stories: [ - '../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)', - '../src/stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', - ], - staticDirs: ['../static'], - addons: [ - getAbsolutePath('@storybook/addon-webpack5-compiler-swc'), - getAbsolutePath('@storybook/addon-essentials'), - getAbsolutePath('@storybook/addon-interactions'), - getAbsolutePath('@storybook/addon-themes'), - ], - framework: { - name: getAbsolutePath('@storybook/react-webpack5'), - options: {}, - }, - // https://storybook.js.org/docs/configure/integration/compilers#the-swc-compiler-doesnt-work-with-react - swc: () => ({ - jsc: { - transform: { - react: { - runtime: 'automatic', - }, - }, - }, - }), -}; -export default config; diff --git a/packages/canon/.storybook/preview.tsx b/packages/canon/.storybook/preview.tsx deleted file mode 100644 index 405cdfa093..0000000000 --- a/packages/canon/.storybook/preview.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import type { Preview, ReactRenderer } from '@storybook/react'; -import { withThemeByDataAttribute } from '@storybook/addon-themes'; -import '../src/css/styles.css'; - -const preview: Preview = { - parameters: { - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - backgrounds: { - disable: true, - }, - options: { - storySort: { - method: 'alphabetical', - order: ['Core Concepts', 'Components'], - }, - }, - viewport: { - viewports: { - initial: { - name: 'Initial', - styles: { - width: '320px', - height: '100%', - }, - }, - xs: { - name: 'Extra Small', - styles: { - width: '640px', - height: '100%', - }, - }, - sm: { - name: 'Small', - styles: { - width: '768px', - height: '100%', - }, - }, - md: { - name: 'Medium', - styles: { - width: '1024px', - height: '100%', - }, - }, - lg: { - name: 'Large', - styles: { - width: '1280px', - height: '100%', - }, - }, - xl: { - name: 'Extra Large', - styles: { - width: '1536px', - height: '100%', - }, - }, - }, - }, - }, - decorators: [ - withThemeByDataAttribute({ - themes: { - Light: 'light', - Dark: 'dark', - }, - defaultTheme: 'Light', - }), - Story => { - document.body.style.backgroundColor = 'var(--canon-bg)'; - - const docsStoryElements = document.getElementsByClassName('docs-story'); - Array.from(docsStoryElements).forEach(element => { - (element as HTMLElement).style.backgroundColor = 'var(--canon-bg)'; - }); - - return ; - }, - ], -}; - -export default preview; diff --git a/packages/canon/CHANGELOG.md b/packages/canon/CHANGELOG.md deleted file mode 100644 index dea67aa06c..0000000000 --- a/packages/canon/CHANGELOG.md +++ /dev/null @@ -1,177 +0,0 @@ -# @backstage/canon - -## 0.4.0-next.3 - -### Patch Changes - -- c8f32db: Use correct colour token for TextField clear button icon, prevent layout shift whenever it is hidden or shown and properly size focus area around it. Also stop leading icon shrinking when used together with clear button. - -## 0.4.0-next.2 - -### Patch Changes - -- 6189bfd: Added new icon and onClear props to the TextField to make it easier to accessorize inputs. -- 97b25a1: Pin version of @base-ui-components/react. -- 185d3a8: Use the Field component from Base UI within the TextField. - -## 0.4.0-next.1 - -### Minor Changes - -- ea36f74: **Breaking Change** Icons on Button and IconButton now need to be imported and placed like this: - ); - }, -); - -export default Button; diff --git a/packages/canon/src/components/Button/index.tsx b/packages/canon/src/components/Button/index.tsx deleted file mode 100644 index 9051f1145e..0000000000 --- a/packages/canon/src/components/Button/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -export { Button } from './Button'; -export type { ButtonProps } from './types'; -export { buttonPropDefs } from './Button.props'; -export type { ButtonOwnProps } from './Button.props'; diff --git a/packages/canon/src/components/Button/styles.css b/packages/canon/src/components/Button/styles.css deleted file mode 100644 index a4afd85c9b..0000000000 --- a/packages/canon/src/components/Button/styles.css +++ /dev/null @@ -1,107 +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. - */ - -.canon-Button { - border: none; - display: inline-flex; - align-items: center; - justify-content: center; - user-select: none; - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-bold); - padding: 0; - cursor: pointer; - border-radius: var(--canon-radius-2); - gap: var(--canon-space-1_5); - - &:disabled { - cursor: not-allowed; - } -} - -.canon-Button[data-variant='primary'] { - background-color: var(--canon-bg-solid); - color: var(--canon-fg-solid); - transition: background-color 150ms ease, box-shadow 150ms ease; - - &:hover { - background-color: var(--canon-bg-solid-hover); - } - - &:active { - background-color: var(--canon-bg-solid-pressed); - } - - &:focus-visible { - outline: 2px solid var(--canon-ring); - outline-offset: 2px; - } - - &:disabled { - background-color: var(--canon-bg-solid-disabled); - color: var(--canon-fg-solid-disabled); - } -} - -.canon-Button[data-variant='secondary'] { - background-color: var(--canon-bg-surface-1); - box-shadow: inset 0 0 0 1px var(--canon-border); - color: var(--canon-fg-primary); - transition: box-shadow 150ms ease; - - &:hover { - box-shadow: inset 0 0 0 1px var(--canon-border-hover); - } - - &:active { - box-shadow: inset 0 0 0 1px var(--canon-border-pressed); - } - - &:focus-visible { - outline: none; - transition: none; - box-shadow: inset 0 0 0 2px var(--canon-ring); - } - - &:disabled { - box-shadow: inset 0 0 0 1px var(--canon-border-disabled); - color: var(--canon-fg-disabled); - } -} - -.canon-Button[data-size='medium'] { - font-size: var(--canon-font-size-4); - padding: 0 var(--canon-space-3); - height: 40px; -} - -.canon-Button[data-size='small'] { - font-size: var(--canon-font-size-3); - padding: 0 var(--canon-space-2); - height: 32px; -} - -.canon-ButtonIcon[data-size='small'], -.canon-ButtonIcon[data-size='small'] svg { - width: 1rem; - height: 1rem; -} - -.canon-ButtonIcon[data-size='medium'], -.canon-ButtonIcon[data-size='medium'] svg { - width: 1.25rem; - height: 1.25rem; -} diff --git a/packages/canon/src/components/Checkbox/Checkbox.tsx b/packages/canon/src/components/Checkbox/Checkbox.tsx deleted file mode 100644 index 5bf6520891..0000000000 --- a/packages/canon/src/components/Checkbox/Checkbox.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { forwardRef } from 'react'; -import { Checkbox as CheckboxPrimitive } from '@base-ui-components/react/checkbox'; -import { Icon } from '@backstage/canon'; -import type { CheckboxProps } from './types'; -import clsx from 'clsx'; - -/** @public */ -export const Checkbox = forwardRef( - (props, ref) => { - const { - label, - checked, - onChange, - disabled, - required, - className, - name, - value, - style, - } = props; - - const checkboxElement = ( - - - - - - ); - - return label ? ( - - ) : ( - checkboxElement - ); - }, -); diff --git a/packages/canon/src/components/Checkbox/styles.css b/packages/canon/src/components/Checkbox/styles.css deleted file mode 100644 index 8468980bf2..0000000000 --- a/packages/canon/src/components/Checkbox/styles.css +++ /dev/null @@ -1,52 +0,0 @@ -.canon-CheckboxRoot { - border: none; - display: flex; - align-items: center; - justify-content: center; - width: 1rem; - height: 1rem; - box-shadow: inset 0 0 0 1px var(--canon-border); - cursor: pointer; - border-radius: 2px; - transition: background-color 0.2s ease-in-out; - background-color: var(--canon-bg-surface-1); - padding: 0; - flex-shrink: 0; -} - -.canon-CheckboxRoot:focus-visible { - transition: none; - outline: 2px solid var(--canon-ring); - outline-offset: 2px; -} - -.canon-CheckboxRoot[data-checked] { - background-color: var(--canon-bg-solid); - box-shadow: none; - color: var(--canon-fg-solid); -} - -.canon-CheckboxLabel { - display: flex; - flex-direction: row; - align-items: center; - gap: var(--canon-space-2); - font-size: var(--canon-font-size-3); - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - user-select: none; - - &:hover { - & .canon-CheckboxRoot:not([data-checked]) { - box-shadow: inset 0 0 0 1px var(--canon-border-hover); - } - } -} - -.canon-CheckboxIndicator { - display: flex; - align-items: center; - justify-content: center; - color: var(--canon-fg-solid); -} diff --git a/packages/canon/src/components/Collapsible/Collapsible.stories.tsx b/packages/canon/src/components/Collapsible/Collapsible.stories.tsx deleted file mode 100644 index 175dadba85..0000000000 --- a/packages/canon/src/components/Collapsible/Collapsible.stories.tsx +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { Meta, StoryObj } from '@storybook/react'; -import { Collapsible } from './'; -import { Button } from '../Button'; -import { Box } from '../Box'; -import { Text } from '../Text'; -import { Icon } from '../Icon'; - -const meta = { - title: 'Components/Collapsible', - component: Collapsible.Root, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - args: { - style: { - display: 'flex', - flexDirection: 'column', - gap: 'var(--canon-space-2)', - alignItems: 'center', - }, - children: ( - <> - ( - - )} - /> - - - - It's the edge of the world and all of Western civilization - - - The sun may rise in the East, at least it settled in a final - location - - It's understood that Hollywood sells Californication - - - - ), - }, -}; - -export const Open: Story = { - args: { - ...Default.args, - defaultOpen: true, - }, -}; diff --git a/packages/canon/src/components/Collapsible/Collapsible.tsx b/packages/canon/src/components/Collapsible/Collapsible.tsx deleted file mode 100644 index 75ba4565e0..0000000000 --- a/packages/canon/src/components/Collapsible/Collapsible.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { forwardRef } from 'react'; -import { Collapsible as CollapsiblePrimitive } from '@base-ui-components/react/collapsible'; -import clsx from 'clsx'; - -const CollapsibleRoot = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -CollapsibleRoot.displayName = CollapsiblePrimitive.Root.displayName; - -const CollapsibleTrigger = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -CollapsibleTrigger.displayName = CollapsiblePrimitive.Trigger.displayName; - -const CollapsiblePanel = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -CollapsiblePanel.displayName = CollapsiblePrimitive.Panel.displayName; - -/** - * Collapsible is a component that allows you to collapse and expand content. - * It is a wrapper around the CollapsiblePrimitive component from base-ui-components. - * - * @public - */ -export const Collapsible = { - Root: CollapsibleRoot, - Trigger: CollapsibleTrigger, - Panel: CollapsiblePanel, -}; diff --git a/packages/canon/src/components/Container/styles.css b/packages/canon/src/components/Container/styles.css deleted file mode 100644 index 1ebf63987f..0000000000 --- a/packages/canon/src/components/Container/styles.css +++ /dev/null @@ -1,18 +0,0 @@ -.canon-Container { - max-width: 120rem; - padding: 0 var(--canon-space-4); - margin: 0 auto; - transition: padding 0.2s ease-in-out; -} - -@media (min-width: 640px) { - .canon-Container { - padding: 0 var(--canon-space-8); - } -} - -@media (min-width: 1024px) { - .canon-Container { - padding: 0 var(--canon-space-12); - } -} diff --git a/packages/canon/src/components/DataTable/DataTable.stories.tsx b/packages/canon/src/components/DataTable/DataTable.stories.tsx deleted file mode 100644 index 266aedc533..0000000000 --- a/packages/canon/src/components/DataTable/DataTable.stories.tsx +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { Meta, StoryObj } from '@storybook/react'; -import { DataTable } from '.'; -import { data, DataProps } from './mocked-components'; -import { columns } from './mocked-columns'; -import { - flexRender, - getCoreRowModel, - getPaginationRowModel, - useReactTable, - PaginationState, -} from '@tanstack/react-table'; -import { useState } from 'react'; - -const meta = { - title: 'Components/DataTable', -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Uncontrolled: Story = { - render: () => { - const table = useReactTable({ - data, - columns, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - }); - - return ( - - - - - ); - }, -}; - -export const Controlled: Story = { - render: () => { - const [pagination, setPagination] = useState({ - pageIndex: 4, - pageSize: 5, - }); - - const table = useReactTable({ - data, - columns, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - state: { - pagination, - }, - onPaginationChange: setPagination, - }); - - return ( - - - - - ); - }, -}; - -export const WithCustomTable: Story = { - render: () => { - const table = useReactTable({ - data, - columns, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - }); - - return ( - - - - {table.getHeaderGroups().map(headerGroup => ( - - {headerGroup.headers.map(header => { - return ( - - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - ))} - - - {table.getRowModel().rows?.length ? ( - table.getRowModel().rows.map(row => ( - - {row.getVisibleCells().map(cell => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ))} - - )) - ) : ( - - - No results. - - - )} - - - - - ); - }, -}; diff --git a/packages/canon/src/components/DataTable/DataTable.tsx b/packages/canon/src/components/DataTable/DataTable.tsx deleted file mode 100644 index 5a587df56f..0000000000 --- a/packages/canon/src/components/DataTable/DataTable.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { forwardRef } from 'react'; -import { Table } from '../Table'; -import { DataTableRoot } from './Root/DataTableRoot'; -import { DataTablePagination } from './Pagination/DataTablePagination'; -import { Table as TanstackTable } from '@tanstack/react-table'; -import { DataTableTable } from './Table/DataTableTable'; - -const TableRoot = forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ); -TableRoot.displayName = Table.Root.displayName; - -/** - * DataTable component for displaying tabular data with pagination - * @public - */ -export const DataTable = { - Root: DataTableRoot as ( - props: { - table: TanstackTable; - } & React.HTMLAttributes, - ) => JSX.Element, - Pagination: DataTablePagination, - Table: DataTableTable, - TableRoot: TableRoot, - TableHeader: Table.Header, - TableBody: Table.Body, - TableRow: Table.Row, - TableCell: Table.Cell, - TableCellText: Table.CellText, - TableCellLink: Table.CellLink, - TableCellProfile: Table.CellProfile, - TableHead: Table.Head, -}; diff --git a/packages/canon/src/components/DataTable/Pagination/DataTablePagination.stories.tsx b/packages/canon/src/components/DataTable/Pagination/DataTablePagination.stories.tsx deleted file mode 100644 index a2f931aed6..0000000000 --- a/packages/canon/src/components/DataTable/Pagination/DataTablePagination.stories.tsx +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { Meta, StoryObj } from '@storybook/react'; -import { DataTablePagination } from './DataTablePagination'; -import { - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from '@tanstack/react-table'; -import { data, DataProps } from '../mocked-components'; -import { columns } from '../mocked-columns'; -import { DataTable } from '../DataTable'; - -const meta = { - title: 'Components/DataTable/Pagination', - component: DataTablePagination, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Default: Story = { - render: () => { - const table = useReactTable({ - data, - columns, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - getFilteredRowModel: getFilteredRowModel(), - }); - - return ( - - - - ); - }, -}; diff --git a/packages/canon/src/components/DataTable/Pagination/DataTablePagination.styles.css b/packages/canon/src/components/DataTable/Pagination/DataTablePagination.styles.css deleted file mode 100644 index 02d12e73bb..0000000000 --- a/packages/canon/src/components/DataTable/Pagination/DataTablePagination.styles.css +++ /dev/null @@ -1,23 +0,0 @@ -.canon-DataTablePagination { - display: flex; - align-items: center; - justify-content: space-between; - padding-top: var(--canon-space-5); -} - -.canon-DataTablePagination--left { - display: flex; - align-items: center; - justify-content: space-between; -} - -.canon-DataTablePagination--right { - display: flex; - align-items: center; - justify-content: space-between; - gap: var(--canon-space-2); -} - -.canon-DataTablePagination--select { - min-width: 10.5rem; -} diff --git a/packages/canon/src/components/DataTable/Pagination/DataTablePagination.tsx b/packages/canon/src/components/DataTable/Pagination/DataTablePagination.tsx deleted file mode 100644 index 2efa73bf14..0000000000 --- a/packages/canon/src/components/DataTable/Pagination/DataTablePagination.tsx +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { forwardRef } from 'react'; -import { Text } from '../../Text'; -import { DataTablePaginationProps } from './types'; -import { IconButton } from '../../IconButton'; -import clsx from 'clsx'; -import { Select } from '../../Select'; -import { useDataTable } from '../Root/DataTableRoot'; -import { Icon } from '../../Icon'; - -/** @public */ -const DataTablePagination = forwardRef( - ( - props: DataTablePaginationProps, - ref: React.ForwardedRef, - ) => { - const { className, ...rest } = props; - const { table } = useDataTable(); - const pageIndex = table?.getState().pagination.pageIndex; - const pageSize = table?.getState().pagination.pageSize; - const rowCount = table?.getRowCount(); - const fromCount = (pageIndex ?? 0) * (pageSize ?? 10) + 1; - const toCount = Math.min( - ((pageIndex ?? 0) + 1) * (pageSize ?? 10), - rowCount, - ); - - return ( -
    -
    - {!table.options.manualPagination && ( - - ); - }} - /> - - - ); - }, -}; - -export const Controlled: Story = { - render: () => { - const { - handleSubmit, - control, - formState: { errors }, - } = useForm(); - - const [firstname, setFirstname] = useState('John'); - const [lastname, setLastname] = useState('Doe'); - const [city, setCity] = useState('london'); - - const onSubmit: SubmitHandler = data => { - console.log('data', data); - setFirstname(data.firstname); - setLastname(data.lastname); - setCity(data.city); - }; - - return ( -
    - { - return ( - { - field.onChange(e); - setFirstname(e.target.value); - }} - error={errors.firstname?.message} - /> - ); - }} - /> - { - return ( - { - field.onChange(e); - setLastname(e.target.value); - }} - error={errors.lastname?.message} - /> - ); - }} - /> - { - return ( - - - - - ); - } - - return null; -} /** - * Creates an app that is suitable for the public sign-in page, for use in the `index-public-experimental.tsx` file. - * - * @remarks - * - * This app has an override for the `app/layout` extension, which means that - * most extension typically installed in an app will be ignored. However, you - * can still for example install API and root element extensions. - * - * A typical setup of this app will only install a custom sign-in page. - * - * @example - * ```ts - * const app = createPublicSignInApp({ - * features: [signInPageModule], - * }); - * ``` - * * @public + * @deprecated Use {@link @backstage/plugin-app/alpha#appModulePublicSignIn} instead. */ export function createPublicSignInApp(options?: CreateAppOptions) { return createApp({ ...options, - features: [ - ...(options?.features ?? []), - // This is a rather than app plugin override in order for it to take precedence over any supplied app plugin override - createFrontendModule({ - pluginId: 'app', - extensions: [ - appPlugin.getExtension('app/layout').override({ - factory: () => [ - coreExtensionData.reactElement(), - ], - }), - ], - }), - ], + features: [...(options?.features ?? []), appModulePublicSignIn], }); } diff --git a/packages/frontend-defaults/src/discovery.test.ts b/packages/frontend-defaults/src/discovery.test.ts index d1738554a4..b4e595890a 100644 --- a/packages/frontend-defaults/src/discovery.test.ts +++ b/packages/frontend-defaults/src/discovery.test.ts @@ -27,7 +27,7 @@ Object.defineProperty(global, '__@backstage/discovered__', { }); const config = new ConfigReader({ - app: { experimental: { packages: 'all' } }, + app: { packages: 'all' }, }); describe('discoverAvailableFeatures', () => { diff --git a/packages/frontend-defaults/src/discovery.ts b/packages/frontend-defaults/src/discovery.ts index 6da6146389..71d831b58c 100644 --- a/packages/frontend-defaults/src/discovery.ts +++ b/packages/frontend-defaults/src/discovery.ts @@ -26,7 +26,10 @@ interface DiscoveryGlobal { } function readPackageDetectionConfig(config: Config) { - const packages = config.getOptional('app.experimental.packages'); + // The experimental key is deprecated, but supported still for backwards compatibility + const packages = + config.getOptional('app.packages') ?? + config.getOptional('app.experimental.packages'); if (packages === undefined || packages === null) { return undefined; } @@ -34,21 +37,16 @@ function readPackageDetectionConfig(config: Config) { if (typeof packages === 'string') { if (packages !== 'all') { throw new Error( - `Invalid app.experimental.packages mode, got '${packages}', expected 'all'`, + `Invalid app.packages mode, got '${packages}', expected 'all'`, ); } return {}; } if (typeof packages !== 'object' || Array.isArray(packages)) { - throw new Error( - "Invalid config at 'app.experimental.packages', expected object", - ); + throw new Error("Invalid config at 'app.packages', expected object"); } - const packagesConfig = new ConfigReader( - packages, - 'app.experimental.packages', - ); + const packagesConfig = new ConfigReader(packages, 'app.packages'); return { include: packagesConfig.getOptionalStringArray('include'), diff --git a/packages/frontend-defaults/src/index.ts b/packages/frontend-defaults/src/index.ts index 573cc9b08c..37ec62e794 100644 --- a/packages/frontend-defaults/src/index.ts +++ b/packages/frontend-defaults/src/index.ts @@ -20,11 +20,8 @@ * @packageDocumentation */ -export { - createApp, - type CreateAppOptions, - type CreateAppFeatureLoader, -} from './createApp'; +export { createApp, type CreateAppOptions } from './createApp'; export { createPublicSignInApp } from './createPublicSignInApp'; export { discoverAvailableFeatures } from './discovery'; export { resolveAsyncFeatures } from './resolution'; +export { maybeCreateErrorPage } from './maybeCreateErrorPage'; diff --git a/packages/frontend-defaults/src/maybeCreateErrorPage.tsx b/packages/frontend-defaults/src/maybeCreateErrorPage.tsx new file mode 100644 index 0000000000..6bad97f666 --- /dev/null +++ b/packages/frontend-defaults/src/maybeCreateErrorPage.tsx @@ -0,0 +1,116 @@ +/* + * 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 { FrontendPluginInfo } from '@backstage/frontend-plugin-api'; +import { JSX, useEffect, useState } from 'react'; +import { AppError, AppErrorTypes } from '@backstage/frontend-app-api'; + +const DEFAULT_WARNING_CODES: Array = [ + 'EXTENSION_IGNORED', + 'INVALID_EXTENSION_CONFIG_KEY', + 'EXTENSION_INPUT_DATA_IGNORED', + 'EXTENSION_OUTPUT_IGNORED', +]; + +function AppErrorItem(props: { error: AppError }): JSX.Element { + const { context } = props.error; + + const node = 'node' in context ? context.node : undefined; + const extensionId = + 'extensionId' in context ? context.extensionId : node?.spec.id; + const routeId = 'routeId' in context ? context.routeId : undefined; + const plugin = 'plugin' in context ? context.plugin : node?.spec.plugin; + const pluginId = plugin?.id ?? 'N/A'; + + const [info, setInfo] = useState(undefined); + useEffect(() => { + plugin?.info().then(setInfo, error => { + // eslint-disable-next-line no-console + console.error(`Failed to load info for plugin ${plugin.id}: ${error}`); + }); + }, [plugin]); + + return ( +
    + {props.error.code}: {props.error.message} +
    +        {extensionId && 
    extensionId: {extensionId}
    } + {routeId &&
    routeId: {routeId}
    } + {pluginId &&
    pluginId: {pluginId}
    } + {info && ( +
    + package: {info.packageName}@{info.version} +
    + )} +
    +
    + ); +} + +function AppErrorPage(props: { errors: AppError[] }): JSX.Element { + return ( +
    +

    App startup failed

    + {props.errors.map((error, index) => ( + + ))} +
    + ); +} + +/** + * If there are any unrecoverable errors in the app, this will return an error page in the form of a JSX element. + * + * If there are any recoverable errors, they will always be logged as warnings in the console. + * @public + */ +export function maybeCreateErrorPage( + app: { errors?: AppError[] }, + options?: { + warningCodes?: Array; + }, +): JSX.Element | undefined { + if (!app.errors) { + return undefined; + } + + const errors = new Array(); + const warnings = new Array(); + + const warningCodes = new Set(options?.warningCodes ?? DEFAULT_WARNING_CODES); + for (const error of app.errors) { + if (warningCodes.has(error.code)) { + warnings.push(error); + } else { + errors.push(error); + } + } + + if (warnings.length > 0) { + // eslint-disable-next-line no-console + console.warn('App startup encountered warnings:'); + for (const warning of warnings) { + // eslint-disable-next-line no-console + console.warn(`${warning.code}: ${warning.message}`); + } + } + + if (errors.length === 0) { + return undefined; + } + + return ; +} diff --git a/packages/frontend-defaults/src/resolution.test.ts b/packages/frontend-defaults/src/resolution.test.ts index b39e302b24..eb9e58f949 100644 --- a/packages/frontend-defaults/src/resolution.test.ts +++ b/packages/frontend-defaults/src/resolution.test.ts @@ -20,7 +20,6 @@ import { FrontendFeatureLoader, PageBlueprint, } from '@backstage/frontend-plugin-api'; -import { CreateAppFeatureLoader } from './createApp'; import { resolveAsyncFeatures } from './resolution'; import { mockApis } from '@backstage/test-utils'; @@ -42,7 +41,7 @@ describe('resolveAsyncFeatures', () => { extensions: [ PageBlueprint.make({ params: { - defaultPath: '/', + path: '/', loader: () => new Promise(() => {}), }, }), @@ -71,75 +70,6 @@ describe('resolveAsyncFeatures', () => { ]); }); - it('supports deprecated feature loaders', async () => { - const loader: CreateAppFeatureLoader = { - getLoaderName() { - return 'test-loader'; - }, - async load() { - return { - features: [ - createFrontendPlugin({ - pluginId: 'test', - extensions: [ - PageBlueprint.make({ - params: { - defaultPath: '/', - loader: () => new Promise(() => {}), - }, - }), - ], - }), - ], - }; - }, - }; - - const { features } = await resolveAsyncFeatures({ - config: mockApis.config(), - features: [loader], - }); - - expect(features).toMatchObject([ - { - $$type: '@backstage/FrontendPlugin', - id: 'test', - version: 'v1', - extensions: [ - { - $$type: '@backstage/Extension', - id: 'page:test', - version: 'v2', - attachTo: { - id: 'app/routes', - input: 'routes', - }, - }, - ], - }, - ]); - }); - - it('should propagate errors thrown by deprecated feature loaders', async () => { - const loader: CreateAppFeatureLoader = { - getLoaderName() { - return 'test-loader'; - }, - async load() { - throw new TypeError('boom'); - }, - }; - - await expect(() => - resolveAsyncFeatures({ - config: mockApis.config(), - features: [loader], - }), - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Failed to read frontend features from loader 'test-loader', TypeError: boom"`, - ); - }); - it('supports feature loaders', async () => { const loader: FrontendFeatureLoader = createFrontendFeatureLoader({ async loader({ config: _ }) { @@ -149,7 +79,7 @@ describe('resolveAsyncFeatures', () => { extensions: [ PageBlueprint.make({ params: { - defaultPath: '/', + path: '/', loader: () => new Promise(() => {}), }, }), diff --git a/packages/frontend-defaults/src/resolution.ts b/packages/frontend-defaults/src/resolution.ts index 6ab26c3d1d..58f91c45be 100644 --- a/packages/frontend-defaults/src/resolution.ts +++ b/packages/frontend-defaults/src/resolution.ts @@ -20,40 +20,14 @@ import { FrontendFeature, FrontendFeatureLoader, } from '@backstage/frontend-plugin-api'; -import { CreateAppFeatureLoader } from './createApp'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { isInternalFrontendFeatureLoader } from '../../frontend-plugin-api/src/wiring/createFrontendFeatureLoader'; /** @public */ export async function resolveAsyncFeatures(options: { config: Config; - features?: ( - | FrontendFeature - | FrontendFeatureLoader - | CreateAppFeatureLoader - )[]; + features?: (FrontendFeature | FrontendFeatureLoader)[]; }): Promise<{ features: FrontendFeature[] }> { - const features: (FrontendFeature | FrontendFeatureLoader)[] = []; - - // Separate deprecated CreateAppFeatureLoader elements from the frontend features, - // and manage the deprecated elements first. - for (const item of options?.features ?? []) { - if ('load' in item) { - try { - const result = await item.load({ config: options.config }); - features.push(...result.features); - } catch (e) { - throw new Error( - `Failed to read frontend features from loader '${item.getLoaderName()}', ${stringifyError( - e, - )}`, - ); - } - } else { - features.push(item); - } - } - const loadedFeatures: FrontendFeature[] = []; const alreadyMetFeatureLoaders: FrontendFeatureLoader[] = []; const maxRecursionDepth = 5; @@ -96,7 +70,7 @@ export async function resolveAsyncFeatures(options: { } } - await applyFeatureLoaders(features, 1); + await applyFeatureLoaders(options.features ?? [], 1); return { features: loadedFeatures }; } diff --git a/packages/frontend-dynamic-feature-loader/CHANGELOG.md b/packages/frontend-dynamic-feature-loader/CHANGELOG.md index 1b377ed777..cc2c421a4e 100644 --- a/packages/frontend-dynamic-feature-loader/CHANGELOG.md +++ b/packages/frontend-dynamic-feature-loader/CHANGELOG.md @@ -1,5 +1,121 @@ # @backstage/frontend-dynamic-feature-loader +## 0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + +## 0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/config@1.3.5 + +## 0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.1 + +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/config@1.3.3 + +## 0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/config@1.3.3 + +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/frontend-plugin-api@0.10.4 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.1 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/config@1.3.2 + +## 0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/config@1.3.2 + +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/config@1.3.2 + ## 0.1.1-next.1 ### Patch Changes diff --git a/packages/frontend-dynamic-feature-loader/knip-report.md b/packages/frontend-dynamic-feature-loader/knip-report.md index 2661c35327..0645b2b1cc 100644 --- a/packages/frontend-dynamic-feature-loader/knip-report.md +++ b/packages/frontend-dynamic-feature-loader/knip-report.md @@ -1,2 +1,8 @@ # Knip report +## Unused dependencies (1) + +| Name | Location | Severity | +| :---------------- | :----------- | :------- | +| @backstage/config | packages/frontend-dynamic-feature-loader/package.json | error | + diff --git a/packages/frontend-dynamic-feature-loader/package.json b/packages/frontend-dynamic-feature-loader/package.json index d3b05fdc12..ce61447770 100644 --- a/packages/frontend-dynamic-feature-loader/package.json +++ b/packages/frontend-dynamic-feature-loader/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-dynamic-feature-loader", - "version": "0.1.1-next.1", + "version": "0.1.7-next.0", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-dynamic-feature-loader/src/loader.test.tsx b/packages/frontend-dynamic-feature-loader/src/loader.test.tsx index 4b872a5414..b2f6486766 100644 --- a/packages/frontend-dynamic-feature-loader/src/loader.test.tsx +++ b/packages/frontend-dynamic-feature-loader/src/loader.test.tsx @@ -127,10 +127,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -204,10 +202,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -330,10 +326,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -447,10 +441,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -540,10 +532,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -604,10 +594,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -653,10 +641,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -759,10 +745,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -889,10 +873,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -1002,10 +984,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { @@ -1112,10 +1092,8 @@ describe('dynamicFrontendFeaturesLoader', () => { config: mockApis.config({ data: { app: { - experimental: { - packages: { - include: [], - }, + packages: { + include: [], }, }, backend: { diff --git a/packages/frontend-internal/CHANGELOG.md b/packages/frontend-internal/CHANGELOG.md index 65ffbd826f..7b31d280cb 100644 --- a/packages/frontend-internal/CHANGELOG.md +++ b/packages/frontend-internal/CHANGELOG.md @@ -1,5 +1,111 @@ # @internal/frontend +## 0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## 0.0.14 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1 + +## 0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## 0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/types@1.2.2 + +## 0.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + +## 0.0.12 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + +## 0.0.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.0.11 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.4 + +## 0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## 0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + ## 0.0.9-next.1 ### Patch Changes diff --git a/packages/frontend-internal/knip-report.md b/packages/frontend-internal/knip-report.md index d5272513d9..e23233d94e 100644 --- a/packages/frontend-internal/knip-report.md +++ b/packages/frontend-internal/knip-report.md @@ -1,20 +1,19 @@ # Knip report -## Unused dependencies (3) +## Unused dependencies (2) | Name | Location | Severity | | :------------------------ | :----------- | :------- | -| @backstage/version-bridge | package.json | error | -| @backstage/types | package.json | error | -| zod | package.json | error | +| @backstage/version-bridge | packages/frontend-internal/package.json | error | +| zod | packages/frontend-internal/package.json | error | ## Unused devDependencies (5) | Name | Location | Severity | | :----------------------------- | :----------- | :------- | -| @backstage/frontend-test-utils | package.json | error | -| @backstage/frontend-app-api | package.json | error | -| @testing-library/jest-dom | package.json | error | -| @testing-library/react | package.json | error | -| @backstage/test-utils | package.json | error | +| @backstage/frontend-test-utils | packages/frontend-internal/package.json | error | +| @backstage/frontend-app-api | packages/frontend-internal/package.json | error | +| @testing-library/jest-dom | packages/frontend-internal/package.json | error | +| @testing-library/react | packages/frontend-internal/package.json | error | +| @backstage/test-utils | packages/frontend-internal/package.json | error | diff --git a/packages/frontend-internal/package.json b/packages/frontend-internal/package.json index 7f1615c5f5..37727cda97 100644 --- a/packages/frontend-internal/package.json +++ b/packages/frontend-internal/package.json @@ -1,6 +1,6 @@ { "name": "@internal/frontend", - "version": "0.0.9-next.1", + "version": "0.0.15-next.0", "backstage": { "role": "web-library", "inline": true diff --git a/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts b/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts index 44dfb002ad..08f787a4ae 100644 --- a/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts +++ b/packages/frontend-internal/src/wiring/InternalExtensionDefinition.ts @@ -15,11 +15,11 @@ */ import { - AnyExtensionDataRef, ApiHolder, AppNode, ExtensionAttachToSpec, ExtensionDataValue, + ExtensionDataRef, ExtensionDefinition, ExtensionDefinitionParameters, ExtensionInput, @@ -43,13 +43,13 @@ export const OpaqueExtensionDefinition = OpaqueType.create<{ [inputName in string]: { $$type: '@backstage/ExtensionInput'; extensionData: { - [name in string]: AnyExtensionDataRef; + [name in string]: ExtensionDataRef; }; config: { optional: boolean; singleton: boolean }; }; }; readonly output: { - [name in string]: AnyExtensionDataRef; + [name in string]: ExtensionDataRef; }; factory(context: { node: AppNode; @@ -70,22 +70,14 @@ export const OpaqueExtensionDefinition = OpaqueType.create<{ readonly attachTo: ExtensionAttachToSpec; readonly disabled: boolean; readonly configSchema?: PortableSchema; - readonly inputs: { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }; - readonly output: Array; + readonly inputs: { [inputName in string]: ExtensionInput }; + readonly output: Array; factory(context: { node: AppNode; apis: ApiHolder; config: object; inputs: ResolvedExtensionInputs<{ - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; + [inputName in string]: ExtensionInput; }>; }): Iterable>; }; diff --git a/packages/frontend-internal/src/wiring/InternalFrontendPlugin.ts b/packages/frontend-internal/src/wiring/InternalFrontendPlugin.ts index a7be9614b6..3e964af5ca 100644 --- a/packages/frontend-internal/src/wiring/InternalFrontendPlugin.ts +++ b/packages/frontend-internal/src/wiring/InternalFrontendPlugin.ts @@ -17,16 +17,21 @@ import { Extension, FeatureFlagConfig, - FrontendPlugin, + OverridableFrontendPlugin, } from '@backstage/frontend-plugin-api'; +import { JsonObject } from '@backstage/types'; import { OpaqueType } from '@internal/opaque'; export const OpaqueFrontendPlugin = OpaqueType.create<{ - public: FrontendPlugin; + public: OverridableFrontendPlugin; versions: { readonly version: 'v1'; readonly extensions: Extension[]; readonly featureFlags: FeatureFlagConfig[]; + readonly infoOptions?: { + packageJson?: () => Promise; + manifest?: () => Promise; + }; }; }>({ type: '@backstage/FrontendPlugin', diff --git a/packages/frontend-internal/src/wiring/InternalSwappableComponentRef.ts b/packages/frontend-internal/src/wiring/InternalSwappableComponentRef.ts new file mode 100644 index 0000000000..2a5da3fa73 --- /dev/null +++ b/packages/frontend-internal/src/wiring/InternalSwappableComponentRef.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SwappableComponentRef } from '@backstage/frontend-plugin-api'; +import { OpaqueType } from '@internal/opaque'; + +export const OpaqueSwappableComponentRef = OpaqueType.create<{ + public: SwappableComponentRef; + versions: { + readonly version: 'v1'; + readonly transformProps?: (props: object) => object; + readonly defaultComponent: (props: object) => JSX.Element | null; + }; +}>({ + versions: ['v1'], + type: '@backstage/SwappableComponentRef', +}); diff --git a/packages/frontend-internal/src/wiring/createExtensionDataContainer.ts b/packages/frontend-internal/src/wiring/createExtensionDataContainer.ts index e25846a643..34eeca75de 100644 --- a/packages/frontend-internal/src/wiring/createExtensionDataContainer.ts +++ b/packages/frontend-internal/src/wiring/createExtensionDataContainer.ts @@ -15,20 +15,24 @@ */ import { - AnyExtensionDataRef, ExtensionDataContainer, ExtensionDataRef, ExtensionDataValue, } from '@backstage/frontend-plugin-api'; -export function createExtensionDataContainer( +export function createExtensionDataContainer( values: Iterable< UData extends ExtensionDataRef ? ExtensionDataValue : never >, + contextName: string, declaredRefs?: ExtensionDataRef[], ): ExtensionDataContainer { + if (typeof values !== 'object' || !values?.[Symbol.iterator]) { + throw new Error(`${contextName} did not provide an iterable object`); + } + const container = new Map>(); const verifyRefs = declaredRefs && new Map(declaredRefs.map(ref => [ref.id, ref])); diff --git a/packages/frontend-internal/src/wiring/index.ts b/packages/frontend-internal/src/wiring/index.ts index 6a7cf35e27..b61294cb1f 100644 --- a/packages/frontend-internal/src/wiring/index.ts +++ b/packages/frontend-internal/src/wiring/index.ts @@ -15,5 +15,6 @@ */ export { createExtensionDataContainer } from './createExtensionDataContainer'; +export { OpaqueSwappableComponentRef } from './InternalSwappableComponentRef'; export { OpaqueExtensionDefinition } from './InternalExtensionDefinition'; export { OpaqueFrontendPlugin } from './InternalFrontendPlugin'; diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index ce9e73745f..1bf8f64a43 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,834 @@ # @backstage/frontend-plugin-api +## 0.12.2-next.1 + +### Patch Changes + +- 878c251: Updated to `ExtensionInput` to make all type parameters optional. +- Updated dependencies + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + +## 0.12.2-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## 0.12.1 + +### Patch Changes + +- 8ed53eb: Added `coreExtensionData.title`, especially useful for creating extensible layout with tabbed pages, but available for use for other cases too. +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/core-plugin-api@1.11.1 + +## 0.12.1-next.2 + +### Patch Changes + +- 8ed53eb: Added `coreExtensionData.title`, especially useful for creating extensible layout with tabbed pages, but available for use for other cases too. +- Updated dependencies + - @backstage/core-components@0.18.2-next.3 + +## 0.12.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + +## 0.12.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## 0.12.0 + +### Minor Changes + +- 894d514: Make `openshiftApiRef` available to the new frontend system. + +### Patch Changes + +- 2fb8b04: Improved the types of `createFrontendPlugin` and `createFrontendModule` so that errors due to incompatible options are indicated more clearly. +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/core-components@0.18.0 + - @backstage/types@1.2.2 + +## 0.11.1-next.0 + +### Patch Changes + +- 2fb8b04: Improved the types of `createFrontendPlugin` and `createFrontendModule` so that errors due to incompatible options are indicated more clearly. +- Updated dependencies + - @backstage/core-components@0.17.6-next.0 + +## 0.11.0 + +### Minor Changes + +- c5f88b5: **BREAKING**: Remove deprecated `source` property from the `AppNodeSpec` type, use `AppNodeSpec.plugin` instead. +- e4ddf22: **BREAKING**: The `defaultPath` param of `PageBlueprint` has been renamed to `path`. This change does not affect the compatibility of extensions created with older versions of this blueprint. +- fda1bbc: **BREAKING**: The component system has been overhauled to use `SwappableComponent` instead of `ComponentRef`. Several APIs have been removed and replaced: + + - Removed: `createComponentRef`, `createComponentExtension`, `ComponentRef`, `ComponentsApi`, `componentsApiRef`, `useComponentRef`, `coreComponentRefs` + - Added: `createSwappableComponent`, `SwappableComponentBlueprint`, `SwappableComponentRef`, `SwappableComponentsApi`, `swappableComponentsApiRef` + + **BREAKING**: The default `componentRefs` and exported `Core*Props` have been removed and have replacement `SwappableComponents` and revised type names instead. + + - The `errorBoundaryFallback` component and `CoreErrorBoundaryFallbackProps` type have been replaced with `ErrorDisplay` swappable component and `CoreErrorDisplayProps` respectively. + - The `progress` component and `CoreProgressProps` type have been replaced with `Progress` swappable component and `ProgressProps` respectively. + - The `notFoundErrorPage` component and `CoreNotFoundErrorPageProps` type have been replaced with `NotFoundErrorPage` swappable component and `NotFoundErrorPageProps` respectively. + + **Migration for creating swappable components:** + + ```tsx + // OLD: Using createComponentRef and createComponentExtension + import { + createComponentRef, + createComponentExtension, + } from '@backstage/frontend-plugin-api'; + + const myComponentRef = createComponentRef<{ title: string }>({ + id: 'my-plugin.my-component', + }); + + const myComponentExtension = createComponentExtension({ + ref: myComponentRef, + loader: { + lazy: () => import('./MyComponent').then(m => m.MyComponent), + }, + }); + + // NEW: Using createSwappableComponent and SwappableComponentBlueprint + import { + createSwappableComponent, + SwappableComponentBlueprint, + } from '@backstage/frontend-plugin-api'; + + const MySwappableComponent = createSwappableComponent({ + id: 'my-plugin.my-component', + loader: () => import('./MyComponent').then(m => m.MyComponent), + }); + + const myComponentExtension = SwappableComponentBlueprint.make({ + name: 'my-component', + params: { + component: MySwappableComponent, + loader: () => import('./MyComponent').then(m => m.MyComponent), + }, + }); + ``` + + **Migration for using components:** + + ```tsx + // OLD: Using ComponentsApi and useComponentRef + import { + useComponentRef, + componentsApiRef, + useApi, + coreComponentRefs, + } from '@backstage/frontend-plugin-api'; + + const MyComponent = useComponentRef(myComponentRef); + const ProgressComponent = useComponentRef(coreComponentRefs.progress); + + + // NEW: Direct component usage + import { Progress } from '@backstage/frontend-plugin-api'; + + // Use directly as React Component + + + ``` + + **Migration for core component references:** + + ```tsx + // OLD: Core component refs + import { coreComponentRefs } from '@backstage/frontend-plugin-api'; + + coreComponentRefs.progress + coreComponentRefs.notFoundErrorPage + coreComponentRefs.errorBoundaryFallback + + // NEW: Direct swappable component imports + import { Progress, NotFoundErrorPage, ErrorDisplay } from '@backstage/frontend-plugin-api'; + + // Use directly as React components + + + + ``` + +- 6a75e00: **BREAKING**: Removed the deprecated `createFrontendPlugin` variant where the plugin ID is passed via an `id` option. To update existing code, switch to using the `pluginId` option instead. +- 12b6db7: **BREAKING**: Added a new `OverridableFrontendPlugin` type that is used as the return value of `createFrontendPlugin`. This type includes the `withOverrides` and `.getExtension` methods that are helpful when creating plugin overrides, while the base `FrontendPlugin` type no longer includes these methods. This is a breaking change for the `AppTreeApi` and some other places where the `FrontendPlugin` type is still used, but also fixes some cases where the extra plugin methods were causing issues. +- 37f2989: **BREAKING**: Removed the `routable` property from `ExtensionBoundary`. This property was never needed in practice and is instead inferred from whether or not the extension outputs a route reference. It can be safely removed. +- 1e6410b: **BREAKING**: The `ResolveInputValueOverrides` type is no longer exported. +- 29786f6: **BREAKING**: The `NavLogoBlueprint` has been removed and replaced by `NavContentBlueprint`, which instead replaces the entire navbar. The default navbar has also been switched to a more minimal implementation. + + To use `NavContentBlueprint` to install new logos, you can use it as follows: + + ```tsx + NavContentBlueprint.make({ + params: { + component: ({ items }) => { + return compatWrapper( + + + + {/* Other sidebar content */} + + + {items.map((item, index) => ( + + ))} + + + {/* Other sidebar content */} + , + ); + }, + }, + }); + ``` + +- 3243fa6: **BREAKING**: Removed the ability to define a default extension `name` in blueprints. This option had no practical purpose as blueprints already use the `kind` to identity the source of the extension. +- a082429: **BREAKING**: The separate `RouteResolutionApiResolveOptions` type has been removed. +- 5d31d66: **BREAKING**: In an attempt to align some of the API's around providing components to `Blueprints`, we've renamed the parameters for both the `RouterBlueprint` and `AppRootWrapperBlueprint` from `Component` to `component`. + + ```tsx + // old + RouterBlueprint.make({ + params: { + Component: ({ children }) =>
    {children}
    , + }, + }); + + // new + RouterBlueprint.make({ + params: { + component: ({ children }) =>
    {children}
    , + }, + }); + ``` + + ```tsx + // old + AppRootWrapperBlueprint.make({ + params: { + Component: ({ children }) =>
    {children}
    , + }, + }); + + // new + AppRootWrapperBlueprint.make({ + params: { + component: ({ children }) =>
    {children}
    , + }, + }); + ``` + + As part of this change, the type for `component` has also changed from `ComponentType>` to `(props: { children: ReactNode }) => JSX.Element | null` which is not breaking, just a little more reflective of the actual expected component. + +- 45ead4a: **BREAKING**: The `AnyRoutes` and `AnyExternalRoutes` types have been removed and their usage has been inlined instead. + + Existing usage can be replaced according to their previous definitions: + + ```ts + type AnyRoutes = { [name in string]: RouteRef | SubRouteRef }; + type AnyExternalRoutes = { [name in string]: ExternalRouteRef }; + ``` + +- 805c298: **BREAKING**: The `ApiBlueprint` has been updated to use the new advanced type parameters through the new `defineParams` blueprint option. This is an immediate breaking change that requires all existing usages of `ApiBlueprint` to switch to the new callback format. Existing extensions created with the old format are still compatible with the latest version of the plugin API however, meaning that this does not break existing plugins. + + To update existing usages of `ApiBlueprint`, you remove the outer level of the `params` object and replace `createApiFactory(...)` with `defineParams => defineParams(...)`. + + For example, the following old usage: + + ```ts + ApiBlueprint.make({ + name: 'error', + params: { + factory: createApiFactory({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => { + return ...; + }, + }) + }, + }) + ``` + + is migrated to the following: + + ```ts + ApiBlueprint.make({ + name: 'error', + params: defineParams => + defineParams({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => { + return ...; + }, + }), + }) + ``` + +- 805c298: Added support for advanced parameter types in extension blueprints. The primary purpose of this is to allow extension authors to use type inference in the definition of the blueprint parameters. This often removes the need for extra imports and improves discoverability of blueprint parameters. + + This feature is introduced through the new `defineParams` option of `createExtensionBlueprint`, along with accompanying `createExtensionBlueprintParams` function to help implement the new format. + + The following is an example of how to create an extension blueprint that uses the new option: + + ```ts + const ExampleBlueprint = createExtensionBlueprint({ + kind: 'example', + attachTo: { id: 'example', input: 'example' }, + output: [exampleComponentDataRef, exampleFetcherDataRef], + defineParams(params: { + component(props: ExampleProps): JSX.Element | null; + fetcher(options: FetchOptions): Promise>; + }) { + // The returned params must be wrapped with `createExtensionBlueprintParams` + return createExtensionBlueprintParams(params); + }, + *factory(params) { + // These params are now inferred + yield exampleComponentDataRef(params.component); + yield exampleFetcherDataRef(params.fetcher); + }, + }); + ``` + + Usage of the above example looks as follows: + + ```ts + const example = ExampleBlueprint.make({ + params: defineParams => defineParams({ + component: ..., + fetcher: ..., + }), + }); + ``` + + This `defineParams => defineParams()` is also known as the "callback syntax" and is required if a blueprint is created with the new `defineParams` option. The callback syntax can also optionally be used for other blueprints too, which means that it is not a breaking change to remove the `defineParams` option, as long as the external parameter types remain compatible. + +- 121899a: **BREAKING**: The `element` param for `AppRootElementBlueprint` no longer accepts a component. If you are currently passing a component such as `element: () => ` or `element: MyComponent`, simply switch to `element: `. +- a321f3b: **BREAKING**: The `CommonAnalyticsContext` has been removed, and inlined into `AnalyticsContextValue` instead. + +### Patch Changes + +- d9e00e3: Add support for a new `aliasFor` option for `createRouteRef`. This allows for the creation of a new route ref that acts as an alias for an existing route ref that is installed in the app. This is particularly useful when creating modules that override existing plugin pages, without referring to the existing plugin. For example: + + ```tsx + export default createFrontendModule({ + pluginId: 'catalog', + extensions: [ + PageBlueprint.make({ + params: { + defaultPath: '/catalog', + routeRef: createRouteRef({ aliasFor: 'catalog.catalogIndex' }), + loader: () => + import('./CustomCatalogIndexPage').then(m => ( + + )), + }, + }), + ], + }); + ``` + +- 93b5e38: Plugins should now use the new `AnalyticsImplementationBlueprint` to define and provide concrete analytics implementations. For example: + + ```ts + import { AnalyticsImplementationBlueprint } from '@backstage/frontend-plugin-api'; + + const AcmeAnalytics = AnalyticsImplementationBlueprint.make({ + name: 'acme-analytics', + params: define => + define({ + deps: { config: configApiRef }, + factory: ({ config }) => AcmeAnalyticsImpl.fromConfig(config), + }), + }); + ``` + +- 948de17: Tweaked the return types from `createExtension` and `createExtensionBlueprint` to avoid the forwarding of `ConfigurableExtensionDataRef` into exported types. +- 147482b: Updated the recommended naming of the blueprint param callback from `define` to `defineParams`, making the syntax `defineParams => defineParams(...)`. +- 3c3c882: Added added defaults for all type parameters of `ExtensionDataRef` and deprecated `AnyExtensionDataRef`, as it is now redundant. +- 9831f4e: Adjusted the dialog API types to have more sensible defaults +- 1c2cc37: Improved runtime error message clarity when extension factories don't return an iterable object. +- 24558f0: Added inline documentation for `createExtension`, `createExtensionBlueprint`, `createFrontendPlugin`, and `createFrontendModule`. +- Updated dependencies + - @backstage/core-components@0.17.5 + +## 0.11.0-next.2 + +### Minor Changes + +- fda1bbc: **BREAKING**: The component system has been overhauled to use `SwappableComponent` instead of `ComponentRef`. Several APIs have been removed and replaced: + + - Removed: `createComponentRef`, `createComponentExtension`, `ComponentRef`, `ComponentsApi`, `componentsApiRef`, `useComponentRef`, `coreComponentRefs` + - Added: `createSwappableComponent`, `SwappableComponentBlueprint`, `SwappableComponentRef`, `SwappableComponentsApi`, `swappableComponentsApiRef` + + **BREAKING**: The default `componentRefs` and exported `Core*Props` have been removed and have replacement `SwappableComponents` and revised type names instead. + + - The `errorBoundaryFallback` component and `CoreErrorBoundaryFallbackProps` type have been replaced with `ErrorDisplay` swappable component and `CoreErrorDisplayProps` respectively. + - The `progress` component and `CoreProgressProps` type have been replaced with `Progress` swappable component and `ProgressProps` respectively. + - The `notFoundErrorPage` component and `CoreNotFoundErrorPageProps` type have been replaced with `NotFoundErrorPage` swappable component and `NotFoundErrorPageProps` respectively. + + **Migration for creating swappable components:** + + ```tsx + // OLD: Using createComponentRef and createComponentExtension + import { + createComponentRef, + createComponentExtension, + } from '@backstage/frontend-plugin-api'; + + const myComponentRef = createComponentRef<{ title: string }>({ + id: 'my-plugin.my-component', + }); + + const myComponentExtension = createComponentExtension({ + ref: myComponentRef, + loader: { + lazy: () => import('./MyComponent').then(m => m.MyComponent), + }, + }); + + // NEW: Using createSwappableComponent and SwappableComponentBlueprint + import { + createSwappableComponent, + SwappableComponentBlueprint, + } from '@backstage/frontend-plugin-api'; + + const MySwappableComponent = createSwappableComponent({ + id: 'my-plugin.my-component', + loader: () => import('./MyComponent').then(m => m.MyComponent), + }); + + const myComponentExtension = SwappableComponentBlueprint.make({ + name: 'my-component', + params: { + component: MySwappableComponent, + loader: () => import('./MyComponent').then(m => m.MyComponent), + }, + }); + ``` + + **Migration for using components:** + + ```tsx + // OLD: Using ComponentsApi and useComponentRef + import { + useComponentRef, + componentsApiRef, + useApi, + coreComponentRefs, + } from '@backstage/frontend-plugin-api'; + + const MyComponent = useComponentRef(myComponentRef); + const ProgressComponent = useComponentRef(coreComponentRefs.progress); + + + // NEW: Direct component usage + import { Progress } from '@backstage/frontend-plugin-api'; + + // Use directly as React Component + + + ``` + + **Migration for core component references:** + + ```tsx + // OLD: Core component refs + import { coreComponentRefs } from '@backstage/frontend-plugin-api'; + + coreComponentRefs.progress + coreComponentRefs.notFoundErrorPage + coreComponentRefs.errorBoundaryFallback + + // NEW: Direct swappable component imports + import { Progress, NotFoundErrorPage, ErrorDisplay } from '@backstage/frontend-plugin-api'; + + // Use directly as React components + + + + ``` + +- 6a75e00: **BREAKING**: Removed the deprecated `createFrontendPlugin` variant where the plugin ID is passed via an `id` option. To update existing code, switch to using the `pluginId` option instead. +- 1e6410b: **BREAKING**: The `ResolveInputValueOverrides` type is no longer exported. + +### Patch Changes + +- 9831f4e: Adjusted the dialog API types to have more sensible defaults +- 1c2cc37: Improved runtime error message clarity when extension factories don't return an iterable object. +- 24558f0: Added inline documentation for `createExtension`, `createExtensionBlueprint`, `createFrontendPlugin`, and `createFrontendModule`. +- Updated dependencies + - @backstage/core-components@0.17.5-next.2 + +## 0.11.0-next.1 + +### Minor Changes + +- c5f88b5: **BREAKING**: Remove deprecated `source` property from the `AppNodeSpec` type, use `AppNodeSpec.plugin` instead. +- e4ddf22: **BREAKING**: The `defaultPath` param of `PageBlueprint` has been renamed to `path`. This change does not affect the compatibility of extensions created with older versions of this blueprint. +- 37f2989: **BREAKING**: Removed the `routable` property from `ExtensionBoundary`. This property was never needed in practice and is instead inferred from whether or not the extension outputs a route reference. It can be safely removed. +- 3243fa6: **BREAKING**: Removed the ability to define a default extension `name` in blueprints. This option had no practical purpose as blueprints already use the `kind` to identity the source of the extension. +- a082429: **BREAKING**: The separate `RouteResolutionApiResolveOptions` type has been removed. +- 5d31d66: **BREAKING**: In an attempt to align some of the API's around providing components to `Blueprints`, we've renamed the parameters for both the `RouterBlueprint` and `AppRootWrapperBlueprint` from `Component` to `component`. + + ```tsx + // old + RouterBlueprint.make({ + params: { + Component: ({ children }) =>
    {children}
    , + }, + }); + + // new + RouterBlueprint.make({ + params: { + component: ({ children }) =>
    {children}
    , + }, + }); + ``` + + ```tsx + // old + AppRootWrapperBlueprint.make({ + params: { + Component: ({ children }) =>
    {children}
    , + }, + }); + + // new + AppRootWrapperBlueprint.make({ + params: { + component: ({ children }) =>
    {children}
    , + }, + }); + ``` + + As part of this change, the type for `component` has also changed from `ComponentType>` to `(props: { children: ReactNode }) => JSX.Element | null` which is not breaking, just a little more reflective of the actual expected component. + +- 45ead4a: **BREAKING**: The `AnyRoutes` and `AnyExternalRoutes` types have been removed and their usage has been inlined instead. + + Existing usage can be replaced according to their previous definitions: + + ```ts + type AnyRoutes = { [name in string]: RouteRef | SubRouteRef }; + type AnyExternalRoutes = { [name in string]: ExternalRouteRef }; + ``` + +- 121899a: **BREAKING**: The `element` param for `AppRootElementBlueprint` no longer accepts a component. If you are currently passing a component such as `element: () => ` or `element: MyComponent`, simply switch to `element: `. +- a321f3b: **BREAKING**: The `CommonAnalyticsContext` has been removed, and inlined into `AnalyticsContextValue` instead. + +### Patch Changes + +- d9e00e3: Add support for a new `aliasFor` option for `createRouteRef`. This allows for the creation of a new route ref that acts as an alias for an existing route ref that is installed in the app. This is particularly useful when creating modules that override existing plugin pages, without referring to the existing plugin. For example: + + ```tsx + export default createFrontendModule({ + pluginId: 'catalog', + extensions: [ + PageBlueprint.make({ + params: { + defaultPath: '/catalog', + routeRef: createRouteRef({ aliasFor: 'catalog.catalogIndex' }), + loader: () => + import('./CustomCatalogIndexPage').then(m => ( + + )), + }, + }), + ], + }); + ``` + +- 93b5e38: Plugins should now use the new `AnalyticsImplementationBlueprint` to define and provide concrete analytics implementations. For example: + + ```ts + import { AnalyticsImplementationBlueprint } from '@backstage/frontend-plugin-api'; + + const AcmeAnalytics = AnalyticsImplementationBlueprint.make({ + name: 'acme-analytics', + params: define => + define({ + deps: { config: configApiRef }, + factory: ({ config }) => AcmeAnalyticsImpl.fromConfig(config), + }), + }); + ``` + +- 948de17: Tweaked the return types from `createExtension` and `createExtensionBlueprint` to avoid the forwarding of `ConfigurableExtensionDataRef` into exported types. +- 147482b: Updated the recommended naming of the blueprint param callback from `define` to `defineParams`, making the syntax `defineParams => defineParams(...)`. +- 3c3c882: Added added defaults for all type parameters of `ExtensionDataRef` and deprecated `AnyExtensionDataRef`, as it is now redundant. +- Updated dependencies + - @backstage/core-components@0.17.5-next.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.11.0-next.0 + +### Minor Changes + +- 29786f6: **BREAKING**: The `NavLogoBlueprint` has been removed and replaced by `NavContentBlueprint`, which instead replaces the entire navbar. The default navbar has also been switched to a more minimal implementation. + + To use `NavContentBlueprint` to install new logos, you can use it as follows: + + ```tsx + NavContentBlueprint.make({ + params: { + component: ({ items }) => { + return compatWrapper( + + + + {/* Other sidebar content */} + + + {items.map((item, index) => ( + + ))} + + + {/* Other sidebar content */} + , + ); + }, + }, + }); + ``` + +- 805c298: **BREAKING**: The `ApiBlueprint` has been updated to use the new advanced type parameters through the new `defineParams` blueprint option. This is an immediate breaking change that requires all existing usages of `ApiBlueprint` to switch to the new callback format. Existing extensions created with the old format are still compatible with the latest version of the plugin API however, meaning that this does not break existing plugins. + + To update existing usages of `ApiBlueprint`, you remove the outer level of the `params` object and replace `createApiFactory(...)` with `define => define(...)`. + + For example, the following old usage: + + ```ts + ApiBlueprint.make({ + name: 'error', + params: { + factory: createApiFactory({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => { + return ...; + }, + }) + }, + }) + ``` + + is migrated to the following: + + ```ts + ApiBlueprint.make({ + name: 'error', + params: define => + define({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => { + return ...; + }, + }), + }) + ``` + +- 805c298: Added support for advanced parameter types in extension blueprints. The primary purpose of this is to allow extension authors to use type inference in the definition of the blueprint parameters. This often removes the need for extra imports and improves discoverability of blueprint parameters. + + This feature is introduced through the new `defineParams` option of `createExtensionBlueprint`, along with accompanying `createExtensionBlueprintParams` function to help implement the new format. + + The following is an example of how to create an extension blueprint that uses the new option: + + ```ts + const ExampleBlueprint = createExtensionBlueprint({ + kind: 'example', + attachTo: { id: 'example', input: 'example' }, + output: [exampleComponentDataRef, exampleFetcherDataRef], + defineParams(params: { + component(props: ExampleProps): JSX.Element | null; + fetcher(options: FetchOptions): Promise>; + }) { + // The returned params must be wrapped with `createExtensionBlueprintParams` + return createExtensionBlueprintParams(params); + }, + *factory(params) { + // These params are now inferred + yield exampleComponentDataRef(params.component); + yield exampleFetcherDataRef(params.fetcher); + }, + }); + ``` + + Usage of the above example looks as follows: + + ```ts + const example = ExampleBlueprint.make({ + params: define => define({ + component: ..., + fetcher: ..., + }), + }); + ``` + + This `define => define()` is also known as the "callback syntax" and is required if a blueprint is created with the new `defineParams` option. The callback syntax can also optionally be used for other blueprints too, which means that it is not a breaking change to remove the `defineParams` option, as long as the external parameter types remain compatible. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.5-next.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.10.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + +## 0.10.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## 0.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.10.3 + +### Patch Changes + +- 0169b23: Internal tweak to avoid circular dependencies +- 9e3868f: Added a new optional `info` option to `createFrontendPlugin` that lets you provide a loaders for different sources of metadata information about the plugin. + + There are two available loaders. The first one is `info.packageJson`, which can be used to point to a `package.json` file for the plugin. This is recommended for any plugin that is defined within its own package, especially all plugins that are published to a package registry. Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + packageJson: () => import('../package.json'), + }, + }); + ``` + + The second loader is `info.manifest`, which can be used to point to an opaque plugin manifest. This **MUST ONLY** be used by plugins that are intended for use within a single organization. Plugins that are published to an open package registry should **NOT** use this loader. The loader is useful for adding additional internal metadata associated with the plugin, and it is up to the Backstage app to decide how these manifests are parsed and used. The default manifest parser in an app created with `createApp` from `@backstage/frontend-defaults` is able to parse the default `catalog-info.yaml` format and built-in fields such as `spec.owner`. + + Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + manifest: () => import('../catalog-info.yaml'), + }, + }); + ``` + +- 6f48f71: Added a new `useAppNode` hook, which can be used to get a reference to the `AppNode` from by the closest `ExtensionBoundary`. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.10.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.10.3-next.0 + +### Patch Changes + +- 9e3868f: Added a new optional `info` option to `createFrontendPlugin` that lets you provide a loaders for different sources of metadata information about the plugin. + + There are two available loaders. The first one is `info.packageJson`, which can be used to point to a `package.json` file for the plugin. This is recommended for any plugin that is defined within its own package, especially all plugins that are published to a package registry. Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + packageJson: () => import('../package.json'), + }, + }); + ``` + + The second loader is `info.manifest`, which can be used to point to an opaque plugin manifest. This **MUST ONLY** be used by plugins that are intended for use within a single organization. Plugins that are published to an open package registry should **NOT** use this loader. The loader is useful for adding additional internal metadata associated with the plugin, and it is up to the Backstage app to decide how these manifests are parsed and used. The default manifest parser in an app created with `createApp` from `@backstage/frontend-defaults` is able to parse the default `catalog-info.yaml` format and built-in fields such as `spec.owner`. + + Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + manifest: () => import('../catalog-info.yaml'), + }, + }); + ``` + +- 6f48f71: Added a new `useAppNode` hook, which can be used to get a reference to the `AppNode` from by the closest `ExtensionBoundary`. + +## 0.10.2 + +### Patch Changes + +- 173db8f: The `source` property of `AppNodeSpec` has been renamed to `plugin`. The old property has been deprecated and will be removed in a future release. +- fb58f20: The `id` option of `createFrontendPlugin` has been renamed to `pluginId` in order to better align with similar APIs in the frontend and backend systems. + + The old `id` option is deprecated and will be removed in a future release. + +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + ## 0.10.2-next.1 ### Patch Changes diff --git a/packages/frontend-plugin-api/knip-report.md b/packages/frontend-plugin-api/knip-report.md index 402fea3d47..d76f9ef7d9 100644 --- a/packages/frontend-plugin-api/knip-report.md +++ b/packages/frontend-plugin-api/knip-report.md @@ -4,13 +4,13 @@ | Name | Location | Severity | | :------------------------- | :----------- | :------- | -| @backstage/core-components | package.json | error | -| @material-ui/core | package.json | error | -| lodash | package.json | error | +| @backstage/core-components | packages/frontend-plugin-api/package.json | error | +| @material-ui/core | packages/frontend-plugin-api/package.json | error | +| lodash | packages/frontend-plugin-api/package.json | error | ## Unused devDependencies (1) | Name | Location | Severity | | :-------------------------- | :----------- | :------- | -| @backstage/frontend-app-api | package.json | error | +| @backstage/frontend-app-api | packages/frontend-plugin-api/package.json | error | diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index 1e3161489c..c00227563d 100644 --- a/packages/frontend-plugin-api/package.json +++ b/packages/frontend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-plugin-api", - "version": "0.10.2-next.1", + "version": "0.12.2-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-plugin-api/report.api.md b/packages/frontend-plugin-api/report.api.md index cd5d89401d..b7c5b08528 100644 --- a/packages/frontend-plugin-api/report.api.md +++ b/packages/frontend-plugin-api/report.api.md @@ -8,6 +8,7 @@ import { alertApiRef } from '@backstage/core-plugin-api'; import { AlertMessage } from '@backstage/core-plugin-api'; import { AnyApiFactory } from '@backstage/core-plugin-api'; import { AnyApiRef } from '@backstage/core-plugin-api'; +import { AnyRouteRefParams as AnyRouteRefParams_2 } from '@backstage/frontend-plugin-api'; import { ApiFactory } from '@backstage/core-plugin-api'; import { ApiHolder } from '@backstage/core-plugin-api'; import { ApiRef } from '@backstage/core-plugin-api'; @@ -26,6 +27,7 @@ import { bitbucketServerAuthApiRef } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; import { ConfigApi } from '@backstage/core-plugin-api'; import { configApiRef } from '@backstage/core-plugin-api'; +import { ConfigurableExtensionDataRef as ConfigurableExtensionDataRef_2 } from '@backstage/frontend-plugin-api'; import { createApiFactory } from '@backstage/core-plugin-api'; import { createApiRef } from '@backstage/core-plugin-api'; import { createTranslationMessages } from '@backstage/core-plugin-api/alpha'; @@ -38,6 +40,8 @@ import { ErrorApiError } from '@backstage/core-plugin-api'; import { ErrorApiErrorContext } from '@backstage/core-plugin-api'; import { errorApiRef } from '@backstage/core-plugin-api'; import { Expand } from '@backstage/types'; +import { ExtensionBlueprint as ExtensionBlueprint_2 } from '@backstage/frontend-plugin-api'; +import { ExtensionDataRef as ExtensionDataRef_2 } from '@backstage/frontend-plugin-api'; import { FeatureFlag } from '@backstage/core-plugin-api'; import { FeatureFlagsApi } from '@backstage/core-plugin-api'; import { featureFlagsApiRef } from '@backstage/core-plugin-api'; @@ -48,7 +52,8 @@ import { fetchApiRef } from '@backstage/core-plugin-api'; import { githubAuthApiRef } from '@backstage/core-plugin-api'; import { gitlabAuthApiRef } from '@backstage/core-plugin-api'; import { googleAuthApiRef } from '@backstage/core-plugin-api'; -import { IconComponent as IconComponent_2 } from '@backstage/core-plugin-api'; +import { IconComponent as IconComponent_2 } from '@backstage/frontend-plugin-api'; +import { IconComponent as IconComponent_3 } from '@backstage/core-plugin-api'; import { IdentityApi } from '@backstage/core-plugin-api'; import { identityApiRef } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; @@ -64,11 +69,12 @@ import { OAuthScope } from '@backstage/core-plugin-api'; import { oktaAuthApiRef } from '@backstage/core-plugin-api'; import { oneloginAuthApiRef } from '@backstage/core-plugin-api'; import { OpenIdConnectApi } from '@backstage/core-plugin-api'; +import { openshiftAuthApiRef } from '@backstage/core-plugin-api'; import { PendingOAuthRequest } from '@backstage/core-plugin-api'; import { ProfileInfo } from '@backstage/core-plugin-api'; import { ProfileInfoApi } from '@backstage/core-plugin-api'; -import { PropsWithChildren } from 'react'; import { ReactNode } from 'react'; +import { RouteRef as RouteRef_2 } from '@backstage/frontend-plugin-api'; import { SessionApi } from '@backstage/core-plugin-api'; import { SessionState } from '@backstage/core-plugin-api'; import { SignInPageProps } from '@backstage/core-plugin-api'; @@ -110,9 +116,12 @@ export const AnalyticsContext: (options: { }) => JSX_2.Element; // @public -export type AnalyticsContextValue = CommonAnalyticsContext & { - [param in string]: string | boolean | number | undefined; -}; +export interface AnalyticsContextValue { + // (undocumented) + [key: string]: string | boolean | number | undefined; + extensionId: string; + pluginId: string; +} // @public export type AnalyticsEvent = { @@ -128,6 +137,44 @@ export type AnalyticsEventAttributes = { [attribute in string]: string | boolean | number; }; +// @public +export type AnalyticsImplementation = { + captureEvent(event: AnalyticsEvent): void; +}; + +// @public +export const AnalyticsImplementationBlueprint: ExtensionBlueprint<{ + kind: 'analytics'; + params: ( + params: AnalyticsImplementationFactory, + ) => ExtensionBlueprintParams>; + output: ExtensionDataRef< + AnalyticsImplementationFactory<{}>, + 'core.analytics.factory', + {} + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { + factory: ConfigurableExtensionDataRef< + AnalyticsImplementationFactory<{}>, + 'core.analytics.factory', + {} + >; + }; +}>; + +// @public (undocumented) +export type AnalyticsImplementationFactory< + Deps extends { + [name in string]: unknown; + } = {}, +> = { + deps: TypesToApiRefs; + factory(deps: Deps): AnalyticsImplementation; +}; + // @public export type AnalyticsTracker = { captureEvent: ( @@ -144,19 +191,8 @@ export { AnyApiFactory }; export { AnyApiRef }; -// @public (undocumented) -export type AnyExtensionDataRef = ExtensionDataRef< - unknown, - string, - { - optional?: true; - } ->; - -// @public (undocumented) -export type AnyExternalRoutes = { - [name in string]: ExternalRouteRef; -}; +// @public @deprecated (undocumented) +export type AnyExtensionDataRef = ExtensionDataRef; // @public export type AnyRouteRefParams = @@ -165,19 +201,17 @@ export type AnyRouteRefParams = } | undefined; -// @public (undocumented) -export type AnyRoutes = { - [name in string]: RouteRef | SubRouteRef; -}; - // @public export const ApiBlueprint: ExtensionBlueprint<{ kind: 'api'; - name: undefined; - params: { - factory: AnyApiFactory; - }; - output: ConfigurableExtensionDataRef; + params: < + TApi, + TImpl extends TApi, + TDeps extends { [name in string]: unknown }, + >( + params: ApiFactory, + ) => ExtensionBlueprintParams; + output: ExtensionDataRef; inputs: {}; config: {}; configInput: {}; @@ -235,17 +269,16 @@ export interface AppNodeSpec { // (undocumented) readonly id: string; // (undocumented) - readonly source?: FrontendPlugin; + readonly plugin: FrontendPlugin; } // @public export const AppRootElementBlueprint: ExtensionBlueprint<{ kind: 'app-root-element'; - name: undefined; params: { - element: JSX.Element | (() => JSX.Element); + element: JSX.Element; }; - output: ConfigurableExtensionDataRef; + output: ExtensionDataRef; inputs: {}; config: {}; configInput: {}; @@ -255,14 +288,12 @@ export const AppRootElementBlueprint: ExtensionBlueprint<{ // @public export const AppRootWrapperBlueprint: ExtensionBlueprint<{ kind: 'app-root-wrapper'; - name: undefined; params: { - Component: ComponentType>; + Component?: [error: 'Use the `component` parameter instead']; + component: (props: { children: ReactNode }) => JSX.Element | null; }; - output: ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + output: ExtensionDataRef< + (props: { children: ReactNode }) => JSX.Element | null, 'app.root.wrapper', {} >; @@ -271,9 +302,7 @@ export const AppRootWrapperBlueprint: ExtensionBlueprint<{ configInput: {}; dataRefs: { component: ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + (props: { children: ReactNode }) => JSX.Element | null, 'app.root.wrapper', {} >; @@ -295,7 +324,7 @@ export interface AppTree { // @public export interface AppTreeApi { - getNodesByRoutePath(sourcePath: string): { + getNodesByRoutePath(routePath: string): { nodes: AppNode[]; }; getTree(): { @@ -322,27 +351,6 @@ export { bitbucketAuthApiRef }; export { bitbucketServerAuthApiRef }; -// @public -export type CommonAnalyticsContext = { - pluginId: string; - extensionId: string; -}; - -// @public (undocumented) -export type ComponentRef = { - id: string; - T: T; -}; - -// @public -export interface ComponentsApi { - // (undocumented) - getComponent(ref: ComponentRef): ComponentType; -} - -// @public -export const componentsApiRef: ApiRef; - export { ConfigApi }; export { configApiRef }; @@ -367,22 +375,9 @@ export interface ConfigurableExtensionDataRef< >; } -// @public (undocumented) -export const coreComponentRefs: { - progress: ComponentRef; - notFoundErrorPage: ComponentRef; - errorBoundaryFallback: ComponentRef; -}; - -// @public (undocumented) -export type CoreErrorBoundaryFallbackProps = { - plugin?: FrontendPlugin; - error: Error; - resetError: () => void; -}; - // @public (undocumented) export const coreExtensionData: { + title: ConfigurableExtensionDataRef; reactElement: ConfigurableExtensionDataRef< JSX_3.Element, 'core.reactElement', @@ -390,90 +385,21 @@ export const coreExtensionData: { >; routePath: ConfigurableExtensionDataRef; routeRef: ConfigurableExtensionDataRef< - RouteRef, + RouteRef, 'core.routing.ref', {} >; }; -// @public (undocumented) -export type CoreNotFoundErrorPageProps = { - children?: ReactNode; -}; - -// @public (undocumented) -export type CoreProgressProps = {}; - export { createApiFactory }; export { createApiRef }; -// @public (undocumented) -export function createComponentExtension(options: { - ref: ComponentRef; - name?: string; - disabled?: boolean; - loader: - | { - lazy: () => Promise>; - } - | { - sync: () => ComponentType; - }; -}): ExtensionDefinition<{ - config: {}; - configInput: {}; - output: ConfigurableExtensionDataRef< - { - ref: ComponentRef; - impl: ComponentType; - }, - 'core.component.component', - {} - >; - inputs: { - [x: string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; - }; - params: never; - kind: 'component'; - name: string; -}>; - -// @public (undocumented) -export namespace createComponentExtension { - const // (undocumented) - componentDataRef: ConfigurableExtensionDataRef< - { - ref: ComponentRef; - impl: ComponentType; - }, - 'core.component.component', - {} - >; -} - -// @public (undocumented) -export function createComponentRef(options: { - id: string; -}): ComponentRef; - -// @public (undocumented) +// @public export function createExtension< - UOutput extends AnyExtensionDataRef, + UOutput extends ExtensionDataRef, TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType; @@ -503,7 +429,13 @@ export function createExtension< [key in keyof TConfigSchema]: ReturnType; }> >; - output: UOutput; + output: UOutput extends ExtensionDataRef< + infer IData, + infer IId, + infer IConfig + > + ? ExtensionDataRef + : never; inputs: TInputs; params: never; kind: string | undefined extends TKind ? undefined : TKind; @@ -512,30 +444,22 @@ export function createExtension< // @public export function createExtensionBlueprint< - TParams extends object, - UOutput extends AnyExtensionDataRef, + TParams extends object | ExtensionBlueprintDefineParams, + UOutput extends ExtensionDataRef, TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, UFactoryOutput extends ExtensionDataValue, TKind extends string, - TName extends string | undefined = undefined, TDataRefs extends { - [name in string]: AnyExtensionDataRef; + [name in string]: ExtensionDataRef; } = never, >( options: CreateExtensionBlueprintOptions< TKind, - TName, TParams, UOutput, TInputs, @@ -545,9 +469,14 @@ export function createExtensionBlueprint< >, ): ExtensionBlueprint<{ kind: TKind; - name: TName; params: TParams; - output: UOutput; + output: UOutput extends ExtensionDataRef< + infer IData, + infer IId, + infer IConfig + > + ? ExtensionDataRef + : never; inputs: string extends keyof TInputs ? {} : TInputs; config: string extends keyof TConfigSchema ? {} @@ -567,24 +496,17 @@ export function createExtensionBlueprint< // @public (undocumented) export type CreateExtensionBlueprintOptions< TKind extends string, - TName extends string | undefined, - TParams, - UOutput extends AnyExtensionDataRef, + TParams extends object | ExtensionBlueprintDefineParams, + UOutput extends ExtensionDataRef, TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, UFactoryOutput extends ExtensionDataValue, TDataRefs extends { - [name in string]: AnyExtensionDataRef; + [name in string]: ExtensionDataRef; }, > = { kind: TKind; @@ -592,12 +514,16 @@ export type CreateExtensionBlueprintOptions< disabled?: boolean; inputs?: TInputs; output: Array; - name?: TName; config?: { schema: TConfigSchema; }; + defineParams?: TParams extends ExtensionBlueprintDefineParams + ? TParams + : 'The defineParams option must be a function if provided, see the docs for details'; factory( - params: TParams, + params: TParams extends ExtensionBlueprintDefineParams + ? ReturnType['T'] + : TParams, context: { node: AppNode; apis: ApiHolder; @@ -610,6 +536,11 @@ export type CreateExtensionBlueprintOptions< dataRefs?: TDataRefs; } & VerifyExtensionFactoryOutput; +// @public +export function createExtensionBlueprintParams( + params: T, +): ExtensionBlueprintParams; + // @public (undocumented) export function createExtensionDataRef(): { with(options: { @@ -650,15 +581,9 @@ export function createExtensionInput< export type CreateExtensionOptions< TKind extends string | undefined, TName extends string | undefined, - UOutput extends AnyExtensionDataRef, + UOutput extends ExtensionDataRef, TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType; @@ -741,10 +666,10 @@ export interface CreateFrontendFeatureLoaderOptions { >; } -// @public (undocumented) +// @public export function createFrontendModule< TId extends string, - TExtensions extends readonly ExtensionDefinition[] = [], + TExtensions extends readonly ExtensionDefinition[], >(options: CreateFrontendModuleOptions): FrontendModule; // @public (undocumented) @@ -760,34 +685,19 @@ export interface CreateFrontendModuleOptions< pluginId: TPluginId; } -// @public (undocumented) +// @public export function createFrontendPlugin< TId extends string, - TRoutes extends AnyRoutes = {}, - TExternalRoutes extends AnyExternalRoutes = {}, - TExtensions extends readonly ExtensionDefinition[] = [], + TExtensions extends readonly ExtensionDefinition[], + TRoutes extends { + [name in string]: RouteRef | SubRouteRef; + } = {}, + TExternalRoutes extends { + [name in string]: ExternalRouteRef; + } = {}, >( options: PluginOptions, -): FrontendPlugin< - TRoutes, - TExternalRoutes, - MakeSortedExtensionsMap ->; - -// @public @deprecated (undocumented) -export function createFrontendPlugin< - TId extends string, - TRoutes extends AnyRoutes = {}, - TExternalRoutes extends AnyExternalRoutes = {}, - TExtensions extends readonly ExtensionDefinition[] = [], ->( - options: Omit< - PluginOptions, - 'pluginId' - > & { - id: string; - }, -): FrontendPlugin< +): OverridableFrontendPlugin< TRoutes, TExternalRoutes, MakeSortedExtensionsMap @@ -802,7 +712,10 @@ export function createRouteRef< | undefined = undefined, TParamKeys extends string = string, >(config?: { - readonly params: string extends TParamKeys ? (keyof TParams)[] : TParamKeys[]; + readonly params?: string extends TParamKeys + ? (keyof TParams)[] + : TParamKeys[]; + aliasFor?: string; }): RouteRef< keyof TParams extends never ? undefined @@ -822,6 +735,32 @@ export function createSubRouteRef< parent: RouteRef; }): MakeSubRouteRef, ParentParams>; +// @public +export function createSwappableComponent< + TInnerComponentProps extends {}, + TExternalComponentProps extends {} = TInnerComponentProps, +>( + options: CreateSwappableComponentOptions< + TInnerComponentProps, + TExternalComponentProps + >, +): { + (props: TExternalComponentProps): JSX.Element | null; + ref: SwappableComponentRef; +}; + +// @public +export type CreateSwappableComponentOptions< + TInnerComponentProps extends {}, + TExternalComponentProps extends {} = TInnerComponentProps, +> = { + id: string; + loader?: + | (() => (props: TInnerComponentProps) => JSX.Element | null) + | (() => Promise<(props: TInnerComponentProps) => JSX.Element | null>); + transformProps?: (props: TExternalComponentProps) => TInnerComponentProps; +}; + export { createTranslationMessages }; export { createTranslationRef }; @@ -830,14 +769,14 @@ export { createTranslationResource }; // @public export interface DialogApi { - show( + show( elementOrComponent: | JSX.Element | ((props: { dialog: DialogApiDialog; }) => JSX.Element), ): DialogApiDialog; - showModal( + showModal( elementOrComponent: | JSX.Element | ((props: { dialog: DialogApiDialog }) => JSX.Element), @@ -845,7 +784,7 @@ export interface DialogApi { } // @public -export interface DialogApiDialog { +export interface DialogApiDialog { close( ...args: undefined extends TResult ? [result?: TResult] : [result: TResult] ): void; @@ -872,6 +811,19 @@ export { ErrorApiErrorContext }; export { errorApiRef }; +// @public (undocumented) +export const ErrorDisplay: { + (props: ErrorDisplayProps): JSX.Element | null; + ref: SwappableComponentRef; +}; + +// @public (undocumented) +export type ErrorDisplayProps = { + plugin?: FrontendPlugin; + error: Error; + resetError: () => void; +}; + // @public (undocumented) export interface Extension { // (undocumented) @@ -904,14 +856,21 @@ export interface ExtensionBlueprint< // (undocumented) dataRefs: T['dataRefs']; // (undocumented) - make(args: { - name?: TNewName; + make< + TName extends string | undefined, + TParamsInput extends AnyParamsInput>, + >(args: { + name?: TName; attachTo?: ExtensionAttachToSpec; disabled?: boolean; - params: T['params']; + params: TParamsInput extends ExtensionBlueprintDefineParams + ? TParamsInput + : T['params'] extends ExtensionBlueprintDefineParams + ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `.make({ params: defineParams => defineParams() })`' + : T['params']; }): ExtensionDefinition<{ kind: T['kind']; - name: string | undefined extends TNewName ? T['name'] : TNewName; + name: string | undefined extends TName ? undefined : TName; config: T['config']; configInput: T['configInput']; output: T['output']; @@ -919,23 +878,17 @@ export interface ExtensionBlueprint< params: T['params']; }>; makeWithOverrides< - TNewName extends string | undefined, + TName extends string | undefined, TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, UFactoryOutput extends ExtensionDataValue, - UNewOutput extends AnyExtensionDataRef, + UNewOutput extends ExtensionDataRef, TExtraInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, >(args: { - name?: TNewName; + name?: TName; attachTo?: ExtensionAttachToSpec; disabled?: boolean; inputs?: TExtraInputs & { @@ -950,11 +903,17 @@ export interface ExtensionBlueprint< }; }; factory( - originalFactory: ( - params: T['params'], + originalFactory: < + TParamsInput extends AnyParamsInput>, + >( + params: TParamsInput extends ExtensionBlueprintDefineParams + ? TParamsInput + : T['params'] extends ExtensionBlueprintDefineParams + ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams())`' + : T['params'], context?: { config?: T['config']; - inputs?: ResolveInputValueOverrides>; + inputs?: ResolvedInputValueOverrides>; }, ) => ExtensionDataContainer>, context: { @@ -969,7 +928,7 @@ export interface ExtensionBlueprint< }, ): Iterable & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput + ExtensionDataRef extends UNewOutput ? NonNullable : UNewOutput, UFactoryOutput @@ -993,40 +952,45 @@ export interface ExtensionBlueprint< }> >) & T['configInput']; - output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; inputs: T['inputs'] & TExtraInputs; kind: T['kind']; - name: string | undefined extends TNewName ? T['name'] : TNewName; + name: string | undefined extends TName ? undefined : TName; params: T['params']; }>; } +// @public +export type ExtensionBlueprintDefineParams< + TParams extends object = object, + TInput = any, +> = (params: TInput) => ExtensionBlueprintParams; + // @public (undocumented) export type ExtensionBlueprintParameters = { kind: string; - name?: string; - params?: object; + params?: object | ExtensionBlueprintDefineParams; configInput?: { [K in string]: any; }; config?: { [K in string]: any; }; - output?: AnyExtensionDataRef; + output?: ExtensionDataRef; inputs?: { - [KName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [KName in string]: ExtensionInput; }; dataRefs?: { - [name in string]: AnyExtensionDataRef; + [name in string]: ExtensionDataRef; }; }; +// @public +export type ExtensionBlueprintParams = { + $$type: '@backstage/BlueprintParams'; + T: T; +}; + // @public (undocumented) export function ExtensionBoundary(props: ExtensionBoundaryProps): JSX_2.Element; @@ -1050,11 +1014,10 @@ export interface ExtensionBoundaryProps { children: ReactNode; // (undocumented) node: AppNode; - routable?: boolean; } // @public (undocumented) -export type ExtensionDataContainer = +export type ExtensionDataContainer = Iterable< UExtensionData extends ExtensionDataRef< infer IData, @@ -1077,11 +1040,13 @@ export type ExtensionDataContainer = // @public (undocumented) export type ExtensionDataRef< - TData, + TData = unknown, TId extends string = string, TConfig extends { optional?: true; - } = {}, + } = { + optional?: true; + }, > = { readonly $$type: '@backstage/ExtensionDataRef'; readonly id: TId; @@ -1113,16 +1078,11 @@ export type ExtensionDefinition< [key in string]: (zImpl: typeof z) => z.ZodType; }, UFactoryOutput extends ExtensionDataValue, - UNewOutput extends AnyExtensionDataRef, + UNewOutput extends ExtensionDataRef, TExtraInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [inputName in string]: ExtensionInput; }, + TParamsInput extends AnyParamsInput_2>, >( args: Expand< { @@ -1140,15 +1100,23 @@ export type ExtensionDefinition< }; }; factory?( - originalFactory: ( + originalFactory: < + TFactoryParamsReturn extends AnyParamsInput_2< + NonNullable + >, + >( context?: Expand< { config?: T['config']; - inputs?: ResolveInputValueOverrides>; + inputs?: ResolvedInputValueOverrides>; } & ([T['params']] extends [never] ? {} : { - params?: Partial; + params?: TFactoryParamsReturn extends ExtensionBlueprintDefineParams + ? TFactoryParamsReturn + : T['params'] extends ExtensionBlueprintDefineParams + ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams())`' + : Partial; }) >, ) => ExtensionDataContainer>, @@ -1166,11 +1134,15 @@ export type ExtensionDefinition< } & ([T['params']] extends [never] ? {} : { - params?: Partial; + params?: TParamsInput extends ExtensionBlueprintDefineParams + ? TParamsInput + : T['params'] extends ExtensionBlueprintDefineParams + ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams())`' + : Partial; }) > & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput + ExtensionDataRef extends UNewOutput ? NonNullable : UNewOutput, UFactoryOutput @@ -1178,7 +1150,7 @@ export type ExtensionDefinition< ): ExtensionDefinition<{ kind: T['kind']; name: T['name']; - output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; inputs: T['inputs'] & TExtraInputs; config: T['config'] & { [key in keyof TExtensionConfigSchema]: z.infer< @@ -1206,24 +1178,18 @@ export type ExtensionDefinitionParameters = { config?: { [K in string]: any; }; - output?: AnyExtensionDataRef; + output?: ExtensionDataRef; inputs?: { - [KName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; + [KName in string]: ExtensionInput; }; - params?: object; + params?: object | ExtensionBlueprintDefineParams; }; // @public (undocumented) export type ExtensionFactoryMiddleware = ( originalFactory: (contextOverrides?: { config?: JsonObject; - }) => ExtensionDataContainer, + }) => ExtensionDataContainer, context: { node: AppNode; apis: ApiHolder; @@ -1239,10 +1205,13 @@ export interface ExtensionInput< { optional?: true; } - >, + > = ExtensionDataRef, TConfig extends { singleton: boolean; optional: boolean; + } = { + singleton: boolean; + optional: boolean; }, > { // (undocumented) @@ -1306,12 +1275,15 @@ export interface FrontendModule { // @public (undocumented) export interface FrontendPlugin< - TRoutes extends AnyRoutes = AnyRoutes, - TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, - TExtensionMap extends { - [id in string]: ExtensionDefinition; + TRoutes extends { + [name in string]: RouteRef | SubRouteRef; } = { - [id in string]: ExtensionDefinition; + [name in string]: RouteRef | SubRouteRef; + }, + TExternalRoutes extends { + [name in string]: ExternalRouteRef; + } = { + [name in string]: ExternalRouteRef; }, > { // (undocumented) @@ -1319,17 +1291,34 @@ export interface FrontendPlugin< // (undocumented) readonly externalRoutes: TExternalRoutes; // (undocumented) - getExtension(id: TId): TExtensionMap[TId]; - // (undocumented) readonly id: string; + info(): Promise; // (undocumented) readonly routes: TRoutes; - // (undocumented) - withOverrides(options: { - extensions: Array; - }): FrontendPlugin; } +// @public +export interface FrontendPluginInfo { + description?: string; + links?: Array<{ + title: string; + url: string; + }>; + ownerEntityRefs?: string[]; + packageName?: string; + version?: string; +} + +// @public +export type FrontendPluginInfoOptions = { + packageJson?: () => Promise< + { + name: string; + } & JsonObject + >; + manifest?: () => Promise; +}; + export { githubAuthApiRef }; export { gitlabAuthApiRef }; @@ -1339,11 +1328,10 @@ export { googleAuthApiRef }; // @public (undocumented) export const IconBundleBlueprint: ExtensionBlueprint<{ kind: 'icon-bundle'; - name: undefined; params: { icons: { [key in string]: IconComponent }; }; - output: ConfigurableExtensionDataRef< + output: ExtensionDataRef< { [x: string]: IconComponent; }, @@ -1386,19 +1374,57 @@ export { identityApiRef }; export { microsoftAuthApiRef }; +// @public +export const NavContentBlueprint: ExtensionBlueprint_2<{ + kind: 'nav-content'; + params: { + component: NavContentComponent; + }; + output: ExtensionDataRef_2< + NavContentComponent, + 'core.nav-content.component', + {} + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { + component: ConfigurableExtensionDataRef_2< + NavContentComponent, + 'core.nav-content.component', + {} + >; + }; +}>; + +// @public +export type NavContentComponent = ( + props: NavContentComponentProps, +) => JSX.Element | null; + +// @public +export interface NavContentComponentProps { + items: Array<{ + icon: IconComponent_2; + title: string; + routeRef: RouteRef_2; + to: string; + text: string; + }>; +} + // @public export const NavItemBlueprint: ExtensionBlueprint<{ kind: 'nav-item'; - name: undefined; params: { title: string; - icon: IconComponent_2; + icon: IconComponent_3; routeRef: RouteRef; }; - output: ConfigurableExtensionDataRef< + output: ExtensionDataRef< { title: string; - icon: IconComponent_2; + icon: IconComponent_3; routeRef: RouteRef; }, 'core.nav-item.target', @@ -1411,7 +1437,7 @@ export const NavItemBlueprint: ExtensionBlueprint<{ target: ConfigurableExtensionDataRef< { title: string; - icon: IconComponent_2; + icon: IconComponent_3; routeRef: RouteRef; }, 'core.nav-item.target', @@ -1420,36 +1446,16 @@ export const NavItemBlueprint: ExtensionBlueprint<{ }; }>; -// @public -export const NavLogoBlueprint: ExtensionBlueprint<{ - kind: 'nav-logo'; - name: undefined; - params: { - logoIcon: JSX.Element; - logoFull: JSX.Element; - }; - output: ConfigurableExtensionDataRef< - { - logoIcon?: JSX.Element; - logoFull?: JSX.Element; - }, - 'core.nav-logo.logo-elements', - {} - >; - inputs: {}; - config: {}; - configInput: {}; - dataRefs: { - logoElements: ConfigurableExtensionDataRef< - { - logoIcon?: JSX.Element; - logoFull?: JSX.Element; - }, - 'core.nav-logo.logo-elements', - {} - >; - }; -}>; +// @public (undocumented) +export const NotFoundErrorPage: { + (props: NotFoundErrorPageProps): JSX.Element | null; + ref: SwappableComponentRef; +}; + +// @public (undocumented) +export type NotFoundErrorPageProps = { + children?: ReactNode; +}; export { OAuthApi }; @@ -1469,19 +1475,48 @@ export { oneloginAuthApiRef }; export { OpenIdConnectApi }; +export { openshiftAuthApiRef }; + +// @public +export interface OverridableFrontendPlugin< + TRoutes extends { + [name in string]: RouteRef | SubRouteRef; + } = { + [name in string]: RouteRef | SubRouteRef; + }, + TExternalRoutes extends { + [name in string]: ExternalRouteRef; + } = { + [name in string]: ExternalRouteRef; + }, + TExtensionMap extends { + [id in string]: ExtensionDefinition; + } = { + [id in string]: ExtensionDefinition; + }, +> extends FrontendPlugin { + // (undocumented) + getExtension(id: TId): TExtensionMap[TId]; + // (undocumented) + withOverrides(options: { + extensions: Array; + info?: FrontendPluginInfoOptions; + }): OverridableFrontendPlugin; +} + // @public export const PageBlueprint: ExtensionBlueprint<{ kind: 'page'; - name: undefined; params: { - defaultPath: string; + defaultPath?: [Error: `Use the 'path' param instead`]; + path: string; loader: () => Promise; routeRef?: RouteRef; }; output: - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< + | ExtensionDataRef + | ExtensionDataRef + | ExtensionDataRef< RouteRef, 'core.routing.ref', { @@ -1503,8 +1538,12 @@ export { PendingOAuthRequest }; // @public (undocumented) export interface PluginOptions< TId extends string, - TRoutes extends AnyRoutes, - TExternalRoutes extends AnyExternalRoutes, + TRoutes extends { + [name in string]: RouteRef | SubRouteRef; + }, + TExternalRoutes extends { + [name in string]: ExternalRouteRef; + }, TExtensions extends readonly ExtensionDefinition[], > { // (undocumented) @@ -1514,6 +1553,8 @@ export interface PluginOptions< // (undocumented) featureFlags?: FeatureFlagConfig[]; // (undocumented) + info?: FrontendPluginInfoOptions; + // (undocumented) pluginId: TId; // (undocumented) routes?: TRoutes; @@ -1529,19 +1570,27 @@ export { ProfileInfo }; export { ProfileInfoApi }; +// @public (undocumented) +export const Progress: { + (props: ProgressProps): JSX.Element | null; + ref: SwappableComponentRef; +}; + +// @public (undocumented) +export type ProgressProps = {}; + // @public -export type ResolvedExtensionInput< - TExtensionInput extends ExtensionInput, -> = TExtensionInput['extensionData'] extends Array - ? { - node: AppNode; - } & ExtensionDataContainer - : never; +export type ResolvedExtensionInput = + TExtensionInput['extensionData'] extends Array + ? { + node: AppNode; + } & ExtensionDataContainer + : never; // @public export type ResolvedExtensionInputs< TInputs extends { - [name in string]: ExtensionInput; + [name in string]: ExtensionInput; }, > = { [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] @@ -1551,73 +1600,6 @@ export type ResolvedExtensionInputs< : Expand | undefined>; }; -// @public (undocumented) -export type ResolveInputValueOverrides< - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; - } = { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; - }, -> = Expand< - { - [KName in keyof TInputs as TInputs[KName] extends ExtensionInput< - any, - { - optional: infer IOptional extends boolean; - singleton: boolean; - } - > - ? IOptional extends true - ? never - : KName - : never]: TInputs[KName] extends ExtensionInput< - infer IDataRefs, - { - optional: boolean; - singleton: infer ISingleton extends boolean; - } - > - ? ISingleton extends true - ? Iterable> - : Array>> - : never; - } & { - [KName in keyof TInputs as TInputs[KName] extends ExtensionInput< - any, - { - optional: infer IOptional extends boolean; - singleton: boolean; - } - > - ? IOptional extends true - ? KName - : never - : never]?: TInputs[KName] extends ExtensionInput< - infer IDataRefs, - { - optional: boolean; - singleton: infer ISingleton extends boolean; - } - > - ? ISingleton extends true - ? Iterable> - : Array>> - : never; - } ->; - // @public export type RouteFunc = ( ...[params]: TParams extends undefined @@ -1628,14 +1610,12 @@ export type RouteFunc = ( // @public (undocumented) export const RouterBlueprint: ExtensionBlueprint<{ kind: 'app-router-component'; - name: undefined; params: { - Component: ComponentType>; + Component?: [error: 'Use the `component` parameter instead']; + component: (props: { children: ReactNode }) => JSX.Element | null; }; - output: ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + output: ExtensionDataRef< + (props: { children: ReactNode }) => JSX.Element | null, 'app.router.wrapper', {} >; @@ -1644,9 +1624,7 @@ export const RouterBlueprint: ExtensionBlueprint<{ configInput: {}; dataRefs: { component: ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + (props: { children: ReactNode }) => JSX.Element | null, 'app.router.wrapper', {} >; @@ -1671,18 +1649,15 @@ export interface RouteResolutionApi { | RouteRef | SubRouteRef | ExternalRouteRef, - options?: RouteResolutionApiResolveOptions, + options?: { + sourcePath?: string; + }, ): RouteFunc | undefined; } // @public export const routeResolutionApiRef: ApiRef; -// @public (undocumented) -export type RouteResolutionApiResolveOptions = { - sourcePath?: string; -}; - export { SessionApi }; export { SessionState }; @@ -1690,11 +1665,10 @@ export { SessionState }; // @public export const SignInPageBlueprint: ExtensionBlueprint<{ kind: 'sign-in-page'; - name: undefined; params: { loader: () => Promise>; }; - output: ConfigurableExtensionDataRef< + output: ExtensionDataRef< ComponentType, 'core.sign-in-page.component', {} @@ -1729,14 +1703,97 @@ export interface SubRouteRef< readonly T: TParams; } +// @public +export const SwappableComponentBlueprint: ExtensionBlueprint<{ + kind: 'component'; + params: >(params: { + component: Ref extends SwappableComponentRef< + any, + infer IExternalComponentProps + > + ? { + ref: Ref; + } & ((props: IExternalComponentProps) => JSX.Element | null) + : never; + loader: Ref extends SwappableComponentRef + ? + | (() => (props: IInnerComponentProps) => JSX.Element | null) + | (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>) + : never; + }) => ExtensionBlueprintParams<{ + component: Ref extends SwappableComponentRef< + any, + infer IExternalComponentProps + > + ? { + ref: Ref; + } & ((props: IExternalComponentProps) => JSX.Element | null) + : never; + loader: Ref extends SwappableComponentRef + ? + | (() => (props: IInnerComponentProps) => JSX.Element | null) + | (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>) + : never; + }>; + output: ExtensionDataRef< + { + ref: SwappableComponentRef; + loader: + | (() => (props: {}) => JSX.Element | null) + | (() => Promise<(props: {}) => JSX.Element | null>); + }, + 'core.swappableComponent', + {} + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { + component: ConfigurableExtensionDataRef< + { + ref: SwappableComponentRef; + loader: + | (() => (props: {}) => JSX.Element | null) + | (() => Promise<(props: {}) => JSX.Element | null>); + }, + 'core.swappableComponent', + {} + >; + }; +}>; + +// @public (undocumented) +export type SwappableComponentRef< + TInnerComponentProps extends {} = {}, + TExternalComponentProps extends {} = TInnerComponentProps, +> = { + id: string; + TProps: TInnerComponentProps; + TExternalProps: TExternalComponentProps; + $$type: '@backstage/SwappableComponentRef'; +}; + +// @public +export interface SwappableComponentsApi { + // (undocumented) + getComponent< + TInnerComponentProps extends {}, + TExternalComponentProps extends {} = TInnerComponentProps, + >( + ref: SwappableComponentRef, + ): (props: TInnerComponentProps) => JSX.Element | null; +} + +// @public +export const swappableComponentsApiRef: ApiRef; + // @public export const ThemeBlueprint: ExtensionBlueprint<{ kind: 'theme'; - name: undefined; params: { theme: AppTheme; }; - output: ConfigurableExtensionDataRef; + output: ExtensionDataRef; inputs: {}; config: {}; configInput: {}; @@ -1748,11 +1805,10 @@ export const ThemeBlueprint: ExtensionBlueprint<{ // @public export const TranslationBlueprint: ExtensionBlueprint<{ kind: 'translation'; - name: undefined; params: { resource: TranslationResource | TranslationMessages; }; - output: ConfigurableExtensionDataRef< + output: ExtensionDataRef< | TranslationResource | TranslationMessages< string, @@ -1805,9 +1861,7 @@ export { useApi }; export { useApiHolder }; // @public -export function useComponentRef( - ref: ComponentRef, -): ComponentType; +export function useAppNode(): AppNode | undefined; // @public export function useRouteRef( diff --git a/packages/frontend-plugin-api/src/analytics/Tracker.ts b/packages/frontend-plugin-api/src/analytics/Tracker.ts index dd0d770354..5aae3ec19d 100644 --- a/packages/frontend-plugin-api/src/analytics/Tracker.ts +++ b/packages/frontend-plugin-api/src/analytics/Tracker.ts @@ -65,13 +65,18 @@ const globalEvents = getOrCreateGlobalSingleton( export const routableExtensionRenderedEvent = '_ROUTABLE-EXTENSION-RENDERED'; export class Tracker implements AnalyticsTracker { + private readonly analyticsApi: AnalyticsApi; + private context: AnalyticsContextValue; + constructor( - private readonly analyticsApi: AnalyticsApi, - private context: AnalyticsContextValue = { + analyticsApi: AnalyticsApi, + context: AnalyticsContextValue = { pluginId: 'root', extensionId: 'App', }, ) { + this.analyticsApi = analyticsApi; + this.context = context; // Only register a single beforeunload event across all trackers. if (!globalEvents.beforeUnloadRegistered) { // Before the page unloads, attempt to capture any deferred navigation diff --git a/packages/frontend-plugin-api/src/analytics/index.ts b/packages/frontend-plugin-api/src/analytics/index.ts index 651e8e105e..988a4e0163 100644 --- a/packages/frontend-plugin-api/src/analytics/index.ts +++ b/packages/frontend-plugin-api/src/analytics/index.ts @@ -15,5 +15,5 @@ */ export { AnalyticsContext } from './AnalyticsContext'; -export type { AnalyticsContextValue, CommonAnalyticsContext } from './types'; +export type { AnalyticsContextValue } from './types'; export { useAnalytics } from './useAnalytics'; diff --git a/packages/frontend-plugin-api/src/analytics/types.ts b/packages/frontend-plugin-api/src/analytics/types.ts index 3e3a9ad5eb..e9628dc628 100644 --- a/packages/frontend-plugin-api/src/analytics/types.ts +++ b/packages/frontend-plugin-api/src/analytics/types.ts @@ -15,11 +15,11 @@ */ /** - * Common analytics context attributes. + * Analytics context envelope. * * @public */ -export type CommonAnalyticsContext = { +export interface AnalyticsContextValue { /** * The nearest known parent plugin where the event was captured. */ @@ -29,13 +29,6 @@ export type CommonAnalyticsContext = { * The nearest known parent extension where the event was captured. */ extensionId: string; -}; -/** - * Analytics context envelope. - * - * @public - */ -export type AnalyticsContextValue = CommonAnalyticsContext & { - [param in string]: string | boolean | number | undefined; -}; + [key: string]: string | boolean | number | undefined; +} diff --git a/packages/frontend-plugin-api/src/apis/definitions/AnalyticsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/AnalyticsApi.ts index 15b09482b7..2040966464 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/AnalyticsApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/AnalyticsApi.ts @@ -16,6 +16,7 @@ import { ApiRef, createApiRef } from '@backstage/core-plugin-api'; import { AnalyticsContextValue } from '../../analytics/types'; +import type { AnalyticsImplementationBlueprint } from '../../blueprints/'; /** * Represents an event worth tracking in an analytics system that could inform @@ -102,6 +103,26 @@ export type AnalyticsTracker = { ) => void; }; +/** + * Analytics implementations are used to track user behavior in a Backstage + * instance. + * + * @remarks + * + * To instrument your App or Plugin, retrieve an analytics tracker using the + * `useAnalytics()` hook. This will return a pre-configured `AnalyticsTracker` + * with relevant methods for instrumentation. + * + * @public + */ +export type AnalyticsImplementation = { + /** + * Primary event handler responsible for compiling and forwarding events to + * an analytics system. + */ + captureEvent(event: AnalyticsEvent): void; +}; + /** * The Analytics API is used to track user behavior in a Backstage instance. * @@ -124,6 +145,11 @@ export type AnalyticsApi = { /** * The API reference of {@link AnalyticsApi}. * + * @remarks + * + * To define a concrete Analytics Implementation, use + * {@link AnalyticsImplementationBlueprint} instead. + * * @public */ export const analyticsApiRef: ApiRef = createApiRef({ diff --git a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts index c9d9896600..f4fd2f3a6f 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/AppTreeApi.ts @@ -37,7 +37,7 @@ export interface AppNodeSpec { readonly extension: Extension; readonly disabled: boolean; readonly config?: unknown; - readonly source?: FrontendPlugin; + readonly plugin: FrontendPlugin; } /** @@ -113,7 +113,7 @@ export interface AppTreeApi { /** * Get all nodes in the app that are mounted at a given route path. */ - getNodesByRoutePath(sourcePath: string): { nodes: AppNode[] }; + getNodesByRoutePath(routePath: string): { nodes: AppNode[] }; } /** diff --git a/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts deleted file mode 100644 index c5e9d2c44f..0000000000 --- a/packages/frontend-plugin-api/src/apis/definitions/ComponentsApi.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ComponentType } from 'react'; -import { createApiRef, useApi } from '@backstage/core-plugin-api'; -import { ComponentRef } from '../../components'; - -/** - * API for looking up components based on component refs. - * - * @public - */ -export interface ComponentsApi { - // TODO: Should component refs also provide the default implementation so that we're guaranteed to get a component? - getComponent(ref: ComponentRef): ComponentType; -} - -/** - * The `ApiRef` of {@link ComponentsApi}. - * - * @public - */ -export const componentsApiRef = createApiRef({ - id: 'core.components', -}); - -/** - * @public - * Returns the component associated with the given ref. - */ -export function useComponentRef( - ref: ComponentRef, -): ComponentType { - const componentsApi = useApi(componentsApiRef); - return componentsApi.getComponent(ref); -} diff --git a/packages/frontend-plugin-api/src/apis/definitions/DialogApi.ts b/packages/frontend-plugin-api/src/apis/definitions/DialogApi.ts index 71cd70d3aa..801ec88c69 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/DialogApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/DialogApi.ts @@ -25,7 +25,7 @@ import { createApiRef } from '@backstage/core-plugin-api'; * * @public */ -export interface DialogApiDialog { +export interface DialogApiDialog { /** * Closes the dialog with that provided result. * @@ -109,7 +109,7 @@ export interface DialogApi { * @param elementOrComponent - The element or component to render in the dialog. If a component is provided, it will be provided with a `dialog` prop that contains the dialog handle. * @public */ - show( + show( elementOrComponent: | JSX.Element | ((props: { @@ -161,7 +161,7 @@ export interface DialogApi { * @param elementOrComponent - The element or component to render in the dialog. If a component is provided, it will be provided with a `dialog` prop that contains the dialog handle. * @public */ - showModal( + showModal( elementOrComponent: | JSX.Element | ((props: { dialog: DialogApiDialog }) => JSX.Element), diff --git a/packages/frontend-plugin-api/src/apis/definitions/RouteResolutionApi.ts b/packages/frontend-plugin-api/src/apis/definitions/RouteResolutionApi.ts index 30569bde15..6ae25a814e 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/RouteResolutionApi.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/RouteResolutionApi.ts @@ -41,17 +41,6 @@ export type RouteFunc = ( : readonly [params: TParams] ) => string; -/** - * @public - */ -export type RouteResolutionApiResolveOptions = { - /** - * An absolute path to use as a starting point when resolving the route. - * If no path is provided the route will be resolved from the root of the app. - */ - sourcePath?: string; -}; - /** * @public */ @@ -61,7 +50,13 @@ export interface RouteResolutionApi { | RouteRef | SubRouteRef | ExternalRouteRef, - options?: RouteResolutionApiResolveOptions, + options?: { + /** + * An absolute path to use as a starting point when resolving the route. + * If no path is provided the route will be resolved from the root of the app. + */ + sourcePath?: string; + }, ): RouteFunc | undefined; } diff --git a/packages/frontend-plugin-api/src/apis/definitions/SwappableComponentsApi.ts b/packages/frontend-plugin-api/src/apis/definitions/SwappableComponentsApi.ts new file mode 100644 index 0000000000..ed2b20ce80 --- /dev/null +++ b/packages/frontend-plugin-api/src/apis/definitions/SwappableComponentsApi.ts @@ -0,0 +1,41 @@ +/* + * 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 { SwappableComponentRef } from '../../components'; +import { createApiRef } from '@backstage/core-plugin-api'; + +/** + * API for looking up components based on component refs. + * + * @public + */ +export interface SwappableComponentsApi { + getComponent< + TInnerComponentProps extends {}, + TExternalComponentProps extends {} = TInnerComponentProps, + >( + ref: SwappableComponentRef, + ): (props: TInnerComponentProps) => JSX.Element | null; +} + +/** + * The `ApiRef` of {@link SwappableComponentsApi}. + * + * @public + */ +export const swappableComponentsApiRef = createApiRef({ + id: 'core.swappable-components', +}); diff --git a/packages/frontend-plugin-api/src/apis/definitions/auth.ts b/packages/frontend-plugin-api/src/apis/definitions/auth.ts index 89509082f0..5a31c1603d 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/auth.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/auth.ts @@ -37,4 +37,5 @@ export { microsoftAuthApiRef, oneloginAuthApiRef, vmwareCloudAuthApiRef, + openshiftAuthApiRef, } from '@backstage/core-plugin-api'; diff --git a/packages/frontend-plugin-api/src/apis/definitions/index.ts b/packages/frontend-plugin-api/src/apis/definitions/index.ts index 0da23fcacb..7533481d01 100644 --- a/packages/frontend-plugin-api/src/apis/definitions/index.ts +++ b/packages/frontend-plugin-api/src/apis/definitions/index.ts @@ -34,7 +34,7 @@ export * from './auth'; export * from './AlertApi'; export * from './AppThemeApi'; -export * from './ComponentsApi'; +export * from './SwappableComponentsApi'; export * from './ConfigApi'; export * from './DiscoveryApi'; export * from './ErrorApi'; diff --git a/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.test.ts similarity index 53% rename from packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx rename to packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.test.ts index bbd96ea53b..b297b3a3a9 100644 --- a/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.test.ts @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Backstage Authors + * Copyright 2025 The 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,32 +14,36 @@ * limitations under the License. */ -import { NavLogoBlueprint } from './NavLogoBlueprint'; -import { createExtensionTester } from '@backstage/frontend-test-utils'; +import { AnalyticsImplementationBlueprint } from './AnalyticsImplementationBlueprint'; -describe('NavLogoBlueprint', () => { +describe('AnalyticsBlueprint', () => { it('should create an extension with sensible defaults', () => { - const extension = NavLogoBlueprint.make({ - params: { - logoFull:
    Logo Full
    , - logoIcon:
    Logo Icon
    , - }, + const factory = { + deps: {}, + factory: () => ({ captureEvent: () => {} }), + }; + + const extension = AnalyticsImplementationBlueprint.make({ + params: define => define(factory), + name: 'test', }); expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", "T": undefined, - "attachTo": { - "id": "app/nav", - "input": "logos", - }, + "attachTo": [ + { + "id": "api:app/analytics", + "input": "implementations", + }, + ], "configSchema": undefined, "disabled": false, "factory": [Function], "inputs": {}, - "kind": "nav-logo", - "name": undefined, + "kind": "analytics", + "name": "test", "output": [ [Function], ], @@ -49,24 +53,4 @@ describe('NavLogoBlueprint', () => { } `); }); - - it('should return a valid component ref', () => { - const logoFull =
    Logo Full
    ; - const logoIcon =
    Logo Icon
    ; - - const extension = NavLogoBlueprint.make({ - name: 'test', - params: { - logoFull, - logoIcon, - }, - }); - - const tester = createExtensionTester(extension); - - expect(tester.get(NavLogoBlueprint.dataRefs.logoElements)).toEqual({ - logoFull, - logoIcon, - }); - }); }); diff --git a/packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.ts new file mode 100644 index 0000000000..91a0f27092 --- /dev/null +++ b/packages/frontend-plugin-api/src/blueprints/AnalyticsImplementationBlueprint.ts @@ -0,0 +1,55 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AnalyticsImplementation, TypesToApiRefs } from '../apis'; +import { + createExtensionBlueprint, + createExtensionBlueprintParams, + createExtensionDataRef, +} from '../wiring'; + +/** @public */ +export type AnalyticsImplementationFactory< + Deps extends { [name in string]: unknown } = {}, +> = { + deps: TypesToApiRefs; + factory(deps: Deps): AnalyticsImplementation; +}; + +const factoryDataRef = + createExtensionDataRef().with({ + id: 'core.analytics.factory', + }); + +/** + * Creates analytics implementations. + * + * @public + */ +export const AnalyticsImplementationBlueprint = createExtensionBlueprint({ + kind: 'analytics', + attachTo: [{ id: 'api:app/analytics', input: 'implementations' }], + output: [factoryDataRef], + dataRefs: { + factory: factoryDataRef, + }, + defineParams: ( + params: AnalyticsImplementationFactory, + ) => createExtensionBlueprintParams(params as AnalyticsImplementationFactory), + *factory(params) { + yield factoryDataRef(params); + }, +}); diff --git a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts index 862f802810..471e933b12 100644 --- a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts @@ -16,21 +16,19 @@ import { createExtensionInput } from '../wiring'; import { ApiBlueprint } from './ApiBlueprint'; -import { createApiFactory, createApiRef } from '@backstage/core-plugin-api'; +import { createApiRef } from '@backstage/core-plugin-api'; describe('ApiBlueprint', () => { it('should create an extension with sensible defaults', () => { const api = createApiRef<{ foo: string }>({ id: 'test' }); - const factory = createApiFactory({ - api, - deps: {}, - factory: () => ({ foo: 'bar' }), - }); const extension = ApiBlueprint.make({ - params: { - factory, - }, + params: defineParams => + defineParams({ + api, + deps: {}, + factory: () => ({ foo: 'bar' }), + }), name: 'test', }); @@ -58,6 +56,101 @@ describe('ApiBlueprint', () => { `); }); + it('should properly type the API factory', () => { + const fooApi = createApiRef<{ foo: string }>({ id: 'foo' }); + const barApi = createApiRef<{ bar: string }>({ id: 'bar' }); + + expect('test').not.toBe('failing without assertions'); + + ApiBlueprint.make({ + params: defineParams => + defineParams({ + api: fooApi, + deps: {}, + factory: () => ({ foo: 'foo' }), + }), + }); + + ApiBlueprint.make({ + params: defineParams => + defineParams({ + api: fooApi, + deps: {}, + // @ts-expect-error missing property + factory: () => ({}), + }), + }); + + ApiBlueprint.make({ + params: defineParams => + defineParams({ + api: fooApi, + deps: {}, + // @ts-expect-error wrong property + factory: () => ({ + bar: 'bar', + }), + }), + }); + + ApiBlueprint.make({ + params: defineParams => + defineParams({ + api: fooApi, + deps: {}, + factory: () => ({ + // @ts-expect-error wrong type + foo: 1, + }), + }), + }); + + ApiBlueprint.make({ + params: defineParams => + defineParams({ + api: fooApi, + deps: { bar: barApi }, + factory: ({ bar }) => ({ foo: bar.bar }), + }), + }); + + ApiBlueprint.make({ + params: defineParams => + defineParams({ + api: fooApi, + deps: { bar: barApi }, + factory: ({ bar }) => ({ + // @ts-expect-error not an available property + foo: bar.foo, + }), + }), + }); + + ApiBlueprint.make({ + params: defineParams => + defineParams({ + api: fooApi, + deps: { bar: barApi }, + factory: ({ bar }) => ({ + // @ts-expect-error not an available property + foo: bar.foo, + }), + }), + }); + + ApiBlueprint.make({ + params: defineParams => + defineParams({ + api: fooApi, + deps: {}, + factory: ({ bar }) => ({ + // @ts-expect-error unknown dep + foo: bar.bar, + }), + }), + }); + }); + it('should create an extension with custom factory', () => { const api = createApiRef<{ foo: string }>({ id: 'test' }); const factory = jest.fn(() => ({ foo: 'bar' })); @@ -73,13 +166,9 @@ describe('ApiBlueprint', () => { }, name: api.id, factory(originalFactory, { config: _config, inputs: _inputs }) { - return originalFactory({ - factory: createApiFactory({ - api, - deps: {}, - factory, - }), - }); + return originalFactory(defineParams => + defineParams({ api, deps: {}, factory }), + ); }, }); diff --git a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.ts index 1f28a3cf54..a066a362d9 100644 --- a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.ts +++ b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.ts @@ -14,8 +14,9 @@ * limitations under the License. */ +import { AnyApiFactory, ApiFactory } from '../apis/system'; import { createExtensionBlueprint, createExtensionDataRef } from '../wiring'; -import { AnyApiFactory } from '@backstage/core-plugin-api'; +import { createExtensionBlueprintParams } from '../wiring/createExtensionBlueprint'; const factoryDataRef = createExtensionDataRef().with({ id: 'core.api.factory', @@ -33,7 +34,14 @@ export const ApiBlueprint = createExtensionBlueprint({ dataRefs: { factory: factoryDataRef, }, - *factory(params: { factory: AnyApiFactory }) { - yield factoryDataRef(params.factory); + defineParams: < + TApi, + TImpl extends TApi, + TDeps extends { [name in string]: unknown }, + >( + params: ApiFactory, + ) => createExtensionBlueprintParams(params as AnyApiFactory), + *factory(params) { + yield factoryDataRef(params); }, }); diff --git a/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.ts index c823fa56cd..d1c71155f2 100644 --- a/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.ts +++ b/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.ts @@ -26,9 +26,7 @@ export const AppRootElementBlueprint = createExtensionBlueprint({ kind: 'app-root-element', attachTo: { id: 'app/root', input: 'elements' }, output: [coreExtensionData.reactElement], - *factory(params: { element: JSX.Element | (() => JSX.Element) }) { - yield coreExtensionData.reactElement( - typeof params.element === 'function' ? params.element() : params.element, - ); + *factory(params: { element: JSX.Element }) { + yield coreExtensionData.reactElement(params.element); }, }); diff --git a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx index d46975abd9..0f26af3243 100644 --- a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { Fragment } from 'react'; import { AppRootWrapperBlueprint } from './AppRootWrapperBlueprint'; import { screen, waitFor } from '@testing-library/react'; import { @@ -21,13 +21,13 @@ import { createExtension, createExtensionInput, } from '../wiring'; -import { renderInTestApp } from '@backstage/frontend-test-utils'; +import { renderTestApp } from '@backstage/frontend-test-utils'; describe('AppRootWrapperBlueprint', () => { it('should return an extension with sensible defaults', () => { const extension = AppRootWrapperBlueprint.make({ params: { - Component: () =>
    Hello
    , + component: () =>
    Hello
    , }, }); @@ -59,11 +59,11 @@ describe('AppRootWrapperBlueprint', () => { const extension = AppRootWrapperBlueprint.make({ name: 'test', params: { - Component: () =>
    Hello
    , + component: () =>
    Hello
    , }, }); - renderInTestApp(
    , { extensions: [extension] }); + renderTestApp({ extensions: [extension] }); await waitFor(() => expect(screen.getByText('Hello')).toBeInTheDocument()); }); @@ -80,19 +80,21 @@ describe('AppRootWrapperBlueprint', () => { }, *factory(originalFactory, { inputs, config }) { yield* originalFactory({ - Component: ({ children }) => ( + component: ({ children }) => (
    {children} - {inputs.children.flatMap(c => - c.get(coreExtensionData.reactElement), - )} + {inputs.children.flatMap((c, index) => ( + + {c.get(coreExtensionData.reactElement)} + + ))}
    ), }); }, }); - renderInTestApp(
    , { + renderTestApp({ extensions: [ extension, createExtension({ diff --git a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.tsx b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.tsx index 481be1bc0b..493fba05f6 100644 --- a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.tsx +++ b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.tsx @@ -14,11 +14,11 @@ * limitations under the License. */ -import { ComponentType, PropsWithChildren } from 'react'; +import { ReactNode } from 'react'; import { createExtensionBlueprint, createExtensionDataRef } from '../wiring'; const componentDataRef = createExtensionDataRef< - ComponentType> + (props: { children: ReactNode }) => JSX.Element | null >().with({ id: 'app.root.wrapper' }); /** @@ -35,12 +35,11 @@ export const AppRootWrapperBlueprint = createExtensionBlueprint({ dataRefs: { component: componentDataRef, }, - *factory(params: { Component: ComponentType> }) { - // todo(blam): not sure that this wrapping is even necessary anymore. - const Component = (props: PropsWithChildren<{}>) => { - return {props.children}; - }; - - yield componentDataRef(Component); + *factory(params: { + /** @deprecated use the `component` parameter instead */ + Component?: [error: 'Use the `component` parameter instead']; + component: (props: { children: ReactNode }) => JSX.Element | null; + }) { + yield componentDataRef(params.component); }, }); diff --git a/packages/frontend-plugin-api/src/blueprints/NavContentBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/NavContentBlueprint.test.tsx new file mode 100644 index 0000000000..a113a2f21d --- /dev/null +++ b/packages/frontend-plugin-api/src/blueprints/NavContentBlueprint.test.tsx @@ -0,0 +1,112 @@ +/* + * 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 { createRouteRef } from '@backstage/frontend-plugin-api'; +import { NavContentBlueprint } from './NavContentBlueprint'; +import { createExtensionTester } from '@backstage/frontend-test-utils'; + +const routeRef = createRouteRef(); + +describe('NavContentBlueprint', () => { + it('should create an extension with sensible defaults', () => { + const extension = NavContentBlueprint.make({ + params: { + component: () =>
    Nav content
    , + }, + }); + + expect(extension).toMatchInlineSnapshot(` + { + "$$type": "@backstage/ExtensionDefinition", + "T": undefined, + "attachTo": { + "id": "app/nav", + "input": "content", + }, + "configSchema": undefined, + "disabled": false, + "factory": [Function], + "inputs": {}, + "kind": "nav-content", + "name": undefined, + "output": [ + [Function], + ], + "override": [Function], + "toString": [Function], + "version": "v2", + } + `); + }); + + it('should return a valid component', () => { + const extension = NavContentBlueprint.make({ + name: 'test', + params: { + component: () =>
    Nav content
    , + }, + }); + + const tester = createExtensionTester(extension); + + expect( + tester.get(NavContentBlueprint.dataRefs.component)({ items: [] }), + ).toEqual(
    Nav content
    ); + }); + + it('should return a valid component with items', () => { + const extension = NavContentBlueprint.make({ + name: 'test', + params: { + component: ({ items }) => ( +
    + Items: + {items.map((item, index) => ( + + {item.title} + + ))} +
    + ), + }, + }); + + const tester = createExtensionTester(extension); + + expect( + tester.get(NavContentBlueprint.dataRefs.component)({ + items: [ + { + to: '/', + text: 'Home', + title: 'Home', + icon: () => null, + routeRef, + }, + ], + }), + ).toEqual( +
    + Items: + {[ + + Home + , + ]} +
    , + ); + }); +}); diff --git a/packages/frontend-plugin-api/src/blueprints/NavContentBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/NavContentBlueprint.ts new file mode 100644 index 0000000000..a6524ea49e --- /dev/null +++ b/packages/frontend-plugin-api/src/blueprints/NavContentBlueprint.ts @@ -0,0 +1,74 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { IconComponent, RouteRef } from '@backstage/frontend-plugin-api'; +import { createExtensionBlueprint, createExtensionDataRef } from '../wiring'; + +/** + * The props for the {@link NavContentComponent}. + * + * @public + */ +export interface NavContentComponentProps { + /** + * The nav items available to the component. These are all the items created + * with the {@link NavItemBlueprint} in the app. + * + * In addition to the original properties from the nav items, these also + * include a resolved route path as `to`, and duplicated `title` as `text` to + * simplify rendering. + */ + items: Array<{ + // Original props from nav items + icon: IconComponent; + title: string; + routeRef: RouteRef; + + // Additional props to simplify item rendering + to: string; + text: string; + }>; +} + +/** + * A component that renders the nav bar content, to be passed to the {@link NavContentBlueprint}. + * + * @public + */ +export type NavContentComponent = ( + props: NavContentComponentProps, +) => JSX.Element | null; + +const componentDataRef = createExtensionDataRef().with({ + id: 'core.nav-content.component', +}); + +/** + * Creates an extension that replaces the entire nav bar with your own component. + * + * @public + */ +export const NavContentBlueprint = createExtensionBlueprint({ + kind: 'nav-content', + attachTo: { id: 'app/nav', input: 'content' }, + output: [componentDataRef], + dataRefs: { + component: componentDataRef, + }, + *factory(params: { component: NavContentComponent }) { + yield componentDataRef(params.component); + }, +}); diff --git a/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.ts deleted file mode 100644 index 4a37859975..0000000000 --- a/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2024 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createExtensionBlueprint, createExtensionDataRef } from '../wiring'; - -const logoElementsDataRef = createExtensionDataRef<{ - logoIcon?: JSX.Element; - logoFull?: JSX.Element; -}>().with({ id: 'core.nav-logo.logo-elements' }); - -/** - * Creates an extension that replaces the logo in the nav bar with your own. - * - * @public - */ -export const NavLogoBlueprint = createExtensionBlueprint({ - kind: 'nav-logo', - attachTo: { id: 'app/nav', input: 'logos' }, - output: [logoElementsDataRef], - dataRefs: { - logoElements: logoElementsDataRef, - }, - *factory({ - logoIcon, - logoFull, - }: { - logoIcon: JSX.Element; - logoFull: JSX.Element; - }) { - yield logoElementsDataRef({ - logoIcon, - logoFull, - }); - }, -}); diff --git a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx index d3e1a6c954..680d93cd1c 100644 --- a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx @@ -34,7 +34,7 @@ describe('PageBlueprint', () => { name: 'test-page', params: { loader: () => Promise.resolve(
    Test
    ), - defaultPath: '/test', + path: '/test', routeRef: mockRouteRef, }, }); @@ -90,7 +90,7 @@ describe('PageBlueprint', () => { name: 'test-page', params: { loader: () => Promise.resolve(
    Test
    ), - defaultPath: '/test', + path: '/test', routeRef: mockRouteRef, }, }); @@ -123,7 +123,7 @@ describe('PageBlueprint', () => { {inputs.cards.map(c => c.get(coreExtensionData.reactElement))}
    ), - defaultPath: '/test', + path: '/test', routeRef: mockRouteRef, }); }, diff --git a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx index 303e99daaa..92e2ab6172 100644 --- a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx +++ b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.tsx @@ -37,21 +37,23 @@ export const PageBlueprint = createExtensionBlueprint({ }, }, *factory( - { - defaultPath, - loader, - routeRef, - }: { - defaultPath: string; + params: { + /** + * @deprecated Use the `path` param instead. + */ + defaultPath?: [Error: `Use the 'path' param instead`]; + path: string; loader: () => Promise; routeRef?: RouteRef; }, { config, node }, ) { - yield coreExtensionData.routePath(config.path ?? defaultPath); - yield coreExtensionData.reactElement(ExtensionBoundary.lazy(node, loader)); - if (routeRef) { - yield coreExtensionData.routeRef(routeRef); + yield coreExtensionData.routePath(config.path ?? params.path); + yield coreExtensionData.reactElement( + ExtensionBoundary.lazy(node, params.loader), + ); + if (params.routeRef) { + yield coreExtensionData.routeRef(params.routeRef); } }, }); diff --git a/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx index 00015d0c3d..f2e5199124 100644 --- a/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx @@ -27,7 +27,7 @@ describe('RouterBlueprint', () => { it('should return an extension when calling make with sensible defaults', () => { const extension = RouterBlueprint.make({ params: { - Component: props =>
    {props.children}
    , + component: props =>
    {props.children}
    , }, }); @@ -58,7 +58,7 @@ describe('RouterBlueprint', () => { it('should work with simple options', async () => { const extension = RouterBlueprint.make({ params: { - Component: ({ children }) => ( + component: ({ children }) => (
    {children}
    @@ -94,7 +94,7 @@ describe('RouterBlueprint', () => { }, *factory(originalFactory, { inputs, config }) { yield* originalFactory({ - Component: ({ children }) => ( + component: ({ children }) => (
    > + (props: { children: ReactNode }) => JSX.Element | null >().with({ id: 'app.router.wrapper' }); /** @public */ @@ -29,7 +29,11 @@ export const RouterBlueprint = createExtensionBlueprint({ dataRefs: { component: componentDataRef, }, - *factory({ Component }: { Component: ComponentType> }) { - yield componentDataRef(Component); + *factory(params: { + /** @deprecated use the `component` parameter instead */ + Component?: [error: 'Use the `component` parameter instead']; + component: (props: { children: ReactNode }) => JSX.Element | null; + }) { + yield componentDataRef(params.component); }, }); diff --git a/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.tsx b/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.tsx index 0ca9bf4e92..5e4112a8d1 100644 --- a/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.tsx +++ b/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.tsx @@ -48,7 +48,7 @@ export const SignInPageBlueprint = createExtensionBlueprint({ ); yield componentDataRef(props => ( - + )); diff --git a/packages/frontend-plugin-api/src/blueprints/SwappableComponentBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/SwappableComponentBlueprint.test.tsx new file mode 100644 index 0000000000..63436308ed --- /dev/null +++ b/packages/frontend-plugin-api/src/blueprints/SwappableComponentBlueprint.test.tsx @@ -0,0 +1,133 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { renderTestApp } from '@backstage/frontend-test-utils'; +import { createSwappableComponent } from '../components'; +import { SwappableComponentBlueprint } from './SwappableComponentBlueprint'; +import { PageBlueprint } from './PageBlueprint'; +import { screen } from '@testing-library/react'; + +describe('SwappableComponentBlueprint', () => { + it('should allow defining a component override for a component ref', () => { + const Component = createSwappableComponent({ + id: 'test.component', + loader: () => (props: { hello: string }) =>
    {props.hello}
    , + }); + + const extension = SwappableComponentBlueprint.make({ + params: define => + define({ + component: Component, + loader: () => props => { + // @ts-expect-error + const t: number = props.hello; + + return
    Override {props.hello}
    ; + }, + }), + }); + + expect(extension).toBeDefined(); + }); + + it('should render default component refs in the app', async () => { + const TestComponent = createSwappableComponent({ + id: 'test.component', + loader: () => (props: { hello: string }) =>
    {props.hello}
    , + }); + + renderTestApp({ + extensions: [ + PageBlueprint.make({ + params: define => + define({ + path: '/', + loader: async () => , + }), + }), + ], + }); + + await expect(screen.findByText('test!')).resolves.toBeInTheDocument(); + }); + + it('should render a component ref without a default implementation', async () => { + const TestComponent = createSwappableComponent({ + id: 'test.component', + }); + + renderTestApp({ + extensions: [ + PageBlueprint.make({ + params: define => + define({ + path: '/', + loader: async () => , + }), + }), + ], + }); + + await expect( + screen.findByTestId('test.component'), + ).resolves.toBeInTheDocument(); + }); + + it('should render a component ref with an async loader implementation', async () => { + const TestComponent = createSwappableComponent({ + id: 'test.component', + loader: async () => (props: { hello: string }) => +
    {props.hello}
    , + }); + + renderTestApp({ + extensions: [ + PageBlueprint.make({ + params: define => + define({ + // todo(blam): there's a bug that this path cannot be `/`? + path: '/', + loader: async () => , + }), + }), + ], + }); + + await expect(screen.findByText('test!')).resolves.toBeInTheDocument(); + }); + + it('should render a component ref with an async loader implementation and prop transform', async () => { + const TestComponent = createSwappableComponent({ + id: 'test.component', + loader: async () => (props: { hello: string }) => +
    {props.hello}
    , + transformProps: ({ hello }) => ({ hello: `tr ${hello}` }), + }); + + renderTestApp({ + extensions: [ + PageBlueprint.make({ + params: define => + define({ + path: '/', + loader: async () => , + }), + }), + ], + }); + + await expect(screen.findByText('tr test!')).resolves.toBeInTheDocument(); + }); +}); diff --git a/packages/frontend-plugin-api/src/blueprints/SwappableComponentBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/SwappableComponentBlueprint.ts new file mode 100644 index 0000000000..b72d14d87f --- /dev/null +++ b/packages/frontend-plugin-api/src/blueprints/SwappableComponentBlueprint.ts @@ -0,0 +1,63 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { SwappableComponentRef } from '../components'; +import { + createExtensionBlueprint, + createExtensionBlueprintParams, + createExtensionDataRef, +} from '../wiring'; + +export const componentDataRef = createExtensionDataRef<{ + ref: SwappableComponentRef; + loader: + | (() => (props: {}) => JSX.Element | null) + | (() => Promise<(props: {}) => JSX.Element | null>); +}>().with({ id: 'core.swappableComponent' }); + +/** + * Blueprint for creating swappable components from a SwappableComponentRef and a loader + * + * @public + */ +export const SwappableComponentBlueprint = createExtensionBlueprint({ + kind: 'component', + attachTo: { id: 'api:app/swappable-components', input: 'components' }, + output: [componentDataRef], + dataRefs: { + component: componentDataRef, + }, + defineParams>(params: { + component: Ref extends SwappableComponentRef< + any, + infer IExternalComponentProps + > + ? { ref: Ref } & ((props: IExternalComponentProps) => JSX.Element | null) + : never; + loader: Ref extends SwappableComponentRef + ? + | (() => (props: IInnerComponentProps) => JSX.Element | null) + | (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>) + : never; + }) { + return createExtensionBlueprintParams(params); + }, + factory: params => [ + componentDataRef({ + ref: params.component.ref, + loader: params.loader, + }), + ], +}); diff --git a/packages/frontend-plugin-api/src/blueprints/index.ts b/packages/frontend-plugin-api/src/blueprints/index.ts index 85f7a99a2c..c8699b4232 100644 --- a/packages/frontend-plugin-api/src/blueprints/index.ts +++ b/packages/frontend-plugin-api/src/blueprints/index.ts @@ -14,14 +14,23 @@ * limitations under the License. */ +export { + AnalyticsImplementationBlueprint, + type AnalyticsImplementationFactory, +} from './AnalyticsImplementationBlueprint'; export { ApiBlueprint } from './ApiBlueprint'; export { AppRootElementBlueprint } from './AppRootElementBlueprint'; export { AppRootWrapperBlueprint } from './AppRootWrapperBlueprint'; export { IconBundleBlueprint } from './IconBundleBlueprint'; +export { + NavContentBlueprint, + type NavContentComponent, + type NavContentComponentProps, +} from './NavContentBlueprint'; export { NavItemBlueprint } from './NavItemBlueprint'; -export { NavLogoBlueprint } from './NavLogoBlueprint'; export { PageBlueprint } from './PageBlueprint'; export { RouterBlueprint } from './RouterBlueprint'; export { SignInPageBlueprint } from './SignInPageBlueprint'; export { ThemeBlueprint } from './ThemeBlueprint'; export { TranslationBlueprint } from './TranslationBlueprint'; +export { SwappableComponentBlueprint } from './SwappableComponentBlueprint'; diff --git a/packages/frontend-plugin-api/src/components/AppNodeProvider.test.tsx b/packages/frontend-plugin-api/src/components/AppNodeProvider.test.tsx new file mode 100644 index 0000000000..fcc3b74c59 --- /dev/null +++ b/packages/frontend-plugin-api/src/components/AppNodeProvider.test.tsx @@ -0,0 +1,84 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createVersionedContext, + createVersionedValueMap, +} from '@backstage/version-bridge'; +import { AppNode } from '../apis'; +import { renderHook } from '@testing-library/react'; +import { AppNodeProvider, useAppNode } from './AppNodeProvider'; +import { withLogCollector } from '@backstage/test-utils'; + +describe('AppNodeProvider', () => { + it('should provide app node context to children', () => { + const node = { id: 'test' } as unknown as AppNode; + const { result } = renderHook(() => useAppNode(), { + wrapper: ({ children }) => ( + {children} + ), + }); + + expect(result.current).toBe(node); + }); + + it('should return undefined when used outside provider', () => { + const { result } = renderHook(() => useAppNode()); + expect(result.current).toBeUndefined(); + }); + + it('should return the closest app node', () => { + const node1 = { id: 'test1' } as unknown as AppNode; + const node2 = { id: 'test2' } as unknown as AppNode; + + const { result } = renderHook(() => useAppNode(), { + wrapper: ({ children }) => ( + + {children} + + ), + }); + + expect(result.current).toBe(node2); + }); + + it('should throw error for invalid context version', () => { + const node = { id: 'test' } as unknown as AppNode; + const Context = createVersionedContext('app-node-context'); + const value = createVersionedValueMap({ 2: { node } }); + + const { error } = withLogCollector(() => { + expect(() => + renderHook(() => useAppNode(), { + wrapper: ({ children }) => ( + {children} + ), + }), + ).toThrow('AppNodeContext v1 not available'); + }); + expect(error).toEqual([ + expect.objectContaining({ + detail: new Error('AppNodeContext v1 not available'), + }), + expect.objectContaining({ + detail: new Error('AppNodeContext v1 not available'), + }), + expect.stringContaining( + 'The above error occurred in the component:', + ), + ]); + }); +}); diff --git a/packages/frontend-plugin-api/src/components/AppNodeProvider.tsx b/packages/frontend-plugin-api/src/components/AppNodeProvider.tsx new file mode 100644 index 0000000000..2bc9715c10 --- /dev/null +++ b/packages/frontend-plugin-api/src/components/AppNodeProvider.tsx @@ -0,0 +1,74 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createVersionedContext, + createVersionedValueMap, + useVersionedContext, +} from '@backstage/version-bridge'; +import { AppNode } from '../apis'; +import { ReactNode } from 'react'; + +const CONTEXT_KEY = 'app-node-context'; + +type AppNodeContextV1 = { + node?: AppNode; +}; + +type AppNodeContextMap = { + 1: AppNodeContextV1; +}; + +const AppNodeContext = createVersionedContext(CONTEXT_KEY); + +/** @internal */ +export function AppNodeProvider({ + node, + children, +}: { + node: AppNode; + children: ReactNode; +}) { + const versionedValue = createVersionedValueMap({ 1: { node } }); + + return ; +} + +/** + * React hook providing access to the current {@link AppNode}. + * + * @public + * @remarks + * + * This hook will return the {@link AppNode} for the closest extension. This + * relies on the extension using the {@link (ExtensionBoundary:function)} component in its + * implementation, which is included by default for all common blueprints. + * + * If the current component is not inside an {@link (ExtensionBoundary:function)}, it will + * return `undefined`. + */ +export function useAppNode(): AppNode | undefined { + const versionedContext = useVersionedContext(CONTEXT_KEY); + if (!versionedContext) { + return undefined; + } + + const context = versionedContext.atVersion(1); + if (!context) { + throw new Error('AppNodeContext v1 not available'); + } + return context.node; +} diff --git a/packages/frontend-plugin-api/src/components/DefaultSwappableComponents.tsx b/packages/frontend-plugin-api/src/components/DefaultSwappableComponents.tsx new file mode 100644 index 0000000000..7387bfad3c --- /dev/null +++ b/packages/frontend-plugin-api/src/components/DefaultSwappableComponents.tsx @@ -0,0 +1,46 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + ErrorDisplayProps, + NotFoundErrorPageProps, + ProgressProps, +} from '../types'; +import { createSwappableComponent } from './createSwappableComponent'; + +/** + * @public + */ +export const Progress = createSwappableComponent({ + id: 'core-progress', +}); + +/** + * @public + */ +export const NotFoundErrorPage = + createSwappableComponent({ + id: 'core-not-found-error-page', + }); + +/** + * @public + */ +export const ErrorDisplay = createSwappableComponent({ + id: 'core-error-display', + loader: () => props => +
    {props.error.message}
    , +}); diff --git a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx index 8842ff55cc..4cde84ee93 100644 --- a/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ErrorBoundary.tsx @@ -14,13 +14,12 @@ * limitations under the License. */ -import { Component, ComponentType, PropsWithChildren } from 'react'; +import { Component, PropsWithChildren } from 'react'; import { FrontendPlugin } from '../wiring'; -import { CoreErrorBoundaryFallbackProps } from '../types'; +import { ErrorDisplay } from './DefaultSwappableComponents'; type ErrorBoundaryProps = PropsWithChildren<{ plugin?: FrontendPlugin; - Fallback: ComponentType; }>; type ErrorBoundaryState = { error?: Error }; @@ -41,13 +40,15 @@ export class ErrorBoundary extends Component< render() { const { error } = this.state; - const { plugin, children, Fallback } = this.props; + const { plugin, children } = this.props; if (error) { return ( - ); diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx index 46b3956e0e..848ea64a2c 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.tsx @@ -25,16 +25,17 @@ import { AnalyticsContext, useAnalytics } from '@backstage/core-plugin-api'; import { ErrorBoundary } from './ErrorBoundary'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { routableExtensionRenderedEvent } from '../../../core-plugin-api/src/analytics/Tracker'; -import { AppNode, useComponentRef } from '../apis'; -import { coreComponentRefs } from './coreComponentRefs'; +import { AppNode } from '../apis'; import { coreExtensionData } from '../wiring'; +import { AppNodeProvider } from './AppNodeProvider'; +import { Progress } from './DefaultSwappableComponents'; type RouteTrackerProps = PropsWithChildren<{ - disableTracking?: boolean; + enabled?: boolean; }>; const RouteTracker = (props: RouteTrackerProps) => { - const { disableTracking, children } = props; + const { enabled, children } = props; const analytics = useAnalytics(); // This event, never exposed to end-users of the analytics API, @@ -42,9 +43,10 @@ const RouteTracker = (props: RouteTrackerProps) => { // navigation event when the route navigated to is a gathered // mountpoint. useEffect(() => { - if (disableTracking) return; - analytics.captureEvent(routableExtensionRenderedEvent, ''); - }, [analytics, disableTracking]); + if (enabled) { + analytics.captureEvent(routableExtensionRenderedEvent, ''); + } + }, [analytics, enabled]); return <>{children}; }; @@ -52,43 +54,35 @@ const RouteTracker = (props: RouteTrackerProps) => { /** @public */ export interface ExtensionBoundaryProps { node: AppNode; - /** - * This explicitly marks the extension as routable for the purpose of - * capturing analytics events. If not provided, the extension boundary will be - * marked as routable if it outputs a routePath. - */ - routable?: boolean; children: ReactNode; } /** @public */ export function ExtensionBoundary(props: ExtensionBoundaryProps) { - const { node, routable, children } = props; + const { node, children } = props; - const doesOutputRoutePath = Boolean( + const hasRoutePathOutput = Boolean( node.instance?.getData(coreExtensionData.routePath), ); - const plugin = node.spec.source; - const Progress = useComponentRef(coreComponentRefs.progress); - const fallback = useComponentRef(coreComponentRefs.errorBoundaryFallback); + const plugin = node.spec.plugin; // Skipping "routeRef" attribute in the new system, the extension "id" should provide more insight const attributes = { extensionId: node.spec.id, - pluginId: node.spec.source?.id ?? 'app', + pluginId: node.spec.plugin?.id ?? 'app', }; return ( - }> - - - - {children} - - - - + + }> + + + {children} + + + + ); } diff --git a/packages/frontend-plugin-api/src/components/coreComponentRefs.ts b/packages/frontend-plugin-api/src/components/coreComponentRefs.ts deleted file mode 100644 index 64412b8710..0000000000 --- a/packages/frontend-plugin-api/src/components/coreComponentRefs.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - CoreErrorBoundaryFallbackProps, - CoreNotFoundErrorPageProps, - CoreProgressProps, -} from '../types'; -import { createComponentRef } from './createComponentRef'; - -const coreProgressComponentRef = createComponentRef({ - id: 'core.components.progress', -}); - -const coreNotFoundErrorPageComponentRef = - createComponentRef({ - id: 'core.components.notFoundErrorPage', - }); - -const coreErrorBoundaryFallbackComponentRef = - createComponentRef({ - id: 'core.components.errorBoundaryFallback', - }); - -/** @public */ -export const coreComponentRefs = { - progress: coreProgressComponentRef, - notFoundErrorPage: coreNotFoundErrorPageComponentRef, - errorBoundaryFallback: coreErrorBoundaryFallbackComponentRef, -}; diff --git a/packages/frontend-plugin-api/src/components/createComponentRef.tsx b/packages/frontend-plugin-api/src/components/createComponentRef.tsx deleted file mode 100644 index 88181dd079..0000000000 --- a/packages/frontend-plugin-api/src/components/createComponentRef.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** @public */ -export type ComponentRef = { - id: string; - T: T; -}; - -/** @public */ -export function createComponentRef(options: { - id: string; -}): ComponentRef { - const { id } = options; - return { - id, - toString() { - return `ComponentRef{id=${id}}`; - }, - } as ComponentRef; -} diff --git a/packages/frontend-plugin-api/src/components/createSwappableComponent.test.tsx b/packages/frontend-plugin-api/src/components/createSwappableComponent.test.tsx new file mode 100644 index 0000000000..2a73a4da42 --- /dev/null +++ b/packages/frontend-plugin-api/src/components/createSwappableComponent.test.tsx @@ -0,0 +1,163 @@ +/* + * 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 { render, screen } from '@testing-library/react'; +import { createSwappableComponent } from './createSwappableComponent'; + +describe('createSwappableComponent', () => { + it('can be created and read', () => { + const { ref } = createSwappableComponent({ id: 'foo' }); + expect(ref.id).toBe('foo'); + expect(String(ref)).toBe('SwappableComponentRef{id=foo}'); + }); + + it('should allow defining a default component implementation', () => { + const Test = () =>
    test
    ; + + createSwappableComponent<{ foo: string }, { bar: string }>({ + id: 'foo', + loader: + () => + ({ foo }) => + , + }); + + createSwappableComponent<{ foo: string }, { bar: string }>({ + id: 'foo', + loader: + async () => + ({ foo }) => + , + }); + + createSwappableComponent<{ foo: string }, { bar: string }>({ + id: 'foo', + }); + + expect(Test).toBeDefined(); + }); + + it('should allow transformings props', () => { + createSwappableComponent<{ foo: string }, { bar: string }>({ + id: 'foo', + transformProps: props => ({ foo: props.bar }), + }); + + createSwappableComponent<{ foo: string }, { bar: string }>({ + id: 'foo', + // @ts-expect-error - this should be an error as foo is not a string + transformProps: props => ({ foo: 1 }), + }); + + expect(true).toBe(true); + }); + + describe('sync', () => { + it('should create a component from a ref for sync component', async () => { + const Component = createSwappableComponent({ + id: 'random', + loader: () => (props: { name: string }) => { + return
    {props.name}
    ; + }, + transformProps: (props: { id: string }) => ({ + name: props.id, + }), + }); + + render(); + + await expect(screen.findByTestId('test')).resolves.toHaveTextContent( + 'test', + ); + }); + + it('should render a fallback when theres no default implementation provided', async () => { + const Component = createSwappableComponent({ + id: 'random', + }); + + render(); + await expect(screen.findByTestId('random')).resolves.toBeInTheDocument(); + }); + + it('should map props from external to internal', async () => { + const Component = createSwappableComponent({ + id: 'random', + transformProps: (props: { name: string }) => ({ + uppercase: props.name.toUpperCase(), + }), + loader: () => props => { + // @ts-expect-error as uppercase is types as a string + const test: number = props.uppercase; + + return
    {props.uppercase}
    ; + }, + }); + + render(); + + await expect(screen.findByTestId('test')).resolves.toHaveTextContent( + 'TEST', + ); + }); + }); + + describe('async', () => { + it('should create a component from a ref for async component', async () => { + const Component = createSwappableComponent({ + id: 'random', + loader: async () => (props: { name: string }) => { + return
    {props.name}
    ; + }, + }); + + render(); + + await expect(screen.findByTestId('test')).resolves.toBeInTheDocument(); + }); + + it('should render a fallback when theres no default implementation provided', async () => { + const Component = createSwappableComponent({ + id: 'random', + }); + + render(); + + await expect(screen.findByTestId('random')).resolves.toBeInTheDocument(); + }); + + it('should map props from external to internal', async () => { + const Component = createSwappableComponent({ + id: 'random', + transformProps: (props: { name: string }) => ({ + uppercase: props.name.toUpperCase(), + }), + loader: async () => props => { + // @ts-expect-error as uppercase is types as a string + const test: number = props.uppercase; + + return
    {props.uppercase}
    ; + }, + }); + + render(); + + await expect(screen.findByTestId('test')).resolves.toHaveTextContent( + 'TEST', + ); + }); + }); +}); diff --git a/packages/frontend-plugin-api/src/components/createSwappableComponent.tsx b/packages/frontend-plugin-api/src/components/createSwappableComponent.tsx new file mode 100644 index 0000000000..716837f469 --- /dev/null +++ b/packages/frontend-plugin-api/src/components/createSwappableComponent.tsx @@ -0,0 +1,112 @@ +/* + * 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 { OpaqueSwappableComponentRef } from '@internal/frontend'; +import { swappableComponentsApiRef, useApi } from '../apis'; +import { lazy } from 'react'; + +/** @public */ +export type SwappableComponentRef< + TInnerComponentProps extends {} = {}, + TExternalComponentProps extends {} = TInnerComponentProps, +> = { + id: string; + TProps: TInnerComponentProps; + TExternalProps: TExternalComponentProps; + $$type: '@backstage/SwappableComponentRef'; +}; + +/** + * Options for creating an SwappableComponent. + * + * @public + */ +export type CreateSwappableComponentOptions< + TInnerComponentProps extends {}, + TExternalComponentProps extends {} = TInnerComponentProps, +> = { + id: string; + loader?: + | (() => (props: TInnerComponentProps) => JSX.Element | null) + | (() => Promise<(props: TInnerComponentProps) => JSX.Element | null>); + transformProps?: (props: TExternalComponentProps) => TInnerComponentProps; +}; + +const useComponentRefApi = () => { + try { + return useApi(swappableComponentsApiRef); + } catch (e) { + return undefined; + } +}; + +/** + * Creates a SwappableComponent that can be used to render the component, optionally overridden by the app. + * + * @public + */ +export function createSwappableComponent< + TInnerComponentProps extends {}, + TExternalComponentProps extends {} = TInnerComponentProps, +>( + options: CreateSwappableComponentOptions< + TInnerComponentProps, + TExternalComponentProps + >, +): { + (props: TExternalComponentProps): JSX.Element | null; + ref: SwappableComponentRef; +} { + const FallbackComponent = (p: JSX.IntrinsicAttributes) => ( +
    + ); + + const ref = OpaqueSwappableComponentRef.createInstance('v1', { + id: options.id, + TProps: null as unknown as TInnerComponentProps, + TExternalProps: null as unknown as TExternalComponentProps, + toString() { + return `SwappableComponentRef{id=${options.id}}`; + }, + defaultComponent: lazy(async () => { + const Component = (await options.loader?.()) ?? FallbackComponent; + return { default: Component }; + }) as (typeof OpaqueSwappableComponentRef.TInternal)['defaultComponent'], + transformProps: + options.transformProps as (typeof OpaqueSwappableComponentRef.TInternal)['transformProps'], + }); + + const ComponentRefImpl = (props: TExternalComponentProps) => { + const api = useComponentRefApi(); + + if (!api) { + const internalRef = OpaqueSwappableComponentRef.toInternal(ref); + const Component = internalRef.defaultComponent; + const innerProps = internalRef.transformProps?.(props) ?? props; + return ; + } + + const Component = api.getComponent(ref); + return ; + }; + + Object.assign(ComponentRefImpl, { ref }); + + return ComponentRefImpl as { + (props: TExternalComponentProps): JSX.Element | null; + ref: SwappableComponentRef; + }; +} diff --git a/packages/frontend-plugin-api/src/components/index.ts b/packages/frontend-plugin-api/src/components/index.ts index 5066144000..450224bdc4 100644 --- a/packages/frontend-plugin-api/src/components/index.ts +++ b/packages/frontend-plugin-api/src/components/index.ts @@ -18,5 +18,10 @@ export { ExtensionBoundary, type ExtensionBoundaryProps, } from './ExtensionBoundary'; -export { coreComponentRefs } from './coreComponentRefs'; -export { createComponentRef, type ComponentRef } from './createComponentRef'; +export { + createSwappableComponent, + type CreateSwappableComponentOptions, + type SwappableComponentRef, +} from './createSwappableComponent'; +export { useAppNode } from './AppNodeProvider'; +export * from './DefaultSwappableComponents'; diff --git a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx deleted file mode 100644 index f561a73dc6..0000000000 --- a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2023 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { lazy, ComponentType } from 'react'; -import { createExtension, createExtensionDataRef } from '../wiring'; -import { ComponentRef } from '../components'; - -/** @public */ -export function createComponentExtension(options: { - ref: ComponentRef; - name?: string; - disabled?: boolean; - loader: - | { - lazy: () => Promise>; - } - | { - sync: () => ComponentType; - }; -}) { - return createExtension({ - kind: 'component', - name: options.name ?? options.ref.id, - attachTo: { id: 'api:app/components', input: 'components' }, - disabled: options.disabled, - output: [createComponentExtension.componentDataRef], - factory() { - if ('sync' in options.loader) { - return [ - createComponentExtension.componentDataRef({ - ref: options.ref, - impl: options.loader.sync() as ComponentType, - }), - ]; - } - const lazyLoader = options.loader.lazy; - const ExtensionComponent = lazy(() => - lazyLoader().then(Component => ({ - default: Component, - })), - ) as unknown as ComponentType; - - return [ - createComponentExtension.componentDataRef({ - ref: options.ref, - impl: ExtensionComponent, - }), - ]; - }, - }); -} - -/** @public */ -export namespace createComponentExtension { - export const componentDataRef = createExtensionDataRef<{ - ref: ComponentRef; - impl: ComponentType; - }>().with({ id: 'core.component.component' }); -} diff --git a/packages/frontend-plugin-api/src/index.ts b/packages/frontend-plugin-api/src/index.ts index 957ca50bba..9117dc0ef9 100644 --- a/packages/frontend-plugin-api/src/index.ts +++ b/packages/frontend-plugin-api/src/index.ts @@ -24,7 +24,6 @@ export * from './analytics'; export * from './apis'; export * from './blueprints'; export * from './components'; -export * from './extensions'; export * from './icons'; export * from './routing'; export * from './schema'; @@ -33,7 +32,7 @@ export * from './translation'; export * from './wiring'; export type { - CoreProgressProps, - CoreNotFoundErrorPageProps, - CoreErrorBoundaryFallbackProps, + ProgressProps, + NotFoundErrorPageProps, + ErrorDisplayProps, } from './types'; diff --git a/packages/frontend-plugin-api/src/routing/ExternalRouteRef.ts b/packages/frontend-plugin-api/src/routing/ExternalRouteRef.ts index 6ce36707c0..3de276f85c 100644 --- a/packages/frontend-plugin-api/src/routing/ExternalRouteRef.ts +++ b/packages/frontend-plugin-api/src/routing/ExternalRouteRef.ts @@ -71,13 +71,17 @@ class ExternalRouteRefImpl implements InternalExternalRouteRef { readonly $$type = '@backstage/ExternalRouteRef' as any; + readonly params: string[]; + readonly defaultTarget: string | undefined; constructor( - readonly params: string[] = [], - readonly defaultTarget: string | undefined, + params: string[] = [], + defaultTarget: string | undefined, creationSite: string, ) { super(params, creationSite); + this.params = params; + this.defaultTarget = defaultTarget; } getDefaultTarget() { diff --git a/packages/frontend-plugin-api/src/routing/RouteRef.ts b/packages/frontend-plugin-api/src/routing/RouteRef.ts index 1678e14cd4..46076e6258 100644 --- a/packages/frontend-plugin-api/src/routing/RouteRef.ts +++ b/packages/frontend-plugin-api/src/routing/RouteRef.ts @@ -41,6 +41,8 @@ export interface InternalRouteRef< getParams(): string[]; getDescription(): string; + alias: string | undefined; + setId(id: string): void; } @@ -68,18 +70,28 @@ export class RouteRefImpl implements InternalRouteRef { declare readonly T: never; #id?: string; - #params: string[]; - #creationSite: string; + readonly #params: string[]; + readonly #creationSite: string; + readonly #alias?: string; - constructor(readonly params: string[] = [], creationSite: string) { + constructor( + readonly params: string[] = [], + creationSite: string, + alias?: string, + ) { this.#params = params; this.#creationSite = creationSite; + this.#alias = alias; } getParams(): string[] { return this.#params; } + get alias(): string | undefined { + return this.#alias; + } + getDescription(): string { if (this.#id) { return this.#id; @@ -121,7 +133,11 @@ export function createRouteRef< TParamKeys extends string = string, >(config?: { /** A list of parameter names that the path that this route ref is bound to must contain */ - readonly params: string extends TParamKeys ? (keyof TParams)[] : TParamKeys[]; + readonly params?: string extends TParamKeys + ? (keyof TParams)[] + : TParamKeys[]; + + aliasFor?: string; }): RouteRef< keyof TParams extends never ? undefined @@ -132,5 +148,6 @@ export function createRouteRef< return new RouteRefImpl( config?.params as string[] | undefined, describeParentCallSite(), + config?.aliasFor, ) as RouteRef; } diff --git a/packages/frontend-plugin-api/src/types.ts b/packages/frontend-plugin-api/src/types.ts index 9088a9d772..a8ddf43cad 100644 --- a/packages/frontend-plugin-api/src/types.ts +++ b/packages/frontend-plugin-api/src/types.ts @@ -18,15 +18,15 @@ import { ReactNode } from 'react'; import { FrontendPlugin } from './wiring'; /** @public */ -export type CoreProgressProps = {}; +export type ProgressProps = {}; /** @public */ -export type CoreNotFoundErrorPageProps = { +export type NotFoundErrorPageProps = { children?: ReactNode; }; /** @public */ -export type CoreErrorBoundaryFallbackProps = { +export type ErrorDisplayProps = { plugin?: FrontendPlugin; error: Error; resetError: () => void; diff --git a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts index cb48cb8df3..b778539101 100644 --- a/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts +++ b/packages/frontend-plugin-api/src/wiring/coreExtensionData.ts @@ -15,11 +15,12 @@ */ import { JSX } from 'react'; -import { RouteRef } from '../routing'; +import { RouteRef } from '../routing/RouteRef'; import { createExtensionDataRef } from './createExtensionDataRef'; /** @public */ export const coreExtensionData = { + title: createExtensionDataRef().with({ id: 'core.title' }), reactElement: createExtensionDataRef().with({ id: 'core.reactElement', }), diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index 00dd981e26..59a81f1b59 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -1078,7 +1078,7 @@ describe('createExtension', () => { .add(multi2Ext) .get(outputRef), ).toThrowErrorMatchingInlineSnapshot( - `"Failed to instantiate extension 'subject', override data provided for input 'multi' must match the length of the original inputs"`, + `"Failed to resolve the extension tree: Failed to instantiate extension 'subject', override data provided for input 'multi' must match the length of the original inputs"`, ); // Mix forward and data override @@ -1101,7 +1101,7 @@ describe('createExtension', () => { .add(multi2Ext) .get(outputRef), ).toThrowErrorMatchingInlineSnapshot( - `"Failed to instantiate extension 'subject', override data for input 'multi' may not mix forwarded inputs with data overrides"`, + `"Failed to resolve the extension tree: Failed to instantiate extension 'subject', override data for input 'multi' may not mix forwarded inputs with data overrides"`, ); // Required input not provided @@ -1124,7 +1124,7 @@ describe('createExtension', () => { .add(multi2Ext) .get(outputRef), ).toThrowErrorMatchingInlineSnapshot( - `"Failed to instantiate extension 'subject', missing required extension data value(s) 'test1'"`, + `"Failed to resolve the extension tree: Failed to instantiate extension 'subject', missing required extension data value(s) 'test1'"`, ); // Wrong value provided @@ -1153,7 +1153,7 @@ describe('createExtension', () => { .add(multi2Ext) .get(outputRef), ).toThrowErrorMatchingInlineSnapshot( - `"Failed to instantiate extension 'subject', extension data 'test2' was provided but not declared"`, + `"Failed to resolve the extension tree: Failed to instantiate extension 'subject', extension data 'test2' was provided but not declared"`, ); }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 04d7f15240..8ed4b8b259 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -17,19 +17,22 @@ import { ApiHolder, AppNode } from '../apis'; import { Expand } from '@backstage/types'; import { - ResolveInputValueOverrides, + ResolvedInputValueOverrides, resolveInputOverrides, } from './resolveInputOverrides'; import { createExtensionDataContainer } from '@internal/frontend'; -import { - AnyExtensionDataRef, - ExtensionDataValue, -} from './createExtensionDataRef'; +import { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef'; import { ExtensionInput } from './createExtensionInput'; import { z } from 'zod'; import { createSchemaFromZod } from '../schema/createSchemaFromZod'; import { OpaqueExtensionDefinition } from '@internal/frontend'; import { ExtensionDataContainer } from './types'; +import { + ExtensionBlueprint, + ExtensionBlueprintDefineParams, +} from './createExtensionBlueprint'; +import { FrontendPlugin } from './createFrontendPlugin'; +import { FrontendModule } from './createFrontendModule'; /** * This symbol is used to pass parameter overrides from the extension override to the blueprint factory @@ -41,13 +44,12 @@ export const ctxParamsSymbol = Symbol('params'); * Convert a single extension input into a matching resolved input. * @public */ -export type ResolvedExtensionInput< - TExtensionInput extends ExtensionInput, -> = TExtensionInput['extensionData'] extends Array - ? { - node: AppNode; - } & ExtensionDataContainer - : never; +export type ResolvedExtensionInput = + TExtensionInput['extensionData'] extends Array + ? { + node: AppNode; + } & ExtensionDataContainer + : never; /** * Converts an extension input map into a matching collection of resolved inputs. @@ -55,7 +57,7 @@ export type ResolvedExtensionInput< */ export type ResolvedExtensionInputs< TInputs extends { - [name in string]: ExtensionInput; + [name in string]: ExtensionInput; }, > = { [InputName in keyof TInputs]: false extends TInputs[InputName]['config']['singleton'] @@ -90,7 +92,7 @@ type JoinStringUnion< /** @ignore */ export type VerifyExtensionFactoryOutput< - UDeclaredOutput extends AnyExtensionDataRef, + UDeclaredOutput extends ExtensionDataRef, UFactoryOutput extends ExtensionDataValue, > = ( UDeclaredOutput extends any @@ -119,13 +121,8 @@ export type ExtensionAttachToSpec = export type CreateExtensionOptions< TKind extends string | undefined, TName extends string | undefined, - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + UOutput extends ExtensionDataRef, + TInputs extends { [inputName in string]: ExtensionInput }, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, > = { @@ -154,16 +151,25 @@ export type ExtensionDefinitionParameters = { name?: string; configInput?: { [K in string]: any }; config?: { [K in string]: any }; - output?: AnyExtensionDataRef; - inputs?: { - [KName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }; - params?: object; + output?: ExtensionDataRef; + inputs?: { [KName in string]: ExtensionInput }; + params?: object | ExtensionBlueprintDefineParams; }; +/** + * Same as the one in `createExtensionBlueprint`, but with `ParamsFactory` inlined. + * It can't be exported because it breaks API reports. + * @ignore + */ +type AnyParamsInput = + TParams extends ExtensionBlueprintDefineParams + ? IParams | ((define: TParams) => ReturnType) + : + | TParams + | (( + define: ExtensionBlueprintDefineParams, + ) => ReturnType>); + /** @public */ export type ExtensionDefinition< T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters, @@ -176,13 +182,9 @@ export type ExtensionDefinition< [key in string]: (zImpl: typeof z) => z.ZodType; }, UFactoryOutput extends ExtensionDataValue, - UNewOutput extends AnyExtensionDataRef, - TExtraInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + UNewOutput extends ExtensionDataRef, + TExtraInputs extends { [inputName in string]: ExtensionInput }, + TParamsInput extends AnyParamsInput>, >( args: Expand< { @@ -200,14 +202,24 @@ export type ExtensionDefinition< }; }; factory?( - originalFactory: ( + originalFactory: < + TFactoryParamsReturn extends AnyParamsInput< + NonNullable + >, + >( context?: Expand< { config?: T['config']; - inputs?: ResolveInputValueOverrides>; + inputs?: ResolvedInputValueOverrides>; } & ([T['params']] extends [never] ? {} - : { params?: Partial }) + : { + params?: TFactoryParamsReturn extends ExtensionBlueprintDefineParams + ? TFactoryParamsReturn + : T['params'] extends ExtensionBlueprintDefineParams + ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams())`' + : Partial; + }) >, ) => ExtensionDataContainer>, context: { @@ -223,10 +235,16 @@ export type ExtensionDefinition< ): Iterable; } & ([T['params']] extends [never] ? {} - : { params?: Partial }) + : { + params?: TParamsInput extends ExtensionBlueprintDefineParams + ? TParamsInput + : T['params'] extends ExtensionBlueprintDefineParams + ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams())`' + : Partial; + }) > & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput + ExtensionDataRef extends UNewOutput ? NonNullable : UNewOutput, UFactoryOutput @@ -234,7 +252,7 @@ export type ExtensionDefinition< ): ExtensionDefinition<{ kind: T['kind']; name: T['name']; - output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; inputs: T['inputs'] & TExtraInputs; config: T['config'] & { [key in keyof TExtensionConfigSchema]: z.infer< @@ -252,15 +270,44 @@ export type ExtensionDefinition< }>; }; -/** @public */ +/** + * Creates a new extension definition for installation in a Backstage app. + * + * @remarks + * + * This is a low-level function for creation of extensions with arbitrary inputs + * and outputs and is typically only intended to be used for advanced overrides + * or framework-level extensions. For most extension creation needs, it is + * recommended to use existing {@link ExtensionBlueprint}s instead. You can find + * blueprints both in the `@backstage/frontend-plugin-api` package as well as + * other plugin libraries. There is also a list of + * {@link https://backstage.io/docs/frontend-system/building-plugins/common-extension-blueprints | commonly used blueprints} + * in the frontend system documentation. + * + * Extension definitions that are created with this function can be installed in + * a Backstage app via a {@link FrontendPlugin} or {@link FrontendModule}. + * + * For more details on how extensions work, see the + * {@link https://backstage.io/docs/frontend-system/architecture/extensions | documentation for extensions}. + * + * @example + * + * ```ts + * const myExtension = createExtension({ + * name: 'example', + * attachTo: { id: 'app', input: 'root' }, + * output: [coreExtensionData.reactElement], + * factory() { + * return [coreExtensionData.reactElement(

    Hello, world!

    )]; + * }, + * }); + * ``` + * + * @public + */ export function createExtension< - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + UOutput extends ExtensionDataRef, + TInputs extends { [inputName in string]: ExtensionInput }, TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, const TKind extends string | undefined = undefined, @@ -287,7 +334,14 @@ export function createExtension< [key in keyof TConfigSchema]: ReturnType; }> >; - output: UOutput; + // This inference and remapping back to ExtensionDataRef eliminates any occurrences ConfigurationExtensionDataRef + output: UOutput extends ExtensionDataRef< + infer IData, + infer IId, + infer IConfig + > + ? ExtensionDataRef + : never; inputs: TInputs; params: never; kind: string | undefined extends TKind ? undefined : TKind; @@ -378,7 +432,7 @@ export function createExtension< disabled: overrideOptions.disabled ?? options.disabled, inputs: { ...overrideOptions.inputs, ...options.inputs }, output: (overrideOptions.output ?? - options.output) as AnyExtensionDataRef[], + options.output) as ExtensionDataRef[], config: options.config || overrideOptions.config ? { @@ -412,6 +466,7 @@ export function createExtension< ) as any, [ctxParamsSymbol as any]: innerContext?.params, }) as Iterable, + 'original extension factory', options.output, ); }, @@ -423,6 +478,15 @@ export function createExtension< }, ); + if ( + typeof parentResult !== 'object' || + !parentResult?.[Symbol.iterator] + ) { + throw new Error( + 'extension factory override did not provide an iterable object', + ); + } + const deduplicatedResult = new Map< string, ExtensionDataValue diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index 5a44dc4b55..e4cc876ff0 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -15,7 +15,11 @@ */ import { coreExtensionData } from './coreExtensionData'; -import { createExtensionBlueprint } from './createExtensionBlueprint'; +import { + createExtensionBlueprint, + createExtensionBlueprintParams, + ExtensionBlueprintParams, +} from './createExtensionBlueprint'; import { createExtensionTester, renderInTestApp, @@ -387,7 +391,7 @@ describe('createExtensionBlueprint', () => { }); const mockInput = (node: string, ...data: ExtensionDataValue[]) => - Object.assign(createExtensionDataContainer(data), { + Object.assign(createExtensionDataContainer(data, 'mock'), { node, }); const mockParentInputs = { @@ -876,6 +880,21 @@ describe('createExtensionBlueprint', () => { test2: 'orig-2', }); + const extensionDef = blueprint.make({ + // Using defineParams is optional in this case + params: defineParams => + defineParams({ + test1: 'orig-1', + test2: 'orig-2', + }), + }); + + expect(getOutputs(extensionDef)).toEqual({ + test1: 'orig-1', + test2: 'orig-2', + }); + + // Plain override expect( getOutputs( extension.override({ @@ -896,6 +915,8 @@ describe('createExtensionBlueprint', () => { extension.override({ params: { test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', }, }), ), @@ -904,6 +925,58 @@ describe('createExtensionBlueprint', () => { test2: 'override-2', }); + // Partial override with original defineParams + expect( + getOutputs( + extensionDef.override({ + params: { + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }, + }), + ), + ).toEqual({ + test1: 'orig-1', + test2: 'override-2', + }); + + // Override with defineParams + expect( + getOutputs( + extension.override({ + params: defineParams => + defineParams({ + test1: 'override-1', + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }), + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + + // Override with defineParams with original defineParams + expect( + getOutputs( + extensionDef.override({ + params: defineParams => + defineParams({ + test1: 'override-1', + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }), + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + expect( getOutputs( extension.override({ @@ -930,6 +1003,8 @@ describe('createExtensionBlueprint', () => { return origFactory({ params: { test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', }, }); }, @@ -940,6 +1015,70 @@ describe('createExtensionBlueprint', () => { test2: 'override-2', }); + // Partial override via factory with original defineParams + expect( + getOutputs( + extensionDef.override({ + factory(origFactory) { + return origFactory({ + params: { + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }, + }); + }, + }), + ), + ).toEqual({ + test1: 'orig-1', + test2: 'override-2', + }); + + // Override via factory with defineParams + expect( + getOutputs( + extension.override({ + factory(origFactory) { + return origFactory({ + params: defineParams => + defineParams({ + test1: 'override-1', + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }), + }); + }, + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + + // Override via factory with defineParams with original defineParams + expect( + getOutputs( + extensionDef.override({ + factory(origFactory) { + return origFactory({ + params: defineParams => + defineParams({ + test1: 'override-1', + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }), + }); + }, + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + expect(() => getOutputs( extension.override({ @@ -991,6 +1130,21 @@ describe('createExtensionBlueprint', () => { test2: 'orig-2', }); + const extensionDef = blueprint.make({ + // Using defineParams is optional in this case + params: defineParams => + defineParams({ + test1: 'orig-1', + test2: 'orig-2', + }), + }); + + expect(getOutputs(extensionDef)).toEqual({ + test1: 'orig-1', + test2: 'orig-2', + }); + + // Plain override expect( getOutputs( extension.override({ @@ -1011,6 +1165,8 @@ describe('createExtensionBlueprint', () => { extension.override({ params: { test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', }, }), ), @@ -1019,6 +1175,59 @@ describe('createExtensionBlueprint', () => { test2: 'override-2', }); + // Partial override with original defineParams + expect( + getOutputs( + extensionDef.override({ + params: { + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }, + }), + ), + ).toEqual({ + test1: 'orig-1', + test2: 'override-2', + }); + + // Override with defineParams + expect( + getOutputs( + extension.override({ + params: defineParams => + defineParams({ + test1: 'override-1', + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }), + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + + // Override with defineParams with original defineParams + expect( + getOutputs( + extensionDef.override({ + params: defineParams => + defineParams({ + test1: 'override-1', + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }), + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + + // Override via factory expect( getOutputs( extension.override({ @@ -1045,6 +1254,8 @@ describe('createExtensionBlueprint', () => { return origFactory({ params: { test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', }, }); }, @@ -1055,6 +1266,70 @@ describe('createExtensionBlueprint', () => { test2: 'override-2', }); + // Partial override via factory with original defineParams + expect( + getOutputs( + extensionDef.override({ + factory(origFactory) { + return origFactory({ + params: { + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }, + }); + }, + }), + ), + ).toEqual({ + test1: 'orig-1', + test2: 'override-2', + }); + + // Override via factory with defineParams + expect( + getOutputs( + extension.override({ + factory(origFactory) { + return origFactory({ + params: defineParams => + defineParams({ + test1: 'override-1', + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }), + }); + }, + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + + // Override via factory with defineParams with original defineParams + expect( + getOutputs( + extensionDef.override({ + factory(origFactory) { + return origFactory({ + params: defineParams => + defineParams({ + test1: 'override-1', + test2: 'override-2', + // @ts-expect-error + test3: 'nonexistent', + }), + }); + }, + }), + ), + ).toEqual({ + test1: 'override-1', + test2: 'override-2', + }); + expect(() => getOutputs( extension.override({ @@ -1069,4 +1344,272 @@ describe('createExtensionBlueprint', () => { ), ).toThrow('Refused to override params and factory at the same time'); }); + + describe('with advanced parameter types', () => { + const testDataRef = createExtensionDataRef().with({ id: 'test' }); + + const TestExtensionBlueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: [testDataRef], + defineParams(params: { + a: A; + b: B; + }) { + return createExtensionBlueprintParams(params); + }, + factory(params) { + return [testDataRef(`${params.a} ${params.b}`)]; + }, + }); + + it('should allow creation of extension blueprints', () => { + TestExtensionBlueprint.make({ + // @ts-expect-error not using define func + params: { + a: 'x', + b: 'y', + }, + }); + + TestExtensionBlueprint.make({ + params: defineParams => + defineParams({ + a: 'x', + // @ts-expect-error b doesn't match a + b: 'y', + }), + }); + + TestExtensionBlueprint.make({ + params: defineParams => + defineParams({ + a: 'x', + b: 'x', + // @ts-expect-error extra param + c: 'y', + }), + }); + + const extension = TestExtensionBlueprint.make({ + params: defineParams => + defineParams({ + a: 'x', + b: 'x', + }), + }); + + expect(extension).toEqual({ + $$type: '@backstage/ExtensionDefinition', + T: undefined, + attachTo: { + id: 'test', + input: 'default', + }, + configSchema: undefined, + disabled: false, + inputs: {}, + kind: 'test-extension', + name: undefined, + namespace: undefined, + output: [testDataRef], + factory: expect.any(Function), + toString: expect.any(Function), + override: expect.any(Function), + version: 'v2', + }); + + expect(createExtensionTester(extension).get(testDataRef)).toBe('x x'); + + extension.override({ + // @ts-expect-error not using define func + params: { + a: 'z', + b: 'w', + }, + }); + + extension.override({ + params: defineParams => + defineParams({ + a: 'z', + // @ts-expect-error b doesn't match a + b: 'w', + }), + }); + + extension.override({ + params: defineParams => + defineParams({ + a: 'z', + b: 'z', + // @ts-expect-error extra param + c: 'w', + }), + }); + + const override = extension.override({ + params: defineParams => + defineParams({ + a: 'z', + b: 'z', + }), + }); + + expect(createExtensionTester(override).get(testDataRef)).toBe('z z'); + }); + + it('should allow overriding of the default factory', () => { + TestExtensionBlueprint.makeWithOverrides({ + factory(originalFactory) { + // @ts-expect-error not using define func + return originalFactory({ + a: 'x', + b: 'y', + }); + }, + }); + + TestExtensionBlueprint.makeWithOverrides({ + factory(originalFactory) { + return originalFactory(defineParams => + defineParams({ + a: 'x', + // @ts-expect-error b doesn't match a + b: 'y', + }), + ); + }, + }); + + const extension = TestExtensionBlueprint.makeWithOverrides({ + factory(originalFactory) { + return originalFactory(defineParams => + defineParams({ + a: 'x', + b: 'x', + }), + ); + }, + }); + + expect(extension).toEqual({ + $$type: '@backstage/ExtensionDefinition', + T: undefined, + attachTo: { + id: 'test', + input: 'default', + }, + configSchema: undefined, + disabled: false, + inputs: {}, + kind: 'test-extension', + name: undefined, + namespace: undefined, + output: [testDataRef], + factory: expect.any(Function), + toString: expect.any(Function), + override: expect.any(Function), + version: 'v2', + }); + + expect(createExtensionTester(extension).get(testDataRef)).toBe('x x'); + + extension.override({ + // @ts-expect-error not using define func + params: { + a: 'z', + b: 'w', + }, + }); + + extension.override({ + params: defineParams => + defineParams({ + a: 'z', + // @ts-expect-error b doesn't match a + b: 'w', + }), + }); + + const override = extension.override({ + params: defineParams => + defineParams({ + a: 'z', + b: 'z', + }), + }); + + expect(createExtensionTester(override).get(testDataRef)).toBe('z z'); + }); + + it('should allow the params definer to transform the params', () => { + const TestTransformExtensionBlueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: [testDataRef], + defineParams(params: { a: number; b: number }) { + return createExtensionBlueprintParams({ + x: params.a + 1, + y: params.b + 1, + }); + }, + factory(params) { + return [testDataRef(`${params.x} ${params.y}`)]; + }, + }); + + const extension = TestTransformExtensionBlueprint.make({ + params: defineParams => + defineParams({ + a: 0, + b: 10, + }), + }); + + expect(createExtensionTester(extension).get(testDataRef)).toBe(`1 11`); + + expect( + createExtensionTester( + extension.override({ + params: defineParams => + defineParams({ + a: 20, + b: 30, + }), + }), + ).get(testDataRef), + ).toBe(`21 31`); + }); + + it('should support overloads', () => { + const TestTransformExtensionBlueprint = createExtensionBlueprint({ + kind: 'test-extension', + attachTo: { id: 'test', input: 'default' }, + output: [testDataRef], + defineParams: (params => createExtensionBlueprintParams(params)) as { + (params: { x: 1 }): ExtensionBlueprintParams<{ x: number }>; + (params: { x: 2 }): ExtensionBlueprintParams<{ x: number }>; + }, + factory(params) { + return [testDataRef(`x: ${params.x}`)]; + }, + }); + + const extension = TestTransformExtensionBlueprint.make({ + params: defineParams => defineParams({ x: 1 }), + }); + + expect(createExtensionTester(extension).get(testDataRef)).toBe(`x: 1`); + + TestTransformExtensionBlueprint.make({ + params: defineParams => defineParams({ x: 2 }), + }); + + TestTransformExtensionBlueprint.make({ + // @ts-expect-error doesn't match any overload + params: defineParams => defineParams({ x: 3 }), + }); + }); + }); }); diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 57848a7980..f8dd55ca80 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -16,6 +16,7 @@ import { ApiHolder, AppNode } from '../apis'; import { Expand } from '@backstage/types'; +import { OpaqueType } from '@internal/opaque'; import { ExtensionAttachToSpec, ExtensionDefinition, @@ -26,46 +27,140 @@ import { } from './createExtension'; import { z } from 'zod'; import { ExtensionInput } from './createExtensionInput'; -import { - AnyExtensionDataRef, - ExtensionDataValue, -} from './createExtensionDataRef'; +import { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef'; import { createExtensionDataContainer } from '@internal/frontend'; import { - ResolveInputValueOverrides, + ResolvedInputValueOverrides, resolveInputOverrides, } from './resolveInputOverrides'; import { ExtensionDataContainer } from './types'; +import { PageBlueprint } from '../blueprints/PageBlueprint'; + +/** + * A function used to define a parameter mapping function in order to facilitate + * advanced parameter typing for extension blueprints. + * + * @remarks + * + * This function is primarily intended to enable the use of inferred type + * parameters for blueprint params, but it can also be used to transoform the + * params before they are handed ot the blueprint. + * + * The function must return an object created with + * {@link createExtensionBlueprintParams}. + * + * @public + */ +export type ExtensionBlueprintDefineParams< + TParams extends object = object, + TInput = any, +> = (params: TInput) => ExtensionBlueprintParams; + +/** + * An opaque type that represents a set of parameters to be passed to a blueprint. + * + * @remarks + * + * Created with {@link createExtensionBlueprintParams}. + * + * @public + */ +export type ExtensionBlueprintParams = { + $$type: '@backstage/BlueprintParams'; + T: T; +}; + +const OpaqueBlueprintParams = OpaqueType.create<{ + public: ExtensionBlueprintParams; + versions: { + version: 'v1'; + params: object; + }; +}>({ + type: '@backstage/BlueprintParams', + versions: ['v1'], +}); + +/** + * Wraps a plain blueprint parameter object in an opaque {@link ExtensionBlueprintParams} object. + * + * This is used in the definition of the `defineParams` option of {@link ExtensionBlueprint}. + * + * @public + * @param params - The plain blueprint parameter object to wrap. + * @returns The wrapped blueprint parameter object. + */ +export function createExtensionBlueprintParams( + params: T, +): ExtensionBlueprintParams { + return OpaqueBlueprintParams.createInstance('v1', { T: null as any, params }); +} /** * @public */ export type CreateExtensionBlueprintOptions< TKind extends string, - TName extends string | undefined, - TParams, - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + TParams extends object | ExtensionBlueprintDefineParams, + UOutput extends ExtensionDataRef, + TInputs extends { [inputName in string]: ExtensionInput }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, - TDataRefs extends { [name in string]: AnyExtensionDataRef }, + TDataRefs extends { [name in string]: ExtensionDataRef }, > = { kind: TKind; attachTo: ExtensionAttachToSpec; disabled?: boolean; inputs?: TInputs; output: Array; - name?: TName; config?: { schema: TConfigSchema; }; + /** + * This option is used to further refine the blueprint params. When this + * option is used, the blueprint will require params to be passed in callback + * form. This function can both transform the params before they are handed to + * the blueprint factory, but importantly it also allows you to define + * inferred type parameters for your blueprint params. + * + * @example + * Blueprint definition with inferred type parameters: + * ```ts + * const ExampleBlueprint = createExtensionBlueprint({ + * kind: 'example', + * attachTo: { id: 'example', input: 'example' }, + * output: [exampleComponentDataRef, exampleFetcherDataRef], + * defineParams(params: { + * component(props: ExampleProps): JSX.Element | null + * fetcher(options: FetchOptions): Promise> + * }) { + * return createExtensionBlueprintParams(params); + * }, + * *factory(params) { + * yield exampleComponentDataRef(params.component) + * yield exampleFetcherDataRef(params.fetcher) + * }, + * }); + * ``` + * + * @example + * Usage of the above example blueprint: + * ```ts + * const example = ExampleBlueprint.make({ + * params: defineParams => defineParams({ + * component: ..., + * fetcher: ..., + * }), + * }); + * ``` + */ + defineParams?: TParams extends ExtensionBlueprintDefineParams + ? TParams + : 'The defineParams option must be a function if provided, see the docs for details'; factory( - params: TParams, + params: TParams extends ExtensionBlueprintDefineParams + ? ReturnType['T'] + : TParams, context: { node: AppNode; apis: ApiHolder; @@ -82,20 +177,30 @@ export type CreateExtensionBlueprintOptions< /** @public */ export type ExtensionBlueprintParameters = { kind: string; - name?: string; - params?: object; + params?: object | ExtensionBlueprintDefineParams; configInput?: { [K in string]: any }; config?: { [K in string]: any }; - output?: AnyExtensionDataRef; - inputs?: { - [KName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }; - dataRefs?: { [name in string]: AnyExtensionDataRef }; + output?: ExtensionDataRef; + inputs?: { [KName in string]: ExtensionInput }; + dataRefs?: { [name in string]: ExtensionDataRef }; }; +/** @ignore */ +type ParamsFactory = ( + defineParams: TDefiner, +) => ReturnType; + +/** + * Represents any form of params input that can be passed to a blueprint. + * This also includes the invalid form of passing a plain params object to a blueprint that uses a definition callback. + * + * @ignore + */ +type AnyParamsInput = + TParams extends ExtensionBlueprintDefineParams + ? IParams | ParamsFactory + : TParams | ParamsFactory>; + /** * @public */ @@ -104,14 +209,21 @@ export interface ExtensionBlueprint< > { dataRefs: T['dataRefs']; - make(args: { - name?: TNewName; + make< + TName extends string | undefined, + TParamsInput extends AnyParamsInput>, + >(args: { + name?: TName; attachTo?: ExtensionAttachToSpec; disabled?: boolean; - params: T['params']; + params: TParamsInput extends ExtensionBlueprintDefineParams + ? TParamsInput + : T['params'] extends ExtensionBlueprintDefineParams + ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `.make({ params: defineParams => defineParams() })`' + : T['params']; }): ExtensionDefinition<{ kind: T['kind']; - name: string | undefined extends TNewName ? T['name'] : TNewName; + name: string | undefined extends TName ? undefined : TName; config: T['config']; configInput: T['configInput']; output: T['output']; @@ -126,20 +238,15 @@ export interface ExtensionBlueprint< * optionally call the original factory with the same params. */ makeWithOverrides< - TNewName extends string | undefined, + TName extends string | undefined, TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; }, UFactoryOutput extends ExtensionDataValue, - UNewOutput extends AnyExtensionDataRef, - TExtraInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + UNewOutput extends ExtensionDataRef, + TExtraInputs extends { [inputName in string]: ExtensionInput }, >(args: { - name?: TNewName; + name?: TName; attachTo?: ExtensionAttachToSpec; disabled?: boolean; inputs?: TExtraInputs & { @@ -154,11 +261,17 @@ export interface ExtensionBlueprint< }; }; factory( - originalFactory: ( - params: T['params'], + originalFactory: < + TParamsInput extends AnyParamsInput>, + >( + params: TParamsInput extends ExtensionBlueprintDefineParams + ? TParamsInput + : T['params'] extends ExtensionBlueprintDefineParams + ? 'Error: This blueprint uses advanced parameter types and requires you to pass parameters as using the following callback syntax: `originalFactory(defineParams => defineParams())`' + : T['params'], context?: { config?: T['config']; - inputs?: ResolveInputValueOverrides>; + inputs?: ResolvedInputValueOverrides>; }, ) => ExtensionDataContainer>, context: { @@ -173,7 +286,7 @@ export interface ExtensionBlueprint< }, ): Iterable & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput + ExtensionDataRef extends UNewOutput ? NonNullable : UNewOutput, UFactoryOutput @@ -197,38 +310,144 @@ export interface ExtensionBlueprint< }> >) & T['configInput']; - output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + output: ExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; inputs: T['inputs'] & TExtraInputs; kind: T['kind']; - name: string | undefined extends TNewName ? T['name'] : TNewName; + name: string | undefined extends TName ? undefined : TName; params: T['params']; }>; } +function unwrapParamsFactory( + // Allow `Function` because `typeof === 'function'` allows it, but in practice this should always be a param factory + params: ParamsFactory | Function, + defineParams: ExtensionBlueprintDefineParams, + kind: string, +): TParams { + const paramDefinition = ( + params as ParamsFactory + )(defineParams); + try { + return OpaqueBlueprintParams.toInternal(paramDefinition).params as TParams; + } catch (e) { + throw new TypeError( + `Invalid invocation of blueprint with kind '${kind}', the parameter definition callback function did not return a valid parameter definition object; Caused by: ${e.message}`, + ); + } +} + +function unwrapParams( + params: object | ParamsFactory | string, + ctx: { node: AppNode; [ctxParamsSymbol]?: any }, + defineParams: ExtensionBlueprintDefineParams | undefined, + kind: string, +): TParams { + const overrideParams = ctx[ctxParamsSymbol] as + | object + | ParamsFactory + | undefined; + + if (defineParams) { + if (overrideParams) { + if (typeof overrideParams !== 'function') { + throw new TypeError( + `Invalid extension override of blueprint with kind '${kind}', the override params were passed as a plain object, but this blueprint requires them to be passed in callback form`, + ); + } + return unwrapParamsFactory(overrideParams, defineParams, kind); + } + + if (typeof params !== 'function') { + throw new TypeError( + `Invalid invocation of blueprint with kind '${kind}', the parameters where passed as a plain object, but this blueprint requires them to be passed in callback form`, + ); + } + return unwrapParamsFactory(params, defineParams, kind); + } + + const base = + typeof params === 'function' + ? unwrapParamsFactory( + params, + createExtensionBlueprintParams, + kind, + ) + : (params as TParams); + const overrides = + typeof overrideParams === 'function' + ? unwrapParamsFactory( + overrideParams, + createExtensionBlueprintParams, + kind, + ) + : (overrideParams as Partial); + + return { + ...base, + ...overrides, + }; +} + /** - * A simpler replacement for wrapping up `createExtension` inside a kind or type. This allows for a cleaner API for creating - * types and instances of those types. + * Creates a new extension blueprint that encapsulates the creation of + * extensions of particular kinds. * + * @remarks + * + * For details on how blueprints work, see the + * {@link https://backstage.io/docs/frontend-system/architecture/extension-blueprints | documentation for extension blueprints} + * in the frontend system documentation. + * + * Extension blueprints make it much easier for users to create new extensions + * for your plugin. Rather than letting them use {@link createExtension} + * directly, you can define a set of parameters and default factory for your + * blueprint, removing a lot of the boilerplate and complexity that is otherwise + * needed to create an extension. + * + * Each blueprint has its own `kind` that helps identify and group the + * extensions that have been created with it. For example the + * {@link PageBlueprint} has the kind `'page'`, and extensions created with it + * will be given the ID `'page:[/]'`. Blueprints should always + * be exported as `Blueprint`. + * + * When creating a blueprint the type of the parameters are inferred from the + * `factory` function that you provide. The exception to that is when you need + * your blueprint to include inferred type parameters, in which case you need to + * use the `defineParams` option. See the documentation for the `defineParams` + * option for more details on how that works. + * + * @example + * ```tsx + * // In your plugin library + * export const GreetingBlueprint = createExtensionBlueprint({ + * kind: 'greeting', + * attachTo: { id: 'example', input: 'greetings' }, + * output: [coreExtensionData.reactElement], + * factory(params: { greeting: string }) { + * return [coreExtensionData.reactElement(

    {params.greeting}

    )]; + * }, + * }); + * + * // Someone using your blueprint in their plugin + * const exampleGreeting = GreetingBlueprint.make({ + * params: { + * greeting: 'Hello, world!', + * }, + * }); + * ``` * @public */ export function createExtensionBlueprint< - TParams extends object, - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + TParams extends object | ExtensionBlueprintDefineParams, + UOutput extends ExtensionDataRef, + TInputs extends { [inputName in string]: ExtensionInput }, TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, UFactoryOutput extends ExtensionDataValue, TKind extends string, - TName extends string | undefined = undefined, - TDataRefs extends { [name in string]: AnyExtensionDataRef } = never, + TDataRefs extends { [name in string]: ExtensionDataRef } = never, >( options: CreateExtensionBlueprintOptions< TKind, - TName, TParams, UOutput, TInputs, @@ -238,9 +457,15 @@ export function createExtensionBlueprint< >, ): ExtensionBlueprint<{ kind: TKind; - name: TName; params: TParams; - output: UOutput; + // This inference and remapping back to ExtensionDataRef eliminates any occurrences ConfigurationExtensionDataRef + output: UOutput extends ExtensionDataRef< + infer IData, + infer IId, + infer IConfig + > + ? ExtensionDataRef + : never; inputs: string extends keyof TInputs ? {} : TInputs; config: string extends keyof TConfigSchema ? {} @@ -254,20 +479,24 @@ export function createExtensionBlueprint< >; dataRefs: TDataRefs; }> { + const defineParams = options.defineParams as + | ExtensionBlueprintDefineParams + | undefined; + return { dataRefs: options.dataRefs, make(args) { return createExtension({ kind: options.kind, - name: args.name ?? options.name, + name: args.name, attachTo: args.attachTo ?? options.attachTo, disabled: args.disabled ?? options.disabled, inputs: options.inputs, - output: options.output as AnyExtensionDataRef[], + output: options.output as ExtensionDataRef[], config: options.config, factory: ctx => options.factory( - { ...args.params, ...(ctx as any)[ctxParamsSymbol] }, + unwrapParams(args.params, ctx, defineParams, options.kind), ctx, ) as Iterable>, }) as ExtensionDefinition; @@ -275,11 +504,11 @@ export function createExtensionBlueprint< makeWithOverrides(args) { return createExtension({ kind: options.kind, - name: args.name ?? options.name, + name: args.name, attachTo: args.attachTo ?? options.attachTo, disabled: args.disabled ?? options.disabled, inputs: { ...args.inputs, ...options.inputs }, - output: (args.output ?? options.output) as AnyExtensionDataRef[], + output: (args.output ?? options.output) as ExtensionDataRef[], config: options.config || args.config ? { @@ -293,9 +522,17 @@ export function createExtensionBlueprint< const { node, config, inputs, apis } = ctx; return args.factory( (innerParams, innerContext) => { - return createExtensionDataContainer( + return createExtensionDataContainer< + UOutput extends ExtensionDataRef< + infer IData, + infer IId, + infer IConfig + > + ? ExtensionDataRef + : never + >( options.factory( - { ...innerParams, ...(ctx as any)[ctxParamsSymbol] }, + unwrapParams(innerParams, ctx, defineParams, options.kind), { apis, node, @@ -307,6 +544,7 @@ export function createExtensionBlueprint< ) as any, }, ) as Iterable, + 'original blueprint factory', options.output, ); }, @@ -322,9 +560,8 @@ export function createExtensionBlueprint< }, } as ExtensionBlueprint<{ kind: TKind; - name: TName; params: TParams; - output: UOutput; + output: any; inputs: string extends keyof TInputs ? {} : TInputs; config: string extends keyof TConfigSchema ? {} diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts index 94acb192a8..1bfbb01740 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionDataRef.ts @@ -23,9 +23,9 @@ export type ExtensionDataValue = { /** @public */ export type ExtensionDataRef< - TData, + TData = unknown, TId extends string = string, - TConfig extends { optional?: true } = {}, + TConfig extends { optional?: true } = { optional?: true }, > = { readonly $$type: '@backstage/ExtensionDataRef'; readonly id: TId; @@ -39,12 +39,11 @@ export type ExtensionDataRefToValue = ? ExtensionDataValue : never; -/** @public */ -export type AnyExtensionDataRef = ExtensionDataRef< - unknown, - string, - { optional?: true } ->; +/** + * @deprecated Use `ExtensionDataRef` without type parameters instead. + * @public + */ +export type AnyExtensionDataRef = ExtensionDataRef; /** @public */ export interface ConfigurableExtensionDataRef< diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts index 7209e6f647..24e14c45b2 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts @@ -18,8 +18,15 @@ import { ExtensionDataRef } from './createExtensionDataRef'; /** @public */ export interface ExtensionInput< - UExtensionData extends ExtensionDataRef, - TConfig extends { singleton: boolean; optional: boolean }, + UExtensionData extends ExtensionDataRef< + unknown, + string, + { optional?: true } + > = ExtensionDataRef, + TConfig extends { singleton: boolean; optional: boolean } = { + singleton: boolean; + optional: boolean; + }, > { $$type: '@backstage/ExtensionInput'; extensionData: Array; diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendFeatureLoader.test.ts b/packages/frontend-plugin-api/src/wiring/createFrontendFeatureLoader.test.ts index 63ce4cb284..50ea0749fd 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendFeatureLoader.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendFeatureLoader.test.ts @@ -46,7 +46,9 @@ function createTestAppRoot({ }) { return createApp({ features: [...features], - configLoader: async () => ({ config: mockApis.config({ data: config }) }), + advanced: { + configLoader: async () => ({ config: mockApis.config({ data: config }) }), + }, }).createRoot(); } diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts b/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts index bece1539fa..cea0760e68 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts @@ -45,10 +45,48 @@ export interface InternalFrontendModule extends FrontendModule { readonly featureFlags: FeatureFlagConfig[]; } -/** @public */ +/** + * Creates a new module that can be installed in a Backstage app. + * + * @remarks + * + * Modules are used to add or override extensions for an existing plugin. If a + * module provides an extension with the same ID as one provided by the plugin, + * the extension provided by the module will always take precedence. + * + * Every module is created for a specific plugin by providing the + * unique ID of the plugin that the module should be installed for. If that + * plugin is not present in the app, the module will be ignored and have no + * effect. + * + * For more information on how modules work, see the + * {@link https://backstage.io/docs/frontend-system/architecture/extension-overrides#creating-a-frontend-module | documentation for modules} + * in the frontend system documentation. + * + * It is recommended to name the module variable of the form `Module`. + * + * @example + * + * ```tsx + * import { createFrontendModule } from '@backstage/frontend-plugin-api'; + * + * export const exampleModuleCustomPage = createFrontendModule({ + * pluginId: 'example', + * extensions: [ + * // Overrides the default page for the 'example' plugin + * PageBlueprint.make({ + * path: '/example', + * loader: () => import('./CustomPage').then(m => ), + * }), + * ], + * }); + * ``` + * + * @public + */ export function createFrontendModule< TId extends string, - TExtensions extends readonly ExtensionDefinition[] = [], + TExtensions extends readonly ExtensionDefinition[], >(options: CreateFrontendModuleOptions): FrontendModule { const { pluginId } = options; diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts index 359f9da417..a3226721a1 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts @@ -128,7 +128,9 @@ function createTestAppRoot({ }) { return createApp({ features: [...features], - configLoader: async () => ({ config: mockApis.config({ data: config }) }), + advanced: { + configLoader: async () => ({ config: mockApis.config({ data: config }) }), + }, }).createRoot(); } @@ -140,13 +142,6 @@ describe('createFrontendPlugin', () => { expect(String(plugin)).toBe('Plugin{id=test}'); }); - it('should create an empty plugin with deprecated id option', () => { - const plugin = createFrontendPlugin({ id: 'test' }); - - expect(plugin).toBeDefined(); - expect(String(plugin)).toBe('Plugin{id=test}'); - }); - it('should create a plugin with extension instances', async () => { const plugin = createFrontendPlugin({ pluginId: 'test', @@ -281,6 +276,60 @@ describe('createFrontendPlugin', () => { ).toThrow("Plugin 'test' provided duplicate extensions: test/2, test/3"); }); + describe('info', () => { + it('should support reading info from package.json', async () => { + const plugin = createFrontendPlugin({ + pluginId: 'test', + info: { packageJson: () => Promise.resolve({ name: '@test/test' }) }, + }); + + await expect((plugin as any).infoOptions?.packageJson()).resolves.toEqual( + { name: '@test/test' }, + ); + }); + + it('should support reading info from actual package.json', async () => { + const plugin = createFrontendPlugin({ + pluginId: 'test', + info: { packageJson: () => import('../../package.json') }, + }); + + await expect( + (plugin as any).infoOptions?.packageJson(), + ).resolves.toMatchObject({ name: '@backstage/frontend-plugin-api' }); + }); + + it('should support reading info from opaque manifest', async () => { + const plugin = createFrontendPlugin({ + pluginId: 'test', + info: { manifest: () => Promise.resolve({ owner: 'me' }) }, + }); + + await expect((plugin as any).infoOptions?.manifest()).resolves.toEqual({ + owner: 'me', + }); + }); + + it('should throw when trying to load info without installing in an app', async () => { + await expect( + createFrontendPlugin({ + pluginId: 'test', + }).info(), + ).rejects.toThrow( + "Attempted to load plugin info for plugin 'test', but the plugin instance is not installed in an app", + ); + + await expect( + createFrontendPlugin({ + pluginId: 'test', + info: { packageJson: () => Promise.resolve({ name: '@test/test' }) }, + }).info(), + ).rejects.toThrow( + "Attempted to load plugin info for plugin 'test', but the plugin instance is not installed in an app", + ); + }); + }); + describe('overrides', () => { it('should return a plugin instance with the correct namespace', () => { const plugin = createFrontendPlugin({ diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts index b7c530a0c0..5555a0b47c 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts @@ -23,32 +23,123 @@ import { Extension, resolveExtensionDefinition, } from './resolveExtensionDefinition'; -import { AnyExternalRoutes, AnyRoutes, FeatureFlagConfig } from './types'; +import { FeatureFlagConfig } from './types'; import { MakeSortedExtensionsMap } from './MakeSortedExtensionsMap'; +import { JsonObject } from '@backstage/types'; +import { RouteRef, SubRouteRef, ExternalRouteRef } from '../routing'; + +/** + * Information about the plugin. + * + * @public + * @remarks + * + * This interface is intended to be extended via [module + * augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) + * in order to add fields that are specific to each project. + * + * For example, one might add a `slackChannel` field that is read from the + * opaque manifest file. + * + * See the options for `createApp` for more information about how to + * customize the parsing of manifest files. + */ +export interface FrontendPluginInfo { + /** + * The name of the package that implements the plugin. + */ + packageName?: string; + + /** + * The version of the plugin, typically the version of the package.json file. + */ + version?: string; + + /** + * As short description of the plugin, typically the description field in + * package.json. + */ + description?: string; + + /** + * The owner entity references of the plugin. + */ + ownerEntityRefs?: string[]; + + /** + * Links related to the plugin. + */ + links?: Array<{ title: string; url: string }>; +} + +/** + * Options for providing information for a plugin. + * + * @public + */ +export type FrontendPluginInfoOptions = { + /** + * A loader function for the package.json file for the plugin. + */ + packageJson?: () => Promise<{ name: string } & JsonObject>; + /** + * A loader function for an opaque manifest file for the plugin. + */ + manifest?: () => Promise; +}; + +/** + * A variant of the {@link FrontendPlugin} interface that can also be used to install overrides for the plugin. + * + * @public + */ +export interface OverridableFrontendPlugin< + TRoutes extends { [name in string]: RouteRef | SubRouteRef } = { + [name in string]: RouteRef | SubRouteRef; + }, + TExternalRoutes extends { [name in string]: ExternalRouteRef } = { + [name in string]: ExternalRouteRef; + }, + TExtensionMap extends { [id in string]: ExtensionDefinition } = { + [id in string]: ExtensionDefinition; + }, +> extends FrontendPlugin { + getExtension(id: TId): TExtensionMap[TId]; + withOverrides(options: { + extensions: Array; + + /** + * Overrides the original info loaders of the plugin one by one. + */ + info?: FrontendPluginInfoOptions; + }): OverridableFrontendPlugin; +} /** @public */ export interface FrontendPlugin< - TRoutes extends AnyRoutes = AnyRoutes, - TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, - TExtensionMap extends { [id in string]: ExtensionDefinition } = { - [id in string]: ExtensionDefinition; + TRoutes extends { [name in string]: RouteRef | SubRouteRef } = { + [name in string]: RouteRef | SubRouteRef; + }, + TExternalRoutes extends { [name in string]: ExternalRouteRef } = { + [name in string]: ExternalRouteRef; }, > { readonly $$type: '@backstage/FrontendPlugin'; readonly id: string; readonly routes: TRoutes; readonly externalRoutes: TExternalRoutes; - getExtension(id: TId): TExtensionMap[TId]; - withOverrides(options: { - extensions: Array; - }): FrontendPlugin; + + /** + * Loads the plugin info. + */ + info(): Promise; } /** @public */ export interface PluginOptions< TId extends string, - TRoutes extends AnyRoutes, - TExternalRoutes extends AnyExternalRoutes, + TRoutes extends { [name in string]: RouteRef | SubRouteRef }, + TExternalRoutes extends { [name in string]: ExternalRouteRef }, TExtensions extends readonly ExtensionDefinition[], > { pluginId: TId; @@ -56,63 +147,53 @@ export interface PluginOptions< externalRoutes?: TExternalRoutes; extensions?: TExtensions; featureFlags?: FeatureFlagConfig[]; + info?: FrontendPluginInfoOptions; } -/** @public */ -export function createFrontendPlugin< - TId extends string, - TRoutes extends AnyRoutes = {}, - TExternalRoutes extends AnyExternalRoutes = {}, - TExtensions extends readonly ExtensionDefinition[] = [], ->( - options: PluginOptions, -): FrontendPlugin< - TRoutes, - TExternalRoutes, - MakeSortedExtensionsMap ->; /** + * Creates a new plugin that can be installed in a Backstage app. + * + * @remarks + * + * Every plugin is created with a unique ID and a set of extensions + * that are installed as part of the plugin. + * + * For more information on how plugins work, see the + * {@link https://backstage.io/docs/frontend-system/building-plugins/index | documentation for plugins} + * in the frontend system documentation. + * + * @example + * + * ```tsx + * import { createFrontendPlugin } from '@backstage/frontend-plugin-api'; + * + * export const examplePlugin = createFrontendPlugin({ + * pluginId: 'example', + * extensions: [ + * PageBlueprint.make({ + * path: '/example', + * loader: () => import('./ExamplePage').then(m => ), + * }), + * ], + * }); + * ``` + * * @public - * @deprecated The `id` option is deprecated, use `pluginId` instead. */ export function createFrontendPlugin< TId extends string, - TRoutes extends AnyRoutes = {}, - TExternalRoutes extends AnyExternalRoutes = {}, - TExtensions extends readonly ExtensionDefinition[] = [], + TExtensions extends readonly ExtensionDefinition[], + TRoutes extends { [name in string]: RouteRef | SubRouteRef } = {}, + TExternalRoutes extends { [name in string]: ExternalRouteRef } = {}, >( - options: Omit< - PluginOptions, - 'pluginId' - > & { id: string }, -): FrontendPlugin< - TRoutes, - TExternalRoutes, - MakeSortedExtensionsMap ->; -export function createFrontendPlugin< - TId extends string, - TRoutes extends AnyRoutes = {}, - TExternalRoutes extends AnyExternalRoutes = {}, - TExtensions extends readonly ExtensionDefinition[] = [], ->( - options: - | PluginOptions - | (Omit< - PluginOptions, - 'pluginId' - > & { id: string }), -): FrontendPlugin< + options: PluginOptions, +): OverridableFrontendPlugin< TRoutes, TExternalRoutes, MakeSortedExtensionsMap > { - const pluginId = 'pluginId' in options ? options.pluginId : options.id; - if (!pluginId) { - throw new Error( - "Either 'id' or 'pluginId' must be provided to createFrontendPlugin", - ); - } + const pluginId = options.pluginId; + const extensions = new Array>(); const extensionDefinitionsById = new Map< string, @@ -150,6 +231,14 @@ export function createFrontendPlugin< externalRoutes: options.externalRoutes ?? ({} as TExternalRoutes), featureFlags: options.featureFlags ?? [], extensions: extensions, + infoOptions: options.info, + + // This method is overridden when the plugin instance is installed in an app + async info() { + throw new Error( + `Attempted to load plugin info for plugin '${pluginId}', but the plugin instance is not installed in an app`, + ); + }, getExtension(id) { const ext = extensionDefinitionsById.get(id); if (!ext) { @@ -178,6 +267,10 @@ export function createFrontendPlugin< ...options, pluginId, extensions: [...nonOverriddenExtensions, ...overrides.extensions], + info: { + ...options.info, + ...overrides.info, + }, }); }, }); diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index b584fc9769..45c80d4a90 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -39,7 +39,10 @@ export { export { createFrontendPlugin, type FrontendPlugin, + type OverridableFrontendPlugin, type PluginOptions, + type FrontendPluginInfo, + type FrontendPluginInfoOptions, } from './createFrontendPlugin'; export { createFrontendModule, @@ -53,8 +56,6 @@ export { } from './createFrontendFeatureLoader'; export { type Extension } from './resolveExtensionDefinition'; export { - type AnyRoutes, - type AnyExternalRoutes, type ExtensionDataContainer, type FeatureFlagConfig, type ExtensionFactoryMiddleware, @@ -64,6 +65,8 @@ export { type CreateExtensionBlueprintOptions, type ExtensionBlueprint, type ExtensionBlueprintParameters, + type ExtensionBlueprintParams, + type ExtensionBlueprintDefineParams, createExtensionBlueprint, + createExtensionBlueprintParams, } from './createExtensionBlueprint'; -export { type ResolveInputValueOverrides } from './resolveInputOverrides'; diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts index b25a7b9375..a74d908024 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts @@ -113,6 +113,7 @@ describe('ResolveExtensionId', () => { kind: TKind; name: TName; output: any; + params: never; }>; const id1: 'k:ns' = {} as ResolveExtensionId< NamedExtension<'k', undefined>, diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts index 7e771c6c2c..a0a9a52dd3 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts @@ -23,10 +23,7 @@ import { } from './createExtension'; import { PortableSchema } from '../schema'; import { ExtensionInput } from './createExtensionInput'; -import { - AnyExtensionDataRef, - ExtensionDataValue, -} from './createExtensionDataRef'; +import { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef'; import { OpaqueExtensionDefinition } from '@internal/frontend'; /** @public */ @@ -50,13 +47,13 @@ export type InternalExtension = Extension< [inputName in string]: { $$type: '@backstage/ExtensionInput'; extensionData: { - [name in string]: AnyExtensionDataRef; + [name in string]: ExtensionDataRef; }; config: { optional: boolean; singleton: boolean }; }; }; readonly output: { - [name in string]: AnyExtensionDataRef; + [name in string]: ExtensionDataRef; }; factory(context: { apis: ApiHolder; @@ -71,22 +68,14 @@ export type InternalExtension = Extension< } | { readonly version: 'v2'; - readonly inputs: { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }; - readonly output: Array; + readonly inputs: { [inputName in string]: ExtensionInput }; + readonly output: Array; factory(options: { apis: ApiHolder; node: AppNode; config: TConfig; inputs: ResolvedExtensionInputs<{ - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; + [inputName in string]: ExtensionInput; }>; }): Iterable>; } @@ -116,6 +105,7 @@ export type ResolveExtensionId< > = TExtension extends ExtensionDefinition<{ kind: infer IKind extends string | undefined; name: infer IName extends string | undefined; + params: any; }> ? [string] extends [IKind | IName] ? never diff --git a/packages/frontend-plugin-api/src/wiring/resolveInputOverrides.ts b/packages/frontend-plugin-api/src/wiring/resolveInputOverrides.ts index b93f7ce370..b46bb426fa 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveInputOverrides.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveInputOverrides.ts @@ -19,25 +19,16 @@ import { Expand } from '@backstage/types'; import { ResolvedExtensionInput } from './createExtension'; import { createExtensionDataContainer } from '@internal/frontend'; import { - AnyExtensionDataRef, ExtensionDataRefToValue, ExtensionDataValue, } from './createExtensionDataRef'; import { ExtensionInput } from './createExtensionInput'; import { ExtensionDataContainer } from './types'; -/** @public */ -export type ResolveInputValueOverrides< - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - } = { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; +/** @ignore */ +export type ResolvedInputValueOverrides< + TInputs extends { [inputName in string]: ExtensionInput } = { + [inputName in string]: ExtensionInput; }, > = Expand< { @@ -90,18 +81,13 @@ function expectItem(value: T | T[]): T { /** @internal */ export function resolveInputOverrides( - declaredInputs?: { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, + declaredInputs?: { [inputName in string]: ExtensionInput }, inputs?: { [KName in string]?: | ({ node: AppNode } & ExtensionDataContainer) | Array<{ node: AppNode } & ExtensionDataContainer>; }, - inputOverrides?: ResolveInputValueOverrides, + inputOverrides?: ResolvedInputValueOverrides, ) { if (!declaredInputs || !inputs || !inputOverrides) { return inputs; @@ -119,6 +105,7 @@ export function resolveInputOverrides( if (providedData) { const providedContainer = createExtensionDataContainer( providedData as Iterable>, + 'extension input override', declaredInput.extensionData, ); if (!originalInput) { @@ -157,6 +144,7 @@ export function resolveInputOverrides( newInputs[name] = providedData.map((data, i) => { const providedContainer = createExtensionDataContainer( data as Iterable>, + 'extension input override', declaredInput.extensionData, ); return Object.assign(providedContainer, { diff --git a/packages/frontend-plugin-api/src/wiring/types.ts b/packages/frontend-plugin-api/src/wiring/types.ts index 22bcbdadb7..460a399871 100644 --- a/packages/frontend-plugin-api/src/wiring/types.ts +++ b/packages/frontend-plugin-api/src/wiring/types.ts @@ -15,13 +15,8 @@ */ import { JsonObject } from '@backstage/types'; -import { ExternalRouteRef, RouteRef, SubRouteRef } from '../routing'; import { ExtensionDefinition } from './createExtension'; -import { - AnyExtensionDataRef, - ExtensionDataRef, - ExtensionDataValue, -} from './createExtensionDataRef'; +import { ExtensionDataRef, ExtensionDataValue } from './createExtensionDataRef'; import { ApiHolder, AppNode } from '../apis'; import { FrontendModule } from './createFrontendModule'; import { FrontendPlugin } from './createFrontendPlugin'; @@ -36,12 +31,6 @@ export type FeatureFlagConfig = { name: string; }; -/** @public */ -export type AnyRoutes = { [name in string]: RouteRef | SubRouteRef }; - -/** @public */ -export type AnyExternalRoutes = { [name in string]: ExternalRouteRef }; - /** @public */ export type ExtensionMap< TExtensionMap extends { [id in string]: ExtensionDefinition }, @@ -50,7 +39,7 @@ export type ExtensionMap< }; /** @public */ -export type ExtensionDataContainer = +export type ExtensionDataContainer = Iterable< UExtensionData extends ExtensionDataRef< infer IData, @@ -75,7 +64,7 @@ export type ExtensionDataContainer = export type ExtensionFactoryMiddleware = ( originalFactory: (contextOverrides?: { config?: JsonObject; - }) => ExtensionDataContainer, + }) => ExtensionDataContainer, context: { node: AppNode; apis: ApiHolder; diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index fba6e9afb5..1fa18a1696 100644 --- a/packages/frontend-test-utils/CHANGELOG.md +++ b/packages/frontend-test-utils/CHANGELOG.md @@ -1,5 +1,210 @@ # @backstage/frontend-test-utils +## 0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.13.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + - @backstage/test-utils@1.7.13-next.0 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-app@0.3.2-next.0 + +## 0.4.0 + +### Minor Changes + +- c41dd80: **BREAKING**: Removed the `extensions` option from `renderInTestApp`. If you need to pass extensions to the test app, use the new `renderTestApp` utility instead. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.3.1 + - @backstage/frontend-plugin-api@0.12.1 + - @backstage/config@1.3.5 + - @backstage/frontend-app-api@0.13.1 + - @backstage/test-utils@1.7.12 + +## 0.3.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/frontend-app-api@0.13.1-next.1 + - @backstage/test-utils@1.7.12-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.1 + - @backstage/plugin-app@0.3.1-next.1 + +## 0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.1-next.0 + - @backstage/plugin-app@0.3.1-next.0 + - @backstage/config@1.3.3 + - @backstage/frontend-app-api@0.13.1-next.0 + - @backstage/test-utils@1.7.11 + - @backstage/types@1.2.2 + - @backstage/version-bridge@1.0.11 + +## 0.3.6 + +### Patch Changes + +- 6516c3d: Internal update to use and throw app errors. +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-app@0.3.0 + - @backstage/frontend-app-api@0.13.0 + - @backstage/types@1.2.2 + +## 0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/frontend-app-api@0.12.1-next.0 + - @backstage/plugin-app@0.2.1-next.0 + +## 0.3.5 + +### Patch Changes + +- df7bd3b: Updated import of the `FrontendFeature` type. +- 5d31d66: Updated the usage of the `RouterBlueprint` and `AppRootWrapperBlueprint` to use the lowercase `component` parameter +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/frontend-app-api@0.12.0 + - @backstage/plugin-app@0.2.0 + - @backstage/test-utils@1.7.11 + +## 0.3.5-next.2 + +### Patch Changes + +- df7bd3b: Updated import of the `FrontendFeature` type. +- 5d31d66: Updated the usage of the `RouterBlueprint` and `AppRootWrapperBlueprint` to use the lowercase `component` parameter +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0-next.1 + - @backstage/frontend-app-api@0.12.0-next.2 + - @backstage/plugin-app@0.2.0-next.1 + - @backstage/config@1.3.3 + - @backstage/test-utils@1.7.11-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.3.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.11.5-next.1 + - @backstage/plugin-app@0.2.0-next.0 + - @backstage/frontend-plugin-api@0.11.0-next.0 + - @backstage/test-utils@1.7.11-next.0 + - @backstage/config@1.3.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.3.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-app-api@0.11.5-next.0 + - @backstage/plugin-app@0.1.11 + - @backstage/frontend-plugin-api@0.10.4 + +## 0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/frontend-app-api@0.11.4 + - @backstage/plugin-app@0.1.11 + - @backstage/frontend-plugin-api@0.10.4 + - @backstage/test-utils@1.7.10 + +## 0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/frontend-app-api@0.11.4-next.1 + - @backstage/test-utils@1.7.10-next.1 + - @backstage/frontend-plugin-api@0.10.4-next.1 + - @backstage/plugin-app@0.1.11-next.1 + +## 0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.11-next.0 + - @backstage/test-utils@1.7.10-next.0 + - @backstage/config@1.3.2 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.10 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-app-api@0.11.3 + - @backstage/config@1.3.2 + - @backstage/test-utils@1.7.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.3.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/plugin-app@0.1.10-next.1 + - @backstage/config@1.3.2 + - @backstage/frontend-app-api@0.11.3-next.1 + - @backstage/test-utils@1.7.8 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## 0.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.10-next.0 + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/frontend-app-api@0.11.3-next.0 + +## 0.3.2 + +### Patch Changes + +- fb58f20: Internal update to use the new `pluginId` option of `createFrontendPlugin`. +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/test-utils@1.7.8 + - @backstage/frontend-app-api@0.11.2 + - @backstage/plugin-app@0.1.9 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + ## 0.3.2-next.3 ### Patch Changes diff --git a/packages/frontend-test-utils/knip-report.md b/packages/frontend-test-utils/knip-report.md index 50f4f788e3..5415a4c648 100644 --- a/packages/frontend-test-utils/knip-report.md +++ b/packages/frontend-test-utils/knip-report.md @@ -4,6 +4,6 @@ | Name | Location | Severity | | :------------------------ | :----------- | :------- | -| @backstage/version-bridge | package.json | error | -| zod | package.json | error | +| @backstage/version-bridge | packages/frontend-test-utils/package.json | error | +| zod | packages/frontend-test-utils/package.json | error | diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 833030129f..18ab54d197 100644 --- a/packages/frontend-test-utils/package.json +++ b/packages/frontend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-test-utils", - "version": "0.3.2-next.3", + "version": "0.4.1-next.0", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-test-utils/report.api.md b/packages/frontend-test-utils/report.api.md index b139538cbe..b99cf843d4 100644 --- a/packages/frontend-test-utils/report.api.md +++ b/packages/frontend-test-utils/report.api.md @@ -5,7 +5,6 @@ ```ts import { AnalyticsApi } from '@backstage/frontend-plugin-api'; import { AnalyticsEvent } from '@backstage/frontend-plugin-api'; -import { AnyExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ApiMock } from '@backstage/test-utils'; import { AppNode } from '@backstage/frontend-plugin-api'; import { AppNodeInstance } from '@backstage/frontend-plugin-api'; @@ -13,7 +12,7 @@ import { ErrorWithContext } from '@backstage/test-utils'; import { ExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExtensionDefinitionParameters } from '@backstage/frontend-plugin-api'; -import { FrontendFeature } from '@backstage/frontend-app-api'; +import { FrontendFeature } from '@backstage/frontend-plugin-api'; import { JsonObject } from '@backstage/types'; import { mockApis } from '@backstage/test-utils'; import { MockConfigApi } from '@backstage/test-utils'; @@ -30,6 +29,7 @@ import { RouteRef } from '@backstage/frontend-plugin-api'; import { TestApiProvider } from '@backstage/test-utils'; import { TestApiProviderProps } from '@backstage/test-utils'; import { TestApiRegistry } from '@backstage/test-utils'; +import { testingLibraryDomTypesQueries } from '@testing-library/dom/types/queries'; import { withLogCollector } from '@backstage/test-utils'; export { ApiMock }; @@ -45,7 +45,7 @@ export function createExtensionTester( export { ErrorWithContext }; // @public (undocumented) -export class ExtensionQuery { +export class ExtensionQuery { constructor(node: AppNode); // (undocumented) get( @@ -62,7 +62,7 @@ export class ExtensionQuery { } // @public (undocumented) -export class ExtensionTester { +export class ExtensionTester { // (undocumented) add( extension: ExtensionDefinition, @@ -120,6 +120,19 @@ export function renderInTestApp( options?: TestAppOptions, ): RenderResult; +// @public +export function renderTestApp( + options: RenderTestAppOptions, +): RenderResult; + +// @public +export type RenderTestAppOptions = { + config?: JsonObject; + extensions?: ExtensionDefinition[]; + features?: FrontendFeature[]; + initialRouteEntries?: string[]; +}; + export { TestApiProvider }; export { TestApiProviderProps }; @@ -132,7 +145,6 @@ export type TestAppOptions = { [path: string]: RouteRef; }; config?: JsonObject; - extensions?: ExtensionDefinition[]; features?: FrontendFeature[]; initialRouteEntries?: string[]; }; diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index 37ec1d8fd9..50d65fddc7 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -15,7 +15,6 @@ */ import { - AnyExtensionDataRef, AppNode, AppTree, Extension, @@ -36,11 +35,13 @@ import { resolveAppNodeSpecs } from '../../../frontend-app-api/src/tree/resolveA import { instantiateAppNodeTree } from '../../../frontend-app-api/src/tree/instantiateAppNodeTree'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { readAppExtensionsConfig } from '../../../frontend-app-api/src/tree/readAppExtensionsConfig'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { createErrorCollector } from '../../../frontend-app-api/src/wiring/createErrorCollector'; import { TestApiRegistry } from '@backstage/test-utils'; import { OpaqueExtensionDefinition } from '@internal/frontend'; /** @public */ -export class ExtensionQuery { +export class ExtensionQuery { #node: AppNode; constructor(node: AppNode) { @@ -75,7 +76,7 @@ export class ExtensionQuery { } /** @public */ -export class ExtensionTester { +export class ExtensionTester { /** @internal */ static forSubject( subject: ExtensionDefinition, @@ -192,16 +193,29 @@ export class ExtensionTester { ); } + const collector = createErrorCollector(); + const tree = resolveAppTree( subject.id, resolveAppNodeSpecs({ features: [], builtinExtensions: this.#extensions.map(_ => _.extension), parameters: readAppExtensionsConfig(this.#getConfig()), + collector, }), + collector, ); - instantiateAppNodeTree(tree.root, TestApiRegistry.from()); + instantiateAppNodeTree(tree.root, TestApiRegistry.from(), collector); + + const errors = collector.collectErrors(); + if (errors) { + throw new Error( + `Failed to resolve the extension tree: ${errors + .map(e => e.message) + .join(', ')}`, + ); + } this.#tree = tree; diff --git a/packages/frontend-test-utils/src/app/index.ts b/packages/frontend-test-utils/src/app/index.ts index 6c6ef26e4c..9db67dbb49 100644 --- a/packages/frontend-test-utils/src/app/index.ts +++ b/packages/frontend-test-utils/src/app/index.ts @@ -21,3 +21,4 @@ export { } from './createExtensionTester'; export { renderInTestApp, type TestAppOptions } from './renderInTestApp'; +export { renderTestApp, type RenderTestAppOptions } from './renderTestApp'; diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx index cee6273cb1..8e1b1e1ea0 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.test.tsx @@ -21,6 +21,7 @@ import { TestApiProvider, } from '@backstage/frontend-test-utils'; import { analyticsApiRef, useAnalytics } from '@backstage/frontend-plugin-api'; +import { Routes, Route } from 'react-router-dom'; import { renderInTestApp } from './renderInTestApp'; describe('renderInTestApp', () => { @@ -65,4 +66,18 @@ describe('renderInTestApp', () => { ]), ); }); + + it('should support setting different locations in the history stack', async () => { + renderInTestApp( + + Index Page} /> + Second Page} /> + , + { + initialRouteEntries: ['/second-page'], + }, + ); + + expect(screen.getByText('Second Page')).toBeInTheDocument(); + }); }); diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.tsx index d4010a92ad..747229e8d6 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.tsx @@ -16,10 +16,7 @@ import { Fragment } from 'react'; import { Link, MemoryRouter } from 'react-router-dom'; -import { - createSpecializedApp, - FrontendFeature, -} from '@backstage/frontend-app-api'; +import { createSpecializedApp } from '@backstage/frontend-app-api'; import { RenderResult, render } from '@testing-library/react'; import { ConfigReader } from '@backstage/config'; import { JsonObject } from '@backstage/types'; @@ -33,6 +30,7 @@ import { RouterBlueprint, NavItemBlueprint, createFrontendPlugin, + FrontendFeature, } from '@backstage/frontend-plugin-api'; import appPlugin from '@backstage/plugin-app'; @@ -69,11 +67,6 @@ export type TestAppOptions = { */ config?: JsonObject; - /** - * Additional extensions to add to the test app. - */ - extensions?: ExtensionDefinition[]; - /** * Additional features to add to the test app. */ @@ -109,6 +102,12 @@ const appPluginOverride = appPlugin.withOverrides({ appPlugin.getExtension('sign-in-page:app').override({ disabled: true, }), + appPlugin.getExtension('app/layout').override({ + disabled: true, + }), + appPlugin.getExtension('app/routes').override({ + disabled: true, + }), appPlugin.getExtension('app/nav').override({ output: [coreExtensionData.reactElement], factory(_originalFactory, { inputs }) { @@ -149,18 +148,15 @@ export function renderInTestApp( ): RenderResult { const extensions: Array = [ createExtension({ - attachTo: { id: 'app/routes', input: 'routes' }, - output: [coreExtensionData.reactElement, coreExtensionData.routePath], + attachTo: { id: 'app/root', input: 'children' }, + output: [coreExtensionData.reactElement], factory: () => { - return [ - coreExtensionData.reactElement(element), - coreExtensionData.routePath('/'), - ]; + return [coreExtensionData.reactElement(element)]; }, }), RouterBlueprint.make({ params: { - Component: ({ children }) => ( + component: ({ children }) => ( {children} @@ -192,10 +188,6 @@ export function renderInTestApp( } } - if (options?.extensions) { - extensions.push(...options.extensions); - } - const features: FrontendFeature[] = [ createFrontendPlugin({ pluginId: 'test', diff --git a/packages/frontend-test-utils/src/app/renderTestApp.tsx b/packages/frontend-test-utils/src/app/renderTestApp.tsx new file mode 100644 index 0000000000..e8d90cadd6 --- /dev/null +++ b/packages/frontend-test-utils/src/app/renderTestApp.tsx @@ -0,0 +1,115 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createSpecializedApp } from '@backstage/frontend-app-api'; +import { + coreExtensionData, + createFrontendPlugin, + ExtensionDefinition, + FrontendFeature, + RouterBlueprint, +} from '@backstage/frontend-plugin-api'; +import { render } from '@testing-library/react'; +import appPlugin from '@backstage/plugin-app'; +import { JsonObject } from '@backstage/types'; +import { ConfigReader } from '@backstage/config'; +import { MemoryRouter } from 'react-router-dom'; + +const DEFAULT_MOCK_CONFIG = { + app: { baseUrl: 'http://localhost:3000' }, + backend: { baseUrl: 'http://localhost:7007' }, +}; + +/** + * Options for `renderTestApp`. + * + * @public + */ +export type RenderTestAppOptions = { + /** + * Additional configuration passed to the app when rendering elements inside it. + */ + config?: JsonObject; + /** + * Additional extensions to add to the test app. + */ + extensions?: ExtensionDefinition[]; + + /** + * Additional features to add to the test app. + */ + features?: FrontendFeature[]; + + /** + * Initial route entries to use for the router. + */ + initialRouteEntries?: string[]; +}; + +const appPluginOverride = appPlugin.withOverrides({ + extensions: [ + appPlugin.getExtension('sign-in-page:app').override({ + disabled: true, + }), + ], +}); + +/** + * Renders the provided extensions inside a Backstage app, returning the same + * utilities as `@testing-library/react` `render` function. + * + * @public + */ +export function renderTestApp(options: RenderTestAppOptions) { + const extensions = [ + RouterBlueprint.make({ + params: { + component: ({ children }) => ( + + {children} + + ), + }, + }), + ...(options.extensions ?? []), + ]; + + const features: FrontendFeature[] = [ + createFrontendPlugin({ + pluginId: 'test', + extensions, + }), + appPluginOverride, + ]; + + if (options.features) { + features.push(...options.features); + } + + const app = createSpecializedApp({ + features, + config: ConfigReader.fromConfigs([ + { + context: 'render-config', + data: options?.config ?? DEFAULT_MOCK_CONFIG, + }, + ]), + }); + + return render( + app.tree.root.instance!.getData(coreExtensionData.reactElement), + ); +} diff --git a/packages/integration-aws-node/CHANGELOG.md b/packages/integration-aws-node/CHANGELOG.md index 41d4eecb08..d49f70955d 100644 --- a/packages/integration-aws-node/CHANGELOG.md +++ b/packages/integration-aws-node/CHANGELOG.md @@ -1,5 +1,51 @@ # @backstage/integration-aws-node +## 0.1.19-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/errors@1.2.7 + +## 0.1.18 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + +## 0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + +## 0.1.17 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + +## 0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + +## 0.1.16 + +### Patch Changes + +- db4630e: Fixed bug in DefaultAwsCredentialsManager where aws.mainAccount.region has no effect on the STS region used for account ID lookup during credential provider lookup when falling back to the main account, and it does not default to us-east-1 +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + ## 0.1.16-next.0 ### Patch Changes diff --git a/packages/integration-aws-node/knip-report.md b/packages/integration-aws-node/knip-report.md index 8927891173..efa9f826b6 100644 --- a/packages/integration-aws-node/knip-report.md +++ b/packages/integration-aws-node/knip-report.md @@ -4,13 +4,13 @@ | Name | Location | Severity | | :-------------------------------- | :----------- | :------- | -| @aws-sdk/credential-provider-node | package.json | error | -| @backstage/errors | package.json | error | +| @aws-sdk/credential-provider-node | packages/integration-aws-node/package.json | error | +| @backstage/errors | packages/integration-aws-node/package.json | error | ## Unused devDependencies (2) | Name | Location | Severity | | :----------------------- | :----------- | :------- | -| @backstage/config-loader | package.json | error | -| @backstage/test-utils | package.json | error | +| @backstage/config-loader | packages/integration-aws-node/package.json | error | +| @backstage/test-utils | packages/integration-aws-node/package.json | error | diff --git a/packages/integration-aws-node/package.json b/packages/integration-aws-node/package.json index 65403727b6..e3cd09cde0 100644 --- a/packages/integration-aws-node/package.json +++ b/packages/integration-aws-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration-aws-node", - "version": "0.1.16-next.0", + "version": "0.1.19-next.0", "description": "Helpers for fetching AWS account credentials", "backstage": { "role": "node-library" diff --git a/packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts b/packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts index b54a4fda26..a02fea1b1c 100644 --- a/packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts +++ b/packages/integration-aws-node/src/DefaultAwsCredentialsManager.ts @@ -199,14 +199,22 @@ export class DefaultAwsCredentialsManager implements AwsCredentialsManager { ); } + private readonly accountCredentialProviders: Map< + string, + AwsCredentialProvider + >; + private readonly accountDefaults: AwsIntegrationDefaultAccountConfig; + private readonly mainAccountCredentialProvider: AwsCredentialProvider; + private constructor( - private readonly accountCredentialProviders: Map< - string, - AwsCredentialProvider - >, - private readonly accountDefaults: AwsIntegrationDefaultAccountConfig, - private readonly mainAccountCredentialProvider: AwsCredentialProvider, - ) {} + accountCredentialProviders: Map, + accountDefaults: AwsIntegrationDefaultAccountConfig, + mainAccountCredentialProvider: AwsCredentialProvider, + ) { + this.accountCredentialProviders = accountCredentialProviders; + this.accountDefaults = accountDefaults; + this.mainAccountCredentialProvider = mainAccountCredentialProvider; + } /** * Returns an {@link AwsCredentialProvider} for a given AWS account. diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index fb44067948..6956f04b08 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,103 @@ # @backstage/integration-react +## 1.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/integration@1.18.2-next.0 + +## 1.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1 + - @backstage/config@1.3.5 + - @backstage/core-plugin-api@1.11.1 + +## 1.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/integration@1.18.1-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + +## 1.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.1-next.0 + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.11.0 + +## 1.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.11.0 + - @backstage/integration@1.18.0 + +## 1.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.18.0-next.0 + +## 1.2.9 + +### Patch Changes + +- 998fd15: Separated gitlab `write_repository` and `api` scope to pass checks in `RefreshingAuthSessionManager` +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration@1.17.1 + +## 1.2.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/integration@1.17.1-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## 1.2.9-next.0 + +### Patch Changes + +- 998fd15: Separated gitlab `write_repository` and `api` scope to pass checks in `RefreshingAuthSessionManager` +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.8 + +## 1.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + +## 1.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/config@1.3.2 + ## 1.2.7-next.3 ### Patch Changes diff --git a/packages/integration-react/knip-report.md b/packages/integration-react/knip-report.md index 551f19ab2f..dd0df6e7f4 100644 --- a/packages/integration-react/knip-report.md +++ b/packages/integration-react/knip-report.md @@ -4,6 +4,6 @@ | Name | Location | Severity | | :------------------- | :----------- | :------- | -| @testing-library/dom | package.json | error | -| msw | package.json | error | +| @testing-library/dom | packages/integration-react/package.json | error | +| msw | packages/integration-react/package.json | error | diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index 529f5011db..ca9dce00d9 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration-react", - "version": "1.2.7-next.3", + "version": "1.2.12-next.0", "description": "Frontend package for managing integrations towards external systems", "backstage": { "role": "web-library" diff --git a/packages/integration-react/src/api/ScmAuth.ts b/packages/integration-react/src/api/ScmAuth.ts index 011422d4cf..823937ac28 100644 --- a/packages/integration-react/src/api/ScmAuth.ts +++ b/packages/integration-react/src/api/ScmAuth.ts @@ -173,7 +173,7 @@ export class ScmAuth implements ScmAuthApi { const host = options?.host ?? 'gitlab.com'; return new ScmAuth('gitlab', gitlabAuthApi, host, { default: ['read_user', 'read_api', 'read_repository'], - repoWrite: ['write_repository api'], + repoWrite: ['write_repository', 'api'], }); } diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md index 832f45e230..bcc2a938ae 100644 --- a/packages/integration/CHANGELOG.md +++ b/packages/integration/CHANGELOG.md @@ -1,5 +1,121 @@ # @backstage/integration +## 1.18.2-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config@1.3.6-next.0 + - @backstage/errors@1.2.7 + +## 1.18.1 + +### Patch Changes + +- d772b51: remove host from azure blob storage integration type +- 84443f1: Adds config definitions for Azure Blob Storage. +- Updated dependencies + - @backstage/config@1.3.5 + +## 1.18.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + +## 1.18.1-next.0 + +### Patch Changes + +- d772b51: remove host from azure blob storage integration type +- 84443f1: Adds config definitions for Azure Blob Storage. +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/errors@1.2.7 + +## 1.18.0 + +### Minor Changes + +- 03bdc68: Added support for limiting GithubAppCredentialsMux to specific apps + +### Patch Changes + +- 56897d7: Fixes issue with Github credentials provider which fails to match organization name if using allowedInstallationOwners + +## 1.18.0-next.0 + +### Minor Changes + +- 03bdc68: Added support for limiting GithubAppCredentialsMux to specific apps + +## 1.17.1 + +### Patch Changes + +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/config@1.3.3 + +## 1.17.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + +## 1.17.1-next.0 + +### Patch Changes + +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## 1.17.0 + +### Minor Changes + +- d945206: Added support for federated credentials using managed identities in the Azure DevOps integration. Federated credentials are only available for Azure DevOps organizations that have been configured to use Entra ID for authentication. + + ```diff + integrations: + azure: + - host: dev.azure.com + credentials: + + - clientId: ${APP_REGISTRATION_CLIENT_ID} + + managedIdentityClientId: system-assigned + + tenantId: ${AZURE_TENANT_ID} + ``` + + This also adds support for automatically using the system-assigned managed identity of an Azure resource by specifying `system-assigned` as the client ID of the managed identity. + + ```diff + integrations: + azure: + - host: dev.azure.com + credentials: + - - clientId: ${AZURE_CLIENT_ID} + + - clientId: system-assigned + ``` + +- f134cea: Implement Edit URL feature for Gerrit 3.9+. + + It's possible to disable the edit url by adding the `disableEditUrl: true` config in the Gerrit integration. + +### Patch Changes + +- f3381d3: Added missing `organizations` property to `azure` section in `config.d.ts` file +- acea1d4: update documentation +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + ## 1.17.0-next.3 ### Minor Changes diff --git a/packages/integration/config.d.ts b/packages/integration/config.d.ts index 4955d0fac3..298d765697 100644 --- a/packages/integration/config.d.ts +++ b/packages/integration/config.d.ts @@ -71,6 +71,66 @@ export interface Config { commitSigningKey?: string; }>; + /** Integration configuration for Azure Blob Storage */ + azureBlobStorage?: Array<{ + /** + * The name of the Azure Storage Account, e.g., "mystorageaccount". + */ + accountName?: string; + + /** + * The primary or secondary key for the Azure Storage Account. + * Only required if connectionString or SAS token are not specified. + * @visibility secret + */ + accountKey?: string; + + /** + * A Shared Access Signature (SAS) token for limited access to resources. + * @visibility secret + */ + sasToken?: string; + + /** + * A full connection string for the Azure Storage Account. + * This includes the account name, key, and endpoint details. + * @visibility secret + */ + connectionString?: string; + + /** + * Optional endpoint suffix for custom domains or sovereign clouds. + * e.g., "core.windows.net" for public Azure or "core.usgovcloudapi.net" for US Government cloud. + */ + endpointSuffix?: string; + + /** + * Optional endpoint URL for custom domain. Uses default if not provided. + * @visibility frontend + */ + endpoint?: string; + /** + * Optional credential to use for Azure Active Directory authentication. + * @deepVisibility secret + */ + aadCredential?: { + /** + * The client ID of the Azure AD application. + */ + clientId: string; + + /** + * The tenant ID for Azure AD. + */ + tenantId: string; + + /** + * The client secret for the Azure AD application. + */ + clientSecret: string; + }; + }>; + /** * Integration configuration for Bitbucket * @deprecated replaced by bitbucketCloud and bitbucketServer diff --git a/packages/integration/package.json b/packages/integration/package.json index 142f17c74a..45928cd59b 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/integration", - "version": "1.17.0-next.3", + "version": "1.18.2-next.0", "description": "Helpers for managing integrations towards external systems", "backstage": { "role": "common-library" diff --git a/packages/integration/report.api.md b/packages/integration/report.api.md index d700c13429..f642058ccd 100644 --- a/packages/integration/report.api.md +++ b/packages/integration/report.api.md @@ -588,6 +588,7 @@ export function getGitilesAuthenticationUrl( export function getGitLabFileFetchUrl( url: string, config: GitLabIntegrationConfig, + token?: string, ): Promise; // @public @@ -668,7 +669,7 @@ export type GithubAppConfig = { // @public export class GithubAppCredentialsMux { - constructor(config: GithubIntegrationConfig); + constructor(config: GithubIntegrationConfig, appIds?: number[]); // (undocumented) getAllInstallations(): Promise< RestEndpointMethodTypes['apps']['listInstallations']['response']['data'] diff --git a/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.test.ts b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.test.ts index ec07d1b465..0468e96e14 100644 --- a/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.test.ts +++ b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.test.ts @@ -231,6 +231,42 @@ describe('SingleInstanceGithubCredentialsProvider tests', () => { expect(token).toEqual(undefined); }); + it('should not fail to issue tokens for an organization when there is a case mismatch in the organization name', async () => { + octokit.apps.listInstallations.mockResolvedValue({ + headers: { + etag: '123', + }, + data: [ + { + id: 1, + repository_selection: 'selected', + account: { + login: 'backstage', + }, + }, + ], + } as RestEndpointMethodTypes['apps']['listInstallations']['response']); + + octokit.apps.createInstallationAccessToken.mockResolvedValueOnce({ + data: { + expires_at: DateTime.local().plus({ hours: 1 }).toString(), + token: 'secret_token', + repository_selection: 'selected', + }, + } as RestEndpointMethodTypes['apps']['createInstallationAccessToken']['response']); + + octokit.apps.listReposAccessibleToInstallation.mockReturnValue({ + data: [{ name: 'some-repo' }], + } as unknown as RestEndpointMethodTypes['apps']['listReposAccessibleToInstallation']['response']); + + const { token, headers } = await github.getCredentials({ + url: 'https://github.com/Backstage', + }); + const expectedToken = 'secret_token'; + expect(headers).toEqual({ Authorization: `Bearer ${expectedToken}` }); + expect(token).toEqual('secret_token'); + }); + it('should not fail to issue tokens for an organization when the app is installed for a single repo', async () => { octokit.apps.listInstallations.mockResolvedValue({ headers: { diff --git a/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts index dc3a86b72b..d2c1e37a65 100644 --- a/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts +++ b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts @@ -102,7 +102,9 @@ class GithubAppManager { private readonly allowedInstallationOwners: string[] | undefined; // undefined allows all installations constructor(config: GithubAppConfig, baseUrl?: string) { - this.allowedInstallationOwners = config.allowedInstallationOwners; + this.allowedInstallationOwners = config.allowedInstallationOwners?.map( + owner => owner.toLocaleLowerCase('en-US'), + ); this.baseUrl = baseUrl; this.baseAuthConfig = { appId: config.appId, @@ -121,7 +123,11 @@ class GithubAppManager { repo?: string, ): Promise<{ accessToken: string | undefined }> { if (this.allowedInstallationOwners) { - if (!this.allowedInstallationOwners?.includes(owner)) { + if ( + !this.allowedInstallationOwners?.includes( + owner.toLocaleLowerCase('en-US'), + ) + ) { return { accessToken: undefined }; // An empty token allows anonymous access to public repos } } @@ -201,9 +207,11 @@ class GithubAppManager { export class GithubAppCredentialsMux { private readonly apps: GithubAppManager[]; - constructor(config: GithubIntegrationConfig) { + constructor(config: GithubIntegrationConfig, appIds: number[] = []) { this.apps = - config.apps?.map(ac => new GithubAppManager(ac, config.apiBaseUrl)) ?? []; + config.apps + ?.filter(app => (appIds.length ? appIds.includes(app.appId) : true)) + .map(ac => new GithubAppManager(ac, config.apiBaseUrl)) ?? []; } async getAllInstallations(): Promise< @@ -271,10 +279,16 @@ export class SingleInstanceGithubCredentialsProvider ); }; + private readonly githubAppCredentialsMux: GithubAppCredentialsMux; + private readonly token?: string; + private constructor( - private readonly githubAppCredentialsMux: GithubAppCredentialsMux, - private readonly token?: string, - ) {} + githubAppCredentialsMux: GithubAppCredentialsMux, + token?: string, + ) { + this.githubAppCredentialsMux = githubAppCredentialsMux; + this.token = token; + } /** * Returns {@link GithubCredentials} for a given URL. diff --git a/packages/integration/src/gitlab/core.test.ts b/packages/integration/src/gitlab/core.test.ts index 81adc29701..d514dba755 100644 --- a/packages/integration/src/gitlab/core.test.ts +++ b/packages/integration/src/gitlab/core.test.ts @@ -188,7 +188,7 @@ describe('gitlab core', () => { }); describe('getGitLabRequestOptions', () => { - it('should return Authorization header when oauthToken is provided', () => { + it('should return Authorization bearer header when a token is provided', () => { const token = '1234567890'; const result = getGitLabRequestOptions( configSelfHosteWithRelativePath, @@ -202,29 +202,12 @@ describe('gitlab core', () => { }); }); - it('should return private-token header when gl-token is provided', () => { - const token = 'glpat-1234566'; - const result = getGitLabRequestOptions( - configSelfHosteWithRelativePath, - token, - ); + it('should return Authorization bearer header using the config token when no token is provided', () => { + const result = getGitLabRequestOptions(configSelfHosteWithRelativePath); expect(result).toEqual({ headers: { - 'PRIVATE-TOKEN': token, - }, - }); - }); - - it('should return private-token header when oauthToken is undefined', () => { - const oauthToken = undefined; - const result = getGitLabRequestOptions( - configSelfHosteWithRelativePath, - oauthToken, - ); - expect(result).toEqual({ - headers: { - 'PRIVATE-TOKEN': configSelfHosteWithRelativePath.token, + Authorization: `Bearer ${configSelfHosteWithRelativePath.token}`, }, }); }); diff --git a/packages/integration/src/gitlab/core.ts b/packages/integration/src/gitlab/core.ts index 4a17b2a15e..65360840b5 100644 --- a/packages/integration/src/gitlab/core.ts +++ b/packages/integration/src/gitlab/core.ts @@ -40,8 +40,9 @@ import { export async function getGitLabFileFetchUrl( url: string, config: GitLabIntegrationConfig, + token?: string, ): Promise { - const projectID = await getProjectId(url, config); + const projectID = await getProjectId(url, config, token); return buildProjectUrl(url, projectID, config).toString(); } @@ -56,20 +57,17 @@ export function getGitLabRequestOptions( config: GitLabIntegrationConfig, token?: string, ): { headers: Record } { - if (token) { - // If token comes from the user and starts with "gl", it's a private token (see https://docs.gitlab.com/ee/security/token_overview.html#token-prefixes) - return { - headers: token.startsWith('gl') - ? { 'PRIVATE-TOKEN': token } - : { Authorization: `Bearer ${token}` }, // Otherwise, it's a bearer token - }; + const headers: Record = {}; + + const accessToken = token || config.token; + if (accessToken) { + // OAuth, Personal, Project, and Group access tokens can all be passed via + // a bearer authorization header + // https://docs.gitlab.com/api/rest/authentication/#personalprojectgroup-access-tokens + headers.Authorization = `Bearer ${accessToken}`; } - // If token not provided, fetch the integration token - const { token: configToken = '' } = config; - return { - headers: { 'PRIVATE-TOKEN': configToken }, - }; + return { headers }; } // Converts @@ -113,6 +111,7 @@ export function buildProjectUrl( export async function getProjectId( target: string, config: GitLabIntegrationConfig, + token?: string, ): Promise { const url = new URL(target); @@ -143,12 +142,18 @@ export async function getProjectId( const response = await fetch( repoIDLookup.toString(), - getGitLabRequestOptions(config), + getGitLabRequestOptions(config, token), ); const data = await response.json(); if (!response.ok) { + if (response.status === 401) { + throw new Error( + 'GitLab Error: 401 - Unauthorized. The access token used is either expired, or does not have permission to read the project', + ); + } + throw new Error( `GitLab Error '${data.error}', ${data.error_description}`, ); diff --git a/packages/opaque-internal/knip-report.md b/packages/opaque-internal/knip-report.md index b131ea8948..b49ecc8f5f 100644 --- a/packages/opaque-internal/knip-report.md +++ b/packages/opaque-internal/knip-report.md @@ -4,6 +4,6 @@ | Name | Location | Severity | | :------------------------ | :----------- | :------- | -| @testing-library/jest-dom | package.json | error | -| @testing-library/react | package.json | error | +| @testing-library/jest-dom | packages/opaque-internal/package.json | error | +| @testing-library/react | packages/opaque-internal/package.json | error | diff --git a/packages/release-manifests/CHANGELOG.md b/packages/release-manifests/CHANGELOG.md index a7f41cbdf8..db9a60d0f4 100644 --- a/packages/release-manifests/CHANGELOG.md +++ b/packages/release-manifests/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/release-manifests +## 0.0.13 + +### Patch Changes + +- 163f3da: This expands the configurability of `release-manifests` to pave the road for more configuration options in the `cli`. + + Specifically it allows the specification of mirrored, proxied, or air-gapped hosts when upgrading across releases when + working in restricted or heavily governed development environments (common in large enterprises and government + entities). + ## 0.0.13-next.0 ### Patch Changes diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json index ec67298ec2..7998845125 100644 --- a/packages/release-manifests/package.json +++ b/packages/release-manifests/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/release-manifests", - "version": "0.0.13-next.0", + "version": "0.0.13", "description": "Helper library for receiving release manifests", "backstage": { "role": "common-library" diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index ed05f6dc0e..ad70afb07e 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,210 @@ # @backstage/repo-tools +## 0.15.4-next.1 + +### Patch Changes + +- 8f56eae: Updated knip-reports to detect dependencies in dev/alpha pattern +- Updated dependencies + - @backstage/backend-plugin-api@1.5.0-next.1 + +## 0.15.4-next.0 + +### Patch Changes + +- 05f60e1: Refactored constructor parameter properties to explicit property declarations for compatibility with TypeScript's `erasableSyntaxOnly` setting. This internal refactoring maintains all existing functionality while ensuring TypeScript compilation compatibility. +- Updated dependencies + - @backstage/config-loader@1.10.6-next.0 + - @backstage/cli-node@0.2.15-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/backend-plugin-api@1.4.5-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## 0.15.3 + +### Patch Changes + +- 1359279: Fixed an issue with the OpenAPI generated client and server where import/export statements were duplicated. +- Updated dependencies + - @backstage/config-loader@1.10.5 + - @backstage/backend-plugin-api@1.4.4 + +## 0.15.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.4-next.0 + - @backstage/backend-plugin-api@1.4.4-next.0 + - @backstage/cli-node@0.2.14 + +## 0.15.2 + +### Patch Changes + +- 133ac7a: Fixed knip-reports command failing when workspace path contains spaces and process termination issues by replacing `execFile` with `spawn` and removing `shell` option. +- Updated dependencies + - @backstage/config-loader@1.10.3 + - @backstage/backend-plugin-api@1.4.3 + +## 0.15.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.3-next.0 + +## 0.15.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.3-next.0 + +## 0.15.1 + +### Patch Changes + +- 33060b5: Removed build-in ignore of the `packages/canon` package for knip reports. +- 225d7c2: Added `stringEnums` to `mustache` templates +- Updated dependencies + - @backstage/cli-node@0.2.14 + - @backstage/backend-plugin-api@1.4.2 + +## 0.15.1-next.1 + +### Patch Changes + +- 33060b5: Removed build-in ignore of the `packages/canon` package for knip reports. + +## 0.15.1-next.0 + +### Patch Changes + +- 225d7c2: Added `stringEnums` to `mustache` templates +- Updated dependencies + - @backstage/backend-plugin-api@1.4.2-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## 0.15.0 + +### Minor Changes + +- 1e7082e: Clear output directory before running `package-docs` and skip all internal packages. + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-plugin-api@1.4.1 + +## 0.15.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config-loader@1.10.2-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-plugin-api@1.4.1-next.0 + +## 0.15.0-next.0 + +### Minor Changes + +- 1e7082e: Clear output directory before running `package-docs` and skip all internal packages. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## 0.14.0 + +### Minor Changes + +- bf9a173: Add support for caching the per-package output from the `package-docs` command. + +### Patch Changes + +- 4bff5d0: Fixed a bug where linting would fail with the generated clients when defining top-level `enum` schema values. +- 2d20024: Fix an issue where errors were not printed to console when running `backstage-repo-tools schema openapi generate` without the `--watch` flag. +- e643ee4: Add missing highlight language for the `package-docs` command. +- c83cd8b: Fixed some circular or otherwise unclear imports +- a372bf1: Updated dependency `@electric-sql/pglite` to `^0.3.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + +## 0.14.0-next.2 + +### Patch Changes + +- 4bff5d0: Fixed a bug where linting would fail with the generated clients when defining top-level `enum` schema values. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + +## 0.14.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + +## 0.14.0-next.0 + +### Minor Changes + +- bf9a173: Add support for caching the per-package output from the `package-docs` command. + +### Patch Changes + +- 2d20024: Fix an issue where errors were not printed to console when running `backstage-repo-tools schema openapi generate` without the `--watch` flag. +- e643ee4: Add missing highlight language for the `package-docs` command. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + +## 0.13.3 + +### Patch Changes + +- b229476: Support passing additional properties to OpenAPI server generator +- 659f2ce: Updated dependency `typedoc` to `^0.28.0`. +- 72d019d: Removed various typos +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/backend-plugin-api@1.3.1 + - @backstage/config-loader@1.10.1 + - @backstage/cli-node@0.2.13 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + ## 0.13.3-next.3 ### Patch Changes diff --git a/packages/repo-tools/knip-report.md b/packages/repo-tools/knip-report.md index 5eec8fdd29..f87d954145 100644 --- a/packages/repo-tools/knip-report.md +++ b/packages/repo-tools/knip-report.md @@ -1,25 +1,24 @@ # Knip report -## Unused dependencies (5) +## Unused dependencies (4) | Name | Location | Severity | | :---------------------------------- | :----------- | :------- | -| @openapitools/openapi-generator-cli | package.json | error | -| @stoplight/spectral-runtime | package.json | error | -| @electric-sql/pglite | package.json | error | -| is-glob | package.json | error | -| glob | package.json | error | +| @openapitools/openapi-generator-cli | packages/repo-tools/package.json | error | +| @stoplight/spectral-runtime | packages/repo-tools/package.json | error | +| @electric-sql/pglite | packages/repo-tools/package.json | error | +| is-glob | packages/repo-tools/package.json | error | ## Unused devDependencies (2) | Name | Location | Severity | | :------------- | :----------- | :------- | -| @types/is-glob | package.json | error | -| typedoc | package.json | error | +| @types/is-glob | packages/repo-tools/package.json | error | +| typedoc | packages/repo-tools/package.json | error | ## Referenced optional peerDependencies (1) | Name | Location | Severity | | :------- | :----------- | :------- | -| prettier | package.json | error | +| prettier | packages/repo-tools/package.json | error | diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 2aa4e1d80d..f6de3a7cba 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/repo-tools", - "version": "0.13.3-next.3", + "version": "0.15.4-next.1", "description": "CLI for Backstage repo tooling ", "backstage": { "role": "cli" @@ -49,7 +49,7 @@ "@backstage/cli-node": "workspace:^", "@backstage/config-loader": "workspace:^", "@backstage/errors": "workspace:^", - "@electric-sql/pglite": "^0.2.15", + "@electric-sql/pglite": "^0.3.0", "@manypkg/get-packages": "^1.1.3", "@microsoft/api-documenter": "^7.25.7", "@microsoft/api-extractor": "^7.47.2", @@ -69,6 +69,7 @@ "commander": "^12.0.0", "fs-extra": "^11.2.0", "glob": "^8.0.3", + "globby": "^11.0.0", "is-glob": "^4.0.3", "js-yaml": "^4.1.0", "just-diff": "^6.0.2", @@ -81,7 +82,8 @@ "portfinder": "^1.0.32", "tar": "^6.1.12", "ts-morph": "^24.0.0", - "yaml-diff-patch": "^2.0.0" + "yaml-diff-patch": "^2.0.0", + "zod": "^3.22.4" }, "devDependencies": { "@backstage/backend-test-utils": "workspace:^", diff --git a/packages/repo-tools/src/commands/knip-reports/knip-extractor.ts b/packages/repo-tools/src/commands/knip-reports/knip-extractor.ts index 763989f9c7..af3e32d2f4 100644 --- a/packages/repo-tools/src/commands/knip-reports/knip-extractor.ts +++ b/packages/repo-tools/src/commands/knip-reports/knip-extractor.ts @@ -21,11 +21,6 @@ import fs from 'fs-extra'; import type { KnipConfig } from 'knip'; import { createBinRunner } from '../util'; -// Ignore these -const ignoredPackages = [ - 'packages/canon', // storybook config is different from the rest -]; - interface KnipExtractionOptions { packageDirs: string[]; isLocalBuild: boolean; @@ -63,7 +58,7 @@ async function generateKnipConfig({ knipConfigPath }: KnipConfigOptions) { workspaces: { '.': {}, '{packages,plugins}/*': { - entry: ['dev/index.{ts,tsx}', 'src/index.{ts,tsx}'], + entry: ['dev/**/*.{ts,tsx}', 'src/index.{ts,tsx}'], ignore: [ '.eslintrc.js', 'config.d.ts', @@ -104,23 +99,24 @@ async function handlePackage({ isLocalBuild, }: KnipPackageOptions) { console.log(`## Processing ${packageDir}`); - if (ignoredPackages.includes(packageDir)) { - console.log(`Skipping ${packageDir}`); - return; - } + const fullDir = cliPaths.resolveTargetRoot(packageDir); const reportPath = resolvePath(fullDir, 'knip-report.md'); const run = createBinRunner(cliPaths.targetRoot, ''); let report = await run( `${knipDir}/knip.js`, - `-W ${packageDir}`, // Run the desired workspace - '--config knip.json', + '-W', // Run the desired workspace + packageDir, + '--config', + 'knip.json', '--no-exit-code', // Removing this will end the process in case there are findings by knip '--no-progress', // Remove unnecessary debugging from output // TODO: Add more checks when dependencies start to look ok, see https://knip.dev/reference/cli#--include - '--include dependencies,unlisted', - '--reporter markdown', + '--include', + 'dependencies,unlisted', + '--reporter', + 'markdown', ); // Adjust report paths to be relative to workspace diff --git a/packages/repo-tools/src/commands/package-docs/Cache.test.ts b/packages/repo-tools/src/commands/package-docs/Cache.test.ts new file mode 100644 index 0000000000..3fe52dcabd --- /dev/null +++ b/packages/repo-tools/src/commands/package-docs/Cache.test.ts @@ -0,0 +1,178 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Lockfile } from '@backstage/cli-node'; +import { PackageDocsCache } from './Cache'; +import { + createMockDirectory, + MockDirectory, +} from '@backstage/backend-test-utils'; +import { readFile } from 'fs/promises'; +import { join as joinPath } from 'path'; + +jest.mock('crypto', () => { + const hash = { + update: jest.fn(), + digest: jest.fn().mockReturnValue('test'), + }; + return { + createHash: jest.fn().mockReturnValue(hash), + }; +}); + +describe('PackageDocsCache', () => { + let testDir: MockDirectory; + beforeAll(async () => { + testDir = createMockDirectory(); + }); + afterEach(async () => { + testDir.clear(); + }); + it('should be able to parse cache files', async () => { + testDir.addContent({ + '.cache': { + 'package-docs': { + test: { + 'cache.json': JSON.stringify({ + hash: 'test', + packageName: 'test', + restoreTo: 'test', + version: '1', + }), + }, + }, + }, + test: { + 'package.json': JSON.stringify({ + name: '@test/test', + }), + }, + }); + const lockfile = { + getDependencyTreeHash: () => 'test', + } as any as Lockfile; + const cache = await PackageDocsCache.loadAsync(testDir.path, lockfile); + expect(await cache.has('test')).toBe(true); + }); + + it('should be able to restore cache', async () => { + testDir.addContent({ + '.cache': { + 'package-docs': { + test: { + 'cache.json': JSON.stringify({ + hash: 'test', + packageName: 'test', + restoreTo: 'test', + version: '1', + }), + contents: { + 'src/index.ts': 'export const test = "test";', + }, + }, + }, + }, + test: { + 'package.json': JSON.stringify({ + name: '@test/test', + }), + }, + }); + const lockfile = { + getDependencyTreeHash: () => 'test', + } as any as Lockfile; + const cache = await PackageDocsCache.loadAsync(testDir.path, lockfile); + await cache.restore('test'); + expect( + await readFile(joinPath(testDir.path, 'test', 'src/index.ts'), 'utf-8'), + ).toBe('export const test = "test";'); + }); + + it('should be able to write cache', async () => { + testDir.addContent({ + '.cache': {}, + test: { + 'package.json': JSON.stringify({ + name: '@test/test', + }), + 'src/index.ts': 'export const test = "test";', + }, + }); + const lockfile = { + getDependencyTreeHash: () => 'test', + } as any as Lockfile; + const cache = await PackageDocsCache.loadAsync(testDir.path, lockfile); + await cache.write('test', joinPath(testDir.path, 'test')); + expect( + await readFile( + joinPath(testDir.path, '.cache', 'package-docs', 'test', 'cache.json'), + 'utf-8', + ), + ).toBe( + JSON.stringify({ + hash: 'test', + packageName: '@test/test', + restoreTo: 'test', + version: '1', + }), + ); + expect( + await readFile( + joinPath( + testDir.path, + '.cache', + 'package-docs', + 'test', + 'contents', + 'src/index.ts', + ), + 'utf-8', + ), + ).toBe('export const test = "test";'); + }); + + it.each([ + { + content: JSON.stringify({ + hash: 'test', + packageName: 'test', + restoreTo: 'test', + version: '2', + }), + }, + { + content: JSON.stringify({ + hash: 'test', + packageName: 1, + }), + }, + ])('should skip invalid cache files', async content => { + testDir.addContent({ + '.cache': {}, + test: { + 'package.json': JSON.stringify({ + name: '@test/test', + }), + }, + 'cache.json': content, + }); + const lockfile = { + getDependencyTreeHash: () => 'test', + } as any as Lockfile; + const cache = await PackageDocsCache.loadAsync(testDir.path, lockfile); + expect(await cache.has('test')).toBe(false); + }); +}); diff --git a/packages/repo-tools/src/commands/package-docs/Cache.ts b/packages/repo-tools/src/commands/package-docs/Cache.ts new file mode 100644 index 0000000000..ec0811b77a --- /dev/null +++ b/packages/repo-tools/src/commands/package-docs/Cache.ts @@ -0,0 +1,165 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { readFile, writeFile, cp } from 'fs/promises'; +import globby from 'globby'; +import { dirname, join as joinPath, relative } from 'path'; +import crypto from 'crypto'; +import { Lockfile } from '@backstage/cli-node'; +import { exists, rm, mkdirp } from 'fs-extra'; +import { z } from 'zod'; +import { CACHE_DIR, CACHE_FILE } from './constants'; + +const version = '1'; + +interface CacheEntry { + hash: string; + packageName: string; + restoreTo: string; + version: string; +} + +const cacheEntrySchema = z.object({ + hash: z.string(), + packageName: z.string(), + restoreTo: z.string(), + version: z.string(), +}); + +export class PackageDocsCache { + // A map of package directory to package hash. + private keyCache: Map; + private readonly lockfile: Lockfile; + // A map of package directory to cache entry. + private readonly cache: Map; + private readonly baseDirectory: string; + + constructor( + lockfile: Lockfile, + cache: Map, + baseDirectory: string, + ) { + this.lockfile = lockfile; + this.cache = cache; + this.baseDirectory = baseDirectory; + this.keyCache = new Map(); + } + static async loadAsync(baseDirectory: string, lockfile: Lockfile) { + const cacheDir = joinPath(baseDirectory, CACHE_DIR); + await mkdirp(cacheDir); + const cacheFiles = await globby(`**/${CACHE_FILE}`, { + cwd: cacheDir, + }); + const map = new Map(); + for (const file of cacheFiles) { + const pkg = dirname(file); + const cache = await readFile(joinPath(cacheDir, file), 'utf-8'); + try { + const cacheJson = JSON.parse(cache); + const parsed = cacheEntrySchema.parse(cacheJson); + if (parsed.version !== version) { + console.warn( + `Skipping cache file ${file} due to version mismatch: ${parsed.version} !== ${version}`, + ); + continue; + } + map.set(pkg, parsed); + } catch (e) { + console.error(`Skipping unparseable cache file ${file}: ${e}`); + } + } + return new PackageDocsCache(lockfile, map, baseDirectory); + } + + async directoryToName(directory: string) { + const packageJson = await readFile( + joinPath(this.baseDirectory, directory, 'package.json'), + 'utf-8', + ); + return JSON.parse(packageJson).name; + } + + private async toKey(pkg: string) { + if (this.keyCache.has(pkg)) { + return this.keyCache.get(pkg)!; + } + const name = await this.directoryToName(pkg); + const result = await globby('src/**', { + gitignore: true, + onlyFiles: true, + cwd: pkg, + }); + + const hash = crypto.createHash('sha1'); + hash.update(version); + hash.update('\0'); + + for (const path of result.sort()) { + const absPath = joinPath(this.baseDirectory, pkg, path); + const pathInPackage = joinPath(absPath, path); + hash.update(pathInPackage); + hash.update('\0'); + hash.update(await readFile(absPath)); + hash.update('\0'); + } + hash.update(this.lockfile.getDependencyTreeHash(name)); + hash.update('\0'); + const hashString = hash.digest('hex'); + this.keyCache.set(pkg, hashString); + return hashString; + } + + async has(pkg: string) { + const cache = this.cache.get(pkg); + if (!cache) { + return false; + } + const hashString = await this.toKey(pkg); + return cache.hash === hashString; + } + + async restore(pkg: string) { + if (!this.has(pkg)) { + throw new Error(`Cache entry for ${pkg} not found`); + } + const cacheEntry = this.cache.get(pkg); + const restoreTo = cacheEntry!.restoreTo; + const cacheDir = joinPath(this.baseDirectory, CACHE_DIR, pkg); + const contentsDir = joinPath(cacheDir, 'contents'); + + const targetDir = joinPath(this.baseDirectory, restoreTo); + await mkdirp(targetDir); + await cp(contentsDir, targetDir, { recursive: true }); + } + + async write(pkg: string, contentDirectory: string) { + const cacheDir = joinPath(this.baseDirectory, CACHE_DIR, pkg); + const contentsDir = joinPath(cacheDir, 'contents'); + if (await exists(contentsDir)) { + await rm(contentsDir, { recursive: true }); + } else { + await mkdirp(contentsDir); + } + const hashString = await this.toKey(pkg); + await cp(contentDirectory, contentsDir, { recursive: true }); + const cacheEntry: CacheEntry = { + hash: hashString, + packageName: await this.directoryToName(pkg), + restoreTo: relative(this.baseDirectory, contentDirectory), + version, + }; + await writeFile(joinPath(cacheDir, CACHE_FILE), JSON.stringify(cacheEntry)); + } +} diff --git a/packages/repo-tools/src/commands/package-docs/command.ts b/packages/repo-tools/src/commands/package-docs/command.ts index 8c30b06145..174a1d949d 100644 --- a/packages/repo-tools/src/commands/package-docs/command.ts +++ b/packages/repo-tools/src/commands/package-docs/command.ts @@ -17,8 +17,12 @@ import { exec } from 'child_process'; import { promisify } from 'util'; import { paths as cliPaths, resolvePackagePaths } from '../../lib/paths'; import { createTemporaryTsConfig } from './utils'; -import { mkdir, readFile, writeFile } from 'fs/promises'; +import { readFile, rm, writeFile } from 'fs/promises'; import pLimit from 'p-limit'; +import { mkdirp } from 'fs-extra'; +import { PackageDocsCache } from './Cache'; +import { Lockfile } from '@backstage/cli-node'; +import { glob } from 'glob'; const limit = pLimit(8); @@ -38,6 +42,7 @@ const EXCLUDE = [ 'packages/techdocs-cli-embedded-app', 'packages/yarn-plugin', 'packages/backend', + 'packages/backend-legacy', ]; const HIGHLIGHT_LANGUAGES = [ @@ -52,6 +57,7 @@ const HIGHLIGHT_LANGUAGES = [ 'diff', 'js', 'json', + 'docker', ]; function getExports(packageJson: any) { @@ -75,60 +81,104 @@ async function generateDocJson(pkg: string) { !exports.length || !exports.some(e => e.startsWith('src') || e.startsWith('./src')) ) { - return; + return false; } - try { - await mkdir(cliPaths.resolveTargetRoot(`dist-types`, pkg), { - recursive: true, - }); + await mkdirp(cliPaths.resolveTargetRoot(`dist-types`, pkg)); - const { stdout, stderr } = await execAsync( - [ - cliPaths.resolveTargetRoot('node_modules/.bin/typedoc'), - '--json', - cliPaths.resolveTargetRoot(`dist-types`, pkg, 'docs.json'), - '--tsconfig', - temporaryTsConfigPath, - '--basePath', - cliPaths.targetRoot, - '--skipErrorChecking', - ...(getExports(packageJson).flatMap(e => [ - '--entryPoints', - e, - ]) as string[]), - ].join(' '), - { - cwd: pkg, - env: { ...process.env, NODE_OPTIONS: '--max-old-space-size=12288' }, - }, - ); - console.log(`### Processed ${pkg}`); - console.log(stdout); - console.error(stderr); - } catch (e) { - console.error('Failed to generate docs for', pkg); - console.error(e); - } + const { stdout, stderr } = await execAsync( + [ + cliPaths.resolveTargetRoot('node_modules/.bin/typedoc'), + '--json', + cliPaths.resolveTargetRoot(`dist-types`, pkg, 'docs.json'), + '--tsconfig', + temporaryTsConfigPath, + '--basePath', + cliPaths.targetRoot, + '--skipErrorChecking', + ...(getExports(packageJson).flatMap(e => [ + '--entryPoints', + e, + ]) as string[]), + ].join(' '), + { + cwd: pkg, + env: { ...process.env, NODE_OPTIONS: '--max-old-space-size=12288' }, + }, + ); + console.log(`### Processed ${pkg}`); + console.log(stdout); + console.error(stderr); + return true; } export default async function packageDocs(paths: string[] = [], opts: any) { console.warn('!!! This is an experimental command !!!'); + + const existingDocsJsonPaths = glob.sync( + cliPaths.resolveTargetRoot('dist-types/**/docs.json'), + ); + if (existingDocsJsonPaths.length > 0) { + console.warn( + `!!! Deleting all ${existingDocsJsonPaths.length} existing docs.json files !!!`, + ); + + for (const path of existingDocsJsonPaths) { + await rm(path, { force: true }); + } + } + console.warn('!!! Deleting existing docs output !!!'); + await rm(cliPaths.resolveTargetRoot('type-docs'), { + recursive: true, + force: true, + }); const selectedPackageDirs = await resolvePackagePaths({ paths, include: opts.include, exclude: opts.exclude, }); + const cache = await PackageDocsCache.loadAsync( + cliPaths.resolveTargetRoot(), + await Lockfile.load(cliPaths.resolveTargetRoot('yarn.lock')), + ); + console.log(`### Generating docs.`); await Promise.all( selectedPackageDirs.map(pkg => limit(async () => { - if (EXCLUDE.includes(pkg)) { + const pkgJson = JSON.parse( + await readFile( + cliPaths.resolveTargetRoot(pkg, 'package.json'), + 'utf-8', + ), + ); + if (EXCLUDE.includes(pkg) || pkgJson.name.startsWith('@internal/')) { return; } - console.log(`### Processing ${pkg}`); - await generateDocJson(pkg); + if (await cache.has(pkg)) { + console.log(`### Skipping ${pkg} due to cache hit`); + try { + await cache.restore(pkg); + return; + } catch (e) { + console.error('Failed to restore cache for', pkg); + console.error(e); + } + } + try { + console.log(`### Processing ${pkg}`); + const success = await generateDocJson(pkg); + if (success) { + await cache.write( + pkg, + cliPaths.resolveTargetRoot(`dist-types`, pkg), + ); + } + } catch (e) { + console.error('Failed to generate docs for', pkg); + console.error(e); + } }), ), ); diff --git a/packages/repo-tools/src/commands/package-docs/constants.ts b/packages/repo-tools/src/commands/package-docs/constants.ts new file mode 100644 index 0000000000..a8372afad8 --- /dev/null +++ b/packages/repo-tools/src/commands/package-docs/constants.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const CACHE_FILE = 'cache.json'; +export const CACHE_DIR = '.cache/package-docs'; diff --git a/packages/repo-tools/src/commands/package/schema/openapi/generate/client.ts b/packages/repo-tools/src/commands/package/schema/openapi/generate/client.ts index edcb49a9be..8a8817c721 100644 --- a/packages/repo-tools/src/commands/package/schema/openapi/generate/client.ts +++ b/packages/repo-tools/src/commands/package/schema/openapi/generate/client.ts @@ -28,6 +28,7 @@ import { getPathToCurrentOpenApiSpec, toGeneratorAdditionalProperties, } from '../../../../../lib/openapi/helpers'; +import { deduplicateImports } from '../../../../../lib/openapi/dedupe-imports'; async function generate( outputDirectory: string, @@ -101,6 +102,14 @@ async function generate( }); } + // Deduplicate imports in generated files + const generatedFiles = await fs.readdir(resolvedOutputDirectory); + for (const file of generatedFiles) { + if (file.endsWith('.ts')) { + deduplicateImports(resolve(resolvedOutputDirectory, file)); + } + } + fs.removeSync(resolve(resolvedOutputDirectory, '.openapi-generator-ignore')); fs.rmSync(resolve(resolvedOutputDirectory, '.openapi-generator'), { diff --git a/packages/repo-tools/src/commands/package/schema/openapi/generate/index.ts b/packages/repo-tools/src/commands/package/schema/openapi/generate/index.ts index bda80d2fb1..822c644c55 100644 --- a/packages/repo-tools/src/commands/package/schema/openapi/generate/index.ts +++ b/packages/repo-tools/src/commands/package/schema/openapi/generate/index.ts @@ -95,6 +95,7 @@ export async function command(opts: OptionValues) { try { await sharedCommand(); } catch (err) { + console.error(chalk.red('Error: ', err)); process.exit(1); } } diff --git a/packages/repo-tools/src/commands/package/schema/openapi/generate/server.ts b/packages/repo-tools/src/commands/package/schema/openapi/generate/server.ts index 1a8dd36cab..130c93cf71 100644 --- a/packages/repo-tools/src/commands/package/schema/openapi/generate/server.ts +++ b/packages/repo-tools/src/commands/package/schema/openapi/generate/server.ts @@ -14,24 +14,25 @@ * limitations under the License. */ +import { resolvePackagePath } from '@backstage/backend-plugin-api'; import chalk from 'chalk'; -import { resolve, dirname, join } from 'path'; +import fs from 'fs-extra'; import YAML from 'js-yaml'; +import { dirname, join, resolve } from 'path'; +import { exec } from '../../../../../lib/exec'; import { OLD_SCHEMA_PATH, OPENAPI_IGNORE_FILES, OUTPUT_PATH, TS_SCHEMA_PATH, } from '../../../../../lib/openapi/constants'; -import { paths as cliPaths } from '../../../../../lib/paths'; -import fs from 'fs-extra'; -import { exec } from '../../../../../lib/exec'; -import { resolvePackagePath } from '@backstage/backend-plugin-api'; +import { deduplicateImports } from '../../../../../lib/openapi/dedupe-imports'; import { getPathToCurrentOpenApiSpec, getRelativePathToFile, toGeneratorAdditionalProperties, } from '../../../../../lib/openapi/helpers'; +import { paths as cliPaths } from '../../../../../lib/paths'; async function generateSpecFile() { const openapiPath = await getPathToCurrentOpenApiSpec(); @@ -60,7 +61,7 @@ async function generateSpecFile() { // * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * // ****************************************************************** import {createValidatedOpenApiRouterFromGeneratedEndpointMap} from '@backstage/backend-openapi-utils'; -import {EndpointMap} from './'; +import {EndpointMap} from './apis'; export const spec = ${JSON.stringify(yaml, null, 2)} as const; export const createOpenApiRouter = async ( options?: Parameters['1'], @@ -133,6 +134,14 @@ async function generate( }, ); + // Deduplicate imports in generated files + const generatedFiles = await fs.readdir(resolvedOutputDirectory); + for (const file of generatedFiles) { + if (file.endsWith('.ts')) { + deduplicateImports(resolve(resolvedOutputDirectory, file)); + } + } + await exec( `yarn backstage-cli package lint --fix ${resolvedOutputDirectory}`, [], diff --git a/packages/repo-tools/src/commands/util.ts b/packages/repo-tools/src/commands/util.ts index ff4cdad1b8..c232a8aff2 100644 --- a/packages/repo-tools/src/commands/util.ts +++ b/packages/repo-tools/src/commands/util.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { execFile } from 'child_process'; +import { spawn } from 'child_process'; import os from 'os'; import pLimit from 'p-limit'; @@ -29,26 +29,43 @@ export function createBinRunner(cwd: string, path: string) { limiter( () => new Promise((resolve, reject) => { - execFile( - 'node', - [path, ...command], - { - cwd, - shell: true, - timeout: 3 * 60 * 1000, - maxBuffer: 1024 * 1024, - }, - (err, stdout, stderr) => { - if (err) { - console.log('err', err); - reject(new Error(`${err.message}\n${stderr}`)); - } else if (stderr) { - reject(new Error(`Command printed error output: ${stderr}`)); - } else { - resolve(stdout); - } - }, - ); + // Handle the case where path is empty and the script path is the first command argument + const args = path ? [path, ...command] : command; + const child = spawn('node', args, { + cwd, + stdio: ['ignore', 'pipe', 'pipe'], + }); + + let stdout = ''; + let stderr = ''; + + child.stdout?.on('data', data => { + stdout += data.toString(); + }); + + child.stderr?.on('data', data => { + stderr += data.toString(); + }); + + child.on('error', err => { + reject(new Error(`Process error: ${err.message}`)); + }); + + child.on('close', (code, signal) => { + if (signal) { + reject( + new Error( + `Process was killed with signal ${signal}\n${stderr}`, + ), + ); + } else if (code !== 0) { + reject(new Error(`Process exited with code ${code}\n${stderr}`)); + } else if (stderr.trim()) { + reject(new Error(`Command printed error output: ${stderr}`)); + } else { + resolve(stdout); + } + }); }), ); } diff --git a/packages/repo-tools/src/lib/openapi/dedupe-imports.ts b/packages/repo-tools/src/lib/openapi/dedupe-imports.ts new file mode 100644 index 0000000000..c398a43e82 --- /dev/null +++ b/packages/repo-tools/src/lib/openapi/dedupe-imports.ts @@ -0,0 +1,74 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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'; + +/** + * Removes duplicate import and export statements from TypeScript/JavaScript files. + * Preserves different import syntaxes, multi-line imports, and code structure. + * + * @param filePath - Absolute path to the file to deduplicate + */ +export function deduplicateImports(filePath: string): void { + const content = fs.readFileSync(filePath, 'utf8'); + const lines = content.split('\n'); + const seen = new Set(); + const result: string[] = []; + let i = 0; + + while (i < lines.length) { + const line = lines[i]; + const trimmed = line.trim(); + + // Handle import/export statements + if (trimmed.startsWith('import ') || trimmed.startsWith('export ')) { + let fullStatement = line; + let endIndex = i; + + // Check if multi-line (has { but no }) + if (trimmed.includes('{') && !trimmed.includes('}')) { + // Collect full multi-line statement + while (endIndex < lines.length && !lines[endIndex].includes('}')) { + endIndex++; + } + if (endIndex < lines.length) { + fullStatement = lines.slice(i, endIndex + 1).join('\n'); + } + } + + // Normalize for comparison (remove comments, extra spaces) + const normalized = fullStatement + .replace(/\/\/.*$/gm, '') + .replace(/\s+/g, ' ') + .trim(); + + if (!seen.has(normalized)) { + seen.add(normalized); + // Add all lines of the statement + for (let j = i; j <= endIndex; j++) { + result.push(lines[j]); + } + } + + i = endIndex + 1; + } else { + result.push(line); + i++; + } + } + + fs.writeFileSync(filePath, result.join('\n')); +} diff --git a/packages/repo-tools/src/lib/openapi/helpers.ts b/packages/repo-tools/src/lib/openapi/helpers.ts index 868623b874..0eaa090ac4 100644 --- a/packages/repo-tools/src/lib/openapi/helpers.ts +++ b/packages/repo-tools/src/lib/openapi/helpers.ts @@ -14,14 +14,13 @@ * limitations under the License. */ -import { pathExists } from 'fs-extra'; -import { paths } from '../paths'; -import { YAML_SCHEMA_PATH } from './constants'; -import { resolve } from 'path'; +import Parser from '@apidevtools/swagger-parser'; +import fs, { pathExists } from 'fs-extra'; import YAML from 'js-yaml'; import { cloneDeep } from 'lodash'; -import Parser from '@apidevtools/swagger-parser'; -import fs from 'fs-extra'; +import { resolve } from 'path'; +import { paths } from '../paths'; +import { YAML_SCHEMA_PATH } from './constants'; export const getPathToFile = async (directory: string, filename: string) => { return resolve(directory, filename); diff --git a/packages/repo-tools/templates/typescript-backstage-client/modelEnum.mustache b/packages/repo-tools/templates/typescript-backstage-client/modelEnum.mustache index 3a1b5ce86d..09bc5bdbca 100644 --- a/packages/repo-tools/templates/typescript-backstage-client/modelEnum.mustache +++ b/packages/repo-tools/templates/typescript-backstage-client/modelEnum.mustache @@ -17,15 +17,4 @@ export enum {{classname}} { * @public */ export type {{classname}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}}; - -/** - * @public - */ -export const {{classname}} = { -{{#allowableValues}} -{{#enumVars}} - {{name}}: {{{value}}} as {{classname}}{{^-last}},{{/-last}} -{{/enumVars}} -{{/allowableValues}} -}; {{/stringEnums}} diff --git a/packages/repo-tools/templates/typescript-backstage-server/modelEnum.mustache b/packages/repo-tools/templates/typescript-backstage-server/modelEnum.mustache index 3a1b5ce86d..09bc5bdbca 100644 --- a/packages/repo-tools/templates/typescript-backstage-server/modelEnum.mustache +++ b/packages/repo-tools/templates/typescript-backstage-server/modelEnum.mustache @@ -17,15 +17,4 @@ export enum {{classname}} { * @public */ export type {{classname}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}}; - -/** - * @public - */ -export const {{classname}} = { -{{#allowableValues}} -{{#enumVars}} - {{name}}: {{{value}}} as {{classname}}{{^-last}},{{/-last}} -{{/enumVars}} -{{/allowableValues}} -}; {{/stringEnums}} diff --git a/packages/scaffolder-internal/CHANGELOG.md b/packages/scaffolder-internal/CHANGELOG.md index 01824c4df6..3b3a6f7c8c 100644 --- a/packages/scaffolder-internal/CHANGELOG.md +++ b/packages/scaffolder-internal/CHANGELOG.md @@ -1,5 +1,140 @@ # @internal/scaffolder +## 0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.3-next.0 + - @backstage/frontend-plugin-api@0.12.2-next.0 + +## 0.0.14 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.2 + - @backstage/frontend-plugin-api@0.12.1 + +## 0.0.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.2-next.0 + - @backstage/frontend-plugin-api@0.12.1-next.0 + +## 0.0.13 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.12.0 + - @backstage/plugin-scaffolder-react@1.19.1 + +## 0.0.13-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.1-next.0 + - @backstage/plugin-scaffolder-react@1.19.1-next.1 + +## 0.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-scaffolder-react@1.19.1-next.0 + +## 0.0.12 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.11.0 + - @backstage/plugin-scaffolder-react@1.19.0 + +## 0.0.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.19.0-next.1 + - @backstage/frontend-plugin-api@0.11.0-next.0 + +## 0.0.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.18.1-next.0 + - @backstage/frontend-plugin-api@0.10.4 + +## 0.0.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.18.0 + - @backstage/frontend-plugin-api@0.10.4 + +## 0.0.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.18.0-next.2 + +## 0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## 0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/frontend-plugin-api@0.10.3 + +## 0.0.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.1 + - @backstage/plugin-scaffolder-react@1.16.1-next.2 + +## 0.0.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.16.1-next.1 + - @backstage/frontend-plugin-api@0.10.3-next.0 + +## 0.0.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3-next.0 + - @backstage/plugin-scaffolder-react@1.16.1-next.0 + +## 0.0.9 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.2 + - @backstage/plugin-scaffolder-react@1.16.0 + ## 0.0.9-next.3 ### Patch Changes diff --git a/packages/scaffolder-internal/package.json b/packages/scaffolder-internal/package.json index dc727b99d3..256ec5b5e3 100644 --- a/packages/scaffolder-internal/package.json +++ b/packages/scaffolder-internal/package.json @@ -1,6 +1,6 @@ { "name": "@internal/scaffolder", - "version": "0.0.9-next.3", + "version": "0.0.15-next.0", "backstage": { "role": "web-library", "inline": true diff --git a/packages/scaffolder-internal/src/wiring/InternalFormField.ts b/packages/scaffolder-internal/src/wiring/InternalFormField.ts index 5d7bf1ee7d..b711341ea5 100644 --- a/packages/scaffolder-internal/src/wiring/InternalFormField.ts +++ b/packages/scaffolder-internal/src/wiring/InternalFormField.ts @@ -17,12 +17,10 @@ import { OpaqueType } from '@internal/opaque'; import { z } from 'zod'; -import { FormFieldExtensionData } from '@backstage/plugin-scaffolder-react/alpha'; - -/** @alpha */ -export interface FormField { - readonly $$type: '@backstage/scaffolder/FormField'; -} +import { + FormFieldExtensionData, + FormField, +} from '@backstage/plugin-scaffolder-react/alpha'; /** @alpha */ export const OpaqueFormField = OpaqueType.create<{ diff --git a/packages/scaffolder-internal/src/wiring/index.ts b/packages/scaffolder-internal/src/wiring/index.ts index 37c8bd09cb..5195a1fa64 100644 --- a/packages/scaffolder-internal/src/wiring/index.ts +++ b/packages/scaffolder-internal/src/wiring/index.ts @@ -13,5 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { OpaqueFormField, type FormField } from './InternalFormField'; +export { OpaqueFormField } from './InternalFormField'; export { OpaqueFormDecorator } from './InternalFormDecorator'; diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 4e504b8f60..3fe53ec2d6 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,398 @@ # techdocs-cli-embedded-app +## 0.2.114-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.2 + - @backstage/plugin-techdocs@1.16.0-next.1 + - @backstage/plugin-catalog@1.32.0-next.1 + - @backstage/cli@0.34.5-next.1 + - @backstage/core-components@0.18.3-next.1 + - @backstage/core-plugin-api@1.11.2-next.1 + - @backstage/core-app-api@1.19.2-next.1 + +## 0.2.114-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/ui@0.9.0-next.1 + +## 0.2.114-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.5-next.0 + - @backstage/ui@0.8.2-next.0 + - @backstage/plugin-techdocs@1.15.2-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/core-components@0.18.3-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/app-defaults@1.7.2-next.0 + - @backstage/integration-react@1.2.12-next.0 + - @backstage/test-utils@1.7.13-next.0 + - @backstage/theme@0.7.0 + - @backstage/plugin-catalog@1.31.5-next.0 + - @backstage/plugin-techdocs-react@1.3.5-next.0 + +## 0.2.113 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2 + - @backstage/cli@0.34.4 + - @backstage/config@1.3.5 + - @backstage/theme@0.7.0 + - @backstage/plugin-catalog@1.31.4 + - @backstage/app-defaults@1.7.1 + - @backstage/test-utils@1.7.12 + - @backstage/plugin-techdocs@1.15.1 + - @backstage/plugin-techdocs-react@1.3.4 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/integration-react@1.2.11 + +## 0.2.113-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.4-next.2 + - @backstage/core-components@0.18.2-next.2 + - @backstage/theme@0.6.9-next.0 + - @backstage/app-defaults@1.7.1-next.2 + - @backstage/test-utils@1.7.12-next.1 + - @backstage/plugin-techdocs@1.15.1-next.2 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + +## 0.2.113-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/cli@0.34.4-next.1 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-components@0.18.2-next.1 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/integration-react@1.2.11-next.1 + - @backstage/test-utils@1.7.12-next.0 + - @backstage/plugin-techdocs@1.15.1-next.1 + - @backstage/plugin-techdocs-react@1.3.4-next.1 + - @backstage/app-defaults@1.7.1-next.1 + - @backstage/plugin-catalog@1.31.4-next.1 + +## 0.2.113-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.18.2-next.0 + - @backstage/cli@0.34.4-next.0 + - @backstage/plugin-catalog@1.31.4-next.0 + - @backstage/plugin-techdocs@1.15.1-next.0 + - @backstage/app-defaults@1.7.1-next.0 + - @backstage/integration-react@1.2.11-next.0 + - @backstage/plugin-techdocs-react@1.3.4-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.19.0 + - @backstage/core-plugin-api@1.11.0 + - @backstage/test-utils@1.7.11 + - @backstage/theme@0.6.8 + +## 0.2.112 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.2 + - @backstage/plugin-techdocs@1.15.0 + - @backstage/app-defaults@1.7.0 + - @backstage/plugin-techdocs-react@1.3.3 + - @backstage/core-plugin-api@1.11.0 + - @backstage/plugin-catalog@1.31.3 + - @backstage/core-components@0.18.0 + - @backstage/core-app-api@1.19.0 + - @backstage/integration-react@1.2.10 + +## 0.2.112-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.2-next.1 + - @backstage/core-components@0.17.6-next.0 + - @backstage/plugin-catalog@1.31.3-next.1 + - @backstage/plugin-techdocs@1.14.2-next.1 + - @backstage/plugin-techdocs-react@1.3.3-next.0 + - @backstage/integration-react@1.2.10-next.0 + - @backstage/app-defaults@1.6.6-next.0 + +## 0.2.112-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.1-next.0 + - @backstage/plugin-techdocs@1.14.2-next.0 + - @backstage/plugin-catalog@1.31.3-next.0 + - @backstage/app-defaults@1.6.5 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-components@0.17.5 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/test-utils@1.7.11 + - @backstage/theme@0.6.8 + - @backstage/plugin-techdocs-react@1.3.2 + +## 0.2.111 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2 + - @backstage/core-components@0.17.5 + - @backstage/cli@0.34.0 + - @backstage/plugin-techdocs@1.14.0 + - @backstage/theme@0.6.8 + - @backstage/app-defaults@1.6.5 + - @backstage/test-utils@1.7.11 + - @backstage/plugin-techdocs-react@1.3.2 + +## 0.2.111-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.34.0-next.1 + - @backstage/plugin-techdocs@1.14.0-next.2 + - @backstage/plugin-catalog@1.31.2-next.2 + - @backstage/core-components@0.17.5-next.1 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + - @backstage/test-utils@1.7.11-next.0 + - @backstage/theme@0.6.8-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + +## 0.2.111-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.1 + - @backstage/plugin-techdocs@1.14.0-next.1 + - @backstage/theme@0.6.8-next.0 + - @backstage/cli@0.33.2-next.0 + - @backstage/plugin-techdocs-react@1.3.2-next.0 + - @backstage/app-defaults@1.6.5-next.0 + - @backstage/core-components@0.17.5-next.0 + - @backstage/test-utils@1.7.11-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/integration-react@1.2.9 + +## 0.2.111-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.2-next.0 + - @backstage/plugin-techdocs@1.13.3-next.0 + - @backstage/cli@0.33.1 + - @backstage/integration-react@1.2.9 + +## 0.2.110 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2 + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/cli@0.33.1 + - @backstage/plugin-catalog@1.31.1 + - @backstage/core-components@0.17.4 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-app-api@1.18.0 + - @backstage/integration-react@1.2.9 + - @backstage/app-defaults@1.6.4 + - @backstage/test-utils@1.7.10 + - @backstage/plugin-techdocs-react@1.3.1 + +## 0.2.110-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.33.1-next.2 + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-components@0.17.4-next.2 + - @backstage/app-defaults@1.6.4-next.2 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/test-utils@1.7.10-next.2 + - @backstage/plugin-catalog@1.31.1-next.2 + - @backstage/plugin-techdocs@1.13.2-next.1 + +## 0.2.110-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/cli@0.33.1-next.1 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-components@0.17.4-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/integration-react@1.2.9-next.1 + - @backstage/test-utils@1.7.10-next.1 + - @backstage/plugin-techdocs@1.13.2-next.1 + - @backstage/plugin-techdocs-react@1.3.1-next.1 + - @backstage/plugin-catalog@1.31.1-next.1 + - @backstage/app-defaults@1.6.4-next.1 + +## 0.2.110-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/test-utils@1.7.10-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + +## 0.2.109 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/test-utils@1.7.9 + - @backstage/theme@0.6.6 + +## 0.2.109-next.3 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.33.0-next.2 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.3-next.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration-react@1.2.7 + - @backstage/test-utils@1.7.8 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + +## 0.2.109-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3-next.0 + - @backstage/cli@0.33.0-next.1 + - @backstage/plugin-catalog@1.31.0-next.2 + - @backstage/plugin-techdocs@1.13.0-next.2 + - @backstage/app-defaults@1.6.3-next.0 + - @backstage/integration-react@1.2.7 + - @backstage/plugin-techdocs-react@1.3.0-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/test-utils@1.7.8 + - @backstage/theme@0.6.6 + +## 0.2.109-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.32.2-next.0 + - @backstage/plugin-techdocs@1.13.0-next.1 + - @backstage/plugin-catalog@1.31.0-next.1 + - @backstage/app-defaults@1.6.2 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.0 + - @backstage/core-components@0.17.2 + - @backstage/core-plugin-api@1.10.7 + - @backstage/integration-react@1.2.7 + - @backstage/test-utils@1.7.8 + - @backstage/theme@0.6.6 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + +## 0.2.109-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.0-next.0 + - @backstage/plugin-catalog@1.31.0-next.0 + - @backstage/plugin-techdocs-react@1.3.0-next.0 + - @backstage/cli@0.32.1 + - @backstage/integration-react@1.2.7 + +## 0.2.108 + +### Patch Changes + +- Updated dependencies + - @backstage/test-utils@1.7.8 + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/cli@0.32.1 + - @backstage/core-components@0.17.2 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-techdocs@1.12.6 + - @backstage/plugin-catalog@1.30.0 + - @backstage/plugin-techdocs-react@1.2.17 + - @backstage/core-plugin-api@1.10.7 + - @backstage/app-defaults@1.6.2 + - @backstage/config@1.3.2 + - @backstage/integration-react@1.2.7 + ## 0.2.108-next.3 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/app-config.yaml b/packages/techdocs-cli-embedded-app/app-config.yaml index 6ede05b587..c8dfa1683c 100644 --- a/packages/techdocs-cli-embedded-app/app-config.yaml +++ b/packages/techdocs-cli-embedded-app/app-config.yaml @@ -7,3 +7,7 @@ backend: techdocs: builder: 'external' + sanitizer: + # Allow live reload locally. Added in this config to avoid updating the main techdocs plugin. + allowedCustomElementTagNameRegExp: '^live-reload$' + allowedCustomElementAttributeNameRegExp: '^live-reload-(epoch|request-id)$' diff --git a/packages/techdocs-cli-embedded-app/knip-report.md b/packages/techdocs-cli-embedded-app/knip-report.md index 96aa361a87..3711ac996d 100644 --- a/packages/techdocs-cli-embedded-app/knip-report.md +++ b/packages/techdocs-cli-embedded-app/knip-report.md @@ -4,14 +4,14 @@ | Name | Location | Severity | | :-------- | :----------- | :------- | -| react-use | package.json | error | -| history | package.json | error | +| react-use | packages/techdocs-cli-embedded-app/package.json | error | +| history | packages/techdocs-cli-embedded-app/package.json | error | ## Unused devDependencies (3) | Name | Location | Severity | | :-------------------------- | :----------- | :------- | -| @testing-library/user-event | package.json | error | -| @testing-library/dom | package.json | error | -| cross-env | package.json | error | +| @testing-library/user-event | packages/techdocs-cli-embedded-app/package.json | error | +| @testing-library/dom | packages/techdocs-cli-embedded-app/package.json | error | +| cross-env | packages/techdocs-cli-embedded-app/package.json | error | diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 0683378df9..024d8039cd 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,6 +1,6 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.108-next.3", + "version": "0.2.114-next.2", "backstage": { "role": "frontend" }, @@ -45,6 +45,7 @@ "@backstage/plugin-techdocs-react": "workspace:^", "@backstage/test-utils": "workspace:^", "@backstage/theme": "workspace:^", + "@backstage/ui": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "history": "^5.0.0", diff --git a/packages/techdocs-cli-embedded-app/public/index.html b/packages/techdocs-cli-embedded-app/public/index.html index 18bb3f50a9..196c711417 100644 --- a/packages/techdocs-cli-embedded-app/public/index.html +++ b/packages/techdocs-cli-embedded-app/public/index.html @@ -4,6 +4,7 @@ + @@ -71,6 +80,7 @@ const routes = ( > {techDocsPage} + diff --git a/packages/techdocs-cli-embedded-app/src/LiveReloadAddon.test.tsx b/packages/techdocs-cli-embedded-app/src/LiveReloadAddon.test.tsx new file mode 100644 index 0000000000..1a80def9e9 --- /dev/null +++ b/packages/techdocs-cli-embedded-app/src/LiveReloadAddon.test.tsx @@ -0,0 +1,111 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { render } from '@testing-library/react'; +import { TechDocsLiveReload } from './LiveReloadAddon'; + +jest.mock('@backstage/plugin-techdocs-react', () => ({ + useShadowRootElements: jest.fn(() => [ + { + querySelector: jest.fn((selector: string) => { + if (selector === 'live-reload') { + return { + getAttribute: (name: string) => { + if (name === 'live-reload-epoch') return '10'; + if (name === 'live-reload-request-id') return '1'; + return null; + }, + }; + } + return null; + }), + }, + ]), +})); + +describe('TechDocsLiveReload', () => { + const originalXHR = global.XMLHttpRequest; + let originalLocation: Location; + let openSpy: jest.Mock; + let sendSpy: jest.Mock; + + beforeEach(() => { + originalLocation = window.location; + openSpy = jest.fn(); + sendSpy = jest.fn(function (this: any) { + // simulate long-poll response that does NOT trigger reload (epoch unchanged) + setTimeout(() => { + (this as any).status = 200; + (this as any).responseText = '10'; + (this as any).onloadend?.call(this); + }, 0); + }); + + class MockXHR { + onloadend: ((this: any) => void) | null = null; + status = 0; + responseText = ''; + open = openSpy; + send = sendSpy as any; + abort = jest.fn(); + } + + global.XMLHttpRequest = MockXHR as any; + + // Replace window.location with a mutable object for tests + delete (window as any).location; + (window as any).location = { ...originalLocation, reload: jest.fn() }; + jest.spyOn(window, 'addEventListener').mockImplementation(() => {}); + jest.spyOn(window, 'removeEventListener').mockImplementation(() => {}); + Object.defineProperty(document, 'visibilityState', { + value: 'visible', + configurable: true, + }); + }); + + afterEach(() => { + global.XMLHttpRequest = originalXHR; + jest.restoreAllMocks(); + // restore original window.location + delete (window as any).location; + (window as any).location = originalLocation; + }); + + it('polls livereload endpoint and does not reload when epoch unchanged', async () => { + const reloadSpy = window.location.reload as unknown as jest.Mock; + render(); + expect(openSpy).toHaveBeenCalledWith('GET', '/.livereload/10/1'); + // give microtask queue a tick + await new Promise(res => setTimeout(res, 0)); + expect(reloadSpy).not.toHaveBeenCalled(); + }); + + it('reloads when server epoch increases', async () => { + const reloadSpy = window.location.reload as unknown as jest.Mock; + + sendSpy.mockImplementation(function (this: any) { + setTimeout(() => { + (this as any).status = 200; + (this as any).responseText = '11'; + (this as any).onloadend?.call(this); + }, 0); + }); + + render(); + await new Promise(res => setTimeout(res, 0)); + expect(reloadSpy).toHaveBeenCalled(); + }); +}); diff --git a/packages/techdocs-cli-embedded-app/src/LiveReloadAddon.tsx b/packages/techdocs-cli-embedded-app/src/LiveReloadAddon.tsx new file mode 100644 index 0000000000..905a339c72 --- /dev/null +++ b/packages/techdocs-cli-embedded-app/src/LiveReloadAddon.tsx @@ -0,0 +1,121 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useShadowRootElements } from '@backstage/plugin-techdocs-react'; +import { useEffect, useRef } from 'react'; + +interface TechDocsLiveReloadProps { + /** Whether to enable livereload (default: true in development) */ + enabled?: boolean; +} + +/** + * LiveReload addon for Techdocs CLI. + * + * Support mkdocs built-in livereload, in a TechDocs CLI preview environment. + * See https://github.com/backstage/backstage/issues/30514 for more details. + */ +export const TechDocsLiveReload = ({ + enabled = true, +}: TechDocsLiveReloadProps) => { + const body = useShadowRootElements(['body']); + const reqRef = useRef(null); + const timeoutRef = useRef(null); + const LIVE_RELOAD_ELEMENT = 'live-reload'; + const LIVE_RELOAD_ATTR_EPOCH = 'live-reload-epoch'; + const LIVE_RELOAD_ATTR_REQUEST_ID = 'live-reload-request-id'; + const CLI_LIVERELOAD_PATH = '/.livereload'; + + useEffect(() => { + if (!enabled || !body[0]) { + return undefined; + } + + const liveReloadElement = body[0].querySelector(LIVE_RELOAD_ELEMENT); + + if (!liveReloadElement) { + return undefined; + } + + const epoch = parseInt( + liveReloadElement.getAttribute(LIVE_RELOAD_ATTR_EPOCH) || '0', + 10, + ); + const requestId = parseInt( + liveReloadElement.getAttribute(LIVE_RELOAD_ATTR_REQUEST_ID) || '0', + 10, + ); + + if (!epoch || !requestId) { + return undefined; + } + + const livereloadUrl = CLI_LIVERELOAD_PATH; + + const poll = () => { + reqRef.current = new XMLHttpRequest(); + reqRef.current.onloadend = function handleLoadEnd(this: XMLHttpRequest) { + if (parseFloat(this.responseText) > epoch) { + window.location.reload(); + } else { + timeoutRef.current = setTimeout(poll, this.status === 200 ? 0 : 3000); + } + }; + reqRef.current.open('GET', `${livereloadUrl}/${epoch}/${requestId}`); + reqRef.current.send(); + }; + + const stop = () => { + if (reqRef.current) { + reqRef.current.abort(); + reqRef.current = null; + } + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + timeoutRef.current = null; + } + }; + + // Stop when tab is inactive + const handleVisibilityChange = () => { + if (document.visibilityState === 'visible') { + poll(); + } else { + stop(); + } + }; + + const handleBeforeUnload = () => { + stop(); + }; + + // Start polling if page is visible + if (document.visibilityState === 'visible') { + poll(); + } + + document.addEventListener('visibilitychange', handleVisibilityChange); + window.addEventListener('beforeunload', handleBeforeUnload); + + return () => { + stop(); + document.removeEventListener('visibilitychange', handleVisibilityChange); + window.removeEventListener('beforeunload', handleBeforeUnload); + }; + }, [body, enabled]); + + return null; +}; diff --git a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx index 479ad3161d..dfe728da86 100644 --- a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx +++ b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx @@ -49,15 +49,15 @@ const useStyles = makeStyles((theme: Theme) => ({ }, })); -enum Themes { - LIGHT = 'light', - DARK = 'dark', -} +const Themes = { + LIGHT: 'light', + DARK: 'dark', +} as const; export const TechDocsThemeToggle = () => { const appThemeApi = useApi(appThemeApiRef); const classes = useStyles(); - const [theme, setTheme] = useState( + const [theme, setTheme] = useState<(typeof Themes)[keyof typeof Themes]>( appThemeApi.getActiveThemeId() === Themes.DARK ? Themes.DARK : Themes.LIGHT, ); diff --git a/packages/techdocs-cli-embedded-app/src/index.tsx b/packages/techdocs-cli-embedded-app/src/index.tsx index 81b80e9bcc..f50db079b0 100644 --- a/packages/techdocs-cli-embedded-app/src/index.tsx +++ b/packages/techdocs-cli-embedded-app/src/index.tsx @@ -16,6 +16,7 @@ import '@backstage/cli/asset-types'; import ReactDOM from 'react-dom/client'; +import '@backstage/ui/css/styles.css'; import App from './App'; ReactDOM.createRoot(document.getElementById('root')!).render(); diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 3ce409bbc4..13413f46c8 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,170 @@ # @techdocs/cli +## 1.10.1-next.0 + +### Patch Changes + +- c2a2017: Fix for missing styles due to move to BUI. +- Updated dependencies + - @backstage/backend-defaults@0.13.1-next.0 + - @backstage/plugin-techdocs-node@1.13.9-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/catalog-model@1.7.6-next.0 + - @backstage/cli-common@0.1.15 + +## 1.10.0 + +### Minor Changes + +- 43afbe5: Techdocs CLI serve supports automatic refresh, relying on `mkdocs` `watch` feature. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0 + - @backstage/config@1.3.5 + - @backstage/plugin-techdocs-node@1.13.8 + +## 1.9.9-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/backend-defaults@0.13.0-next.1 + - @backstage/plugin-techdocs-node@1.13.8-next.1 + +## 1.9.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.13.0-next.0 + - @backstage/plugin-techdocs-node@1.13.8-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + +## 1.9.8 + +### Patch Changes + +- db63208: Fixed an issue where `@techdocs/cli serve` command did not pick up the latest changes to TechDocs. +- Updated dependencies + - @backstage/backend-defaults@0.12.1 + - @backstage/plugin-techdocs-node@1.13.7 + +## 1.9.8-next.0 + +### Patch Changes + +- db63208: Fixed an issue where `@techdocs/cli serve` command did not pick up the latest changes to TechDocs. +- Updated dependencies + - @backstage/backend-defaults@0.12.1-next.0 + - @backstage/plugin-techdocs-node@1.13.7-next.0 + +## 1.9.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.12.0 + - @backstage/plugin-techdocs-node@1.13.6 + +## 1.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.2-next.0 + - @backstage/plugin-techdocs-node@1.13.6-next.0 + - @backstage/catalog-model@1.7.5 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.3 + +## 1.9.5 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/catalog-model@1.7.5 + - @backstage/backend-defaults@0.11.1 + - @backstage/plugin-techdocs-node@1.13.5 + +## 1.9.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/catalog-model@1.7.5-next.0 + - @backstage/backend-defaults@0.11.1-next.1 + - @backstage/plugin-techdocs-node@1.13.5-next.1 + +## 1.9.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-techdocs-node@1.13.5-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## 1.9.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4 + +## 1.9.4-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0-next.2 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## 1.9.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4-next.1 + +## 1.9.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.1-next.0 + - @backstage/plugin-techdocs-node@1.13.4-next.0 + +## 1.9.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.10.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-techdocs-node@1.13.3 + - @backstage/config@1.3.2 + - @backstage/cli-common@0.1.15 + ## 1.9.3-next.3 ### Patch Changes diff --git a/packages/techdocs-cli/knip-report.md b/packages/techdocs-cli/knip-report.md index 5948844a00..f13d2d7ab6 100644 --- a/packages/techdocs-cli/knip-report.md +++ b/packages/techdocs-cli/knip-report.md @@ -4,12 +4,12 @@ | Name | Location | Severity | | :----------- | :----------- | :------- | -| global-agent | package.json | error | +| global-agent | packages/techdocs-cli/package.json | error | ## Unused devDependencies (2) | Name | Location | Severity | | :------------------------ | :----------- | :------- | -| techdocs-cli-embedded-app | package.json | error | -| @types/webpack-env | package.json | error | +| techdocs-cli-embedded-app | packages/techdocs-cli/package.json | error | +| @types/webpack-env | packages/techdocs-cli/package.json | error | diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 3034be2715..5f978adada 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,6 +1,6 @@ { "name": "@techdocs/cli", - "version": "1.9.3-next.3", + "version": "1.10.2-next.0", "description": "Utility CLI for managing TechDocs sites in Backstage.", "backstage": { "role": "cli" diff --git a/packages/techdocs-cli/src/lib/httpServer.ts b/packages/techdocs-cli/src/lib/httpServer.ts index c38bc86d7a..d7e8f62ea0 100644 --- a/packages/techdocs-cli/src/lib/httpServer.ts +++ b/packages/techdocs-cli/src/lib/httpServer.ts @@ -18,6 +18,10 @@ import serveHandler from 'serve-handler'; import http from 'http'; import httpProxy from 'http-proxy'; import { createLogger } from './utility'; +import { + proxyHtmlWithLivereloadInjection, + proxyMkdocsLivereload, +} from './livereload'; export default class HTTPServer { private readonly proxyEndpoint: string; @@ -59,8 +63,8 @@ export default class HTTPServer { const proxyHandler = this.createProxy(); const server = http.createServer( (request: http.IncomingMessage, response: http.ServerResponse) => { - // This endpoind is used by the frontend to issue a cookie for the user. - // But the MkDocs server doesn't expose it as a the Backestage backend does. + // This endpoint is used by the frontend to issue a cookie for the user. + // But the MkDocs server doesn't expose it as a the Backstage backend does. // So we need to fake it here to prevent 404 errors. if (request.url === '/api/techdocs/.backstage/auth/v1/cookie') { const oneHourInMilliseconds = 60 * 60 * 1000; @@ -72,6 +76,19 @@ export default class HTTPServer { } if (request.url?.startsWith(this.proxyEndpoint)) { + // Handle HTML files with livereload parameter injection + if (request.url?.endsWith('.html')) { + proxyHtmlWithLivereloadInjection({ + request, + response, + mkdocsTargetAddress: this.mkdocsTargetAddress, + proxyEndpoint: this.proxyEndpoint, + onError: (error: Error) => reject(error), + }); + return; + } + + // Handle non-HTML files with regular proxy const [proxy, forwardPath] = proxyHandler(request); proxy.on('error', (error: Error) => { @@ -93,6 +110,17 @@ export default class HTTPServer { return; } + // This endpoint is used by the frontend to pass livereload requests to the mkdocs server. + if (request.url?.startsWith('/.livereload')) { + proxyMkdocsLivereload({ + request, + response, + mkdocsTargetAddress: this.mkdocsTargetAddress, + onError: (error: Error) => reject(error), + }); + return; + } + serveHandler(request, response, { public: this.backstageBundleDir, trailingSlash: true, diff --git a/packages/techdocs-cli/src/lib/livereload.test.ts b/packages/techdocs-cli/src/lib/livereload.test.ts new file mode 100644 index 0000000000..b21251c45a --- /dev/null +++ b/packages/techdocs-cli/src/lib/livereload.test.ts @@ -0,0 +1,180 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import http from 'http'; +import { + injectLivereloadParameters, + proxyHtmlWithLivereloadInjection, + proxyMkdocsLivereload, +} from './livereload'; + +// Note: This mock returns a singleton proxy object so tests can access the +// registered event handlers (e.g. `proxyRes`) from code under test. +jest.mock('http-proxy', () => { + const handlers: Record = {}; + const fakeProxy = { + on: jest.fn((event: string, cb: Function) => { + handlers[event] = cb; + }), + web: jest.fn((_req: unknown, _res: unknown) => { + // no-op; tests will manually trigger handlers['proxyRes'] when needed + }), + __handlers: handlers, + }; + const create = jest.fn(() => fakeProxy); + return { + __esModule: true, + default: { createProxyServer: create }, + createProxyServer: create, + }; +}); + +describe('livereload helpers', () => { + describe('injectLivereloadParameters', () => { + it('injects live-reload element when mkdocs script is present', () => { + const html = + ''; + const result = injectLivereloadParameters(html); + expect(result).toContain(''); + }); + + it('returns original html when mkdocs script is absent', () => { + const html = '

    No livereload

    '; + const result = injectLivereloadParameters(html); + expect(result).toBe(html); + }); + }); + + describe('proxyHtmlWithLivereloadInjection', () => { + it('injects parameters into HTML responses and sets CORS headers', () => { + const { createProxyServer } = jest.requireMock('http-proxy') as any; + const proxy = createProxyServer(); + + const req = { + url: '/api/techdocs/some/path/index.html', + } as unknown as http.IncomingMessage; + const headers: Record = {}; + const res = { + setHeader: (k: string, v: any) => { + headers[k] = String(v); + }, + end: jest.fn(), + } as unknown as http.ServerResponse; + + proxyHtmlWithLivereloadInjection({ + request: req, + response: res, + mkdocsTargetAddress: 'http://localhost:8000', + proxyEndpoint: '/api/techdocs/', + onError: () => {}, + }); + + // Simulate mkdocs proxy response with HTML + const proxyRes: any = { + headers: { 'content-type': 'text/html; charset=utf-8' }, + on: (event: string, cb: Function) => { + if (event === 'data') { + cb(''); + } + if (event === 'end') { + cb(); + } + }, + pipe: jest.fn(), + }; + + (proxy as any).__handlers.proxyRes(proxyRes, {} as any, res); + + expect(res.end).toHaveBeenCalled(); + const injectedHtml = (res.end as jest.Mock).mock.calls[0][0] as string; + expect(injectedHtml).toContain(' { + const { createProxyServer } = jest.requireMock('http-proxy') as any; + const proxy = createProxyServer(); + + const req = { + url: '/api/techdocs/some/path/asset.css', + } as unknown as http.IncomingMessage; + const headers: Record = {}; + const res = { + setHeader: (k: string, v: any) => { + headers[k] = String(v); + }, + end: jest.fn(), + } as unknown as http.ServerResponse; + + proxyHtmlWithLivereloadInjection({ + request: req, + response: res, + mkdocsTargetAddress: 'http://localhost:8000', + proxyEndpoint: '/api/techdocs/', + onError: () => {}, + }); + + const proxyRes: any = { + headers: { 'content-type': 'text/css' }, + on: jest.fn(), + pipe: jest.fn(), + }; + + (proxy as any).__handlers.proxyRes(proxyRes, {} as any, res); + + expect(res.end).not.toHaveBeenCalled(); + expect(proxyRes.pipe).toHaveBeenCalledWith(res); + expect(headers['Access-Control-Allow-Origin']).toBe('*'); + expect(headers['Access-Control-Allow-Methods']).toBe('GET, OPTIONS'); + }); + }); + + describe('proxyMkdocsLivereload', () => { + it('rewrites path and sets CORS headers', () => { + const { createProxyServer } = jest.requireMock('http-proxy') as any; + const proxy = createProxyServer(); + + const req = { + url: '/.livereload/1/2', + } as unknown as http.IncomingMessage; + const headers: Record = {}; + const res = { + setHeader: (k: string, v: any) => { + headers[k] = String(v); + }, + } as unknown as http.ServerResponse; + + proxyMkdocsLivereload({ + request: req, + response: res, + mkdocsTargetAddress: 'http://localhost:8000', + onError: () => {}, + }); + + expect(req.url).toBe('/livereload/1/2'); + expect(headers['Access-Control-Allow-Origin']).toBe('*'); + expect(headers['Access-Control-Allow-Methods']).toBe('GET, OPTIONS'); + expect(headers['Access-Control-Allow-Headers']).toBe('Content-Type'); + expect((proxy as any).web).toHaveBeenCalled(); + }); + }); +}); diff --git a/packages/techdocs-cli/src/lib/livereload.ts b/packages/techdocs-cli/src/lib/livereload.ts new file mode 100644 index 0000000000..c108971b82 --- /dev/null +++ b/packages/techdocs-cli/src/lib/livereload.ts @@ -0,0 +1,175 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import http from 'http'; +import httpProxy from 'http-proxy'; + +/** + * Livereload support for techdocs-cli. + * + * Context: + * - MkDocs implements autoreload using a long-poll endpoint `/livereload` and a script that injects + * a call like: `livereload(epoch, request_id)`, where `epoch` is derived from Python's + * `time.monotonic()`. + * - Node.js monotonic clocks (`process.hrtime`/`performance.now`) are not compatible with Python's + * value across processes and platforms. We therefore CANNOT reliably re-create the same epoch on + * the frontend or in this CLI, and must read the values produced by MkDocs itself. + * - The MkDocs script tag is removed by DOM sanitization (DomPurify) in TechDocs, so we can't rely + * on the script being present in the embedded app. To bridge this, we extract the parameters on + * the server side while proxying HTML and inject them as a safe custom element that survives + * sanitization: ``. + * - The frontend addon reads that element and polls `/.livereload` (served by techdocs-cli), which + * this module maps to MkDocs `/livereload` with permissive CORS headers. + * - Quality-of-life: if extraction fails or the endpoint is unavailable, normal docs still work. + * + * See issue for background and rationale: https://github.com/backstage/backstage/issues/30514 + */ + +const LIVE_RELOAD_ELEMENT = 'live-reload'; +const LIVE_RELOAD_ATTR_EPOCH = 'live-reload-epoch'; +const LIVE_RELOAD_ATTR_REQUEST_ID = 'live-reload-request-id'; +const CLI_LIVERELOAD_PATH = '/.livereload'; +const MKDOCS_LIVERELOAD_PATH = '/livereload'; +const CONTENT_TYPE_HTML = 'text/html'; +const HEADER_CONTENT_LENGTH = 'content-length'; + +const BODY_START_RE = /]*>/; +// Matches mkdocs injected call livereload(epoch, requestId) +const MKDOCS_LIVERELOAD_CALL_RE = /livereload\(\s*(\d+)\s*,\s*(\d+)\s*\)\s*;?/; + +/** + * Extract livereload parameters from mkdocs HTML and inject them as a custom element. + * The injected element will later be read by the frontend addon even after DOM sanitization. + * + * Note: + * - we don't add to because of DomPurify sanitization. + * - we add close to the body opening to avoid reading too far into the body. + * - we should use streamed injection to improve performance. + */ +export function injectLivereloadParameters(html: string): string { + const livereloadMatch = html.match(MKDOCS_LIVERELOAD_CALL_RE); + + // If we couldn't find livereload parameters, return original HTML untouched. + if (!livereloadMatch) { + return html; + } + + const [, epoch, requestId] = livereloadMatch; + // Insert a minimal custom element that the frontend addon can discover post-sanitization. + // Note: embedded app needs a custom config to allow the element to survive sanitization. + const liveReloadTag = `<${LIVE_RELOAD_ELEMENT} ${LIVE_RELOAD_ATTR_EPOCH}="${epoch}" ${LIVE_RELOAD_ATTR_REQUEST_ID}="${requestId}">`; + + // Naively find where to insert the livereload tag. + const bodyStart = html.match(BODY_START_RE); + const bodyStartIndex = bodyStart?.index ?? 0; + const bodyStartLength = bodyStart?.[0]?.length ?? 0; + if (bodyStartIndex === 0 || bodyStartLength === 0) { + return html; + } + const bodyEndIndex = bodyStartIndex + bodyStartLength; + + return html.slice(0, bodyEndIndex) + liveReloadTag + html.slice(bodyEndIndex); +} + +function setCorsHeaders(response: http.ServerResponse) { + response.setHeader('Access-Control-Allow-Origin', '*'); + response.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS'); +} + +/** + * Proxies a mkdocs HTML response, injecting livereload parameters into the HTML body. + */ +export function proxyHtmlWithLivereloadInjection(options: { + request: http.IncomingMessage; + response: http.ServerResponse; + mkdocsTargetAddress: string; + proxyEndpoint: string; + onError: (error: Error) => void; +}): void { + const { request, response, mkdocsTargetAddress, proxyEndpoint, onError } = + options; + + const htmlProxy = httpProxy.createProxyServer({ + target: mkdocsTargetAddress, + selfHandleResponse: true, + }); + + htmlProxy.on('error', onError); + + // Intercept HTML responses to inject `` + htmlProxy.on('proxyRes', (proxyRes, _req, res) => { + const contentType = proxyRes.headers['content-type']; + const contentEncoding = proxyRes.headers['content-encoding']; + const isHtml = + contentType && + typeof contentType === 'string' && + contentType.startsWith(CONTENT_TYPE_HTML); + if (isHtml && !contentEncoding) { + const chunks: Buffer[] = []; + proxyRes.on('data', (chunk: Buffer | string) => { + chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)); + }); + proxyRes.on('end', () => { + const body = Buffer.concat(chunks).toString('utf8'); + const modifiedHtml = injectLivereloadParameters(body); + res.statusCode = (proxyRes.statusCode as number | undefined) ?? 200; + Object.keys(proxyRes.headers).forEach(key => { + if (key.toLowerCase() !== HEADER_CONTENT_LENGTH) { + res.setHeader(key, proxyRes.headers[key]!); + } + }); + setCorsHeaders(res); + res.end(modifiedHtml); + }); + } else { + res.statusCode = (proxyRes.statusCode as number | undefined) ?? 200; + Object.keys(proxyRes.headers).forEach(key => { + res.setHeader(key, proxyRes.headers[key]!); + }); + setCorsHeaders(res); + proxyRes.pipe(res); + } + }); + + const forwardPath = + request.url?.replace(new RegExp(`^${proxyEndpoint}`, 'i'), '') || ''; + request.url = forwardPath; + htmlProxy.web(request, response); +} + +/** + * Proxies mkdocs livereload long-polling requests, mapping the CLI path to mkdocs path. + */ +export function proxyMkdocsLivereload(options: { + request: http.IncomingMessage; + response: http.ServerResponse; + mkdocsTargetAddress: string; + onError: (error: Error) => void; +}): void { + const { request, response, mkdocsTargetAddress, onError } = options; + + const proxy = httpProxy.createProxyServer({ target: mkdocsTargetAddress }); + proxy.on('error', onError); + + setCorsHeaders(response); + response.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + + request.url = request.url?.replace( + CLI_LIVERELOAD_PATH, + MKDOCS_LIVERELOAD_PATH, + ); + proxy.web(request, response); +} diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index e8acf8edd1..7beeed27c1 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,140 @@ # @backstage/test-utils +## 1.7.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-react@0.4.38-next.0 + - @backstage/core-app-api@1.19.2-next.0 + - @backstage/core-plugin-api@1.11.2-next.0 + - @backstage/config@1.3.6-next.0 + - @backstage/theme@0.7.0 + - @backstage/types@1.2.2 + - @backstage/plugin-permission-common@0.9.3-next.0 + +## 1.7.12 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.5 + - @backstage/theme@0.7.0 + - @backstage/core-app-api@1.19.1 + - @backstage/core-plugin-api@1.11.1 + - @backstage/plugin-permission-common@0.9.2 + - @backstage/plugin-permission-react@0.4.37 + +## 1.7.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.9-next.0 + +## 1.7.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.4-next.0 + - @backstage/core-app-api@1.19.1-next.0 + - @backstage/core-plugin-api@1.11.1-next.0 + - @backstage/plugin-permission-common@0.9.2-next.0 + - @backstage/plugin-permission-react@0.4.37-next.0 + +## 1.7.11 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.8 + +## 1.7.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.8-next.0 + - @backstage/config@1.3.3 + - @backstage/core-app-api@1.18.0 + - @backstage/core-plugin-api@1.10.9 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/plugin-permission-react@0.4.36 + +## 1.7.10 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3 + - @backstage/plugin-permission-common@0.9.1 + - @backstage/core-plugin-api@1.10.9 + - @backstage/theme@0.6.7 + - @backstage/core-app-api@1.18.0 + - @backstage/plugin-permission-react@0.4.36 + +## 1.7.10-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.1 + - @backstage/core-app-api@1.18.0-next.1 + - @backstage/core-plugin-api@1.10.9-next.0 + +## 1.7.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.3-next.0 + - @backstage/plugin-permission-common@0.9.1-next.0 + - @backstage/core-app-api@1.17.2-next.0 + - @backstage/core-plugin-api@1.10.9-next.0 + - @backstage/plugin-permission-react@0.4.36-next.0 + +## 1.7.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## 1.7.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## 1.7.8 + +### Patch Changes + +- b573341: Added support for interpolating JSX elements with the `MockTranslationApi`. +- Updated dependencies + - @backstage/theme@0.6.6 + - @backstage/core-app-api@1.17.0 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/core-plugin-api@1.10.7 + - @backstage/config@1.3.2 + - @backstage/plugin-permission-react@0.4.34 + - @backstage/types@1.2.1 + ## 1.7.8-next.2 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 0824422425..b40fa8a0d8 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/test-utils", - "version": "1.7.8-next.2", + "version": "1.7.13-next.0", "description": "Utilities to test Backstage plugins and apps.", "backstage": { "role": "web-library" diff --git a/packages/theme/CHANGELOG.md b/packages/theme/CHANGELOG.md index e7e3b98236..1b5b158102 100644 --- a/packages/theme/CHANGELOG.md +++ b/packages/theme/CHANGELOG.md @@ -1,5 +1,64 @@ # @backstage/theme +## 0.7.0 + +### Minor Changes + +- 865bce8: **BREAKING**: Removed the built-in `CssBaseline` from `UnifiedThemeProvider`. If your Backstage instance looks broken after this update, you likely forgot to add our new Backstage UI global CSS. To do that, please import `@backstage/ui/css/styles.css` in `packages/app/src/index.tsx`: + + ```tsx + import '@backstage/ui/css/styles.css'; + ``` + + This change also removes the `noCssBaseline` prop, which became redundant. + +### Patch Changes + +- d5cbdba: The `UnifiedThemeProvider` now coordinates theme attributes on the document `body` in case multiple theme providers are rendered. + +## 0.6.9-next.0 + +### Patch Changes + +- d5cbdba: The `UnifiedThemeProvider` now coordinates theme attributes on the document `body` in case multiple theme providers are rendered. + +## 0.6.8 + +### Patch Changes + +- b731527: We are introducing two new data attributes on the `body` to support Backstage UI (BUI) new theming system. + +## 0.6.8-next.0 + +### Patch Changes + +- b731527: We are introducing two new data attributes on the `body` to support Backstage UI (BUI) new theming system. + +## 0.6.7 + +### Patch Changes + +- 373486e: Add a different background colour to focused `MenuItem`s to fix a bug in MUI 4 (which is fixed in MUI 5) +- b68d269: Update uncomfortably bright color in recently visited and top visited home page cards + +## 0.6.7-next.1 + +### Patch Changes + +- 373486e: Add a different background colour to focused `MenuItem`s to fix a bug in MUI 4 (which is fixed in MUI 5) + +## 0.6.7-next.0 + +### Patch Changes + +- b68d269: Update uncomfortably bright color in recently visited and top visited home page cards + +## 0.6.6 + +### Patch Changes + +- 1b14572: Show arrow when MuiTableSortLabel receives focus + ## 0.6.6-next.0 ### Patch Changes diff --git a/packages/theme/knip-report.md b/packages/theme/knip-report.md index 9aa0ae1d46..270d625e91 100644 --- a/packages/theme/knip-report.md +++ b/packages/theme/knip-report.md @@ -4,5 +4,5 @@ | Name | Location | Severity | | :--------------- | :----------- | :------- | -| react-router-dom | package.json | error | +| react-router-dom | packages/theme/package.json | error | diff --git a/packages/theme/package.json b/packages/theme/package.json index acf9b891d4..cb7d5c12ce 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/theme", - "version": "0.6.6-next.0", + "version": "0.7.0", "description": "material-ui theme for use with Backstage.", "backstage": { "role": "web-library" diff --git a/packages/theme/report.api.md b/packages/theme/report.api.md index ebdae12a05..18ac96ecec 100644 --- a/packages/theme/report.api.md +++ b/packages/theme/report.api.md @@ -459,8 +459,6 @@ export interface UnifiedThemeProviderProps { // (undocumented) children: ReactNode; // (undocumented) - noCssBaseline?: boolean; - // (undocumented) theme: UnifiedTheme; } ``` diff --git a/packages/theme/src/base/pageTheme.ts b/packages/theme/src/base/pageTheme.ts index 12a73b6089..3e1e8641fc 100644 --- a/packages/theme/src/base/pageTheme.ts +++ b/packages/theme/src/base/pageTheme.ts @@ -50,7 +50,7 @@ export const colorVariants: Record = { rubyRed: ['#98002B', '#8D1134'], toastyOrange: ['#BE2200', '#A41D00'], purpleSky: ['#8912CA', '#3E00EA'], - eveningSea: ['#00FFF2', '#035355'], + eveningSea: ['#00CFC5', '#035355'], teal: ['#005B4B'], pinkSea: ['#C8077A', '#C2297D'], greens: ['#4BB8A5', '#187656'], diff --git a/packages/theme/src/unified/UnifiedThemeProvider.tsx b/packages/theme/src/unified/UnifiedThemeProvider.tsx index 32b0fd2708..d0886cd146 100644 --- a/packages/theme/src/unified/UnifiedThemeProvider.tsx +++ b/packages/theme/src/unified/UnifiedThemeProvider.tsx @@ -15,7 +15,6 @@ */ import { ReactNode } from 'react'; -import CssBaseline from '@material-ui/core/CssBaseline'; import { ThemeProvider, StylesProvider, @@ -38,7 +37,6 @@ import { unstable_ClassNameGenerator as ClassNameGenerator } from '@mui/material export interface UnifiedThemeProviderProps { children: ReactNode; theme: UnifiedTheme; - noCssBaseline?: boolean; } /** @@ -58,6 +56,8 @@ const generateV4ClassName = createGenerateClassName({ productionPrefix: 'jss4-', }); +import { useApplyThemeAttributes } from './useApplyThemeAttributes'; + /** * Provides themes for all Material UI versions supported by the provided unified theme. * @@ -66,23 +66,18 @@ const generateV4ClassName = createGenerateClassName({ export function UnifiedThemeProvider( props: UnifiedThemeProviderProps, ): JSX.Element { - const { children, theme, noCssBaseline = false } = props; + const { children, theme } = props; const v4Theme = theme.getTheme('v4') as Mui4Theme; const v5Theme = theme.getTheme('v5') as Mui5Theme; - let cssBaseline: JSX.Element | undefined = undefined; - if (!noCssBaseline) { - cssBaseline = ; - } - - let result = ( - <> - {cssBaseline} - {children} - + useApplyThemeAttributes( + v4Theme ? v4Theme.palette.type : v5Theme?.palette.mode, + 'backstage', ); + let result = children as JSX.Element; + if (v4Theme) { result = ( diff --git a/packages/theme/src/unified/useApplyThemeAttributes.test.tsx b/packages/theme/src/unified/useApplyThemeAttributes.test.tsx new file mode 100644 index 0000000000..b6c1ec1852 --- /dev/null +++ b/packages/theme/src/unified/useApplyThemeAttributes.test.tsx @@ -0,0 +1,60 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '@testing-library/jest-dom'; +import { renderHook } from '@testing-library/react'; +import { useApplyThemeAttributes } from './useApplyThemeAttributes'; + +describe('useApplyThemeAttributes', () => { + beforeEach(() => { + document.body.removeAttribute('data-unified-theme-stack'); + document.body.removeAttribute('data-theme-mode'); + document.body.removeAttribute('data-theme-name'); + }); + + it('pushes attributes on mount and pops on unmount', () => { + const { unmount } = renderHook(() => + useApplyThemeAttributes('light', 'one'), + ); + expect(document.body.getAttribute('data-theme-mode')).toBe('light'); + expect(document.body.getAttribute('data-theme-name')).toBe('one'); + expect( + JSON.parse(document.body.getAttribute('data-unified-theme-stack') || '[]') + .length, + ).toBe(1); + + unmount(); + expect(document.body.getAttribute('data-theme-mode')).toBeNull(); + expect(document.body.getAttribute('data-theme-name')).toBeNull(); + expect(document.body.getAttribute('data-unified-theme-stack')).toBeNull(); + }); + + it('stacks multiple mounts and applies top-most', () => { + const r1 = renderHook(() => useApplyThemeAttributes('light', 'one')); + const r2 = renderHook(() => useApplyThemeAttributes('dark', 'two')); + + expect(document.body.getAttribute('data-theme-mode')).toBe('dark'); + expect(document.body.getAttribute('data-theme-name')).toBe('two'); + + r2.unmount(); + expect(document.body.getAttribute('data-theme-mode')).toBe('light'); + expect(document.body.getAttribute('data-theme-name')).toBe('one'); + + r1.unmount(); + expect(document.body.getAttribute('data-theme-mode')).toBeNull(); + expect(document.body.getAttribute('data-theme-name')).toBeNull(); + }); +}); diff --git a/packages/theme/src/unified/useApplyThemeAttributes.ts b/packages/theme/src/unified/useApplyThemeAttributes.ts new file mode 100644 index 0000000000..8295d69ec6 --- /dev/null +++ b/packages/theme/src/unified/useApplyThemeAttributes.ts @@ -0,0 +1,72 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useEffect } from 'react'; + +type ThemeFrame = { mode?: string; name?: string }; + +const STACK_ATTR = 'data-unified-theme-stack'; +const MODE_ATTR = 'data-theme-mode'; +const NAME_ATTR = 'data-theme-name'; + +function mutateAttrStack(mutator: (stack: ThemeFrame[]) => void) { + const stack = (() => { + const raw = document.body.getAttribute(STACK_ATTR); + if (!raw) { + return [] as ThemeFrame[]; + } + try { + const parsed = JSON.parse(raw); + return Array.isArray(parsed) ? (parsed as ThemeFrame[]) : []; + } catch { + return [] as ThemeFrame[]; + } + })(); + + mutator(stack); + + if (stack.length === 0) { + document.body.removeAttribute(STACK_ATTR); + } else { + document.body.setAttribute(STACK_ATTR, JSON.stringify(stack)); + } + + const top = stack[stack.length - 1]; + if (top?.mode) { + document.body.setAttribute(MODE_ATTR, String(top.mode)); + } else { + document.body.removeAttribute(MODE_ATTR); + } + if (top?.name) { + document.body.setAttribute(NAME_ATTR, String(top.name)); + } else { + document.body.removeAttribute(NAME_ATTR); + } +} + +export function useApplyThemeAttributes(themeMode: string, themeName: string) { + useEffect(() => { + mutateAttrStack(stack => { + stack.push({ mode: themeMode, name: themeName }); + }); + + return () => { + mutateAttrStack(stack => { + stack.pop(); + }); + }; + }, [themeMode, themeName]); +} diff --git a/packages/theme/src/v5/defaultComponentThemes.ts b/packages/theme/src/v5/defaultComponentThemes.ts index 1d07c318a0..d627ecdcb7 100644 --- a/packages/theme/src/v5/defaultComponentThemes.ts +++ b/packages/theme/src/v5/defaultComponentThemes.ts @@ -269,4 +269,14 @@ export const defaultComponentThemes: ThemeOptions['components'] = { MuiPaper: { styleOverrides: { root: { backgroundImage: 'unset' } }, }, + MuiMenuItem: { + styleOverrides: { + root: ({ theme }) => ({ + // Fixes a bug with MUI 4 that's fixed in MUI 5 + '&:focus': { + backgroundColor: theme.palette.action.focus, + }, + }), + }, + }, }; diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index c6adabdae1..abfaacfd45 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/types +## 1.2.2 + +### Patch Changes + +- a95cebd: Internal refactoring for better type support + ## 1.2.1 ### Patch Changes diff --git a/packages/types/package.json b/packages/types/package.json index 55c3a36f4a..f7dcb5d11f 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/types", - "version": "1.2.1", + "version": "1.2.2", "description": "Common TypeScript types used within Backstage", "backstage": { "role": "common-library" diff --git a/packages/types/src/observable.ts b/packages/types/src/observable.ts index f7292c293c..667875ccd1 100644 --- a/packages/types/src/observable.ts +++ b/packages/types/src/observable.ts @@ -46,7 +46,7 @@ export type Subscription = { // We get the actual runtime polyfill from zen-observable declare global { interface SymbolConstructor { - readonly observable: symbol; + readonly observable: unique symbol; } } diff --git a/packages/canon/.eslintrc.js b/packages/ui/.eslintrc.js similarity index 79% rename from packages/canon/.eslintrc.js rename to packages/ui/.eslintrc.js index f7c0e8cbd1..9638ff6e45 100644 --- a/packages/canon/.eslintrc.js +++ b/packages/ui/.eslintrc.js @@ -3,6 +3,7 @@ module.exports = { extends: ['plugin:storybook/recommended'], rules: { 'react/forbid-elements': 'off', + '@backstage/no-mixed-plugin-imports': 'off' }, }; diff --git a/packages/canon/.gitignore b/packages/ui/.gitignore similarity index 100% rename from packages/canon/.gitignore rename to packages/ui/.gitignore diff --git a/packages/ui/CHANGELOG.md b/packages/ui/CHANGELOG.md new file mode 100644 index 0000000000..254ad0a7a4 --- /dev/null +++ b/packages/ui/CHANGELOG.md @@ -0,0 +1,543 @@ +# @backstage/ui + +## 0.9.0-next.2 + +### Minor Changes + +- 539cf26: **BREAKING**: Migrated Avatar component from Base UI to custom implementation with size changes: + + - Base UI-specific props are no longer supported + - Size values have been updated: + - New `x-small` size added (1.25rem / 20px) + - `small` size unchanged (1.5rem / 24px) + - `medium` size unchanged (2rem / 32px, default) + - `large` size **changed from 3rem to 2.5rem** (40px) + - New `x-large` size added (3rem / 48px) + + Migration: + + ```diff + # Remove Base UI-specific props + - + + + + # Update large size usage to x-large for same visual size + - + + + ``` + + Added `purpose` prop for accessibility control (`'informative'` or `'decoration'`). + +- 134151f: Fixing styles on SearchField in Backstage UI after migration to CSS modules. `SearchField` has now its own set of class names. We previously used class names from `TextField` but this approach was creating some confusion so going forward in your theme you'll be able to theme `TextField` and `SearchField` separately. + +### Patch Changes + +- d01de00: Fix broken external links in Backstage UI Header component. +- deaa427: Fixed Text component to prevent `truncate` prop from being spread to the underlying DOM element. +- 1059f95: Improved the Link component structure in Backstage UI. +- 6874094: Migrated CellProfile component from Base UI Avatar to Backstage UI Avatar component. +- 719d772: Avatar components in x-small and small sizes now display only one initial instead of two, improving readability at smaller dimensions. +- 3b18d80: Fixed RadioGroup radio button ellipse distortion by preventing flex shrink and grow. +- e16ece5: Set the color-scheme property depending on theme + +## 0.9.0-next.1 + +### Minor Changes + +- 5c614ff: **BREAKING**: Migrated Checkbox component from Base UI to React Aria Components. + + API changes required: + + - `checked` → `isSelected` + - `defaultChecked` → `defaultSelected` + - `disabled` → `isDisabled` + - `required` → `isRequired` + - `label` prop removed - use `children` instead + - CSS: `bui-CheckboxLabel` class removed + - Data attribute: `data-checked` → `data-selected` + - Use without label is no longer supported + + Migration examples: + + Before: + + ```tsx + + ``` + + After: + + ```tsx + + Accept terms + + ``` + + Before: + + ```tsx + + ``` + + After: + + ```tsx + Option + ``` + + Before: + + ```tsx + + ``` + + After: + + ```tsx + + Accessible label + + ``` + +- b78fc45: **BREAKING**: Changed className prop behavior to augment default styles instead of being ignored or overriding them. + + Affected components: + + - Menu, MenuListBox, MenuAutocomplete, MenuAutocompleteListbox, MenuItem, MenuListBoxItem, MenuSection, MenuSeparator + - Switch + - Skeleton + - FieldLabel + - Header, HeaderToolbar + - HeaderPage + - Tabs, TabList, Tab, TabPanel + + If you were passing custom className values to any of these components that relied on the previous behavior, you may need to adjust your styles to account for the default classes now being applied alongside your custom classes. + +### Patch Changes + +- ff9f0c3: Enable tree-shaking of imports other than `*.css`. +- 1ef3ca4: Added new VisuallyHidden component for hiding content visually while keeping it accessible to screen readers. + +## 0.8.2-next.0 + +### Patch Changes + +- 26c6a78: Fix default text color in Backstage UI +- dac851f: Fix the default font size in Backstage UI. +- 3c0ea67: Fix CSS layer ordering in Backstage UI to make sure component styles are loaded after tokens and base declarations. +- 4eb455c: Fix font smoothing as default in Backstage UI. +- 00bfb83: Fix default font wight and font family in Backstage UI. + +## 0.8.0 + +### Minor Changes + +- 9acc1d6: **BREAKING**: Added a new `PasswordField` component. As part of this change, the `password` and `search` types have been removed from `TextField`. +- b0d11b5: **BREAKING** Restructure Backstage UI component styling to use CSS Modules instead of pure CSS. We don't expect this to be an issue in practice but it is important to call out that all styles are now loaded through CSS modules with generated class names. We are still providing fixed class names for all components to allow anyone to style their Backstage instance. +- 0c53517: **BREAKING** The ScrollArea component has been removed from Backstage UI because it did not meet our accessibility standards. +- 7b319c5: **BREAKING** Remove Icon component in Backstage UI. This component was creating issue for tree-shaking. It is recommended to use icons from @remixicon/react until we found a better alternative in Backstage UI. + +### Patch Changes + +- 2591b42: Adding a new Dialog component to Backstage UI. +- 827340f: remove default selection of tab +- 5dc17cc: Fix margin utility classes in Backstage UI. +- 85faee0: Fix scroll jumping when opening menu in Backstage UI. +- 3c921c5: Making href mandatory in tabs that are part of a Header component +- df7d2cf: Update react-aria-components to version 1.13.0 +- 507ee55: Fix table sorting icon position in Backstage UI. +- 8b7c3c9: Add new `virtualized`, `maxWidth` and `maxHeight` props to `Menu`, `MenuListBox`, `MenuAutocomplete` and `MenuAutocompleteListBox` to allow for virtalization of long lists inside menus. +- b940062: Added support for data attributes in ``, ``, ``, and `` components, ensuring they are correctly applied to the rendered elements. +- 206c801: Cleaning up Backstage UI props definitions as well as removing ScrollArea in Card to improve accessibility. +- 5c21e45: Add react router for internal routing for ButtonLinks +- 865bce8: Added a background color default on the body +- af4d9b4: We are restructuring our CSS to have a better layer structure. +- 9a47125: Improved SearchField component flex layout and animations. Fixed SearchField behavior in Header components by switching from width-based transitions to flex-basis transitions for better responsive behavior. Added new Storybook stories to test SearchField integration with Header component. +- 9781815: Remove auto selection of tabs for tabs that all have href defined +- 4adbb03: Avoid overriding onChange when spreading props +- f6dff5b: Using react router for internal links in the Menu component + +## 0.7.2-next.2 + +### Patch Changes + +- 3c921c5: Making href mandatory in tabs that are part of a Header component +- 5c21e45: Add react router for internal routing for ButtonLinks +- 9781815: Remove auto selection of tabs for tabs that all have href defined +- f6dff5b: Using react router for internal links in the Menu component + +## 0.7.2-next.1 + +### Patch Changes + +- a9b88be: Enable tooltips on disabled buttons with automatic wrapper +- 4adbb03: Avoid overriding onChange when spreading props + +## 0.7.2-next.0 + +### Patch Changes + +- 827340f: remove default selection of tab +- 9a47125: Improved SearchField component flex layout and animations. Fixed SearchField behavior in Header components by switching from width-based transitions to flex-basis transitions for better responsive behavior. Added new Storybook stories to test SearchField integration with Header component. + +## 0.7.1 + +### Patch Changes + +- 7307930: Add missing class for flex: baseline +- 89da341: Fix Select component to properly attach aria-label and aria-labelledby props to the rendered element for improved accessibility. +- 0ffa4c7: Removed the need to mock `window.matchMedia` in tests, falling back to default breakpoint values instead. + +## 0.7.1-next.0 + +### Patch Changes + +- 7307930: Add missing class for flex: baseline +- 89da341: Fix Select component to properly attach aria-label and aria-labelledby props to the rendered element for improved accessibility. + +## 0.7.0 + +### Minor Changes + +- 0615e54: We are moving our DataTable component to React Aria. We removed our DataTable to only use Table as a single and opinionated option for tables. This new structure is made possible by using React Aria under the hood. +- b245c9d: Backstage UI - HeaderPage - We are updating the breadcrumb to be more visible and accessible. +- 800f593: **Breaking change** We are updating the Menu component to use React Aria under the hood. The structure and all props are changing to follow React Aria's guidance. +- b0e47f3: **Breaking** We are upgrading our `Text` component to support all font sizes making the `Heading` component redundant. The new `Text` component introduces 4 sizes for title and 4 sizes for body text. All of these work in multiple colors and font weights. We improved the `as` prop to include all possible values. The `Link` component has also been updated to match the new `Text` component. + +### Patch Changes + +- de89a3d: Fixes some styles on the Select component in BUI. +- a251b3e: Export CardHeader, CardBody and CardFooter from Card component index +- f761306: Add new TagGroup component to Backstage UI. +- 75fead9: Fixes a couple of small bugs in BUI including setting H1 and H2 correctly on the Header and HeaderPage. +- e7ff178: Update styling of Tooltip element +- 230b410: **Breaking change** Move breadcrumb to fit in the `HeaderPage` instead of the `Header` in Backstage UI. +- 2f9a084: We are motion away from `motion` to use `gsap` instead to make Backstage UI backward compatible with React 17. +- d4e603e: Updated Menu component in Backstage UI to use useId() from React Aria instead of React to support React 17. +- 8bdc491: Remove stylesheet import from Select component. +- 404b426: Add `startCollapsed` prop on the `SearchField` component in BUI. +- e0e886f: Adds onTabSelectionChange to ui header component. + +## 0.7.0-next.3 + +### Minor Changes + +- 0615e54: We are moving our DataTable component to React Aria. We removed our DataTable to only use Table as a single and opinionated option for tables. This new structure is made possible by using React Aria under the hood. + +### Patch Changes + +- 230b410: **Breaking change** Move breadcrumb to fit in the `HeaderPage` instead of the `Header` in Backstage UI. +- 8bdc491: Remove stylesheet import from Select component. +- 404b426: Add `startCollapsed` prop on the `SearchField` component in BUI. + +## 0.7.0-next.2 + +### Patch Changes + +- d4e603e: Updated Menu component in Backstage UI to use useId() from React Aria instead of React to support React 17. + +## 0.7.0-next.1 + +### Patch Changes + +- de89a3d: Fixes some styles on the Select component in BUI. +- 75fead9: Fixes a couple of small bugs in BUI including setting H1 and H2 correctly on the Header and HeaderPage. +- 2f9a084: We are motion away from `motion` to use `gsap` instead to make Backstage UI backward compatible with React 17. + +## 0.7.0-next.0 + +### Minor Changes + +- b0e47f3: **Breaking** We are upgrading our `Text` component to support all font sizes making the `Heading` component redundant. The new `Text` component introduces 4 sizes for title and 4 sizes for body text. All of these work in multiple colors and font weights. We improved the `as` prop to include all possible values. The `Link` component has also been updated to match the new `Text` component. + +### Patch Changes + +- e7ff178: Update styling of Tooltip element +- e0e886f: Adds onTabSelectionChange to ui header component. + +## 0.6.0 + +### Minor Changes + +- e92bb9b: Canon has been renamed to Backstage UI. This means that `@backstage/canon` has been deprecated and replaced by `@backstage/ui`. + +## 0.6.0-next.1 + +### Minor Changes + +- 2e30459: We are moving our Tooltip component to use React Aria under the hood. In doing so, the structure of the component and its prop are changing to follow the new underlying structure. + +### Patch Changes + +- 76255b8: Add new Card component to Canon. +- b0a6c8e: Add new Header component to Canon. +- be76576: Improve Button, ButtonIcon and ButtonLink styling in Canon. +- 17beb9b: Update return types for Heading & Text components for React 19. +- eac4a4c: Add new tertiary variant to Button, ButtonIcon and ButtonLink in Canon. +- 8f2e82d: Add new Skeleton component in Canon + +## 0.6.0-next.0 + +### Minor Changes + +- 4c6d891: **BREAKING CHANGES** + + We’re updating our Button component to provide better support for button links. + + - We’re introducing a new `ButtonLink` component, which replaces the previous render prop pattern. + - To maintain naming consistency across components, `IconButton` is being renamed to `ButtonIcon`. + - Additionally, the render prop will be removed from all button-related components. + + These changes aim to simplify usage and improve clarity in our component API. + +### Patch Changes + +- 140f652: We are consolidating all css files into a single styles.css in Canon. +- 8154fb9: Add new SearchField component in Canon +- 6910892: Add new `RadioGroup` + `Radio` component to Canon +- a8a8514: We are transforming how we structure our class names and data attributes definitions for all components. They are now all set in the same place. +- 667b951: Added placeholder prop to TextField component. +- e71333a: adding export for ButtonLink so it's importable + +## 0.5.0 + +### Minor Changes + +- 621fac9: We are updating the default size of the Button component in Canon to be small instead of medium. +- a842554: We set the default size for IconButton in Canon to be small instead of medium. +- 35fd51d: Move TextField component to use react Aria under the hood. Introducing a new FieldLabel component to help build custom fields. +- 78204a2: **Breaking** We are adding a new as prop on the Heading and Text component to make it easier to change the component tag. We are removing the render prop in favour of the as prop. +- c49e335: TextField in Canon now has multiple label sizes as well as the capacity to hide label and description but still make them available for screen readers. +- 24b45ef: Fixes spacing props on layout components and aligned on naming for the Grid component. You should now call the Grid root component using instead of just . + +### Patch Changes + +- 44df879: Add min-width: 0; by default on every Flex components in Canon to help support truncated texts inside flex elements. +- ee6ffe6: Fix styling for the title4 prop on the Heading component in Canon. +- f2f814a: Added a render prop to the Button component in Canon to use it as a link. +- 98f02a6: Add new Switch component in Canon. +- c94f8e0: The filter input in menu comboboxes should now always use the full width of the menu it's in. +- 269316d: Remove leftover console.log from Container component. + +## 0.5.0-next.2 + +### Patch Changes + +- 44df879: Add min-width: 0; by default on every Flex components in Canon to help support truncated texts inside flex elements. +- ee6ffe6: Fix styling for the title4 prop on the Heading component in Canon. +- f2f814a: Added a render prop to the Button component in Canon to use it as a link. + +## 0.5.0-next.1 + +### Minor Changes + +- 621fac9: We are updating the default size of the Button component in Canon to be small instead of medium. +- a842554: We set the default size for IconButton in Canon to be small instead of medium. + +## 0.5.0-next.0 + +### Minor Changes + +- 24b45ef: Fixes spacing props on layout components and aligned on naming for the Grid component. You should now call the Grid root component using instead of just . + +### Patch Changes + +- 269316d: Remove leftover console.log from Container component. + +## 0.4.0 + +### Minor Changes + +- ea36f74: **Breaking Change** Icons on Button and IconButton now need to be imported and placed like this: