diff --git a/.changeset/afraid-boxes-rhyme.md b/.changeset/afraid-boxes-rhyme.md new file mode 100644 index 0000000000..328a589f7e --- /dev/null +++ b/.changeset/afraid-boxes-rhyme.md @@ -0,0 +1,9 @@ +--- +'@backstage/core-components': patch +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-home': patch +--- + +Add `FavoriteToggle` in `core-components` to standardise favorite marking diff --git a/.changeset/afraid-fans-cross.md b/.changeset/afraid-fans-cross.md new file mode 100644 index 0000000000..1901d8ce0f --- /dev/null +++ b/.changeset/afraid-fans-cross.md @@ -0,0 +1,8 @@ +--- +'@backstage/create-app': patch +'@backstage/cli': patch +--- + +Add `config.d.ts` files to the list of included file in `tsconfig.json`. + +This allows ESLint to detect issues or deprecations in those files. diff --git a/.changeset/angry-hotels-warn.md b/.changeset/angry-hotels-warn.md new file mode 100644 index 0000000000..07caaba574 --- /dev/null +++ b/.changeset/angry-hotels-warn.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-defaults': minor +'@backstage/backend-common': minor +--- + +**BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. diff --git a/.changeset/beige-jobs-begin.md b/.changeset/beige-jobs-begin.md new file mode 100644 index 0000000000..f93e534857 --- /dev/null +++ b/.changeset/beige-jobs-begin.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Remove direct `vite` dependency diff --git a/.changeset/blue-forks-cry.md b/.changeset/blue-forks-cry.md new file mode 100644 index 0000000000..1bcc1d0b59 --- /dev/null +++ b/.changeset/blue-forks-cry.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +--- + +Fix a bug where the signer was checked from the payload instead of the header diff --git a/.changeset/breezy-flowers-dance.md b/.changeset/breezy-flowers-dance.md new file mode 100644 index 0000000000..faa9fd0697 --- /dev/null +++ b/.changeset/breezy-flowers-dance.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Deprecate the `featureDiscoveryServiceFactory` in favor of using `@backstage/backend-defaults#discoveryFeatureLoader` instead. diff --git a/.changeset/calm-brooms-fail.md b/.changeset/calm-brooms-fail.md new file mode 100644 index 0000000000..a87b5ad38c --- /dev/null +++ b/.changeset/calm-brooms-fail.md @@ -0,0 +1,38 @@ +--- +'@backstage/backend-dynamic-feature-service': patch +--- + +Deprecate the `dynamicPluginsServiceRef`, `dynamicPluginsServiceFactory` and `dynamicPluginsServiceFactoryWithOptions` in favor of using the `dynamicPluginsFeatureDiscoveryLoader` to discover dynamic features in a new backend system. + +See usage examples below: + +Example using the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + +```ts +import { createBackend } from '@backstage/backend-defaults'; +import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; +//... + +const backend = createBackend(); +backend.add(dynamicPluginsFeatureDiscoveryLoader); +//... +backend.start(); +``` + +Passing options to the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + +```ts +import { createBackend } from '@backstage/backend-defaults'; +import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; +import { myCustomModuleLoader } from './myCustomModuleLoader'; +//... + +const backend = createBackend(); +backend.add( + dynamicPluginsFeatureDiscoveryLoader({ + moduleLoader: myCustomModuleLoader, + }), +); +//... +backend.start(); +``` diff --git a/.changeset/calm-toes-melt.md b/.changeset/calm-toes-melt.md new file mode 100644 index 0000000000..b8a7b12c46 --- /dev/null +++ b/.changeset/calm-toes-melt.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-app-api': patch +--- + +The `defaultConfigLoader` now also reads configuration from scripts tags with `type="backstage.io/config"`. The tag is expected to contain a JSON-serialized array of `AppConfig` objects. If any of these script tags are present, the injected runtime configuration in the static assets will no longer be used. diff --git a/.changeset/chilled-cameras-change.md b/.changeset/chilled-cameras-change.md new file mode 100644 index 0000000000..8491761594 --- /dev/null +++ b/.changeset/chilled-cameras-change.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-gitlab': patch +--- + +Internal update to use the new cache manager diff --git a/.changeset/chilly-birds-shout.md b/.changeset/chilly-birds-shout.md new file mode 100644 index 0000000000..dfa99b6f5d --- /dev/null +++ b/.changeset/chilly-birds-shout.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-common': minor +--- + +**BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. + +- The deprecated `dropDatabase` function has now been removed, without replacement. diff --git a/.changeset/cool-actors-sin.md b/.changeset/cool-actors-sin.md new file mode 100644 index 0000000000..4d5b2589c5 --- /dev/null +++ b/.changeset/cool-actors-sin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +--- + +Throw correct error when email is missing from the claims diff --git a/.changeset/cool-melons-check.md b/.changeset/cool-melons-check.md new file mode 100644 index 0000000000..462a023dca --- /dev/null +++ b/.changeset/cool-melons-check.md @@ -0,0 +1,21 @@ +--- +'@backstage/frontend-test-utils': patch +'@backstage/frontend-app-api': patch +'@backstage/core-compat-api': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-catalog-graph': patch +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-search-react': 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-search': patch +'@backstage/plugin-home': patch +'@backstage/plugin-org': patch +--- + +Updated exports to use the new type parameters for extensions and extension blueprints. diff --git a/.changeset/dry-beers-shake.md b/.changeset/dry-beers-shake.md new file mode 100644 index 0000000000..59ff5ead54 --- /dev/null +++ b/.changeset/dry-beers-shake.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-defaults': minor +--- + +Initial release of this package, which provides a default app setup through the `createApp` function. This replaces the existing `createApp` method from `@backstage/frontend-app-api`. diff --git a/.changeset/dry-glasses-push.md b/.changeset/dry-glasses-push.md new file mode 100644 index 0000000000..31a04db24a --- /dev/null +++ b/.changeset/dry-glasses-push.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-node': patch +--- + +Extend the "unable to resolve user identity" message diff --git a/.changeset/early-swans-grab.md b/.changeset/early-swans-grab.md new file mode 100644 index 0000000000..4526067275 --- /dev/null +++ b/.changeset/early-swans-grab.md @@ -0,0 +1,12 @@ +--- +'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch +'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +'@backstage/plugin-scaffolder-backend-module-sentry': patch +'@backstage/plugin-scaffolder-backend-module-yeoman': patch +'@backstage/plugin-scaffolder-backend-module-rails': patch +'@backstage/plugin-user-settings-backend': patch +'@backstage/plugin-devtools-backend': patch +--- + +Update README installation instructions diff --git a/.changeset/famous-badgers-drop.md b/.changeset/famous-badgers-drop.md new file mode 100644 index 0000000000..af519cf964 --- /dev/null +++ b/.changeset/famous-badgers-drop.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +Added missing service mock for `mockServices.rootConfig.mock`, and fixed the definition of `mockServices.rootHttpRouter.factory` to not have a duplicate callback. diff --git a/.changeset/five-tigers-share.md b/.changeset/five-tigers-share.md new file mode 100644 index 0000000000..507614c8b8 --- /dev/null +++ b/.changeset/five-tigers-share.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Found the issue during testing the clean up of the workspace for the database implementation. diff --git a/.changeset/flat-kangaroos-push.md b/.changeset/flat-kangaroos-push.md new file mode 100644 index 0000000000..b046beeeb1 --- /dev/null +++ b/.changeset/flat-kangaroos-push.md @@ -0,0 +1,31 @@ +--- +'@backstage/frontend-plugin-api': minor +--- + +**BREAKING**: Updated the type parameters for `ExtensionDefinition` and `ExtensionBlueprint` to only have a single object parameter. The base type parameter is exported as `ExtensionDefinitionParameters` and `ExtensionBlueprintParameters` respectively. This is shipped as an immediate breaking change as we expect usage of these types to be rare, and it does not affect the runtime behavior of the API. + +This is a breaking change as it changes the type parameters. Existing usage can generally be updated as follows: + +- `ExtensionDefinition` -> `ExtensionDefinition` +- `ExtensionDefinition` -> `ExtensionDefinition` +- `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig }>` +- `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig, configInput: TConfigInput }>` + +If you need to infer the parameter you can use `ExtensionDefinitionParameters`, for example: + +```ts +import { + ExtensionDefinition, + ExtensionDefinitionParameters, +} from '@backstage/frontend-plugin-api'; + +function myUtility( + ext: ExtensionDefinition, +): T['config'] { + // ... +} +``` + +The same patterns apply to `ExtensionBlueprint`. + +This change is made to improve the readability of API references and ability to evolve the type parameters in the future. diff --git a/.changeset/forty-toes-float.md b/.changeset/forty-toes-float.md new file mode 100644 index 0000000000..b6ca5139ea --- /dev/null +++ b/.changeset/forty-toes-float.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-test-utils': minor +--- + +**BREAKING**: The deprecated `.render()` method has been removed from the extension tester. diff --git a/.changeset/four-parents-buy.md b/.changeset/four-parents-buy.md new file mode 100644 index 0000000000..ac216c3c08 --- /dev/null +++ b/.changeset/four-parents-buy.md @@ -0,0 +1,7 @@ +--- +'@backstage/frontend-app-api': minor +--- + +**BREAKING**: The `createSpecializedApp` function now creates a bare-bones app without any of the default app structure or APIs. To re-introduce this functionality if you need to use `createSpecializedApp` you can install the `app` plugin from `@backstage/plugin-app`. + +In addition, the `createApp` and `CreateAppFeatureLoader` exports are now deprecated as they are being moved to `@backstage/frontend-defaults`, which should be used instead. diff --git a/.changeset/four-ties-raise.md b/.changeset/four-ties-raise.md new file mode 100644 index 0000000000..163443afff --- /dev/null +++ b/.changeset/four-ties-raise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': minor +--- + +Add `ui:backstage.review.name` option for custom item names on scaffolder review page, and also add support for rendering the `title` property instead of the key name. diff --git a/.changeset/fresh-apes-dress.md b/.changeset/fresh-apes-dress.md new file mode 100644 index 0000000000..6e20e53bcd --- /dev/null +++ b/.changeset/fresh-apes-dress.md @@ -0,0 +1,8 @@ +--- +'@backstage/frontend-plugin-api': patch +'@backstage/frontend-test-utils': patch +'@backstage/frontend-app-api': patch +'@backstage/plugin-app': minor +--- + +Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. diff --git a/.changeset/fresh-bears-prove.md b/.changeset/fresh-bears-prove.md new file mode 100644 index 0000000000..a4098a4b18 --- /dev/null +++ b/.changeset/fresh-bears-prove.md @@ -0,0 +1,6 @@ +--- +'@backstage/cli': patch +'@backstage/create-app': patch +--- + +Update templates to not refer to backend-common diff --git a/.changeset/fresh-pumas-clean.md b/.changeset/fresh-pumas-clean.md new file mode 100644 index 0000000000..2140f62651 --- /dev/null +++ b/.changeset/fresh-pumas-clean.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-app-backend': patch +'@backstage/plugin-app-node': patch +--- + +Fixing dependency metadata with the new `@backstage/plugin-app` package diff --git a/.changeset/friendly-days-march.md b/.changeset/friendly-days-march.md new file mode 100644 index 0000000000..a190c50a43 --- /dev/null +++ b/.changeset/friendly-days-march.md @@ -0,0 +1,7 @@ +--- +'@backstage/frontend-plugin-api': patch +--- + +Added `createFrontendModule` as a replacement for `createExtensionOverrides`, which is now deprecated. + +Deprecated the `BackstagePlugin` and `FrontendFeature` type in favor of `FrontendPlugin` and `FrontendFeature` from `@backstage/frontend-app-api` respectively. diff --git a/.changeset/friendly-months-march.md b/.changeset/friendly-months-march.md new file mode 100644 index 0000000000..0bb9cd7cf0 --- /dev/null +++ b/.changeset/friendly-months-march.md @@ -0,0 +1,6 @@ +--- +'@backstage/frontend-app-api': patch +'@backstage/core-compat-api': patch +--- + +Added support for new `FrontendPlugin` and `FrontendModule` types. diff --git a/.changeset/funny-houses-rest.md b/.changeset/funny-houses-rest.md new file mode 100644 index 0000000000..21efce8c19 --- /dev/null +++ b/.changeset/funny-houses-rest.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-backend': patch +--- + +The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. diff --git a/.changeset/funny-rocks-pull.md b/.changeset/funny-rocks-pull.md new file mode 100644 index 0000000000..9145464137 --- /dev/null +++ b/.changeset/funny-rocks-pull.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder-react': minor +'@backstage/plugin-scaffolder': minor +--- + +Added support for `omitExtraData` and `liveOmit` for rjsf in the scaffolder diff --git a/.changeset/fuzzy-feet-exist.md b/.changeset/fuzzy-feet-exist.md new file mode 100644 index 0000000000..35ef1e58fd --- /dev/null +++ b/.changeset/fuzzy-feet-exist.md @@ -0,0 +1,34 @@ +--- +'@backstage/frontend-plugin-api': patch +'@backstage/plugin-app': patch +--- + +Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. + +You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. + +```ts +// Before +createExtensionOverrides({ + extensions: [ + createExtension({ + name: 'my-extension', + namespace: 'my-namespace', + kind: 'test', + ... + }) + ], +}); + +// After +createFrontendModule({ + pluginId: 'my-namespace', + extensions: [ + createExtension({ + name: 'my-extension', + kind: 'test', + ... + }) + ], +}); +``` diff --git a/.changeset/fuzzy-mails-walk.md b/.changeset/fuzzy-mails-walk.md new file mode 100644 index 0000000000..b46fbd59c4 --- /dev/null +++ b/.changeset/fuzzy-mails-walk.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +Deprecate the `featureDiscoveryServiceRef` in favor of using the new `discoveryFeatureLoader` instead. diff --git a/.changeset/gentle-hats-act.md b/.changeset/gentle-hats-act.md new file mode 100644 index 0000000000..e78076c9c5 --- /dev/null +++ b/.changeset/gentle-hats-act.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-defaults': patch +--- + +Added a new `CreateAppOptions` type for the `createApp` options. diff --git a/.changeset/gorgeous-scissors-wave.md b/.changeset/gorgeous-scissors-wave.md new file mode 100644 index 0000000000..1db406b940 --- /dev/null +++ b/.changeset/gorgeous-scissors-wave.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Updated the error message for missing service dependencies to include the plugin and module IDs. diff --git a/.changeset/great-zebras-hunt.md b/.changeset/great-zebras-hunt.md new file mode 100644 index 0000000000..252f270092 --- /dev/null +++ b/.changeset/great-zebras-hunt.md @@ -0,0 +1,7 @@ +--- +'@backstage/cli': patch +--- + +The app build process now outputs an additional `index.html.tmpl` file. This is an non-templated version of the `index.html` file, which can be used to delay templating until runtime. + +The new `index.html.tmpl` file also sets a `backstage-public-path` meta tag to be templated at runtime. The meta tag is in turn picked up by the new `@backstage/cli/config/webpack-public-path.js` entry point script, which uses it to set the runtime public path of the Webpack bundle. diff --git a/.changeset/green-worms-rescue.md b/.changeset/green-worms-rescue.md new file mode 100644 index 0000000000..992012ad7d --- /dev/null +++ b/.changeset/green-worms-rescue.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Add `checks: 'read'` for default GitHub app permissions diff --git a/.changeset/heavy-suits-judge.md b/.changeset/heavy-suits-judge.md new file mode 100644 index 0000000000..d5c00184c7 --- /dev/null +++ b/.changeset/heavy-suits-judge.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-user-settings-backend': patch +--- + +In preparation to stop supporting to the legacy backend system, the `createRouter` function is now deprecated and we strongly recommend you [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) your backend to the new system. diff --git a/.changeset/khaki-crews-rule.md b/.changeset/khaki-crews-rule.md new file mode 100644 index 0000000000..4d8eb32083 --- /dev/null +++ b/.changeset/khaki-crews-rule.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-app-backend': patch +--- + +**BREAKING**: The app backend now supports the new `index.html.tmpl` output from `@backstage/cli`. If available, the `index.html` will be templated at runtime with the current configuration of the app backend. + +This is marked as a breaking change because you must now supply the app build-time configuration to the backend. This change also affects the public path behavior, where it is no longer necessary to build the app with the correct public path upfront. You now only need to supply a correct `app.baseUrl` to the app backend plugin at runtime. + +An effect that this change has is that the `index.html` will now contain and present the frontend configuration in an easily readable way, which can aid in debugging. This data was always available in the frontend, but it was injected and hidden in the static bundle. + +This templating behavior is enabled by default, but it can be disabled by setting the `app.disableConfigInjection` configuration option to `true`. diff --git a/.changeset/loud-brooms-pull.md b/.changeset/loud-brooms-pull.md new file mode 100644 index 0000000000..8ed3e22c5b --- /dev/null +++ b/.changeset/loud-brooms-pull.md @@ -0,0 +1,8 @@ +--- +'@backstage/catalog-client': patch +'@backstage/plugin-catalog-backend': patch +--- + +Moved `getEntities` ordering to utilize database instead of having it inside catalog client + +Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. diff --git a/.changeset/metal-rivers-grin.md b/.changeset/metal-rivers-grin.md new file mode 100644 index 0000000000..b70750c98d --- /dev/null +++ b/.changeset/metal-rivers-grin.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': patch +--- + +There is a new `mockErrorHandler` utility to help in mocking the error middleware in tests. diff --git a/.changeset/mighty-cheetahs-call.md b/.changeset/mighty-cheetahs-call.md new file mode 100644 index 0000000000..f5d17d8b20 --- /dev/null +++ b/.changeset/mighty-cheetahs-call.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Move down the discovery config to be in the root diff --git a/.changeset/odd-goats-kiss.md b/.changeset/odd-goats-kiss.md new file mode 100644 index 0000000000..0f199c1a1e --- /dev/null +++ b/.changeset/odd-goats-kiss.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Added `titleComponent` prop to `SignInPage` component to allow further customization of the title using `ReactNode` diff --git a/.changeset/olive-phones-sniff.md b/.changeset/olive-phones-sniff.md new file mode 100644 index 0000000000..d70953435c --- /dev/null +++ b/.changeset/olive-phones-sniff.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-common': patch +--- + +Add `pg-format` as a dependency diff --git a/.changeset/orange-shrimps-pull.md b/.changeset/orange-shrimps-pull.md new file mode 100644 index 0000000000..7d509a0e5d --- /dev/null +++ b/.changeset/orange-shrimps-pull.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-notifications-backend': patch +'@backstage/plugin-notifications': patch +--- + +Implement icon in backend and show icon in table if available. diff --git a/.changeset/plenty-dragons-know.md b/.changeset/plenty-dragons-know.md new file mode 100644 index 0000000000..2aa8458011 --- /dev/null +++ b/.changeset/plenty-dragons-know.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-defaults': patch +--- + +Added `createPublicSignInApp`, used to creating apps for the public entry point. diff --git a/.changeset/pre.json b/.changeset/pre.json index f5e95fffc7..0266c977a1 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -15,7 +15,6 @@ "example-backend-legacy": "0.2.101", "@backstage/backend-openapi-utils": "0.1.16", "@backstage/backend-plugin-api": "0.8.0", - "@backstage/backend-tasks": "0.6.0", "@backstage/backend-test-utils": "0.5.0", "@backstage/catalog-client": "1.6.6", "@backstage/catalog-model": "1.6.0", @@ -187,7 +186,125 @@ "@backstage/plugin-techdocs-react": "1.2.7", "@backstage/plugin-user-settings": "0.8.11", "@backstage/plugin-user-settings-backend": "0.2.22", - "@backstage/plugin-user-settings-common": "0.0.1" + "@backstage/plugin-user-settings-common": "0.0.1", + "@backstage/plugin-app": "0.0.0", + "@backstage/frontend-defaults": "0.0.0" }, - "changesets": [] + "changesets": [ + "afraid-fans-cross", + "angry-hotels-warn", + "big-spies-stare", + "blue-forks-cry", + "breezy-flowers-dance", + "brown-actors-clap", + "brown-boxes-arrive", + "brown-worms-sneeze", + "calm-brooms-fail", + "chilled-cameras-change", + "chilly-birds-shout", + "cold-ways-protect", + "cool-actors-sin", + "cool-melons-check", + "cool-poems-hammer", + "cuddly-rocks-invent", + "curly-brooms-raise", + "dry-beers-shake", + "dry-glasses-push", + "dry-monkeys-mate", + "eighty-tables-hope", + "empty-coats-sparkle", + "famous-badgers-drop", + "five-tigers-share", + "flat-kangaroos-push", + "forty-toes-float", + "four-parents-buy", + "four-ties-raise", + "fresh-apes-dress", + "fresh-bears-prove", + "fresh-pumas-clean", + "friendly-days-march", + "friendly-months-march", + "funny-houses-rest", + "fuzzy-feet-exist", + "fuzzy-mails-walk", + "fuzzy-spies-share", + "gentle-hats-act", + "giant-jars-mix", + "gorgeous-scissors-wave", + "green-worms-rescue", + "healthy-moons-drum", + "heavy-suits-judge", + "hip-pandas-think", + "kind-moose-learn", + "kind-walls-speak", + "large-poets-check", + "loud-brooms-pull", + "lucky-sheep-cover", + "metal-garlics-fetch", + "metal-rivers-grin", + "mighty-cheetahs-call", + "mighty-days-kiss", + "nasty-tigers-knock", + "new-poets-unite", + "ninety-mayflies-raise", + "odd-goats-kiss", + "olive-phones-sniff", + "plenty-dragons-know", + "popular-cooks-camp", + "purple-cows-sing", + "purple-glasses-tease", + "quick-suns-swim", + "quiet-spies-clean", + "rare-feet-melt", + "real-pants-rule", + "renovate-53b7d25", + "renovate-546c524", + "renovate-93d032c", + "renovate-b8911c2", + "rich-bees-tickle", + "rotten-crabs-hear", + "serious-cheetahs-help", + "serious-spies-knock", + "sharp-fans-tan", + "sharp-items-study", + "sharp-mayflies-beg", + "shiny-carpets-worried", + "shiny-carpets-worry", + "shiny-zoos-film", + "short-moles-brush", + "silent-eyes-lie", + "six-goats-sort", + "six-humans-guess", + "sixty-rabbits-cheat", + "slimy-chefs-think", + "smart-gifts-report", + "smart-owls-sell", + "spicy-poems-hammer", + "spicy-vans-eat", + "sweet-cows-clean", + "swift-fishes-rush", + "swift-garlics-mix", + "swift-radios-enjoy", + "swift-seahorses-share", + "tall-camels-march", + "tame-hornets-shake", + "tasty-pigs-vanish", + "thick-walls-share", + "tiny-icons-sit", + "tiny-waves-provide", + "tough-peaches-kneel", + "tricky-apricots-film", + "twenty-clouds-melt", + "twenty-queens-grow", + "unlucky-cycles-clean", + "violet-apricots-smoke", + "violet-jokes-tap", + "warm-boxes-grab-2", + "warm-boxes-grab", + "wild-buses-notice", + "wise-forks-play", + "wise-scissors-help", + "witty-years-cry", + "yellow-bees-hope" + ] } diff --git a/.changeset/proud-forks-buy.md b/.changeset/proud-forks-buy.md new file mode 100644 index 0000000000..558d5d9078 --- /dev/null +++ b/.changeset/proud-forks-buy.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +The `ui:options` for `OwnedEntityPicker` field are now passed to `EntityPicker`. This allows you to use any `ui:options` which `EntityPicker` accepts in the `OwnedEntityPicker` field including `allowArbitraryValues` and `defaultNamespace`. diff --git a/.changeset/quick-suns-swim.md b/.changeset/quick-suns-swim.md new file mode 100644 index 0000000000..6113253e22 --- /dev/null +++ b/.changeset/quick-suns-swim.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Accept `ConfigService` instead of `Config` in constructors/factories diff --git a/.changeset/quiet-spies-clean.md b/.changeset/quiet-spies-clean.md new file mode 100644 index 0000000000..ba277f4021 --- /dev/null +++ b/.changeset/quiet-spies-clean.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-graph': patch +--- + +Fixed a bug in the `CatalogGraphPage` component where, after clicking on some nodes, clicking the back button would break the navigation. This issue caused the entire navigation to fail and behaved differently across various browsers. diff --git a/.changeset/real-pants-rule.md b/.changeset/real-pants-rule.md new file mode 100644 index 0000000000..8d6d3dc708 --- /dev/null +++ b/.changeset/real-pants-rule.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-auth-backend-module-microsoft-provider': patch +'@backstage/plugin-auth-backend': patch +'@backstage/plugin-catalog-backend-module-msgraph': patch +--- + +Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. diff --git a/.changeset/red-squids-own.md b/.changeset/red-squids-own.md new file mode 100644 index 0000000000..4f6a1635d6 --- /dev/null +++ b/.changeset/red-squids-own.md @@ -0,0 +1,11 @@ +--- +'@backstage/integration': minor +--- + +The Gerrit integration can now resolve Gitiles urls that point to the following +refs: + +- HEAD +- A SHA +- Tag +- Branch diff --git a/.changeset/renovate-53b7d25.md b/.changeset/renovate-53b7d25.md new file mode 100644 index 0000000000..0c4f7255d3 --- /dev/null +++ b/.changeset/renovate-53b7d25.md @@ -0,0 +1,6 @@ +--- +'@backstage/cli': patch +'@backstage/plugin-scaffolder-backend': patch +--- + +Updated dependency `esbuild` to `^0.23.0`. diff --git a/.changeset/renovate-546c524.md b/.changeset/renovate-546c524.md new file mode 100644 index 0000000000..bbe6d8afc5 --- /dev/null +++ b/.changeset/renovate-546c524.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Updated dependency `@useoptic/openapi-utilities` to `^0.55.0`. diff --git a/.changeset/renovate-93d032c.md b/.changeset/renovate-93d032c.md new file mode 100644 index 0000000000..b34e5a2e23 --- /dev/null +++ b/.changeset/renovate-93d032c.md @@ -0,0 +1,5 @@ +--- +'@backstage/codemods': patch +--- + +Updated dependency `jscodeshift` to `^0.16.0`. diff --git a/.changeset/renovate-a674163.md b/.changeset/renovate-a674163.md new file mode 100644 index 0000000000..396139042a --- /dev/null +++ b/.changeset/renovate-a674163.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-home-react': patch +'@backstage/plugin-home': patch +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder': patch +--- + +Updated dependency `@rjsf/utils` to `5.20.1`. +Updated dependency `@rjsf/core` to `5.20.1`. +Updated dependency `@rjsf/material-ui` to `5.20.1`. +Updated dependency `@rjsf/validator-ajv8` to `5.20.1`. diff --git a/.changeset/renovate-b8911c2.md b/.changeset/renovate-b8911c2.md new file mode 100644 index 0000000000..9f93a13254 --- /dev/null +++ b/.changeset/renovate-b8911c2.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Updated dependency `use-immer` to `^0.10.0`. diff --git a/.changeset/renovate-c59c91d.md b/.changeset/renovate-c59c91d.md new file mode 100644 index 0000000000..eede7c81c2 --- /dev/null +++ b/.changeset/renovate-c59c91d.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend-module-explore': patch +--- + +Updated dependency `@backstage-community/plugin-explore-common` to `^0.0.5`. diff --git a/.changeset/rich-bees-tickle.md b/.changeset/rich-bees-tickle.md new file mode 100644 index 0000000000..a2af89c867 --- /dev/null +++ b/.changeset/rich-bees-tickle.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Wrap scheduled tasks from the scheduler core service now in OpenTelemetry spans diff --git a/.changeset/rich-cheetahs-vanish.md b/.changeset/rich-cheetahs-vanish.md new file mode 100644 index 0000000000..26cc55b917 --- /dev/null +++ b/.changeset/rich-cheetahs-vanish.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-common': patch +'@backstage/plugin-techdocs-node': patch +--- + +Internal fixes to match `testcontainers` update diff --git a/.changeset/rotten-crabs-hear.md b/.changeset/rotten-crabs-hear.md new file mode 100644 index 0000000000..69148c59c1 --- /dev/null +++ b/.changeset/rotten-crabs-hear.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications-backend': patch +--- + +Validate notification link when new notification is created diff --git a/.changeset/serious-spies-knock.md b/.changeset/serious-spies-knock.md new file mode 100644 index 0000000000..1484753019 --- /dev/null +++ b/.changeset/serious-spies-knock.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Skip start without proper config diff --git a/.changeset/sharp-items-study.md b/.changeset/sharp-items-study.md new file mode 100644 index 0000000000..61e8af54b6 --- /dev/null +++ b/.changeset/sharp-items-study.md @@ -0,0 +1,19 @@ +--- +'@backstage/backend-defaults': patch +--- + +Exports the `discoveryFeatureLoader` as a replacement for the deprecated `featureDiscoveryService`. +The `discoveryFeatureLoader` is a new backend system [feature loader](https://backstage.io/docs/backend-system/architecture/feature-loaders/) that discovers backend features from the current `package.json` and its dependencies. +Here is an example using the `discoveryFeatureLoader` loader in a new backend instance: + +```ts +import { createBackend } from '@backstage/backend-defaults'; +import { discoveryFeatureLoader } from '@backstage/backend-defaults'; +//... + +const backend = createBackend(); +//... +backend.add(discoveryFeatureLoader); +//... +backend.start(); +``` diff --git a/.changeset/shiny-carpets-worried.md b/.changeset/shiny-carpets-worried.md new file mode 100644 index 0000000000..c0093b49aa --- /dev/null +++ b/.changeset/shiny-carpets-worried.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-compat-api': minor +--- + +**BREAKING**: The `namespace` parameter for API's is now defaulted to the `pluginId` which was discovered. This means that if you're overriding API's by using ID's directly, they might have changed to include the plugin ID too. diff --git a/.changeset/shiny-carpets-worry.md b/.changeset/shiny-carpets-worry.md new file mode 100644 index 0000000000..53688df920 --- /dev/null +++ b/.changeset/shiny-carpets-worry.md @@ -0,0 +1,7 @@ +--- +'@backstage/frontend-plugin-api': patch +'@backstage/frontend-test-utils': patch +'@backstage/frontend-app-api': patch +--- + +Removing deprecated `namespace` parameter in favour of `pluginId` instead diff --git a/.changeset/shiny-zoos-film.md b/.changeset/shiny-zoos-film.md new file mode 100644 index 0000000000..f9fb8cdce5 --- /dev/null +++ b/.changeset/shiny-zoos-film.md @@ -0,0 +1,21 @@ +--- +'@backstage/plugin-signals': patch +--- + +Added a `SignalsDisplay` extension to allows the signals plugin to be installed in an app as follows: + +```tsx +export default app.createRoot( + <> + + + + + + {routes} + + , +); +``` + +With this in place you can remove the explicit installation via the `plugins` option for `createApp`. diff --git a/.changeset/slimy-chefs-think.md b/.changeset/slimy-chefs-think.md new file mode 100644 index 0000000000..7fa546a399 --- /dev/null +++ b/.changeset/slimy-chefs-think.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-notifications-backend-module-email': patch +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/plugin-notifications-backend': patch +'@backstage/plugin-techdocs-backend': patch +--- + +Refactor to use injected catalog client in the new backend system diff --git a/.changeset/smart-gifts-report.md b/.changeset/smart-gifts-report.md new file mode 100644 index 0000000000..fa3c8d96e9 --- /dev/null +++ b/.changeset/smart-gifts-report.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-catalog-unprocessed-entities': patch +--- + +Show additional info on DevTools unprocessed entities table + +- Location path (so that it's easier to search the failed entity from the YAML URL) +- Time info of last discovery and next refresh time so that users can be aware of it and can sort the errors based on the time. diff --git a/.changeset/smart-owls-sell.md b/.changeset/smart-owls-sell.md new file mode 100644 index 0000000000..0a2b555a20 --- /dev/null +++ b/.changeset/smart-owls-sell.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Properly indent the config schema diff --git a/.changeset/spicy-poems-hammer.md b/.changeset/spicy-poems-hammer.md new file mode 100644 index 0000000000..23e86e178e --- /dev/null +++ b/.changeset/spicy-poems-hammer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-node': patch +--- + +As the `@backstage/backend-common` package is deprecated, we have updated the `techdocs-node` package to stop depending on it. diff --git a/.changeset/sweet-cows-clean.md b/.changeset/sweet-cows-clean.md new file mode 100644 index 0000000000..fa2004186e --- /dev/null +++ b/.changeset/sweet-cows-clean.md @@ -0,0 +1,5 @@ +--- +'@backstage/frontend-test-utils': patch +--- + +Added the ability to provide additional `extensions` and `features` to `renderInTestApp` diff --git a/.changeset/swift-fishes-rush.md b/.changeset/swift-fishes-rush.md new file mode 100644 index 0000000000..ccfa3a0e40 --- /dev/null +++ b/.changeset/swift-fishes-rush.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Fixed an issue where published frontend packages would end up with an invalid import structure if a single module imported both `.css` and `.svg` files. diff --git a/.changeset/swift-seahorses-share.md b/.changeset/swift-seahorses-share.md new file mode 100644 index 0000000000..deaf2ab042 --- /dev/null +++ b/.changeset/swift-seahorses-share.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch +--- + +Updated the README to include documentation for the new backend support diff --git a/.changeset/tall-camels-march.md b/.changeset/tall-camels-march.md new file mode 100644 index 0000000000..892a8f19af --- /dev/null +++ b/.changeset/tall-camels-march.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-signals': patch +--- + +Put a name on the `SignalsDisplay` component extension diff --git a/.changeset/tiny-icons-sit.md b/.changeset/tiny-icons-sit.md new file mode 100644 index 0000000000..7dc35a46fd --- /dev/null +++ b/.changeset/tiny-icons-sit.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Small internal fix to better work with recent `lodash` versions diff --git a/.changeset/tiny-waves-provide.md b/.changeset/tiny-waves-provide.md new file mode 100644 index 0000000000..aabafcfd6b --- /dev/null +++ b/.changeset/tiny-waves-provide.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-plugin-api': patch +'@backstage/backend-defaults': patch +'@backstage/backend-common': patch +--- + +Allow the cache service to accept the human duration format for TTL diff --git a/.changeset/tough-peaches-kneel.md b/.changeset/tough-peaches-kneel.md new file mode 100644 index 0000000000..7674da8879 --- /dev/null +++ b/.changeset/tough-peaches-kneel.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fixed an issue with the by-query call, where ordering by a field that does not exist on all entities led to not all results being returned diff --git a/.changeset/tricky-apricots-film.md b/.changeset/tricky-apricots-film.md new file mode 100644 index 0000000000..7b1c28fdb9 --- /dev/null +++ b/.changeset/tricky-apricots-film.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-signals-react': patch +--- + +Fix for `useSignal` returning the inverse value for `isSignalsAvailable`. diff --git a/.changeset/twenty-jobs-repeat.md b/.changeset/twenty-jobs-repeat.md new file mode 100644 index 0000000000..1ea98319d7 --- /dev/null +++ b/.changeset/twenty-jobs-repeat.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Enhanced the table hover effect with a lighter color and updated the border radius to align with Backstage's theme styling diff --git a/.changeset/violet-apricots-smoke.md b/.changeset/violet-apricots-smoke.md new file mode 100644 index 0000000000..80caf466eb --- /dev/null +++ b/.changeset/violet-apricots-smoke.md @@ -0,0 +1,5 @@ +--- +'@backstage/create-app': patch +--- + +Remove references to the `@backstage/backend-tasks` in versions of the `create-app` package, as it has been deprecated. diff --git a/.changeset/violet-jokes-tap.md b/.changeset/violet-jokes-tap.md new file mode 100644 index 0000000000..5b79ced6cd --- /dev/null +++ b/.changeset/violet-jokes-tap.md @@ -0,0 +1,21 @@ +--- +'@backstage/frontend-plugin-api': patch +'@backstage/frontend-app-api': patch +--- + +Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. + +```ts +export const AppThemeApi = ApiBlueprint.makeWithOverrides({ + name: 'app-theme', + inputs: { + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead + replaces: [{ id: 'app', input: 'themes' }], + }), + }, + factory: () { + ... + } +}); +``` diff --git a/.changeset/wild-buses-notice.md b/.changeset/wild-buses-notice.md new file mode 100644 index 0000000000..3620786aa8 --- /dev/null +++ b/.changeset/wild-buses-notice.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Added the option to skip database migrations by setting `skipMigrations: true` in config. This can be done globally in the database config or by plugin id. diff --git a/.changeset/wise-forks-play.md b/.changeset/wise-forks-play.md new file mode 100644 index 0000000000..1c8be76d19 --- /dev/null +++ b/.changeset/wise-forks-play.md @@ -0,0 +1,17 @@ +--- +'@backstage/backend-defaults': minor +--- + +**BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. + +For the `/database` subpath exports: + +- The deprecated `dropDatabase` function has now been removed, without replacement. +- The deprecated `LegacyRootDatabaseService` type has now been removed. +- The return type from `DatabaseManager.forPlugin` is now directly a `DatabaseService`, as arguably expected. +- `DatabaseManager.forPlugin` now requires the `deps` argument, with the logger and lifecycle services. + +For the `/cache` subpath exports: + +- The `PluginCacheManager` type has been removed. You can still import it from `@backstage/backend-common`, but it's deprecated there, and you should move off of that package by migrating fully to the new backend system. +- Accordingly, `CacheManager.forPlugin` immediately returns a `CacheService` instead of a `PluginCacheManager`. The outcome of this is that you no longer need to make the extra `.getClient()` call. The old `CacheManager` with the old behavior still exists on `@backstage/backend-common`, but the above recommendations apply. diff --git a/.changeset/wise-scissors-help.md b/.changeset/wise-scissors-help.md new file mode 100644 index 0000000000..c8fd2d4c44 --- /dev/null +++ b/.changeset/wise-scissors-help.md @@ -0,0 +1,8 @@ +--- +'@backstage/backend-defaults': patch +'@backstage/backend-app-api': patch +'@backstage/backend-common': patch +'@backstage/backend-plugin-api': patch +--- + +Updates to the config schema to match reality diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 5a70a25512..37f54997c6 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -1,22 +1,17 @@ { $schema: 'https://docs.renovatebot.com/renovate-schema.json', - labels: ['dependencies'], - extends: ['config:best-practices', ':gitSignOff'], // do not pin dev dependencies, which are part of the best-practices preset ignorePresets: [':pinDevDependencies', ':pinDigest', 'docker:pinDigests'], - constraints: { // TODO(freben): Remove this later; it addresses a temporary issue in corepack // https://github.com/nodejs/corepack/issues/379 // https://github.com/renovatebot/renovate/discussions/27465 corepack: '0.24.1', }, - - // the default limit are 10 PRs + // the default limit is 10 PRs prConcurrentLimit: 20, - postUpdateOptions: ['yarnDedupeHighest'], rangeStrategy: 'update-lockfile', ignoreDeps: [ @@ -26,19 +21,19 @@ ], packageRules: [ { - matchSourceUrlPrefixes: ['https://github.com/spotify/web-scripts'], groupName: 'Spotify web-scripts monorepo packages', rangeStrategy: 'replace', + matchSourceUrls: ['https://github.com/spotify/web-scripts{/,}**'], }, { - matchSourceUrlPrefixes: ['https://github.com/microsoft/rushstack'], groupName: 'API Extractor / Rush Stack monorepo packages', rangeStrategy: 'replace', + matchSourceUrls: ['https://github.com/microsoft/rushstack{/,}**'], }, { - matchSourceUrlPrefixes: ['https://github.com/gregberge/svgr'], groupName: 'SVGR monorepo packages', rangeStrategy: 'replace', + matchSourceUrls: ['https://github.com/gregberge/svgr{/,}**'], }, // 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/workflows/api-breaking-changes-comment.yml b/.github/workflows/api-breaking-changes-comment.yml index c3886e05b9..abb98c03e1 100644 --- a/.github/workflows/api-breaking-changes-comment.yml +++ b/.github/workflows/api-breaking-changes-comment.yml @@ -22,7 +22,7 @@ jobs: action: ${{ steps.event.outputs.ACTION }} steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: disable-sudo: true egress-policy: block diff --git a/.github/workflows/api-breaking-changes.yml b/.github/workflows/api-breaking-changes.yml index 1afb7a9391..12d33b450e 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -33,7 +33,7 @@ jobs: registry-url: https://registry.npmjs.org/ - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: linux-v18 @@ -46,7 +46,7 @@ jobs: cat ${{ github.event_path }} > event.json - name: Upload Artifacts - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4 with: name: preview-spec path: | diff --git a/.github/workflows/automate_area-labels.yml b/.github/workflows/automate_area-labels.yml index bde8f15606..fcff8bc11a 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/automate_changeset_feedback.yml b/.github/workflows/automate_changeset_feedback.yml index 94b4b51848..1d8e29fab0 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -34,7 +34,7 @@ jobs: ref: 'refs/pull/${{ github.event.pull_request.number }}/merge' - name: fetch base run: git fetch --depth 1 origin ${{ github.base_ref }} - - uses: backstage/actions/changeset-feedback@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + - uses: backstage/actions/changeset-feedback@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 name: Generate feedback with: diff-ref: 'origin/master' diff --git a/.github/workflows/automate_merge_message.yml b/.github/workflows/automate_merge_message.yml index 2aac0a17f6..2bc7940971 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/automate_stale.yml b/.github/workflows/automate_stale.yml index 6cb16937c6..1ffeac1cc0 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/ci-noop.yml b/.github/workflows/ci-noop.yml index adf0feb926..9b54e6fe6f 100644 --- a/.github/workflows/ci-noop.yml +++ b/.github/workflows/ci-noop.yml @@ -40,7 +40,7 @@ jobs: name: Test ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 168d6205e4..5cbe2e15a3 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -41,7 +41,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -64,7 +64,7 @@ jobs: name: Verify ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -77,7 +77,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -222,7 +222,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index bdbe22aae8..2ac5434f72 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -10,11 +10,11 @@ jobs: timeout-minutes: 10 steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit - - uses: backstage/actions/cron@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + - uses: backstage/actions/cron@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/deploy_docker-image.yml b/.github/workflows/deploy_docker-image.yml index 9f305f9a20..86db3795bc 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -37,7 +37,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -51,14 +51,14 @@ jobs: working-directory: ./example-app - name: Login to GitHub Container Registry - uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 + uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1 - name: Build and push uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0 diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index eafa4a8fcd..f07cf21784 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -8,14 +8,148 @@ permissions: contents: read jobs: - deploy-microsite-and-storybook: - permissions: - contents: write # for JamesIves/github-pages-deploy-action to push changes in repo + stable: runs-on: ubuntu-latest + concurrency: + group: stable-reference-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true env: CI: true NODE_OPTIONS: --max-old-space-size=8192 + + outputs: + release: ${{ steps.find-release.outputs.result }} + + steps: + - name: Harden Runner + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + with: + egress-policy: audit + + - name: find latest release + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7 + id: find-release + with: + script: | + const { data } = await github.rest.repos.listTags({ + owner: context.repo.owner, + repo: context.repo.repo, + per_page: 100, + }) + + const [{tag}] = data + .map(i => i.name) + .filter(tag => tag.match(/^v\d+\.\d+\.\d+$/)) + .map(tag => ({ + tag, + val: tag + .slice(1) + .split('.') + .reduce((val, part) => Number(val) * 1000 + Number(part)) + })) + .sort((a, b) => b.val - a.val) + + return tag + result-encoding: string + + - name: checkout latest release + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + ref: refs/tags/${{ steps.find-release.outputs.result }} + + - name: use node.js 18.x + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + with: + node-version: 18.x + registry-url: https://registry.npmjs.org/ # Needed for auth + + - name: yarn install + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + with: + cache-prefix: ${{ runner.os }}-v18.x + + - name: build API reference + run: yarn build:api-docs + + - name: upload API reference + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4 + with: + name: stable-reference + path: docs/reference/ + if-no-files-found: error + retention-days: 1 + + next: + runs-on: ubuntu-latest + concurrency: + group: next-reference-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + env: + CI: true + NODE_OPTIONS: --max-old-space-size=8192 + + steps: + - name: Harden Runner + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 + with: + egress-policy: audit + + - name: checkout master + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: use node.js 18.x + uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 + with: + node-version: 18.x + registry-url: https://registry.npmjs.org/ # Needed for auth + + - name: yarn install + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 + with: + cache-prefix: ${{ runner.os }}-v18.x + + - name: build API reference + run: yarn build:api-docs + + - name: upload API reference + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4 + with: + name: next-reference + path: docs/reference/ + if-no-files-found: error + retention-days: 1 + + # Also build and upload storybook + - name: storybook yarn install + run: yarn install --immutable + working-directory: storybook + + - name: storybook build + run: yarn build-storybook + working-directory: storybook + + - name: storybook upload + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4 + with: + name: storybook + path: storybook/dist/ + if-no-files-found: error + retention-days: 1 + + deploy-microsite-and-storybook: + permissions: + contents: write # for JamesIves/github-pages-deploy-action to push changes in repo + + runs-on: ubuntu-latest + + needs: + - stable + - next + + env: + CI: true + NODE_OPTIONS: --max-old-space-size=16384 DOCUSAURUS_SSR_CONCURRENCY: 5 concurrency: @@ -24,49 +158,69 @@ jobs: steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - name: use node.js 18.x uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth - # We avoid caching in this workflow, as we're running an install of both the top-level - # dependencies and the microsite. We leave it to the main master workflow to produce the - # cache, as that results in a smaller bundle. - - name: top-level yarn install - run: yarn install --immutable + # Stable docs + - name: checkout latest release + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + ref: refs/tags/${{ needs.stable.outputs.release }} + - name: microsite yarn install run: yarn install --immutable working-directory: microsite - - name: storybook yarn install - run: yarn install --immutable - working-directory: storybook - - name: build API reference - run: yarn build:api-docs + - name: download stable reference + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 + with: + name: stable-reference + path: docs/reference + + - name: generate stable docs + run: yarn docusaurus docs:version stable + working-directory: microsite + + - name: clear API reference + run: rm -r docs/reference + + # Next docs + - name: checkout master + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + with: + clean: false + + - name: microsite yarn install + run: yarn install --immutable + working-directory: microsite + + - name: download next reference + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 + with: + name: next-reference + path: docs/reference - name: build microsite run: yarn build working-directory: microsite - - name: build storybook - run: yarn build-storybook - working-directory: storybook - - - name: move storybook dist into microsite - run: mv storybook/dist/ microsite/build/storybook + - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 + with: + name: storybook + path: microsite/build/storybook - name: Check the build output run: ls microsite/build && ls microsite/build/storybook - name: Deploy both microsite and storybook to gh-pages - uses: JamesIves/github-pages-deploy-action@94f3c658273cf92fb48ef99e5fbc02bd2dc642b2 # v4.6.3 + uses: JamesIves/github-pages-deploy-action@920cbb300dcd3f0568dbc42700c61e2fd9e6139c # v4.6.4 with: branch: gh-pages folder: microsite/build diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml deleted file mode 100644 index 5488b9a189..0000000000 --- a/.github/workflows/deploy_nightly.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: Deploy Nightly Release -on: - schedule: - - cron: '0 2 * * *' # run at 2 AM UTC - -jobs: - build: - if: github.repository == 'backstage/backstage' # prevent running on forks - - runs-on: ubuntu-latest - - env: - CI: true - NODE_OPTIONS: --max-old-space-size=8192 - - steps: - - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 - with: - egress-policy: audit - - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - - name: use node.js 18.x - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 - with: - node-version: 18.x - registry-url: https://registry.npmjs.org/ # Needed for auth - - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 - with: - cache-prefix: ${{ runner.os }}-v18.x - - # No verification done here, only build & publish. If the master branch - # is broken we will see that from those builds, but we still want to push nightly - # builds since upgrading to them is a manual process anyway. - - - name: tsc - run: yarn tsc - - - name: build - run: yarn backstage-cli repo build - - - name: build embedded techdocs app - working-directory: packages/techdocs-cli-embedded-app - run: yarn build - - # Prepares a nightly release version of any package with pending changesets - # Pre-mode is exited if case we're in it, otherwise it has no effect - - name: prepare nightly release - run: | - yarn changeset pre exit || true - yarn changeset version --snapshot nightly - - # Publishes the nightly release to npm, by using tag we make sure the release is - # not flagged as the latest release, which means that people will not get this - # version of the package unless requested explicitly - - name: publish nightly release - run: | - yarn config set -H 'npmAuthToken' "${{secrets.NPM_TOKEN}}" - yarn workspaces foreach -p -j 10 -v --no-private npm publish --access public --tolerate-republish --tag nightly - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Discord notification - if: ${{ failure() }} - uses: Ilshidur/action-discord@0c4b27844ba47cb1c7bee539c8eead5284ce9fa9 # 0.3.2 - env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} - with: - args: 'Nightly build failed https://github.com/{{GITHUB_REPOSITORY}}/actions/runs/{{GITHUB_RUN_ID}}' diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index 7ae5637986..f86c1db4fa 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -1,11 +1,5 @@ name: Deploy Packages on: - workflow_dispatch: - inputs: - force_release: - description: Unconditionally trigger the release job - required: false - type: boolean push: branches: [master, patch/*] @@ -82,7 +76,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -140,7 +134,7 @@ jobs: release: needs: build - if: needs.build.outputs.needs_release == 'true' || inputs.force_release == true + if: needs.build.outputs.needs_release == 'true' runs-on: ubuntu-latest @@ -148,75 +142,16 @@ jobs: matrix: node-version: [18.x] - env: - CI: 'true' - NODE_OPTIONS: --max-old-space-size=8192 - steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - - name: use node.js ${{ matrix.node-version }} - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 - with: - node-version: ${{ matrix.node-version }} - registry-url: https://registry.npmjs.org/ # Needed for auth - - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 - with: - cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - - - name: build type declarations - run: yarn tsc:full - - - name: build packages - run: yarn backstage-cli repo build - - - name: build embedded techdocs app - working-directory: packages/techdocs-cli-embedded-app - run: yarn build - - # Publishes current version of packages that are not already present in the registry - - name: publish - run: | - yarn config set -H 'npmAuthToken' "${{secrets.NPM_TOKEN}}" - if [ -f ".changeset/pre.json" ]; then - yarn workspaces foreach -v --no-private npm publish --access public --tolerate-republish --tag next - else - yarn workspaces foreach -v --no-private npm publish --access public --tolerate-republish - fi - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - # Grabs the version in the root package.json and creates a tag on GitHub - - name: Create a release tag - id: create_tag - run: node scripts/create-release-tag.js - env: - GITHUB_TOKEN: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} - - # Convert the newly created tag into a release with changelog information - - name: Create release on GitHub - run: node scripts/create-github-release.js ${{ steps.create_tag.outputs.tag_name }} 1 - env: - GITHUB_TOKEN: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} - - - name: Dispatch repository event - uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0 - with: - token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} - event-type: release-published - client-payload: '{"version": "${{ steps.create_tag.outputs.version }}"}' - - # Notify everyone about this great new release :D + # Notify maintainers that a new release is ready to be published - name: Discord notification uses: Ilshidur/action-discord@0c4b27844ba47cb1c7bee539c8eead5284ce9fa9 # 0.3.2 env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_RELEASE_WEBHOOK }} - TAG_NAME: ${{ steps.create_tag.outputs.tag_name }} + DISCORD_WEBHOOK: ${{ secrets.DISCORD_MAINTAINERS_WEBHOOK }} with: - args: 'A new release has been published! https://github.com/backstage/backstage/releases/tag/{{TAG_NAME}}' + args: 'A new release is ready to be [published](https://github.com/backstage/publishing/actions/workflows/publish-main.yml) from {{GITHUB_SHA}}' diff --git a/.github/workflows/issue.yaml b/.github/workflows/issue.yaml index 26e394fd87..c8793d3ab0 100644 --- a/.github/workflows/issue.yaml +++ b/.github/workflows/issue.yaml @@ -3,14 +3,20 @@ on: issues: types: [opened] +permissions: + contents: read + jobs: sync: + permissions: + contents: read # for github/issue-labeler to get repo contents + issues: write # for github/issue-labeler to create or remove labels runs-on: ubuntu-latest if: github.repository == 'backstage/backstage' steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/pr-review-comment-trigger.yaml b/.github/workflows/pr-review-comment-trigger.yaml index cfe0e65580..62bf70187b 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -30,7 +30,7 @@ jobs: run: | mkdir -p ./pr echo $PR_NUMBER > ./pr/pr_number - - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: pr_number-${{ github.event.pull_request.number }} path: pr/ diff --git a/.github/workflows/pr-review-comment.yaml b/.github/workflows/pr-review-comment.yaml index 1b2b9ee5be..6133fdef8a 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -40,7 +40,7 @@ jobs: const prNumber = artifact.name.slice('pr_number-'.length) core.setOutput('pr-number', prNumber); - - uses: backstage/actions/re-review@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + - uses: backstage/actions/re-review@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index bf7c5cfa8d..510d5242f4 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -18,12 +18,12 @@ jobs: if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request ) steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit - name: PR sync - uses: backstage/actions/pr-sync@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/pr-sync@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }} app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 26a2fdde11..8196e61bb9 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -58,7 +58,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: 'Upload artifact' - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: SARIF file path: results.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@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 + uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 with: sarif_file: results.sarif diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml index da6bd2592d..859f077095 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -25,7 +25,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/sync_dependabot-changesets.yml b/.github/workflows/sync_dependabot-changesets.yml index ce79efb148..357b7f5cd9 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/sync_release-manifest.yml b/.github/workflows/sync_release-manifest.yml index 62dd7e0c13..898aaa74c7 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -25,7 +25,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@a674369920067381b450d398b27df7039b7ef635 # v0.6.5 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v18.x diff --git a/.github/workflows/sync_renovate-changesets.yml b/.github/workflows/sync_renovate-changesets.yml index 4ba792d4e0..19072a443b 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index af2e4da251..0369f89648 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -24,12 +24,12 @@ jobs: node-version: 18.x registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v18.x - name: Create Snyk report - uses: snyk/actions/node@6312a53377a551c0258438bf25fb8f378afbc977 # master + uses: snyk/actions/node@9213221444c2dc9e8b2502c1e857c26d851e84a7 # 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 1bdf0d30cf..da13ec653f 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Monitor and Synchronize Snyk Policies - uses: snyk/actions/node@6312a53377a551c0258438bf25fb8f378afbc977 # master + uses: snyk/actions/node@9213221444c2dc9e8b2502c1e857c26d851e84a7 # 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@6312a53377a551c0258438bf25fb8f378afbc977 # master + uses: snyk/actions/node@9213221444c2dc9e8b2502c1e857c26d851e84a7 # 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@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 + uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 with: sarif_file: snyk.sarif diff --git a/.github/workflows/sync_version-packages.yml b/.github/workflows/sync_version-packages.yml index 3a10083b7e..3a29ba3c79 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_accessibility-noop.yml b/.github/workflows/verify_accessibility-noop.yml index 6b51713aa1..8d8cb30789 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_accessibility.yml b/.github/workflows/verify_accessibility.yml index 386306dcb1..fd86075ea0 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -30,7 +30,7 @@ jobs: with: node-version: 18.x - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v18.x - name: run Lighthouse CI diff --git a/.github/workflows/verify_codeql.yml b/.github/workflows/verify_codeql.yml index b2fb2dc6ec..177348c30f 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -55,7 +55,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 + uses: github/codeql-action/init@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.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@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 + uses: github/codeql-action/autobuild@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.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@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 # v3.25.14 + uses: github/codeql-action/analyze@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 diff --git a/.github/workflows/verify_docs-quality.yml b/.github/workflows/verify_docs-quality.yml index 2a0c4449a9..8e1a91d850 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-kubernetes-noop.yml b/.github/workflows/verify_e2e-kubernetes-noop.yml index b51c7fd201..544c4e6186 100644 --- a/.github/workflows/verify_e2e-kubernetes-noop.yml +++ b/.github/workflows/verify_e2e-kubernetes-noop.yml @@ -23,7 +23,7 @@ jobs: name: Kubernetes ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-kubernetes.yml b/.github/workflows/verify_e2e-kubernetes.yml index 4647505cbf..18eee7e3f2 100644 --- a/.github/workflows/verify_e2e-kubernetes.yml +++ b/.github/workflows/verify_e2e-kubernetes.yml @@ -22,7 +22,7 @@ jobs: name: Kubernetes ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -35,7 +35,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_e2e-linux-noop.yml b/.github/workflows/verify_e2e-linux-noop.yml index c042bdeac7..024f288255 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index fa303ce1c6..1c1ed7a3eb 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -41,7 +41,7 @@ jobs: name: E2E Linux ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -58,7 +58,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_e2e-techdocs.yml b/.github/workflows/verify_e2e-techdocs.yml index 80686763f4..e2788e2d47 100644 --- a/.github/workflows/verify_e2e-techdocs.yml +++ b/.github/workflows/verify_e2e-techdocs.yml @@ -30,12 +30,12 @@ jobs: name: Techdocs steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: '3.9' diff --git a/.github/workflows/verify_e2e-windows-noop.yml b/.github/workflows/verify_e2e-windows-noop.yml index 299489fcbe..5244a78919 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index ff579958bb..8663e420eb 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -31,7 +31,7 @@ jobs: name: E2E Windows ${{ matrix.node-version }} steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -56,7 +56,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: setup python - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: '3.10' @@ -78,7 +78,7 @@ jobs: uses: browser-actions/setup-chrome@803ef6dfb4fdf22089c9563225d95e4a515820a0 # latest - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_fossa.yml b/.github/workflows/verify_fossa.yml index ad94f9ece5..3a5899d3cf 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_microsite-noop.yml b/.github/workflows/verify_microsite-noop.yml index d8ccaf73e5..daec683da6 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_microsite.yml b/.github/workflows/verify_microsite.yml index ce8391a7eb..a290b221b2 100644 --- a/.github/workflows/verify_microsite.yml +++ b/.github/workflows/verify_microsite.yml @@ -24,7 +24,7 @@ jobs: name: Microsite steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -34,7 +34,7 @@ jobs: uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: node-version: 18.x - - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5 + - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5 with: python-version: '3.9' diff --git a/.github/workflows/verify_microsite_accessibility-noop.yml b/.github/workflows/verify_microsite_accessibility-noop.yml index 9f0ecc65be..a3e8e7fdec 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_microsite_accessibility.yml b/.github/workflows/verify_microsite_accessibility.yml index 220e2633c3..b2c98c1e58 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_storybook-noop.yml b/.github/workflows/verify_storybook-noop.yml index a1a1c1965d..1f9ded9587 100644 --- a/.github/workflows/verify_storybook-noop.yml +++ b/.github/workflows/verify_storybook-noop.yml @@ -28,7 +28,7 @@ jobs: name: Storybook steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index e9da9f0398..9bea2f3dc9 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -28,7 +28,7 @@ jobs: name: Storybook steps: - name: Harden Runner - uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit @@ -42,7 +42,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@772cef06641090d0095188e15c85647acdf0c250 # v0.6.11 + uses: backstage/actions/yarn-install@3c138326f7fcbf253b88170c1f29bae8e975d47c # v0.6.14 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: storybook yarn install @@ -51,7 +51,7 @@ jobs: - run: yarn build-storybook - - uses: chromaui/action@fdbe7756d4dbf493e2fbb822df73be7accd07e1c # v11 + - uses: chromaui/action@b984808b772126a9f44b2b7737b131b68a2ede32 # v11 with: token: ${{ secrets.GITHUB_TOKEN }} # projectToken intentionally shared to allow collaborators to run Chromatic on forks diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index 109e2ee96e..feb209dc2b 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@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 + uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1 with: egress-policy: audit diff --git a/.gitignore b/.gitignore index 6db4bf549c..865918c1f7 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,9 @@ coverage # Bower dependency directory (https://bower.io/) bower_components +# Documentation reference, generated by build:api-docs +docs/reference + # node-waf configuration .lock-wscript diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f10116844b..c1a0283f09 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ Our vision for Backstage is for it to become the trusted standard toolbox (read: UX layer) for the open source infrastructure landscape. Think of it like Kubernetes for developer experience. We realize this is an ambitious goal. We can’t do it alone. -Therefore we want to create a strong community of contributors -- all working together to create the kind of delightful experience that our developers deserve. +Therefore, we want to create a strong community of contributors -- all working together to create the kind of delightful experience that our developers deserve. Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given. ❤️ @@ -41,7 +41,7 @@ We encourage you to catch any accessibility issues already in the development ph ## Get Started! -So...feel ready to jump in? Let's do this. 👏🏻💯 +So... feel ready to jump in? Let's do this. 👏🏻💯 ### Cloning the Repository @@ -103,7 +103,7 @@ If you want to get a better understanding of the layout of the repo now that you ## 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. +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. A consistent coding style is included via [EditorConfig](https://editorconfig.org/) with the file [`.editorconfig`](.editorconfig) at the root of the repo. Depending on your editor of choice, it will either support it out of the box or you can [download a plugin](https://editorconfig.org/#download) for the config to be applied. @@ -184,7 +184,7 @@ Changesets **are** needed for new packages, as that is what triggers the package ### Writing changesets -Changesets are an important part of the development process. They are used to generate Changelog entries for all changes to the project. Ultimately they are read by the end users to learn about important changes and fixes to the project. Some of these fixes might require manual intervention from users so it's important to write changesets that users understand and can take action on. +Changesets are an important part of the development process. They are used to generate Changelog entries for all changes to the project. Ultimately, they are read by the end users to learn about important changes and fixes to the project. Some of these fixes might require manual intervention from users so it's important to write changesets that users understand and can take action on. Here are some important do's and don'ts when writing changesets: @@ -274,7 +274,7 @@ These changes are **required** to `packages/backend/src/plugins/catalog.ts` As with other CNCF projects, Backstage has adopted a [Developers Certificate of Origin (DCO)](https://developercertificate.org/). A DCO is a lightweight way for a developer to certify that they wrote or otherwise have the right to submit code or documentation to a project. -To certify the code you submit to the repository you'll need to add a `Signed-off-by` line to your commits. +To certify the code you submit to the repository, you'll need to add a `Signed-off-by` line to your commits. `$ git commit -s -m 'Awesome commit message'` @@ -330,9 +330,9 @@ There are two ways you can do this: 1. You can run `yarn build:api-reports` from the root of the project and it will go through all of the existing API Reports and update them or create new ones as needed. This may take a while but is generally the best method if you are new to this. 2. You can run `yarn build:api-reports plugins/` from the root and it will update the existing API Report or create a new one. -> Note: the above commands assume you've run `yarn install` before hand or recently +> Note: the above commands assume you've run `yarn install` beforehand or recently. -Each plugin/package has its own API Report which means you might see more then one file updated or created depending on your changes. These changes will then need to be committed as well. +Each plugin/package has its own API Report which means you might see more than one file updated or created depending on your changes. These changes will then need to be committed as well. ## Submitting a Pull Request @@ -374,7 +374,7 @@ Once you've submitted a Pull Request (PR) the various bots will come out and do - checking for commits for their DCO (Developer Certificate of Origin) - kick of the various CI builds -Once these have been completed it's just a matter of being patient as the reviewers have time they will begin to review your PR. When the review begins there may be a few layers to this but the general rule is that you need approval from one of the core maintainers and one from the specific area impacted by your PR. You may also have someone from the community review your changes, this can really help speed things up as they may catch some early items making the review for the maintainers simpler. Once you have the two (2) approvals it's ready to be merged, this task is also done by the maintainers. +Once these steps are completed, it's just a matter of being patient. As the reviewers have time, they will begin reviewing your PR. When the review process begins, there may be a few layers to this, but the general rule is that you need approval from one of the core maintainers and one from the specific area impacted by your PR. You may also have someone from the community review your changes. This can really help speed things up as they may catch some early items making the review for the maintainers simpler. Once you have the two (2) approvals, it's ready to be merged, a task that is also performed by the maintainers. ### Review Tips diff --git a/SECURITY.md b/SECURITY.md index 8de1307356..5c6c8106d5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -59,14 +59,14 @@ function writeTemporaryFile(tmpDir: string, name: string, content: string) { If the `name` of the file is controlled by the user, they can for example enter `../../../../etc/hosts` as the name of the file. This can lead to a file being written outside the intended directory, which in turn can be used to inject malicious code or other form of attacks. -The recommended solution to this is to use `resolveSafeChildPath` from `@backstage/backend-common` to resolve the file path instead. It makes sure that the resolved path does not fall outside the provided directory. If you simply want to validate whether a file path is safe, you can use `isChildPath` instead. +The recommended solution to this is to use `resolveSafeChildPath` from `@backstage/backend-plugin-api` to resolve the file path instead. It makes sure that the resolved path does not fall outside the provided directory. If you simply want to validate whether a file path is safe, you can use `isChildPath` instead. The insecure example above should instead be written like this: ```ts // THIS IS GOOD, DO THIS -import { resolveSafeChildPath } from '@backstage/backend-common'; +import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; import fs from 'fs-extra'; function writeTemporaryFile(tmpDir: string, name: string, content: string) { diff --git a/beps/0002-dynamic-frontend-plugins/README.md b/beps/0002-dynamic-frontend-plugins/README.md index 34c6e2d435..db223c959d 100644 --- a/beps/0002-dynamic-frontend-plugins/README.md +++ b/beps/0002-dynamic-frontend-plugins/README.md @@ -301,7 +301,7 @@ An example of [integration with scalprum](https://github.com/backstage/backstage **Dynamic Feature configuration** -The dynamic remote loading can be added directly into the [`createApp`](https://github.com/backstage/backstage/blob/master/packages/frontend-app-api/src/wiring/createApp.tsx#L234) function. +The dynamic remote loading can be added directly into the [`createApp`](https://backstage.io/docs/reference/frontend-defaults.createapp) function. The current `feature` type can be expanded with a `DynamicFrontendFeature` type: @@ -351,7 +351,7 @@ const scalprum = initialize({ }); ``` -Because the [`appLoader`](https://github.com/backstage/backstage/blob/master/packages/frontend-app-api/src/wiring/createApp.tsx#L193) is already async, it is a perfect place to load the plugin registry and init the dynamic plugins. +Because the [`appLoader`](https://backstage.io/docs/reference/frontend-defaults.createapp) is already async, it is a perfect place to load the plugin registry and init the dynamic plugins. Initializing the dynamic feature is just a case of mapping the `DynamicFrontendFeature` to `FrontendFeature` via Scalprum: diff --git a/contrib/docs/tutorials/help-im-behind-a-corporate-proxy.md b/contrib/docs/tutorials/help-im-behind-a-corporate-proxy.md index deef356d84..3aab9261c9 100644 --- a/contrib/docs/tutorials/help-im-behind-a-corporate-proxy.md +++ b/contrib/docs/tutorials/help-im-behind-a-corporate-proxy.md @@ -111,3 +111,7 @@ The `proxy-agent` package can be used as an alternative to `global-agent` (do no ``` 4. Start the backend with `yarn start` + +## Backstage CLI + +The Backstage CLI [versions:bump](https://backstage.io/docs/tooling/cli/commands#versionsbump) command also supports proxies via `global-agent` environment variable configuration. See the [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated/#proxy) docs for more information. diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 90b1e2c7ef..0000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# This is generated by build:api-docs in the root -reference diff --git a/docs/api/utility-apis.md b/docs/api/utility-apis.md index 44c00d1ab7..5df8fc334a 100644 --- a/docs/api/utility-apis.md +++ b/docs/api/utility-apis.md @@ -6,10 +6,7 @@ description: Backstage Utility APIs ## Introduction -Backstage Plugins strive to be self-contained, with as much functionality as -possible residing within the plugin itself and its backend APIs. There will -however always be a need for plugins to communicate outside of its boundaries, -both with other plugins and the app itself. +Backstage plugins strive to be self-contained, with as much functionality as possible residing within the plugin itself and its backend APIs. There will, however, always be a need for plugins to communicate outside of their boundaries, both with other plugins and with the app itself. Backstage provides two primary methods for plugins to communicate across their boundaries in client-side code. The first one being the @@ -61,7 +58,7 @@ Note that there is no explicit type given for embedded, and [`useApi`](../reference/core-plugin-api.useapi.md) is able to infer the type. -Also note that consuming Utility APIs is not limited to plugins, it can be done +Also note that consuming Utility APIs is not limited to plugins; it can be done from any component inside Backstage, including the ones in [`@backstage/core-plugin-api`](../reference/core-plugin-api.md). The only requirement is that they are beneath the `AppProvider` in the react tree. @@ -93,7 +90,7 @@ createApiFactory({ }); ``` -In this example the [`errorApiRef`](../reference/core-plugin-api.errorapiref.md) +In this example, the [`errorApiRef`](../reference/core-plugin-api.errorapiref.md) is our API, which encapsulates the [`ErrorApi`](../reference/core-plugin-api.errorapi.md) type. The [`alertApiRef`](../reference/core-plugin-api.alertapiref.md) is our single @@ -135,11 +132,11 @@ there is no step that needs to be taken to include these APIs in an app. ### Plugin APIs In addition to the core APIs, plugins can define and export their own APIs. -While doing so they should usually also provide default implementations of their -own APIs, for example, the `catalog` plugin exports `catalogApiRef`, and also +While doing so, they should usually also provide default implementations of their +own APIs; for example, the `catalog` plugin exports `catalogApiRef` and also supplies a default [`ApiFactory`](../reference/core-plugin-api.apifactory.md) of that API using the `CatalogClient`. There is one restriction to plugin-provided -API Factories: plugins may not supply factories for core APIs, trying to do so +API Factories: plugins may not supply factories for core APIs; trying to do so will cause the app to refuse to start. Plugins supply their APIs through the `apis` option of @@ -165,16 +162,16 @@ export const techdocsPlugin = createPlugin({ ### App APIs Lastly, the app itself is the final point where APIs can be added, and what has -the final say in what APIs will be loaded at runtime. The app may override the +the final say in what APIs will be loaded at runtime? The app may override the factories for any of the core or plugin APIs, with the exception of the config, app theme, and identity APIs. These are static APIs that are tied into the -[`createApp`](../reference/app-defaults.createapp.md) implementation, and +[`createApp`](../reference/app-defaults.createapp.md) implementation and therefore not possible to override. Overriding APIs is useful for apps that want to switch out behavior to tailor it -to their environment. In some cases plugins may also export multiple +to their environment. In some cases plugins, may also export multiple implementations of the same API, where they each have their own different -requirements on for example backend storage and surrounding environment. +requirements, for example, backend storage and the surrounding environment. Supplying APIs to the app works just like for plugins: @@ -238,21 +235,14 @@ checked by the type embedded in the ## Defining custom Utility APIs Plugins are free to define their own Utility APIs. Simply define the TypeScript -interface for the API, and create an +interface for the API and create an [`ApiRef`](../reference/core-plugin-api.apiref.md) using [`createApiRef`](../reference/core-plugin-api.createapiref.md) exported from -[`@backstage/core-plugin-api`](../reference/core-plugin-api.md). Also be sure to -provide at least one implementation of the API, and to declare a default factory +[`@backstage/core-plugin-api`](../reference/core-plugin-api.md). Also, be sure to +provide at least one implementation of the API and to declare a default factory for the API in [`createPlugin`](../reference/core-plugin-api.createplugin.md). -Custom Utility APIs can be either public or private, which is up to the plugin -to choose. Private APIs do not expose an external API surface, and it's -therefore possible to make breaking changes to the API without affecting other -users of the plugin. If an API is made public however, it opens up for other -plugins to make use of the API, and it also makes it possible for users for your -plugin to override the API in the app. It is however important to maintain -backwards compatibility of public APIs, as you may otherwise break apps that are -using your plugin. +Custom Utility APIs can be either public or private, which is up to the plugin to choose. Private APIs do not expose an external API surface, and it's therefore possible to make breaking changes to the API without affecting other users of the plugin. If an API is made public, however, it opens up for other plugins to make use of the API, and it also makes it possible for users for your plugin to override the API in the app. It is, however, important to maintain backward compatibility of public APIs, as you may otherwise break apps that are using your plugin. To make an API public, simply export the [`ApiRef`](../reference/core-plugin-api.apiref.md) of the API, and any associated diff --git a/docs/auth/add-auth-provider.md b/docs/auth/add-auth-provider.md index d1dad0b183..8ea8a4ffc0 100644 --- a/docs/auth/add-auth-provider.md +++ b/docs/auth/add-auth-provider.md @@ -1,13 +1,12 @@ --- id: add-auth-provider -title: Contributing New Providers +title: Contributing New Provider Modules description: Documentation on adding new authentication providers --- :::note Note -The primary audience for this documentation are contributors to the main -Backstage project that want to add support for new authentication providers. +The primary audience for this documentation are contributors that want to add support for new authentication providers. While you can follow it to implement your own custom providers it is much more advanced than using our built-in providers. @@ -122,191 +121,137 @@ due to its comprehensive set of supported authentication ### Quick guide -[1.](#installing-the-dependencies) Install the passport-js based provider -package. +[1.](#create-new-auth-provider-module) Create a new auth provider module -[2.](#create-implementation) Create a new folder structure for the provider. +[3.](#adding-an-oauth-based-provider) or [adding a proxy auth based provider](#creating-proxy-auth-based-provider) depending on your needs. -[3.](#adding-an-oauth-based-provider) Implement the provider, extending the -suitable framework if needed. +[4.](#add-the-provider-to-the-backend) Add the provider to the backend. -[4.](#hook-it-up-to-the-backend) Add the provider to the backend. +### Create new auth provider module -### Installing the dependencies: +In this example we will create auth module for a made up service named foobar. + +Create a new module using `yarn new`, pick `backend-module` and provide `auth-backend` as the plugin ID and `foobar-provider` as the module ID. + +Make sure that the module has the appropriate passport provider as a dependency. ```bash -cd plugins/auth-backend +cd plugins/auth-backend-backend-module-foobar-provider yarn add passport-provider-a yarn add @types/passport-provider-a ``` -### Create implementation - -Make a new folder with the name of the provider following the below file -structure: - -```bash -plugins/auth-backend/src/providers/providerA -├── index.ts -└── provider.ts -``` - -**`plugins/auth-backend/src/providers/providerA/provider.ts`** defines the -provider class which implements a handler for the chosen framework. - ### Adding an OAuth based provider -If we're adding an `OAuth` based provider we would implement the -`OAuthHandlers` interface. By implementing this -interface we can use the `OAuthProvider` class provided by `lib/oauth`, meaning -we don't need to implement the full -`AuthProviderRouteHandlers` interface that providers -otherwise need to implement. +We're then creating a new module that can extend the Auth backend using the `authProvidersExtensionPoint`. -The provider class takes the provider's options as a class parameter. It also -imports the `Strategy` from the passport package. +```ts title="plugins/auth-backend-foobar-provider/src/module.ts" +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { + authProvidersExtensionPoint, + commonSignInResolvers, + createOAuthProviderFactory, +} from '@backstage/plugin-auth-node'; +import { providerAuthenticator } from './authenticator'; -```ts -import { Strategy as ProviderAStrategy } from 'passport-provider-a'; - -export type ProviderAProviderOptions = OAuthProviderOptions & { - // extra options here -} - -export class ProviderAAuthProvider implements OAuthHandlers { - private readonly _strategy: ProviderAStrategy; - - constructor(options: ProviderAProviderOptions) { - this._strategy = new ProviderAStrategy( - { - clientID: options.clientId, - clientSecret: options.clientSecret, - callbackURL: options.callbackUrl, - passReqToCallback: false, - response_type: 'code', - /// ... etc - } - verifyFunction, // See the "Verify Callback" section - ); - } - - async start() {} - async handler() {} -} -``` - -### Adding an non-OAuth based provider - -An non-`OAuth` based provider could implement -`AuthProviderRouteHandlers` instead. - -```ts -type ProviderAOptions = { - // ... -}; - -export class ProviderAAuthProvider implements AuthProviderRouteHandlers { - private readonly _strategy: ProviderAStrategy; - - constructor(options: ProviderAOptions) { - this._strategy = new ProviderAStrategy( - { - // ... +/** @public */ +export const authModuleFoobarProvider = createBackendModule({ + pluginId: 'auth', + moduleId: 'foobar', + register(reg) { + reg.registerInit({ + deps: { + providers: authProvidersExtensionPoint, }, - verifyFunction, // See the "Verify Callback" section - ); - } - - async start() {} - async frameHandler() {} - async logout() {} - async refresh() {} // If supported -} -``` - -#### Integration Wrapper - -Each provider exports an object that provides a way to create new instances -of the provider, along with related utilities like predefined sign-in resolvers. - -The object is created using `createAuthProviderIntegration`, with the most -important part being the `create` method that acts as the factory function -for our provider. - -The factory should return an implementation of `AuthProviderFactory`, which -passes in a object with utilities for configuration, logging, token issuing, -etc. The factory should return an implementation of -`AuthProviderRouteHandlers`. - -The factory is what decides the mapping from -[static configuration](../conf/index.md) to the creation of auth providers. For -example, OAuth providers use `OAuthEnvironmentHandler` to allow for multiple -different configurations, one for each environment, which looks like this; - -```ts -export const okta = createAuthProviderIntegration({ - create(options?: { - /** - * The profile transformation function used to verify and convert the auth response - * into the profile that will be presented to the user. - */ - authHandler?: AuthHandler; - - /** - * Configure sign-in for this provider, without it the provider can not be used to sign users in. - */ - signIn?: { - /** - * Maps an auth result to a Backstage identity for the user. - */ - resolver: SignInResolver; - }; - }) { - return ({ providerId, globalConfig, config, resolverContext }) => - OAuthEnvironmentHandler.mapConfig(config, envConfig => { - // read options from config - const clientId = envConfig.getString('clientId'); - const clientSecret = envConfig.getString('clientSecret'); - - // Use provided auth handler, or create a default one - const authHandler: AuthHandler = options?.authHandler - ? options.authHandler - : async ({ fullProfile, params }) => ({ - profile: makeProfileInfo(fullProfile, params.id_token), - }); - - // instantiate our OAuthHandlers implementation - const provider = new OktaAuthProvider({ - audience, - clientId, - clientSecret, - callbackUrl, - authHandler, - signInResolver: options?.signIn?.resolver, - resolverContext, + async init({ providers }) { + providers.registerProvider({ + providerId: 'foobar', + factory: createOAuthProviderFactory({ + authenticator: providerAuthenticator, + signInResolverFactories: { + ...commonSignInResolvers, + }, + }), }); - - // Wrap the OAuthHandlers with OAuthProvider, which implements AuthProviderRouteHandlers - return OAuthProvider.fromConfig(globalConfig, provider, { - providerId, - tokenIssuer, - }); - }); - }, - resolvers: { - /** - * Looks up the user by matching their email local part to the entity name. - */ - emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver, - - // ... additional predefined resolvers + }, + }); }, }); ``` -The purpose of the different environments is to allow for a single auth-backend -to serve as the authentication service for multiple different frontend -environments, such as local development, staging, and production. +Now let's implement the actual authenticator for our provider using `Strategy` from a passport package. +The authenticator is responsible for creating the passport strategy and handling the authentication flow using secrets from the config file. + +```ts title="plugins/auth-backend-foobar-provider/src/authenticator.ts" +import { Strategy as ProviderStrategy } from 'passport-provider-a'; +import { + createOAuthAuthenticator, + PassportOAuthAuthenticatorHelper, + PassportOAuthDoneCallback, + PassportProfile, +} from '@backstage/plugin-auth-node'; + +/** @public */ +export const providerAuthenticator = createOAuthAuthenticator({ + defaultProfileTransform: + PassportOAuthAuthenticatorHelper.defaultProfileTransform, + scopes: { + // Scopes required by the provider + required: ['openid', 'email', 'profile', 'offline_access'], + }, + initialize({ callbackUrl, config }) { + const clientId = config.getString('clientId'); + const clientSecret = config.getString('clientSecret'); + + return PassportOAuthAuthenticatorHelper.from( + new ProviderStrategy( + { + clientID: clientId, + clientSecret: clientSecret, + // ... other options + }, + ( + accessToken: string, + refreshToken: string, + params: any, + fullProfile: PassportProfile, + done: PassportOAuthDoneCallback, + ) => { + done( + undefined, + { fullProfile, params, accessToken }, + { refreshToken }, + ); + }, + ), + ); + }, + + async start(input, helper) { + return helper.start(input); + }, + + async authenticate(input, helper) { + return helper.authenticate(input); + }, + + async refresh(input, helper) { + return helper.refresh(input); + }, +}); +``` + +Here are some examples of authenticators that are already implemented in the codebase: + +- [Google](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-google-provider/src/authenticator.ts) +- [Github](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-github-provider/src/authenticator.ts) +- [Okta](https://github.com/backstage/backstage/blob/master/plugins/auth-backend-module-okta-provider/src/authenticator.ts) + +### Creating proxy auth based provider + +A proxy auth provider is a provider that uses another provider to authenticate for example Google IAP or AWS ALB, please note that those providers are already supported by Backstage. + +The implementation is similar to the OAuth provider, but the `authenticator` function is different. There are already some examples on how to implement a proxy provider in the codebase, for example [auth-backend-module-gcp-iap-provider](https://github.com/backstage/backstage/tree/master/plugins/auth-backend-module-gcp-iap-provider) and [auth-backend-module-aws-alb-provider](https://github.com/backstage/backstage/tree/master/plugins/auth-backend-module-aws-alb-provider) #### Verify Callback @@ -323,27 +268,20 @@ environments, such as local development, staging, and production. > > http://www.passportjs.org/docs/configure/ -**`plugins/auth-backend/src/providers/providerA/index.ts`** is simply -re-exporting the factory function to be used for hooking the provider up to the -backend. +### Add the provider to the backend + +The process for adding the new module is the same as for any other type of module or backend plugin. + +If this provider is internal to your installation the import path that you add to `packages/backend/src/index.ts` would be something like: ```ts -export { createProviderAProvider } from './provider'; +backend.add(import('@internal/plugin-auth-backend-module-foobar-provider')); ``` -### Hook it up to the backend - -**`plugins/auth-backend/src/providers/factories.ts`** When the `auth-backend` -starts it sets up routing for all the available providers by calling -the factory function of each provider. You need to import the factory -function from the provider and add it to the factory: +But if this module is contributed directly to Backstage the module would be imported as ```ts -import { createProviderAProvider } from './providerA'; - -const factories: { [providerId: string]: AuthProviderFactory } = { - providerA: createProviderAProvider, -}; +backend.add(import('@backstage/plugin-auth-backend-module-foobar-provider')); ``` By doing this `auth-backend` automatically adds these endpoints: 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 4dfca00d4e..db78faaced 100644 --- a/docs/backend-system/building-plugins-and-modules/01-index.md +++ b/docs/backend-system/building-plugins-and-modules/01-index.md @@ -159,8 +159,7 @@ The same applies for modules that perform their own migrations and interact with the database. They will run on the same logical database instance as the target plugin, so care must be taken to choose table names that do not risk colliding with those of the plugin. A recommended naming pattern is `__`, for example the `@backstage/backend-tasks` package creates -tables named `backstage_backend_tasks__
`. If you use the default [`Knex` migration facilities](https://knexjs.org/guide/migrations.html), you will also +name>__
`, for example the scheduler core service creates tables named `backstage_backend_tasks__
`, because it used to be the case that the service lived in a package named `@backstage/backend-tasks`. Things have since moved around a bit, but the effects of the rule are still visible. If you use the default [`Knex` migration facilities](https://knexjs.org/guide/migrations.html), you will also want to make sure that it uses similarly prefixed migration state tables for its internal bookkeeping needs, so they do not collide with the main ones used by the plugin itself. You can do this as follows: 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 addcc72c84..38107f0242 100644 --- a/docs/backend-system/building-plugins-and-modules/02-testing.md +++ b/docs/backend-system/building-plugins-and-modules/02-testing.md @@ -31,17 +31,20 @@ import { myPlugin } from './plugin.ts'; describe('myPlugin', () => { it('can serve values from config', async () => { const fakeConfig = { myPlugin: { value: 7 } }; + const mockLogger = mockServices.logger.mock(); const { server } = await startTestBackend({ features: [ myPlugin(), mockServices.rootConfig.factory({ data: fakeConfig }), + mockLogger, ], }); const response = await request(server).get('/api/example/get-value'); expect(response.status).toBe(200); expect(response.body).toEqual({ value: 7 }); + expect(mockLogger.info).toHaveBeenCalledWith('Starting myPlugin'); }); }); ``` @@ -53,6 +56,76 @@ The returned server also has a `port()` method which returns the dynamically bound listening port. You can use this to perform lower level network interactions with the running test service. +### mock services + +The [`mockServices`](https://backstage.io/docs/reference/backend-test-utils.mockservices) object from `@backstage/backend-test-utils` provides service factory functions, and mocks for all core services that you can use to verify interactions between plugin and services. + +All mock services provide a factory function that is sufficient for most tests. Here's an example: + +```ts +const fakeConfig = { myPlugin: { value: 7 } }; +const { server } = await startTestBackend({ + features: [ + // Will provide access to the default urlReaders automatically. + mockServices.urlReader.factory(), + // Some factories accept options, in this example we provide some fake config. + mockServices.rootConfig.factory({ data: fakeConfig }), + ], +}); +``` + +There might be situations where you want to mock a service implementation to verify interactions, in those cases you can use the `mock` function to get a mock object that you can interact with. Here's an example: + +```ts +import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; +import { myPlugin } from './plugin.ts'; + +describe('myPlugin', () => { + it('should call use UrlReader', async () => { + const mockReader = mockServices.urlReader.mock(); + + await startTestBackend({ + features: [myPlugin(), mockReader], + }); + + expect(mockReader.readUrl).toHaveBeenCalledWith('https://backstage.io'); + }); + + it('should call use UrlReader again', async () => { + const partialImpl = jest.fn(); + await startTestBackend({ + features: [ + myPlugin(), + // You could also supply partial implementations to the mock function. + mockServices.urlReader.mock({ readUrl: partialImpl }), + ], + }); + expect(partialImpl).toHaveBeenCalledWith('https://backstage.io'); + }); +}); +``` + +Available services: + +- [`auth`](https://backstage.io/docs/reference/backend-test-utils.mockservices.auth/) +- [`cache`](https://backstage.io/docs/reference/backend-test-utils.mockservices.cache/) +- [`database`](https://backstage.io/docs/reference/backend-test-utils.mockservices.database/) +- [`discovery`](https://backstage.io/docs/reference/backend-test-utils.mockservices.discovery/) +- [`events`](https://backstage.io/docs/reference/backend-test-utils.mockservices.events/) +- [`httpAuth`](https://backstage.io/docs/reference/backend-test-utils.mockservices.httpAuth/) +- [`httpRouter`](https://backstage.io/docs/reference/backend-test-utils.mockservices.httpRouter/) +- [`lifecycle`](https://backstage.io/docs/reference/backend-test-utils.mockservices.lifecycle/) +- [`logger`](https://backstage.io/docs/reference/backend-test-utils.mockservices.logger/) +- [`permissions`](https://backstage.io/docs/reference/backend-test-utils.mockservices.permissions/) +- [`rootConfig`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootConfig/) +- [`rootHealth`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootHealth/) +- [`rootHttpRouter`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootHttpRouter/) +- [`rootLifecycle`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootLifecycle/) +- [`rootLogger`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootLogger/) +- [`scheduler`](https://backstage.io/docs/reference/backend-test-utils.mockservices.scheduler/) +- [`urlReader`](https://backstage.io/docs/reference/backend-test-utils.mockservices.urlReader/) +- [`userInfo`](https://backstage.io/docs/reference/backend-test-utils.mockservices.userInfo/) + ## Testing Remote Service Interactions If your backend plugin or service interacts with external services using HTTP diff --git a/docs/backend-system/core-services/database.md b/docs/backend-system/core-services/database.md index e083f0b44d..2a172cbe46 100644 --- a/docs/backend-system/core-services/database.md +++ b/docs/backend-system/core-services/database.md @@ -20,7 +20,7 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { resolvePackagePath } from '@backstage/backend-common'; +import { resolvePackagePath } from '@backstage/backend-plugin-api'; createBackendPlugin({ pluginId: 'example', diff --git a/docs/backend-system/core-services/url-reader.md b/docs/backend-system/core-services/url-reader.md index b9616a029e..242ffd2307 100644 --- a/docs/backend-system/core-services/url-reader.md +++ b/docs/backend-system/core-services/url-reader.md @@ -45,3 +45,114 @@ createBackendPlugin({ }, }); ``` + +## Providing custom URL readers + +You can also create an internal or bespoke reader and provide it to the backend using a service factory. The following example shows how to create a custom URL reader and provide it to the backend. + +```ts title="packages/backend/src/index.ts" +import { createBackend } from '@backstage/backend-defaults'; +import { + ReaderFactory, + urlReaderFactoriesServiceRef, +} from '@backstage/backend-defaults/urlReader'; +import { + createServiceFactory, + UrlReaderService, +} from '@backstage/backend-plugin-api'; +import { Config } from '@backstage/config'; + +class CustomUrlReader implements UrlReaderService { + static factory: ReaderFactory = ({ config, treeResponseFactory }) => { + const reader = new CustomUrlReader(config); + const predicate = (url: URL) => url.host === 'myCustomDomain'; + return [{ reader, predicate }]; + }; + + constructor(private readonly config: Config) {} + // implementations of read, readTree and search methods skipped for this example +} + +const customReader = createServiceFactory({ + service: urlReaderFactoriesServiceRef, + deps: {}, + async factory() { + return CustomUrlReader.factory; + }, +}); + +const backend = createBackend(); +// backend.add() of other plugins and modules excluded +backend.add(customReader); +``` + +## Writing URL Readers + +We want to make sure all URL Readers behave in the same way. Hence if possible, +all the methods of the `UrlReaderService` interface should be implemented. However it +is okay to start by implementing just one of them and creating issues for the +remaining ones. + +You can choose to make new URL Readers open source if the use case is beneficial to other users. Either as its own package or by updating the +[`default` factory](https://github.com/backstage/backstage/blob/ce2ca68f07ad3334401d3277b989bf145b728a64/packages/backend-defaults/src/entrypoints/urlReader/lib/UrlReaders.ts#L82-L102) +method of URL Readers. It's recommended to create an issue in the Backstage repository to discuss the use case and get feedback before starting the implementation of a new core URL Reader. + +Here are some general guidelines for writing URL Readers + +#### `readUrl` + +`readUrl` method expects a user-friendly URL, something which can be copied from +the browser naturally when a person is browsing the provider in their browser. + +- ✅ Valid URL : + `https://github.com/backstage/backstage/blob/master/ADOPTERS.md` +- ❌ Not a valid URL : + `https://raw.githubusercontent.com/backstage/backstage/master/ADOPTERS.md` +- ❌ Not a valid URL : `https://github.com/backstage/backstage/ADOPTERS.md` + +Upon receiving the URL, `readUrl` converts the user-friendly URL into an API URL +which can be used to request the provider's API. + +`readUrl` then makes an authenticated request to the provider API and returns the response containing the file's contents and `ETag` (if the provider supports it). + +#### `readTree` + +`readTree` method also expects user-friendly URLs similar to `read` but the URL +should point to a tree (could be the root of a repository or even a +sub-directory). + +- ✅ Valid URL : `https://github.com/backstage/backstage` +- ✅ Valid URL : `https://github.com/backstage/backstage/blob/master` +- ✅ Valid URL : `https://github.com/backstage/backstage/blob/master/docs` + +Using the provider's API documentation, find out an API endpoint which can be +used to download either a zip or a tarball. You can download the entire tree +(e.g. a repository) and filter out in case the user is expecting only a +sub-tree. But some APIs are smart enough to accept a path and return only a +sub-tree in the downloaded archive. + +#### `search` + +`search` method expects a glob pattern of a URL and returns a list of files +matching the query. + +- ✅ Valid URL : + `https://github.com/backstage/backstage/blob/master/**/catalog-info.yaml` +- ✅ Valid URL : `https://github.com/backstage/backstage/blob/master/**/*.md` +- ✅ Valid URL : + `https://github.com/backstage/backstage/blob/master/*/package.json` +- ✅ Valid URL : `https://github.com/backstage/backstage/blob/master/README` + +The core logic of `readTree` can be used here to extract all the files inside +the tree and return the files matching the pattern in the `url`. + +### Caching + +All of the methods above support ETag based caching. If the method is called +without an ETag, the response contains the ETag of the resource (should ideally +forward the ETag returned by the provider). If the method is called with an +ETag, it first compares the ETag and returns a `NotModifiedError` in case the +resource has not been modified. This approach is very similar to the actual +[`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) and +[`If-None-Match`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) +HTTP headers. diff --git a/docs/contribute/project-structure.md b/docs/contribute/project-structure.md index 16f20a66ca..f06fba0523 100644 --- a/docs/contribute/project-structure.md +++ b/docs/contribute/project-structure.md @@ -82,9 +82,11 @@ are separated out into their own folder, see further down. package. The `backend` uses plugins to construct a working backend that the frontend (`app`) can use. -- [`backend-common/`](https://github.com/backstage/backstage/tree/master/packages/backend-common) - - There are no "core" packages in the backend. Instead we have `backend-common` - which contains helper middleware and other utils. +- [`backend-app-api/`](https://github.com/backstage/backstage/tree/master/packages/backend-app-api) - + This package contains the central wiring for how to make Backstage backends. + +- [`backend-plugin-api/`](https://github.com/backstage/backstage/tree/master/packages/backend-plugin-api) - + This package contains the core APIs that are used to make Backstage backend features such as plugins and modules. - [`catalog-client`](https://github.com/backstage/backstage/tree/master/packages/catalog-client) - An isomorphic client to interact with the Software Catalog. Backend plugins diff --git a/docs/features/software-catalog/extending-the-model.md b/docs/features/software-catalog/extending-the-model.md index 51acd44c1d..f9d20d03c2 100644 --- a/docs/features/software-catalog/extending-the-model.md +++ b/docs/features/software-catalog/extending-the-model.md @@ -597,7 +597,7 @@ import { coreServices, createBackendModule, } from '@backstage/backend-plugin-api'; -import { catalogModelExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; /* highlight-add-next-line */ import { FoobarEntitiesProcessor } from './providers'; diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 98fae5a95e..4d5b283c4e 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -1031,3 +1031,292 @@ backend.add(catalogModuleCustomDataParser); backend.start(); ``` + +## Incremental Entity Provider + +For large data sources that may not fit into memory but support pagination, the Incremental Entity Provider offers an efficient way to ingest data incrementally, handling deletions and updates seamlessly while minimizing memory usage. + +You can find more details about [why it was created](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend-module-incremental-ingestion#why-did-we-create-it) and its [requirements](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend-module-incremental-ingestion#requirements). + +### Installation + +1. Install `@backstage/plugin-catalog-backend-module-incremental-ingestion` with `yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-incremental-ingestion` from the Backstage root directory. + +2. Add the following code to the `packages/backend/src/index.ts` file: + +```ts title="packages/backend/src/index.ts" +const backend = createBackend(); + +/* highlight-add-start */ +backend.add( + import( + '@backstage/plugin-catalog-backend-module-incremental-ingestion/alpha' + ), +); +/* highlight-add-end */ + +backend.start(); +``` + +### Writing an Incremental Entity Provider + +To create an Incremental Entity Provider, you need to know how to retrieve a single page of data from an API with pagination. The `IncrementalEntityProvider` facilitates this by requiring: + +- **getProviderName:** A unique name to avoid conflicts with other providers. +- **next:** Fetches a specific page of entities, moving the cursor forward. +- **around:** Handles setup and tear-down, wrapping the process that iterates through multiple pages. + +For more information on compatibility, refer to the [requirements](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend-module-incremental-ingestion#requirements). + +In this tutorial, we'll implement an Incremental Entity Provider that interacts with an imaginary API to fetch a list of imaginary services. + +```ts +interface MyApiClient { + getServices(page: number): MyPaginatedResults; +} + +interface MyPaginatedResults { + items: T[]; + totalPages: number; +} + +interface Service { + name: string; +} +``` + +These are the only 3 methods that you need to implement. `getProviderName()` is pretty self explanatory and it's identical to the `getProviderName()` method on a regular Entity Provider. + +```ts +import { IncrementalEntityProvider } from '@backstage/plugin-catalog-backend-module-incremental-ingestion'; + +// This will include your pagination information, let's say our API accepts a `page` parameter. +// In this case, the cursor will include `page` +interface Cursor { + page: number; +} + +// This interface describes the type of data that will be passed to your burst function. +interface Context { + apiClient: MyApiClient; +} + +export class MyIncrementalEntityProvider + implements IncrementalEntityProvider +{ + getProviderName() { + return `MyIncrementalEntityProvider`; + } +} +``` + +`around` method is used for setup and tear-down. For example, if you need to create a client that will connect to the API, you would do that here. + +```ts +export class MyIncrementalEntityProvider + implements IncrementalEntityProvider +{ + getProviderName() { + return `MyIncrementalEntityProvider`; + } + + async around(burst: (context: Context) => Promise): Promise { + const apiClient = new MyApiClient(); + + await burst({ apiClient }); + + // If you need to do any teardown, you can do it here. + } +} +``` + +If you need to pass a token to your API, then you can create a constructor that will receive a token and use the token to setup the client. + +```ts +export class MyIncrementalEntityProvider + implements IncrementalEntityProvider +{ + private readonly token: string; + + constructor(token: string) { + this.token = token; + } + + getProviderName() { + return `MyIncrementalEntityProvider`; + } + + async around(burst: (context: Context) => Promise): Promise { + const apiClient = new MyApiClient(this.token); + + await burst({ apiClient }); + } +} +``` + +The last step is to implement the actual `next` method that will accept the cursor, call the API, process the result and return the result. + +```ts +export class MyIncrementalEntityProvider + implements IncrementalEntityProvider +{ + private readonly token: string; + + constructor(token: string) { + this.token = token; + } + + getProviderName() { + return `MyIncrementalEntityProvider`; + } + + async around(burst: (context: Context) => Promise): Promise { + const apiClient = new MyApiClient(this.token); + + await burst({ apiClient }); + } + + async next( + context: Context, + cursor?: Cursor = { page: 1 }, + ): Promise> { + const { apiClient } = context; + + // call your API with the current cursor + const data = await apiClient.getServices(cursor); + + // calculate the next page + const nextPage = page + 1; + + // figure out if there are any more pages to fetch + const done = nextPage > data.totalPages; + + // convert returned items into entities + const entities = data.items.map(item => ({ + entity: { + apiVersion: 'backstage.io/v1beta1', + kind: 'Component', + metadata: { + name: item.name, + annotations: { + // You need to define these, otherwise they'll fail validation + [ANNOTATION_LOCATION]: this.getProviderName(), + [ANNOTATION_ORIGIN_LOCATION]: this.getProviderName(), + }, + }, + spec: { + type: 'service', + lifecycle: 'production', // Ideally your source has this information + owner: 'unknown', // Ideally your source has this information + }, + }, + })); + + // create the next cursor + const nextCursor = { + page: nextPage, + }; + + return { + done, + entities, + cursor: nextCursor, + }; + } +} +``` + +Now that you have your new Incremental Entity Provider, we can connect it to the catalog. + +### Installing the Incremental Entity Provider + +We'll assume you followed the [Installation](#installation) instructions. Now create a module inside `packages/backend/src/extensions/catalogCustomIncrementalIngestion.ts`. + +```ts title="packages/backend/src/extensions/catalogCustomIncrementalIngestion.ts" +import { + coreServices, + createBackendModule, +} from '@backstage/backend-plugin-api'; +import { incrementalIngestionProvidersExtensionPoint } from '@backstage/plugin-catalog-backend-module-incremental-ingestion/alpha'; + +export const catalogModuleCustomIncrementalIngestionProvider = + createBackendModule({ + pluginId: 'catalog', + moduleId: 'custom-incremental-ingestion-provider', + register(env) { + env.registerInit({ + deps: { + incrementalBuilder: incrementalIngestionProvidersExtensionPoint, + config: coreServices.rootConfig, + }, + async init({ incrementalBuilder, config }) { + // Assuming the token for the API comes from config + const token = config.getString('myApiClient.token'); + const myEntityProvider = new MyIncrementalEntityProvider(token); + + const options = { + // How long should it attempt to read pages from the API in a + // single burst? Keep this short. The Incremental Entity Provider + // will attempt to read as many pages as it can in this time + burstLength: { seconds: 3 }, + + // How long should it wait between bursts? + burstInterval: { seconds: 3 }, + + // How long should it rest before re-ingesting again? + restLength: { day: 1 }, + + // Optional back-off configuration - how long should it wait to retry + // in the event of an error? + backoff: [ + { seconds: 5 }, + { seconds: 30 }, + { minutes: 10 }, + { hours: 3 }, + ], + + // Optional. Use this to prevent removal of entities above a given + // percentage. This can be helpful if a data source is flaky and + // sometimes returns a successful status, but fewer than expected + // assets to add or maintain in the catalog. + rejectRemovalsAbovePercentage: 5, + + // Optional. Similar to rejectRemovalsAbovePercentage, except it + // applies to complete, 100% failure of a data source. If true, + // a data source that returns a successful status but does not + // provide any assets to turn into entities will have its empty + // data set rejected. + rejectEmptySourceCollections: true, + }; + + incrementalBuilder.addProvider({ + provider: myEntityProvider, + options, + }); + }, + }); + }, + }); +``` + +Add the module to `packages/backend/src/index.ts` + +```ts title="packages/backend/src/index.ts" +/* highlight-add-next-line */ +import { catalogModuleCustomIncrementalIngestionProvider } from './extensions/catalogCustomIncrementalIngestion'; + +const backend = createBackend(); + +backend.add( + import( + '@backstage/plugin-catalog-backend-module-incremental-ingestion/alpha' + ), +); + +/* highlight-add-next-line */ +backend.add(catalogModuleCustomIncrementalIngestionProvider); + +backend.start(); +``` + +For a deep dive into the technical details of the Incremental Entity Provider, see [the README](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend-module-incremental-ingestion). diff --git a/docs/features/software-templates/input-examples.md b/docs/features/software-templates/input-examples.md index dd1228290f..ef90013e49 100644 --- a/docs/features/software-templates/input-examples.md +++ b/docs/features/software-templates/input-examples.md @@ -297,7 +297,7 @@ spec: type: string steps: - - $yaml: https://github.com//example/path/to/action.yaml + - $yaml: https://github.com/example/path/to/action.yaml - id: fetch name: Fetch template diff --git a/docs/features/software-templates/writing-custom-field-extensions.md b/docs/features/software-templates/writing-custom-field-extensions.md index d53b8bdf2f..feb0f68048 100644 --- a/docs/features/software-templates/writing-custom-field-extensions.md +++ b/docs/features/software-templates/writing-custom-field-extensions.md @@ -95,7 +95,7 @@ import { createScaffolderFieldExtension } from '@backstage/plugin-scaffolder-rea import { ValidateKebabCase, validateKebabCaseValidation, -} from './ValidateKebabCase/ValidateKebabCaseExtension'; +} from './ValidateKebabCaseExtension'; export const ValidateKebabCaseFieldExtension = scaffolderPlugin.provide( createScaffolderFieldExtension({ diff --git a/docs/features/techdocs/how-to-guides.md b/docs/features/techdocs/how-to-guides.md index 59198e919b..e47af8d1d7 100644 --- a/docs/features/techdocs/how-to-guides.md +++ b/docs/features/techdocs/how-to-guides.md @@ -580,6 +580,10 @@ Note: To refer external diagram files, we need to include the diagrams directory ## How to add Mermaid support in TechDocs +There are two options for adding Mermaid support in TechDocs: using [Kroki](https://kroki.io) or by using [markdown-inline-mermaid](https://github.com/johanneswuerbach/markdown-inline-mermaid). We currently use `markdown-inline-mermaid` for the [Mermaid example on the Demo site](https://demo.backstage.io/docs/default/component/backstage-demo/examples/mermaid/). + +### Using Kroki + To add `Mermaid` support in TechDocs, you can use [`kroki`](https://kroki.io) that creates diagrams from Textual descriptions. It is a single rendering gateway for all popular diagrams-as-a-code tools. It supports an enormous number @@ -678,6 +682,30 @@ Done! Now you have a support of the following diagrams along with mermaid: - `Vega-Lite` - `WaveDrom` +### Using `markdown-inline-mermaid` + +To use `markdown-inline-mermaid` to generate your Mermaid diagrams in TechDocs you'll need to do the following: + +1. In your Dockerfile you will need to make sure you install `markdown-inline-mermaid` like this: `RUN pip3 install mkdocs-techdocs-core markdown-inline-mermaid` +2. You will also need to install the `@mermaid-js/mermaid-cli`, to do that add this: `RUN yarn global add @mermaid-js/mermaid-cli` +3. Now in your `mkdocs.yml` file you will need to add the following section (this is at the root level like `plugins` which you should already have): + + ```yaml title="mkdocs.yml" + markdown_extensions: + - markdown_inline_mermaid + ``` + +4. With this in place you can now add Mermaid diagrams in your Markdown files like this: + + ````md + ```mermaid + sequenceDiagram + Alice->>John: Hello John, how are you? + John-->>Alice: Great! + Alice-)John: See you later! + ``` + ```` + ## How to implement a hybrid build strategy One limitation of the [Recommended deployment](./architecture.md#recommended-deployment) is that diff --git a/docs/frontend-system/architecture/10-app.md b/docs/frontend-system/architecture/10-app.md index 532971d124..d1c3820f09 100644 --- a/docs/frontend-system/architecture/10-app.md +++ b/docs/frontend-system/architecture/10-app.md @@ -16,7 +16,7 @@ Below is a simple example of how to create and render an app instance: ```ts import ReactDOM from 'react-dom/client'; -import { createApp } from '@backstage/frontend-app-api'; +import { createApp } from '@backstage/frontend-defaults'; // Create your app instance const app = createApp({ diff --git a/docs/frontend-system/architecture/23-extension-blueprints.md b/docs/frontend-system/architecture/23-extension-blueprints.md index ee09e7fec6..fb10749845 100644 --- a/docs/frontend-system/architecture/23-extension-blueprints.md +++ b/docs/frontend-system/architecture/23-extension-blueprints.md @@ -20,7 +20,7 @@ The following is a simple example of how one might use the blueprint `make` meth const myPageExtension = PageBlueprint.make({ params: { defaultPath: '/my-page', - loader: () => import('./components/MyPage').them(m => ), + loader: () => import('./components/MyPage').then(m => ), }, }); ``` @@ -47,7 +47,7 @@ const myPageExtension = PageBlueprint.makeWithOverrides({ return originalFactory({ defaultPath: '/my-page', loader: () => - import('./components/MyPage').them(m => ( + import('./components/MyPage').then(m => ( // We can now access values from the factory context when providing // the blueprint parameters, such as config values. @@ -104,7 +104,7 @@ Most of the options provided to `createExtensionBlueprint` can be overridden whe 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. -To do that, we create a new extension data reference for our widget title. This references is provided via the `dataRefs` options when we create the blueprint, which makes it available for use via `MyWidgetBlueprint.dataRefs.widgetTitle`. +To do that, we create a new extension data reference for our widget title. This reference is provided via the `dataRefs` options when we create the blueprint, which makes it available for use via `MyWidgetBlueprint.dataRefs.widgetTitle`. ```tsx export interface MyWidgetBlueprintParams { diff --git a/docs/frontend-system/architecture/25-extension-overrides.md b/docs/frontend-system/architecture/25-extension-overrides.md index d47e2697a9..785843f6e0 100644 --- a/docs/frontend-system/architecture/25-extension-overrides.md +++ b/docs/frontend-system/architecture/25-extension-overrides.md @@ -295,7 +295,7 @@ export default createExtensionOverrides({ Assuming the above code resides in the `@internal/search-page` package, you can install it in your app like this: ```tsx title="packages/app/src/App.tsx" -import { createApp } from '@backstage/frontend-app-api'; +import { createApp } from '@backstage/frontend-defaults'; import searchPageOverride from '@internal/search-page'; const app = createApp({ diff --git a/docs/frontend-system/architecture/36-routes.md b/docs/frontend-system/architecture/36-routes.md index e684932414..2a9b372b1c 100644 --- a/docs/frontend-system/architecture/36-routes.md +++ b/docs/frontend-system/architecture/36-routes.md @@ -256,7 +256,7 @@ app: We also have the ability to express this in code as an option to `createApp`, but you of course only need to use one of these two methods: ```tsx title="packages/app/src/App.tsx" -import { createApp } from '@backstage/frontend-app-api'; +import { createApp } from '@backstage/frontend-defaults'; import catalog from '@backstage/plugin-catalog'; import scaffolder from '@backstage/plugin-scaffolder'; diff --git a/docs/frontend-system/building-apps/01-index.md b/docs/frontend-system/building-apps/01-index.md index 16aacc1185..5b5298a2c5 100644 --- a/docs/frontend-system/building-apps/01-index.md +++ b/docs/frontend-system/building-apps/01-index.md @@ -30,13 +30,13 @@ The created-app is currently templated for legacy frontend system applications, ## The app instance -The starting point of a frontend app is the `createApp` function, which accepts a single options object as its only parameter. It is imported from `@backstage/frontend-app-api`, which is where you will find most of the common APIs for building apps. +The starting point of a frontend app is the `createApp` function, which accepts a single options object as its only parameter. It is imported from `@backstage/frontend-defaults`, which is where you will find most of the common APIs for building apps. This is how to create a minimal app: ```tsx title="in src/index.ts" import ReactDOM from 'react-dom/client'; -import { createApp } from '@backstage/frontend-app-api'; +import { createApp } from '@backstage/frontend-defaults'; import catalogPlugin from '@backstage/plugin-catalog/alpha'; // Create your app instance @@ -87,7 +87,7 @@ Previously you would customize the application routes, components, apis, sidebar A manual installation is required if your packages are not discovered automatically, either because you are not using `@backstage/cli` to build your application or because the features are defined in local modules in the app package. In order to manually install a feature, you must import it and pass it to the `createApp` function: ```tsx title="packages/app/src/App.tsx" -import { createApp } from '@backstage/frontend-app-api'; +import { createApp } from '@backstage/frontend-defaults'; // This plugin was create as a local module in the app import { somePlugin } from './plugins'; @@ -104,10 +104,10 @@ You can also pass overrides to the features array, for more details, please read ### Using an async features loader -In case you need to perform asynchronous operations before passing features to the `createApp` function, define a [feature loader](https://backstage.io/docs/reference/frontend-app-api.createappfeatureloader/) object and pass it to the `features` option: +In case you need to perform asynchronous operations before passing features to the `createApp` function, define a [feature loader](https://backstage.io/docs/reference/frontend-defaults.createappfeatureloader/) object and pass it to the `features` option: ```tsx title="packages/app/src/App.tsx" -import { createApp } from '@backstage/frontend-app-api'; +import { createApp } from '@backstage/frontend-defaults'; const app = createApp({ features: { @@ -129,7 +129,7 @@ export default app.createRoot(); In some cases we want to load our configuration from a backend server and to do so, you can pass an callback to the `configLoader` option when calling the `createApp` function, the callback should return a promise of an object with the config object: ```tsx title="packages/app/src/App.tsx" -import { createApp } from '@backstage/frontend-app-api'; +import { createApp } from '@backstage/frontend-defaults'; import { getConfigFromServer } from './utils'; // Example lazy loading the app configuration diff --git a/docs/frontend-system/building-apps/08-migrating.md b/docs/frontend-system/building-apps/08-migrating.md index ceb3f34c35..96e7dd2bd5 100644 --- a/docs/frontend-system/building-apps/08-migrating.md +++ b/docs/frontend-system/building-apps/08-migrating.md @@ -18,7 +18,7 @@ The first step in migrating an app is to switch out the `createApp` function for // highlight-remove-next-line import { createApp } from '@backstage/app-defaults'; // highlight-add-next-line -import { createApp } from '@backstage/frontend-app-api'; +import { createApp } from '@backstage/frontend-defaults'; ``` This immediate switch will lead to a lot of breakages that we need to fix. @@ -495,7 +495,7 @@ The entity pages are typically defined in `packages/app/src/components/catalog` New apps feature a built-in sidebar extension (`app/nav`) that will render all nav item extensions provided by plugins. This is a placeholder implementation and not intended as a long-term solution. In the future we will aim to provide a more flexible sidebar extension that allows for more customization out of the box. -Because the built-in sidebar is quite limited you may want to override the sidebar with your own custom implementation. To do so, use `createExtension` directly and refer to the [original sidebar implementation](https://github.com/backstage/backstage/blob/master/packages/frontend-app-api/src/extensions/AppNav.tsx). The following is an example of how to take your existing sidebar from the `Root` component that you typically find in `packages/app/src/components/Root.tsx`, and use it in an [extension override](../architecture/25-extension-overrides.md): +Because the built-in sidebar is quite limited you may want to override the sidebar with your own custom implementation. To do so, use `createExtension` directly and refer to the [original sidebar implementation](https://github.com/backstage/backstage/blob/master/plugins/app/src/extensions/AppNav.tsx). The following is an example of how to take your existing sidebar from the `Root` component that you typically find in `packages/app/src/components/Root.tsx`, and use it in an [extension override](../architecture/25-extension-overrides.md): ```tsx const nav = createExtension({ diff --git a/docs/frontend-system/building-plugins/01-index.md b/docs/frontend-system/building-plugins/01-index.md index 57a783d406..633afd6ce8 100644 --- a/docs/frontend-system/building-plugins/01-index.md +++ b/docs/frontend-system/building-plugins/01-index.md @@ -64,8 +64,8 @@ export const rootRouteRef = createRouteRef(); ```tsx title="in src/plugin.ts" import { createFrontendPlugin, - createPageExtension, - createNavItemExtension, + PageBlueprint, + NavItemBlueprint, } from '@backstage/frontend-plugin-api'; import { rootRouteRef } from './routes'; @@ -155,10 +155,7 @@ export function ExamplePage() { ``` ```tsx title="in src/plugin.ts - Registering a factory for our API" -import { - createApiFactory, - createApiExtension, -} from '@backstage/frontend-plugin-api'; +import { createApiFactory, ApiBlueprint } from '@backstage/frontend-plugin-api'; import { exampleApiRef, DefaultExampleApi } from './api'; // highlight-add-start diff --git a/docs/getting-started/config/authentication.md b/docs/getting-started/config/authentication.md index e97ed3d89c..5d0262c682 100644 --- a/docs/getting-started/config/authentication.md +++ b/docs/getting-started/config/authentication.md @@ -1,50 +1,54 @@ --- id: authentication title: Authentication -description: How to set up authentication into your Backstage installation +description: How to setup authentication for your Backstage app --- Audience: Admins or Developers -### Setting up authentication +## Summary -There are multiple authentication providers available for you to use with -Backstage, feel free to follow -[the instructions for adding authentication](../../auth/index.md). +We'll be walking you through how to setup authentication for your Backstage app using Github. After finishing this guide, you'll have both working authentication and users in your Backstage app to match to the users logging in! -For this tutorial we choose to use GitHub, a free service most of you might be -familiar with. For other options, see -[the auth provider documentation](../../auth/github/provider.md#create-an-oauth-app-on-github). +There are multiple authentication providers available for you to use with Backstage, feel free to follow [their instructions for adding authentication](../../auth/index.md). -Go to -[https://github.com/settings/applications/new](https://github.com/settings/applications/new) -to create your OAuth App. The `Homepage URL` should point to Backstage's -frontend, in our tutorial it would be `http://localhost:3000`. The -`Authorization callback URL` will point to the auth backend, which will most -likely be `http://localhost:7007/api/auth/github/handler/frame`. +:::note Note + +The default Backstage app comes with a guest Sign In Resolver. This resolver makes all users share a single "guest" identity and is only intended as a minimum requirement to quickly get up and running. You can read more about how [Sign In Resolvers](../../auth/identity-resolver.md#sign-in-resolvers) play a role in creating a [Backstage User Identity](../../auth/identity-resolver.md#backstage-user-identity) for logged in users. + +::: + +## Setting up authentication + +For this tutorial we choose to use GitHub, a free service most of you might be familiar with, and we'll be using an OAuth app. For detailed options, see +[the GitHub auth provider documentation](../../auth/github/provider.md#create-an-oauth-app-on-github). + +Go to [https://github.com/settings/applications/new](https://github.com/settings/applications/new) to create your OAuth App. The "Homepage URL" should point to Backstage's frontend, in our tutorial it would be `http://localhost:3000`. The "Authorization callback URL" will point to the auth backend, which will most likely be `http://localhost:7007/api/auth/github/handler/frame`. ![Screenshot of the GitHub OAuth creation page](../../assets/getting-started/gh-oauth.png) -Take note of the `Client ID` and the `Client Secret`. Open `app-config.yaml`, -and add your `clientId` and `clientSecret` to this file. It should end up -looking like this: +Take note of the `Client ID` and the `Client Secret` (clicking the "Generate a new client secret" button will get this value for you). Open `app-config.yaml`, and add them as `clientId` and `clientSecret` in this file. It should end up looking like this: ```yaml title="app-config.yaml" auth: # see https://backstage.io/docs/auth/ to learn about auth providers + /* highlight-add-start */ environment: development + /* highlight-add-end */ providers: + # See https://backstage.io/docs/auth/guest/provider + guest: {} + /* highlight-add-start */ github: development: clientId: YOUR CLIENT ID clientSecret: YOUR CLIENT SECRET + /* highlight-add-end */ ``` -### Add sign-in option to the frontend +## Add sign-in option to the frontend -Backstage will re-read the configuration. If there's no errors, that's great! We -can continue with the last part of the configuration. The next step is needed to -change the sign-in page, this you actually need to add in the source code. +The next step is to change the sign-in page. For this, you'll actually need to write some code. Open `packages/app/src/App.tsx` and below the last `import` line, add: @@ -71,13 +75,52 @@ components: { }, ``` -:::note Note +## Add sign-in resolver(s) -The default Backstage app comes with a guest Sign In Resolver. This resolver makes all users share a single "guest" identity and is only intended as a minimum requirement to quickly get up and running. You can read more about how [Sign In Resolvers](../../auth/identity-resolver.md#sign-in-resolvers) play a role in creating a [Backstage User Identity](../../auth/identity-resolver.md#backstage-user-identity) for logged in users. +Next we need to add the sign-in resolver to our configuration. Here's how: -::: +```yaml title="app-config.yaml" +auth: + # see https://backstage.io/docs/auth/ to learn about auth providers + environment: development + providers: + # See https://backstage.io/docs/auth/guest/provider + guest: {} + github: + development: + clientId: YOUR CLIENT ID + clientSecret: YOUR CLIENT SECRET + /* highlight-add-start */ + signIn: + resolvers: + # Matches the GitHub username with the Backstage user entity name. + # See https://backstage.io/docs/auth/github/provider#resolvers for more resolvers. + - resolver: usernameMatchingUserEntityName + /* highlight-add-end */ +``` -Restart Backstage from the terminal, by stopping it with `Control-C`, and starting it with `yarn dev` . You should be welcomed by a login prompt! +What this will do is take the user details provided by the auth provider and match that against a User in the Catalog. In this case - `usernameMatchingUserEntityName` - will match the GitHub user name with the `metadata.name` value of a User in the Catalog, if none is found you will get an "Failed to sign-in, unable to resolve user identity" message. We'll cover this in the next few sections. + +Learn more about this topic in the [Sign-in Resolvers](../../auth/identity-resolver.md#sign-in-resolvers) documentation. + +## Add the auth provider to the backend + +To add the auth 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-github-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-github-provider')); +/* highlight-add-end */ +``` + +Restart Backstage from the terminal, by stopping it with `Ctrl+C`, and starting it with `yarn dev`. You should be welcomed by a login prompt! If you try to login at this point you will get a "Failed to sign-in, unable to resolve user identity" message, read on as we'll fix that next. :::note Note @@ -85,33 +128,46 @@ Sometimes the frontend starts before the backend resulting in errors on the sign ::: +## Adding a User + +The recommended approach for adding Users, and Groups, into your Catalog is to use one of the existing Org Entity Providers - [like this one for GitHub](https://backstage.io/docs/integrations/github/org) - or if those don't work you may need to [create one](https://backstage.io/docs/features/software-catalog/external-integrations#custom-entity-providers) that fits your Organization's needs. + +For the sake of this guide we'll simply step you though adding a User to the `org.yaml` file that is included when you create a new Backstage instance. Let's do that: + +1. First open the `/examples/org.yaml` file in your text editor of choice +2. At the bottom we'll add the following YAML: + + ```yaml + --- + apiVersion: backstage.io/v1alpha1 + kind: User + metadata: + name: YOUR GITHUB USERNAME + spec: + memberOf: [guests] + ``` + +3. Now make sure to replace the text "YOUR GITHUB USERNAME" with your actual GitHub User name. + +Let's restart Backstage from the terminal once more, by stopping it with `Ctrl+C`, and starting it with `yarn dev`. You should now be able to log into Backstage and see items in your Catalog. + To learn more about Authentication in Backstage, here are some docs you could read: - [Authentication in Backstage](../../auth/index.md) - [Using organizational data from GitHub](../../integrations/github/org.md) -### Setting up a GitHub Integration +## Setting up a GitHub Integration -The GitHub integration supports loading catalog entities from GitHub or GitHub -Enterprise. Entities can be added to static catalog configuration, registered -with the catalog-import plugin, or discovered from a GitHub organization. Users -and Groups can also be loaded from an organization. While using [GitHub Apps](../../integrations/github/github-apps.md) -might be the best way to set up integrations, for this tutorial you'll use a -Personal Access Token. +The GitHub integration supports loading catalog entities from GitHub or GitHub Enterprise. Entities can be added to static catalog configuration, registered with the catalog-import plugin, or discovered from a GitHub organization. Users and Groups can also be loaded from an organization. While using [GitHub Apps](../../integrations/github/github-apps.md) might be the best way to set up integrations, for this tutorial you'll use a Personal Access Token. -Create your Personal Access Token by opening -[the GitHub token creation page](https://github.com/settings/tokens/new). Use a -name to identify this token and put it in the notes field. Choose a number of -days for expiration. If you have a hard time picking a number, we suggest to go -for 7 days, it's a lucky number. +Create your Personal Access Token by opening [the GitHub token creation page](https://github.com/settings/tokens/new). Use a name to identify this token and put it in the notes field. Choose a number of days for expiration. If you have a hard time picking a number, we suggest to go for 7 days, it's a lucky number. ![Screenshot of the GitHub Personal Access Token creation page](../../assets/getting-started/gh-pat.png) Set the scope to your likings. For this tutorial, selecting `repo` and `workflow` is required as the scaffolding job in this guide configures a GitHub actions workflow for the newly created project. -For this tutorial, we will be writing the token to `app-config.local.yaml`. This file might not exist for you, so if it doesn't go ahead and create it alongside the `app-config.yaml` at the root of the project. -This file should also be excluded in `.gitignore`, to avoid accidental committing of this file. +For this tutorial, we will be writing the token to `app-config.local.yaml`. This file might not exist for you, so if it doesn't go ahead and create it alongside the `app-config.yaml` at the root of the project. This file should also be excluded in `.gitignore`, to avoid accidental committing of this file. More details on this file can be found in the [Static Configuration documentation](../../conf/index.md). In your `app-config.local.yaml` go ahead and add the following: diff --git a/docs/getting-started/keeping-backstage-updated.md b/docs/getting-started/keeping-backstage-updated.md index 88e4a02ef2..19062904e2 100644 --- a/docs/getting-started/keeping-backstage-updated.md +++ b/docs/getting-started/keeping-backstage-updated.md @@ -76,3 +76,15 @@ While package duplication might be acceptable in many cases, you might want to deduplicate packages for the purpose of optimizing bundle size and installation speed. We recommend using deduplication utilities such as `yarn dedupe` to trim down the number of duplicate packages. + +## Proxy + +The Backstage CLI uses [global-agent](https://www.npmjs.com/package/global-agent) to configure HTTP/HTTPS proxy settings using environment variables. This allows you to route the CLI’s network traffic through a proxy server, which can be useful in environments with restricted internet access. + +### Example Configuration + +```bash +export GLOBAL_AGENT_HTTP_PROXY=http://proxy.company.com:8080 +export GLOBAL_AGENT_HTTPS_PROXY=https://secure-proxy.company.com:8080 +export GLOBAL_AGENT_NO_PROXY=localhost,internal.company.com +``` diff --git a/docs/notifications/index.md b/docs/notifications/index.md index 95d77a9b7f..d4234b494e 100644 --- a/docs/notifications/index.md +++ b/docs/notifications/index.md @@ -33,7 +33,7 @@ Example of use-cases: ## Installation in Older Environments -Newer versions of instances created by the create-app have both the notifications and signals plugins included by default, this section can be skipped right to the Configuration. +Newer versions of instances created by the create-app have both the notifications and signals plugins included by default; this section can be skipped right to the Configuration. Following installation instructions are valid for enabling the plugins in older environments. @@ -54,7 +54,7 @@ backend.add(import('@backstage/plugin-notifications-backend')); ### Add Notifications Frontend ```bash -yarn workspace app add @backstage/notifications +yarn workspace app add @backstage/plugin-notifications ``` To add the notifications main menu, add following to your `packages/app/src/components/Root/Root.tsx`: @@ -109,22 +109,23 @@ Start with: yarn workspace app add @backstage/plugin-signals ``` -To install the plugin, you have to add the following to your `packages/app/src/plugins.ts`: +To install the plugin, add the `SignalsDisplay` to your app root in `packages/app/src/App.tsx`: -```ts -export { signalsPlugin } from '@backstage/plugin-signals'; -``` +```tsx +import { SignalsDisplay } from '@backstage/plugin-signals'; -And make sure that your `packages/app/src/App.tsx` contains: - -```ts -import * as plugins from './plugins'; - -const app = createApp({ - // ... - plugins: Object.values(plugins), - // ... -}); +export default app.createRoot( + <> + + + {/* highlight-add-next-line */} + + + + {routes} + + , +); ``` If the signals plugin is properly configured, it will be automatically discovered by the notifications plugin and used. @@ -135,15 +136,15 @@ If the signals plugin is properly configured, it will be automatically discovere The Notifications backend plugin provides an API to create notifications, list notifications per logged-in user, and search based on parameters. -The plugin uses a relational [database](https://backstage.io/docs/getting-started/config/database) for persistence, no specifics are introduced in this context. +The plugin uses a relational [database](https://backstage.io/docs/getting-started/config/database) for persistence; no specifics are introduced in this context. No additional configuration in the app-config is needed, except for optional additional modules for `processors`. ### Notifications Frontend -The recipients of notifications have to be entities in the catalog, e.g. of the User or Group kind. +The recipients of notifications have to be entities in the catalog, e.g., of the User or Group kind. -Otherwise no specific configuration is needed for the front-end notifications plugin. +Otherwise, no specific configuration is needed for the front-end notifications plugin. All parametrization is done through component properties, such as the `NotificationsSidebarItem`, which can be used as an active left-side menu item in the front-end. @@ -218,6 +219,59 @@ React.useEffect(() => { }, [lastSignal, notificationsApi]); ``` +#### Using signals in your own plugin + +It's possible to use signals in your own plugin to deliver data from the backend to the frontend in near real-time. + +To use signals in your own frontend plugin, you need to add the `useSignal` hook from `@backstage/plugin-signals-react` from `@backstage/plugin-notifications-common` with optional generic type of the signal. + +```ts +// To use the same type of signal in the backend, this should be placed in a shared common package +export type MySignalType = { + user: string; + data: string; + // .... +}; + +const { lastSignal } = useSignal('my-plugin'); + +useEffect(() => { + if (lastSignal) { + // Do something with the signal + } +}, [lastSignal]); +``` + +To send signals from the backend plugin, you must add the `signalsServiceRef` to your plugin or module as a dependency. + +```ts +import { signalsServiceRef } from '@backstage/plugin-signals-node'; +export const myPlugin = createBackendPlugin({ + pluginId: 'my', + register(env) { + env.registerInit({ + deps: { + httpRouter: coreServices.httpRouter, + signals: signalsServiceRef, + }, + async init({ httpRouter, signals }) { + httpRouter.use( + await createRouter({ + signals, + }), + ); + }, + }); + }, +}); +``` + +To send the signal using the service, you can use the `publish` method. + +```ts +signals.publish({ user: 'user', data: 'test' }); +``` + ### Consuming Notifications In a front-end plugin, the simplest way to query a notification is by its ID: @@ -249,14 +303,18 @@ import { Notification } from '@backstage/plugin-notifications-common'; import { NotificationProcessor } from '@backstage/plugin-notifications-node'; class MyNotificationProcessor implements NotificationProcessor { - async decorate(notification: Notification): Promise { + // preProcess is called before the notification is saved to database. + // This is a good place to modify the notification before it is saved and sent to the user. + async preProcess(notification: Notification): Promise { if (notification.origin === 'plugin-my-plugin') { notification.payload.icon = 'my-icon'; } return notification; } - async send(notification: Notification): Promise { + // postProcess is called after the notification is saved to database and the signal is emitted. + // This is a good place to send the notification to external services. + async postProcess(notification: Notification): Promise { nodemailer.sendEmail({ from: 'backstage', to: 'user', diff --git a/docs/permissions/plugin-authors/01-setup--old.md b/docs/permissions/plugin-authors/01-setup--old.md new file mode 100644 index 0000000000..34802d004f --- /dev/null +++ b/docs/permissions/plugin-authors/01-setup--old.md @@ -0,0 +1,134 @@ +--- +id: 01-setup--old +title: 1. Tutorial setup +description: How to get started with the permission framework as a plugin author +--- + +:::info +This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./01-setup.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + +The following tutorial is designed to help plugin authors add support for permissions to their plugins. We'll add support for permissions to example `todo-list` and `todo-list-backend` plugins, but the process should be similar for other plugins! + +The rest of this page is focused on adding the `todo-list` and `todo-list-backend` plugins to your Backstage instance. If you want to add support for permissions to your own plugin instead, feel free to skip to the [next section](./02-adding-a-basic-permission-check.md). + +## Setup for the Tutorial + +We will use a "Todo list" feature, composed of the `todo-list` and `todo-list-backend` plugins, as well as their dependency, `todo-list-common`. + +The source code is available here: + +- [todo-list](https://github.com/backstage/backstage/blob/master/plugins/example-todo-list) +- [todo-list-backend](https://github.com/backstage/backstage/blob/master/plugins/example-todo-list-backend) +- [todo-list-common](https://github.com/backstage/backstage/blob/master/plugins/example-todo-list-common) + +1. Copy-paste the three folders into the plugins folder of your backstage application repository (removing the `example-` prefix from each folder) or run the following script from the root of your backstage application: + + ```bash + $ cd $(mktemp -d) + git clone --depth 1 --quiet --no-checkout --filter=blob:none https://github.com/backstage/backstage.git . + git checkout master -- plugins/example-todo-list/ + git checkout master -- plugins/example-todo-list-backend/ + git checkout master -- plugins/example-todo-list-common/ + sed -i '' 's/workspace:\^/\*/g' plugins/example-todo-list/package.json + sed -i '' 's/workspace:\^/\*/g' plugins/example-todo-list-backend/package.json + sed -i '' 's/workspace:\^/\*/g' plugins/example-todo-list-common/package.json + for file in plugins/*; do mv "$file" "$OLDPWD/${file/example-todo/todo}"; done + cd - + ``` + + The `plugins` directory of your project should now include `todo-list`, `todo-list-backend`, and `todo-list-common`. + + **Important**: if you are on **Windows**, make sure you have WSL and git installed on your machine before executing the script above. + +2. Add these packages as dependencies for your Backstage app: + + ```sh title="From your Backstage root directory" + yarn --cwd packages/backend add @internal/plugin-todo-list-backend @internal/plugin-todo-list-common + yarn --cwd packages/app add @internal/plugin-todo-list + ``` + +3. Include the backend and frontend plugin in your application: + + Create a new `packages/backend/src/plugins/todolist.ts` with the following content: + + ```typescript title="packages/backend/src/plugins/todolist.ts" + import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; + import { createRouter } from '@internal/plugin-todo-list-backend'; + import { Router } from 'express'; + import { PluginEnvironment } from '../types'; + + export default async function createPlugin({ + logger, + discovery, + }: PluginEnvironment): Promise { + return await createRouter({ + logger, + identity: DefaultIdentityClient.create({ + discovery, + issuer: await discovery.getExternalBaseUrl('auth'), + }), + }); + } + ``` + + Apply the following changes to `packages/backend/src/index.ts`: + + ```ts title="packages/backend/src/index.ts" + import techdocs from './plugins/techdocs'; + /* highlight-add-next-line */ + import todoList from './plugins/todolist'; + import search from './plugins/search'; + + async function main() { + const searchEnv = useHotMemoize(module, () => createEnv('search')); + const appEnv = useHotMemoize(module, () => createEnv('app')); + /* highlight-add-next-line */ + const todoListEnv = useHotMemoize(module, () => createEnv('todolist')); + // .. + + apiRouter.use('/proxy', await proxy(proxyEnv)); + apiRouter.use('/search', await search(searchEnv)); + apiRouter.use('/permission', await permission(permissionEnv)); + /* highlight-add-next-line */ + apiRouter.use('/todolist', await todoList(todoListEnv)); + // Add backends ABOVE this line; this 404 handler is the catch-all fallback + apiRouter.use(notFoundHandler()); + // .. + } + ``` + + Apply the following changes to `packages/app/src/App.tsx`: + + ```tsx title="packages/app/src/App.tsx" + /* highlight-add-next-line */ + import { TodoListPage } from '@internal/plugin-todo-list'; + + const routes = ( + + }> + {searchPage} + + } /> + {/* highlight-add-next-line */} + } /> + {/* ... */} + + ); + ``` + +Now if you start your application you should be able to reach the `/todo-list` page: + +![Todo List plugin page](../../assets/permissions/permission-todo-list-page.png) + +--- + +## Integrate the new plugin + +If you play with the UI, you will notice that it is possible to perform a few actions: + +- create a new todo item (`POST /todos`) +- view todo items (`GET /todos`) +- edit an existing todo item (`PUT /todos`) + +Let's try to bring authorization on top of each one of them. diff --git a/docs/permissions/plugin-authors/01-setup.md b/docs/permissions/plugin-authors/01-setup.md index f11bdff930..f3c361e8b5 100644 --- a/docs/permissions/plugin-authors/01-setup.md +++ b/docs/permissions/plugin-authors/01-setup.md @@ -4,6 +4,10 @@ title: 1. Tutorial setup description: How to get started with the permission framework as a plugin author --- +:::info +This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./01-setup--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + The following tutorial is designed to help plugin authors add support for permissions to their plugins. We'll add support for permissions to example `todo-list` and `todo-list-backend` plugins, but the process should be similar for other plugins! The rest of this page is focused on adding the `todo-list` and `todo-list-backend` plugins to your Backstage instance. If you want to add support for permissions to your own plugin instead, feel free to skip to the [next section](./02-adding-a-basic-permission-check.md). @@ -40,58 +44,31 @@ The source code is available here: 2. Add these packages as dependencies for your Backstage app: ```sh title="From your Backstage root directory" - yarn --cwd packages/backend add @internal/plugin-todo-list-backend @internal/plugin-todo-list-common + yarn --cwd packages/backend add @backstage/plugin-permission-backend @backstage/plugin-permission-backend-module-allow-all-policy @internal/plugin-todo-list-backend @internal/plugin-todo-list-common yarn --cwd packages/app add @internal/plugin-todo-list ``` 3. Include the backend and frontend plugin in your application: - Create a new `packages/backend/src/plugins/todolist.ts` with the following content: - - ```typescript title="packages/backend/src/plugins/todolist.ts" - import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; - import { createRouter } from '@internal/plugin-todo-list-backend'; - import { Router } from 'express'; - import { PluginEnvironment } from '../types'; - - export default async function createPlugin({ - logger, - discovery, - }: PluginEnvironment): Promise { - return await createRouter({ - logger, - identity: DefaultIdentityClient.create({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - }), - }); - } - ``` - Apply the following changes to `packages/backend/src/index.ts`: ```ts title="packages/backend/src/index.ts" - import techdocs from './plugins/techdocs'; - /* highlight-add-next-line */ - import todoList from './plugins/todolist'; - import search from './plugins/search'; - - async function main() { - const searchEnv = useHotMemoize(module, () => createEnv('search')); - const appEnv = useHotMemoize(module, () => createEnv('app')); - /* highlight-add-next-line */ - const todoListEnv = useHotMemoize(module, () => createEnv('todolist')); - // .. - - apiRouter.use('/proxy', await proxy(proxyEnv)); - apiRouter.use('/search', await search(searchEnv)); - apiRouter.use('/permission', await permission(permissionEnv)); - /* highlight-add-next-line */ - apiRouter.use('/todolist', await todoList(todoListEnv)); - // Add backends ABOVE this line; this 404 handler is the catch-all fallback - apiRouter.use(notFoundHandler()); - // .. - } + import { createBackend } from '@backstage/backend-defaults'; + //... + const backend = createBackend(); + //... + /* highlight-add-start */ + // Installing the permission plugin + backend.add(import('@backstage/plugin-permission-backend/alpha')); + // Installing the allow all permission policy module + backend.add( + import('@backstage/plugin-permission-backend-module-allow-all-policy'), + ); + // Installing the todolist plugin + backend.add(import('@internal/plugin-todo-list-backend')); + /* highlight-add-end */ + //... + backend.start(); ``` Apply the following changes to `packages/app/src/App.tsx`: @@ -99,13 +76,11 @@ The source code is available here: ```tsx title="packages/app/src/App.tsx" /* highlight-add-next-line */ import { TodoListPage } from '@internal/plugin-todo-list'; + //... const routes = ( - }> - {searchPage} - - } /> + {/* ... */} {/* highlight-add-next-line */} } /> {/* ... */} diff --git a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check--old.md b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check--old.md new file mode 100644 index 0000000000..7c8dad3d87 --- /dev/null +++ b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check--old.md @@ -0,0 +1,387 @@ +--- +id: 02-adding-a-basic-permission-check--old +title: 2. Adding a basic permission check +description: Explains how to add a basic permission check to a Backstage plugin +--- + +:::info +This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./02-adding-a-basic-permission-check.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + +If the outcome of a permission check doesn't need to change for different [resources](../../references/glossary.md#resource-permission-plugin), you can use a _basic permission check_. For this kind of check, we simply need to define a permission, and call `authorize` with it. + +For this tutorial, we'll use a basic permission check to authorize the `create` endpoint in our todo-backend. This will allow Backstage integrators to control whether each of their users is authorized to create todos by adjusting their [permission policy](../../references/glossary.md#policy-permission-plugin). + +We'll start by creating a new permission, and then we'll use the permission api to call `authorize` with it during todo creation. + +## Creating a new permission + +Let's navigate to the file `plugins/todo-list-common/src/permissions.ts` and add our first permission: + +```ts title="plugins/todo-list-common/src/permissions.ts" +import { createPermission } from '@backstage/plugin-permission-common'; + +/* highlight-remove-start */ +export const tempExamplePermission = createPermission({ + name: 'temp.example.noop', + attributes: {}, +/* highlight-remove-end */ +/* highlight-add-start */ +export const todoListCreatePermission = createPermission({ + name: 'todo.list.create', + attributes: { action: 'create' }, +/* highlight-add-end */ +}); + +/* highlight-remove-next-line */ +export const todoListPermissions = [tempExamplePermission]; +/* highlight-add-next-line */ +export const todoListPermissions = [todoListCreatePermission]; +``` + +For this tutorial, we've automatically exported all permissions from this file (see `plugins/todo-list-common/src/index.ts`). + +:::note Note + +We use a separate `todo-list-common` package since all permissions authorized by your plugin should be exported from a ["common-library" package](https://backstage.io/docs/tooling/cli/build-system#package-roles). This allows Backstage integrators to reference them in frontend components as well as permission policies. + +::: + +## Authorizing using the new permission + +Install the following module: + +``` +$ yarn workspace @internal/plugin-todo-list-backend \ + add @backstage/plugin-permission-common @backstage/plugin-permission-node @internal/plugin-todo-list-common +``` + +Edit `plugins/todo-list-backend/src/service/router.ts`: + +```ts title="plugins/todo-list-backend/src/service/router.ts" +/* highlight-remove-start */ +import { InputError } from '@backstage/errors'; +import { IdentityApi } from '@backstage/plugin-auth-node'; +/* highlight-remove-end */ +/* highlight-add-start */ +import { InputError, NotAllowedError } from '@backstage/errors'; +import { getBearerTokenFromAuthorizationHeader, IdentityApi } from '@backstage/plugin-auth-node'; +import { PermissionEvaluator, AuthorizeResult } from '@backstage/plugin-permission-common'; +import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; +import { todoListCreatePermission } from '@internal/plugin-todo-list-common'; +/* highlight-add-end */ + +export interface RouterOptions { + logger: Logger; + identity: IdentityApi; + /* highlight-add-next-line */ + permissions: PermissionEvaluator; +} + +export async function createRouter( + options: RouterOptions, +): Promise { + /* highlight-remove-next-line */ + const { logger, identity } = options; + /* highlight-add-next-line */ + const { logger, identity, permissions } = options; + + /* highlight-add-start */ + const permissionIntegrationRouter = createPermissionIntegrationRouter({ + permissions: [todoListCreatePermission], + }); + /* highlight-add-end */ + + const router = Router(); + router.use(express.json()); + + router.get('/health', (_, response) => { + logger.info('PONG!'); + response.json({ status: 'ok' }); + }); + + /* highlight-add-next-line */ + router.use(permissionIntegrationRouter); + + router.get('/todos', async (_req, res) => { + res.json(getAll()); + }); + + router.post('/todos', async (req, res) => { + let author: string | undefined = undefined; + + const user = await identity.getIdentity({ request: req }); + author = user?.identity.userEntityRef; + /* highlight-add-start */ + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); + const decision = ( + await permissions.authorize([{ permission: todoListCreatePermission }], { + token, + }) + )[0]; + + if (decision.result === AuthorizeResult.DENY) { + throw new NotAllowedError('Unauthorized'); + } + /* highlight-add-end */ + + if (!isTodoCreateRequest(req.body)) { + throw new InputError('Invalid payload'); + } + + const todo = add({ title: req.body.title, author }); + res.json(todo); + }); + + // ... +``` + +Pass the `permissions` object to the plugin in `packages/backend/src/plugins/todolist.ts`: + +```ts title="packages/backend/src/plugins/todolist.ts" +import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; +import { createRouter } from '@internal/plugin-todo-list-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin({ + logger, + discovery, + /* highlight-add-next-line */ + permissions, +}: PluginEnvironment): Promise { + return await createRouter({ + logger, + identity: DefaultIdentityClient.create({ + discovery, + issuer: await discovery.getExternalBaseUrl('auth'), + }), + /* highlight-add-next-line */ + permissions, + }); +} +``` + +That's it! Now your plugin is fully configured. Let's try to test the logic by denying the permission. + +## Test the authorized create endpoint + +Before running this step, please make sure you followed the steps described in [Getting started](../getting-started.md) section. + +In order to test the logic above, the integrators of your backstage instance need to change their permission policy to return `DENY` for our newly-created permission: + +```ts title="packages/backend/src/plugins/permission.ts" +import { + PermissionPolicy, + /* highlight-add-start */ + PolicyQuery, + PolicyQueryUser, + /* highlight-add-end */ +} from '@backstage/plugin-permission-node'; +/* highlight-add-start */ +import { isPermission } from '@backstage/plugin-permission-common'; +import { todoListCreatePermission } from '@internal/plugin-todo-list-common'; +/* highlight-add-end */ + +class TestPermissionPolicy implements PermissionPolicy { + /* highlight-remove-next-line */ + async handle(): Promise { + /* highlight-add-start */ + async handle( + request: PolicyQuery, + _user?: PolicyQueryUser, + ): Promise { + if (isPermission(request.permission, todoListCreatePermission)) { + return { + result: AuthorizeResult.DENY, + }; + } + /* highlight-add-end */ + + return { + result: AuthorizeResult.ALLOW, + }; +} +``` + +Now the frontend should show an error whenever you try to create a new Todo item. + +Let's flip the result back to `ALLOW` before moving on. + +```ts +if (isPermission(request.permission, todoListCreatePermission)) { + return { + /* highlight-remove-next-line */ + result: AuthorizeResult.DENY, + /* highlight-add-next-line */ + result: AuthorizeResult.ALLOW, + }; +} +``` + +At this point everything is working but if you run `yarn tsc` you'll get some errors, let's fix those up. + +First we'll clean up the `plugins/todo-list-backend/src/service/router.test.ts`: + +```ts title="plugins/todo-list-backend/src/service/router.test.ts" +import { getVoidLogger } from '@backstage/backend-common'; +import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; +/* highlight-add-next-line */ +import { PermissionEvaluator } from '@backstage/plugin-permission-common'; +import express from 'express'; +import request from 'supertest'; + +import { createRouter } from './router'; + +/* highlight-add-start */ +const mockedAuthorize: jest.MockedFunction = + jest.fn(); +const mockedPermissionQuery: jest.MockedFunction< + PermissionEvaluator['authorizeConditional'] +> = jest.fn(); + +const permissionEvaluator: PermissionEvaluator = { + authorize: mockedAuthorize, + authorizeConditional: mockedPermissionQuery, +}; +/* highlight-add-end */ + +describe('createRouter', () => { + let app: express.Express; + + beforeAll(async () => { + const router = await createRouter({ + logger: getVoidLogger(), + identity: {} as DefaultIdentityClient, + /* highlight-add-next-line */ + permissions: permissionEvaluator, + }); + app = express().use(router); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('GET /health', () => { + it('returns ok', async () => { + const response = await request(app).get('/health'); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ status: 'ok' }); + }); + }); +}); +``` + +Then we want to update the `plugins/todo-list-backend/src/service/standaloneServer.ts`: + +```ts title="plugins/todo-list-backend/src/service/standaloneServer.ts" +import { + createServiceBuilder, + loadBackendConfig, + SingleHostDiscovery, + /* highlight-add-next-line */ + ServerTokenManager, +} from '@backstage/backend-common'; +import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; +/* highlight-add-next-line */ +import { ServerPermissionClient } from '@backstage/plugin-permission-node'; +import { Server } from 'http'; +import { Logger } from 'winston'; +import { createRouter } from './router'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'todo-list-backend' }); + logger.debug('Starting application server...'); + const config = await loadBackendConfig({ logger, argv: process.argv }); + const discovery = SingleHostDiscovery.fromConfig(config); + /* highlight-add-start */ + const tokenManager = ServerTokenManager.fromConfig(config, { + logger, + }); + const permissions = ServerPermissionClient.fromConfig(config, { + discovery, + tokenManager, + }); + /* highlight-add-end */ + const router = await createRouter({ + logger, + identity: DefaultIdentityClient.create({ + discovery, + issuer: await discovery.getExternalBaseUrl('auth'), + }), + /* highlight-add-next-line */ + permissions, + }); + + let service = createServiceBuilder(module) + .setPort(options.port) + .addRouter('/todo-list', router); + if (options.enableCors) { + service = service.enableCors({ origin: 'http://localhost:3000' }); + } + + return await service.start().catch(err => { + logger.error(err); + process.exit(1); + }); +} + +module.hot?.accept(); +``` + +Finally, we need to update `plugins/todo-list-backend/src/plugin.ts`: + +```ts title="plugins/todo-list-backend/src/plugin.ts" +import { loggerToWinstonLogger } from '@backstage/backend-common'; +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { createRouter } from './service/router'; + +/** +* The example TODO list backend plugin. +* +* @public +*/ +export const exampleTodoListPlugin = createBackendPlugin({ + pluginId: 'exampleTodoList', + register(env) { + env.registerInit({ + deps: { + identity: coreServices.identity, + logger: coreServices.logger, + httpRouter: coreServices.httpRouter, + /* highlight-add-next-line */ + permissions: coreServices.permissions, + }, + /* highlight-remove-next-line */ + async init({ identity, logger, httpRouter }) { + /* highlight-add-next-line */ + async init({ identity, logger, httpRouter, permissions }) { + httpRouter.use( + await createRouter({ + identity, + logger: loggerToWinstonLogger(logger), + permissions, + }), + ); + }, + }); + }, +}); +``` + +Now when you run `yarn tsc` you should have no more errors. diff --git a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md index 724edb7ccb..2d39d5cef3 100644 --- a/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md +++ b/docs/permissions/plugin-authors/02-adding-a-basic-permission-check.md @@ -4,6 +4,10 @@ title: 2. Adding a basic permission check description: Explains how to add a basic permission check to a Backstage plugin --- +:::info +This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./02-adding-a-basic-permission-check--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + If the outcome of a permission check doesn't need to change for different [resources](../../references/glossary.md#resource-permission-plugin), you can use a _basic permission check_. For this kind of check, we simply need to define a permission, and call `authorize` with it. For this tutorial, we'll use a basic permission check to authorize the `create` endpoint in our todo-backend. This will allow Backstage integrators to control whether each of their users is authorized to create todos by adjusting their [permission policy](../../references/glossary.md#policy-permission-plugin). @@ -57,30 +61,30 @@ Edit `plugins/todo-list-backend/src/service/router.ts`: ```ts title="plugins/todo-list-backend/src/service/router.ts" /* highlight-remove-start */ import { InputError } from '@backstage/errors'; -import { IdentityApi } from '@backstage/plugin-auth-node'; +import { LoggerService, HttpAuthService } from '@backstage/backend-plugin-api'; /* highlight-remove-end */ /* highlight-add-start */ import { InputError, NotAllowedError } from '@backstage/errors'; -import { getBearerTokenFromAuthorizationHeader, IdentityApi } from '@backstage/plugin-auth-node'; -import { PermissionEvaluator, AuthorizeResult } from '@backstage/plugin-permission-common'; +import { LoggerService, HttpAuthService, PermissionsService } from '@backstage/backend-plugin-api'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; import { todoListCreatePermission } from '@internal/plugin-todo-list-common'; /* highlight-add-end */ export interface RouterOptions { - logger: Logger; - identity: IdentityApi; + logger: LoggerService; + httpAuth: HttpAuthService; /* highlight-add-next-line */ - permissions: PermissionEvaluator; + permissions: PermissionsService; } export async function createRouter( options: RouterOptions, ): Promise { /* highlight-remove-next-line */ - const { logger, identity } = options; + const { logger, httpAuth } = options; /* highlight-add-next-line */ - const { logger, identity, permissions } = options; + const { logger, httpAuth, permissions } = options; /* highlight-add-start */ const permissionIntegrationRouter = createPermissionIntegrationRouter({ @@ -109,13 +113,12 @@ export async function createRouter( const user = await identity.getIdentity({ request: req }); author = user?.identity.userEntityRef; /* highlight-add-start */ - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); const decision = ( - await permissions.authorize([{ permission: todoListCreatePermission }], { - token, - }) + await permissions.authorize( + [{ permission: todoListCreatePermission }], + { credentials }, + ) )[0]; if (decision.result === AuthorizeResult.DENY) { @@ -134,30 +137,43 @@ export async function createRouter( // ... ``` -Pass the `permissions` object to the plugin in `packages/backend/src/plugins/todolist.ts`: +Pass the `permissions` object to the plugin in `plugins/todo-list-backend/src/plugin.ts`: -```ts title="packages/backend/src/plugins/todolist.ts" -import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; -import { createRouter } from '@internal/plugin-todo-list-backend'; -import { Router } from 'express'; -import { PluginEnvironment } from '../types'; +```ts title="plugins/todo-list-backend/src/plugin.ts" +import { coreServices, createBackendPlugin } from '@backstage/backend-plugin-api'; +import { createRouter } from './service/router'; -export default async function createPlugin({ - logger, - discovery, - /* highlight-add-next-line */ - permissions, -}: PluginEnvironment): Promise { - return await createRouter({ - logger, - identity: DefaultIdentityClient.create({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - }), - /* highlight-add-next-line */ - permissions, - }); -} +export const exampleTodoListPlugin = createBackendPlugin({ + pluginId: 'todolist', + register(env) { + env.registerInit({ + deps: { + logger: coreServices.logger, + httpAuth: coreServices.httpAuth, + httpRouter: coreServices.httpRouter, + /* highlight-add-next-line */ + permissions: coreServices.permissions, + }, + /* highlight-remove-next-line */ + async init({ logger, httpAuth, httpRouter }) { + /* highlight-add-next-line */ + async init({ logger, httpAuth, httpRouter, permissions }) { + httpRouter.use( + await createRouter({ + logger, + httpAuth, + /* highlight-add-next-line */ + permissions, + }), + ); + httpRouter.addAuthPolicy({ + path: '/health', + allow: 'unauthenticated', + }); + }, + }); + }, +}); ``` That's it! Now your plugin is fully configured. Let's try to test the logic by denying the permission. @@ -168,7 +184,15 @@ Before running this step, please make sure you followed the steps described in [ In order to test the logic above, the integrators of your backstage instance need to change their permission policy to return `DENY` for our newly-created permission: -```ts title="packages/backend/src/plugins/permission.ts" +```ts title="packages/backend/src/extensions/permissionsPolicyExtension.ts" +import { createBackendModule } from '@backstage/backend-plugin-api'; +import { + PolicyDecision, + /* highlight-add-start */ + isPermission, + /* highlight-add-end */ + AuthorizeResult, +} from '@backstage/plugin-permission-common'; import { PermissionPolicy, /* highlight-add-start */ @@ -177,9 +201,9 @@ import { /* highlight-add-end */ } from '@backstage/plugin-permission-node'; /* highlight-add-start */ -import { isPermission } from '@backstage/plugin-permission-common'; import { todoListCreatePermission } from '@internal/plugin-todo-list-common'; /* highlight-add-end */ +import { policyExtensionPoint } from '@backstage/plugin-permission-node/alpha'; class TestPermissionPolicy implements PermissionPolicy { /* highlight-remove-next-line */ @@ -200,6 +224,19 @@ class TestPermissionPolicy implements PermissionPolicy { result: AuthorizeResult.ALLOW, }; } + +export default createBackendModule({ + pluginId: 'permission', + moduleId: 'permission-policy', + register(reg) { + reg.registerInit({ + deps: { policy: policyExtensionPoint }, + async init({ policy }) { + policy.setPolicy(new TestPermissionPolicy()); + }, + }); + }, +}); ``` Now the frontend should show an error whenever you try to create a new Todo item. @@ -217,42 +254,26 @@ if (isPermission(request.permission, todoListCreatePermission)) { } ``` -At this point everything is working but if you run `yarn tsc` you'll get some errors, let's fix those up. +At this point everything is working but if you run `yarn tsc` you'll get an error, let's fix this up. -First we'll clean up the `plugins/todo-list-backend/src/service/router.test.ts`: +Clean up the `plugins/todo-list-backend/src/service/router.test.ts`: ```ts title="plugins/todo-list-backend/src/service/router.test.ts" -import { getVoidLogger } from '@backstage/backend-common'; -import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; -/* highlight-add-next-line */ -import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import express from 'express'; import request from 'supertest'; import { createRouter } from './router'; - -/* highlight-add-start */ -const mockedAuthorize: jest.MockedFunction = - jest.fn(); -const mockedPermissionQuery: jest.MockedFunction< - PermissionEvaluator['authorizeConditional'] -> = jest.fn(); - -const permissionEvaluator: PermissionEvaluator = { - authorize: mockedAuthorize, - authorizeConditional: mockedPermissionQuery, -}; -/* highlight-add-end */ +import { mockServices } from '@backstage/backend-test-utils'; describe('createRouter', () => { let app: express.Express; beforeAll(async () => { const router = await createRouter({ - logger: getVoidLogger(), - identity: {} as DefaultIdentityClient, + logger: mockServices.logger.mock(), + httpAuth: mockServices.httpAuth.mock(), /* highlight-add-next-line */ - permissions: permissionEvaluator, + permissions: mockServices.permissions.mock(), }); app = express().use(router); }); @@ -272,112 +293,4 @@ describe('createRouter', () => { }); ``` -Then we want to update the `plugins/todo-list-backend/src/service/standaloneServer.ts`: - -```ts title="plugins/todo-list-backend/src/service/standaloneServer.ts" -import { - createServiceBuilder, - loadBackendConfig, - SingleHostDiscovery, - /* highlight-add-next-line */ - ServerTokenManager, -} from '@backstage/backend-common'; -import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; -/* highlight-add-next-line */ -import { ServerPermissionClient } from '@backstage/plugin-permission-node'; -import { Server } from 'http'; -import { Logger } from 'winston'; -import { createRouter } from './router'; - -export interface ServerOptions { - port: number; - enableCors: boolean; - logger: Logger; -} - -export async function startStandaloneServer( - options: ServerOptions, -): Promise { - const logger = options.logger.child({ service: 'todo-list-backend' }); - logger.debug('Starting application server...'); - const config = await loadBackendConfig({ logger, argv: process.argv }); - const discovery = SingleHostDiscovery.fromConfig(config); - /* highlight-add-start */ - const tokenManager = ServerTokenManager.fromConfig(config, { - logger, - }); - const permissions = ServerPermissionClient.fromConfig(config, { - discovery, - tokenManager, - }); - /* highlight-add-end */ - const router = await createRouter({ - logger, - identity: DefaultIdentityClient.create({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - }), - /* highlight-add-next-line */ - permissions, - }); - - let service = createServiceBuilder(module) - .setPort(options.port) - .addRouter('/todo-list', router); - if (options.enableCors) { - service = service.enableCors({ origin: 'http://localhost:3000' }); - } - - return await service.start().catch(err => { - logger.error(err); - process.exit(1); - }); -} - -module.hot?.accept(); -``` - -Finally, we need to update `plugins/todo-list-backend/src/plugin.ts`: - -```ts title="plugins/todo-list-backend/src/plugin.ts" -import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; -import { createRouter } from './service/router'; - -/** -* The example TODO list backend plugin. -* -* @public -*/ -export const exampleTodoListPlugin = createBackendPlugin({ - pluginId: 'exampleTodoList', - register(env) { - env.registerInit({ - deps: { - identity: coreServices.identity, - logger: coreServices.logger, - httpRouter: coreServices.httpRouter, - /* highlight-add-next-line */ - permissions: coreServices.permissions, - }, - /* highlight-remove-next-line */ - async init({ identity, logger, httpRouter }) { - /* highlight-add-next-line */ - async init({ identity, logger, httpRouter, permissions }) { - httpRouter.use( - await createRouter({ - identity, - logger: loggerToWinstonLogger(logger), - permissions, - }), - ); - }, - }); - }, -}); -``` - Now when you run `yarn tsc` you should have no more errors. diff --git a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check--old.md b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check--old.md new file mode 100644 index 0000000000..ee06629e71 --- /dev/null +++ b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check--old.md @@ -0,0 +1,299 @@ +--- +id: 03-adding-a-resource-permission-check--old +title: 3. Adding a resource permission check +description: Explains how to add a resource permission check to a Backstage plugin +--- + +:::info +This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./03-adding-a-resource-permission-check.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + +When performing updates (or other operations) on specific [resources](../../references/glossary.md#resource-permission-plugin), the permissions framework allows for the decision to be based on characteristics of the resource itself. This means that it's possible to write policies that (for example) allow the operation for users that own a resource, and deny the operation otherwise. + +## Creating the update permission + +Let's add a new permission to the file `plugins/todo-list-common/src/permissions.ts` from [the previous section](./02-adding-a-basic-permission-check.md). + +```ts title="plugins/todo-list-common/src/permissions.ts" +import { createPermission } from '@backstage/plugin-permission-common'; + +/* highlight-add-next-line */ +export const TODO_LIST_RESOURCE_TYPE = 'todo-item'; + +export const todoListCreatePermission = createPermission({ + name: 'todo.list.create', + attributes: { action: 'create' }, +}); + +/* highlight-add-start */ +export const todoListUpdatePermission = createPermission({ + name: 'todo.list.update', + attributes: { action: 'update' }, + resourceType: TODO_LIST_RESOURCE_TYPE, +}); +/* highlight-add-end */ + +/* highlight-remove-next-line */ +export const todoListPermissions = [todoListCreatePermission]; +/* highlight-add-start */ +export const todoListPermissions = [ + todoListCreatePermission, + todoListUpdatePermission, +]; +/* highlight-add-end */ +``` + +Notice that unlike `todoListCreatePermission`, the `todoListUpdatePermission` permission contains a `resourceType` field. This field indicates to the permission framework that this permission is intended to be authorized in the context of a resource with type `'todo-item'`. You can use whatever string you like as the resource type, as long as you use the same value consistently for each type of resource. + +## Setting up authorization for the update permission + +To start, let's edit `plugins/todo-list-backend/src/service/router.ts` in the same manner as we did in the previous section: + +```ts title="plugins/todo-list-backend/src/service/router.ts" +/* highlight-remove-next-line */ +import { todoListCreatePermission } from '@internal/plugin-todo-list-common'; +/* highlight-add-start */ +import { + todoListCreatePermission, + todoListUpdatePermission, +} from '@internal/plugin-todo-list-common'; +/* highlight-add-end */ + +// ... + +const permissionIntegrationRouter = createPermissionIntegrationRouter({ + /* highlight-remove-next-line */ + permissions: [todoListCreatePermission], + /* highlight-add-next-line */ + permissions: [todoListCreatePermission, todoListUpdatePermission], +}); + +// ... + +router.put('/todos', async (req, res) => { + /* highlight-add-start */ + const token = getBearerTokenFromAuthorizationHeader( + req.header('authorization'), + ); + /* highlight-add-end */ + + if (!isTodoUpdateRequest(req.body)) { + throw new InputError('Invalid payload'); + } + /* highlight-add-start */ + const decision = ( + await permissions.authorize( + [{ permission: todoListUpdatePermission, resourceRef: req.body.id }], + { + token, + }, + ) + )[0]; + + if (decision.result !== AuthorizeResult.ALLOW) { + throw new NotAllowedError('Unauthorized'); + } + /* highlight-add-end */ + + res.json(update(req.body)); +}); +``` + +**Important:** Notice that we are passing an extra `resourceRef` field, with the `id` of the todo item as the value. + +This enables decisions based on characteristics of the resource, but it's important to note that policy authors will not have access to the resource ref inside of their permission policies. Instead, the policies will return conditional decisions, which we need to now support in our plugin. + +## Adding support for conditional decisions + +Install the missing module: + +```bash +$ yarn workspace @internal/plugin-todo-list-backend add zod +``` + +Create a new `plugins/todo-list-backend/src/service/rules.ts` file and append the following code: + +```typescript title="plugins/todo-list-backend/src/service/rules.ts" +import { makeCreatePermissionRule } from '@backstage/plugin-permission-node'; +import { TODO_LIST_RESOURCE_TYPE } from '@internal/plugin-todo-list-common'; +import { z } from 'zod'; +import { Todo, TodoFilter } from './todos'; + +export const createTodoListPermissionRule = makeCreatePermissionRule< + Todo, + TodoFilter, + typeof TODO_LIST_RESOURCE_TYPE +>(); + +export const isOwner = createTodoListPermissionRule({ + name: 'IS_OWNER', + description: 'Should allow only if the todo belongs to the user', + resourceType: TODO_LIST_RESOURCE_TYPE, + paramsSchema: z.object({ + userId: z.string().describe('User ID to match on the resource'), + }), + apply: (resource: Todo, { userId }) => { + return resource.author === userId; + }, + toQuery: ({ userId }) => { + return { + property: 'author', + values: [userId], + }; + }, +}); + +export const rules = { isOwner }; +``` + +`makeCreatePermissionRule` is a helper used to ensure that rules created for this plugin use consistent types for the resource and query. + +:::note Note + +To support custom rules defined by Backstage integrators, you must export `createTodoListPermissionRule` from the backend package and provide some way for custom rules to be passed in before the backend starts, likely via `createRouter`. + +::: + +We have created a new `isOwner` rule, which is going to be automatically used by the permission framework whenever a conditional response is returned in response to an authorized request with an attached `resourceRef`. +Specifically, the `apply` function is used to understand whether the passed resource should be authorized or not. + +Let's skip the `toQuery` function for now, we'll come back to that in the next section. + +Now, let's create the new endpoint by editing `plugins/todo-list-backend/src/service/router.ts`. This uses the `createPermissionIntegrationRouter` helper to add the APIs needed by the permission framework to your plugin. You'll need to supply: + +- `getResources`: a function that accepts an array of `resourceRefs` in the same format you expect to be passed to `authorize`, and returns an array of the corresponding resources. +- `resourceType`: the same value used in the permission rule above. +- `permissions`: the list of permissions that your plugin accepts. +- `rules`: an array of all the permission rules you want to support in conditional decisions. + +```ts title="plugins/todo-list-backend/src/service/router.ts" +// ... +import { + /* highlight-add-next-line */ + TODO_LIST_RESOURCE_TYPE, + todoListCreatePermission, + todoListUpdatePermission, +} from '@internal/plugin-todo-list-common'; +/* highlight-remove-next-line */ +import { add, getAll, update } from './todos'; +/* highlight-add-start */ +import { add, getAll, getTodo, update } from './todos'; +import { rules } from './rules'; +/* highlight-add-end */ + +export async function createRouter( + options: RouterOptions, +): Promise { + const { logger, identity, permissions } = options; + + const permissionIntegrationRouter = createPermissionIntegrationRouter({ + permissions: [todoListCreatePermission, todoListUpdatePermission], + /* highlight-add-start */ + getResources: async resourceRefs => { + return resourceRefs.map(getTodo); + }, + resourceType: TODO_LIST_RESOURCE_TYPE, + rules: Object.values(rules), + /* highlight-add-end */ + }); + + const router = Router(); + router.use(express.json()); + + // ... +} +``` + +## Provide utilities for policy authors + +Now that we have a new resource type and a corresponding rule, we need to export some utilities for policy authors to reference them. + +Create a new `plugins/todo-list-backend/src/conditionExports.ts` file and add the following code: + +```typescript title="plugins/todo-list-backend/src/conditionExports.ts" +import { TODO_LIST_RESOURCE_TYPE } from '@internal/plugin-todo-list-common'; +import { createConditionExports } from '@backstage/plugin-permission-node'; +import { rules } from './service/rules'; + +const { conditions, createConditionalDecision } = createConditionExports({ + pluginId: 'todolist', + resourceType: TODO_LIST_RESOURCE_TYPE, + rules, +}); + +export const todoListConditions = conditions; + +export const createTodoListConditionalDecision = createConditionalDecision; +``` + +Make sure `todoListConditions` and `createTodoListConditionalDecision` are exported from the `todo-list-backend` package by editing `plugins/todo-list-backend/src/index.ts`: + +```ts title="plugins/todo-list-backend/src/index.ts" +export * from './service/router'; +/* highlight-add-next-line */ +export * from './conditionExports'; +export { exampleTodoListPlugin } from './plugin'; +``` + +## Test the authorized update endpoint + +Let's go back to the permission policy's handle function and try to authorize our new permission with an `isOwner` condition. + +```ts title="packages/backend/src/plugins/permission.ts" +import { + IdentityClient +} from '@backstage/plugin-auth-node'; +import { + PermissionPolicy, + PolicyQuery, + PolicyQueryUser, +} from '@backstage/plugin-permission-node'; +import { isPermission } from '@backstage/plugin-permission-common'; +/* highlight-remove-next-line */ +import { todoListCreatePermission } from '@internal/plugin-todo-list-common'; +/* highlight-add-start */ +import { + todoListCreatePermission, + todoListUpdatePermission, +} from '@internal/plugin-todo-list-common'; +import { + todoListConditions, + createTodoListConditionalDecision, +} from '@internal/plugin-todo-list-backend'; +/* highlight-add-end */ + + +async handle( + request: PolicyQuery, + /* highlight-remove-next-line */ + _user?: PolicyQueryUser, + /* highlight-add-next-line */ + user?: PolicyQueryUser, +): Promise { + if (isPermission(request.permission, todoListCreatePermission)) { + return { + result: AuthorizeResult.ALLOW, + }; + } + /* highlight-add-start */ + if (isPermission(request.permission, todoListUpdatePermission)) { + return createTodoListConditionalDecision( + request.permission, + todoListConditions.isOwner({ + userId: user?.info.userEntityRef ?? '', + }), + ); + } + /* highlight-add-end */ + + return { + result: AuthorizeResult.ALLOW, + }; +} +``` + +For any incoming update requests, we now return a _Conditional Decision_. We are saying: + +> Hey permission framework, I can't make a decision alone. Please go to the plugin with id `todolist` and ask it to apply these conditions. + +To check that everything works as expected, you should now see an error in the UI whenever you try to edit an item that wasn’t created by you. Success! diff --git a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md index 7ad551e926..3f5a9777b3 100644 --- a/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md +++ b/docs/permissions/plugin-authors/03-adding-a-resource-permission-check.md @@ -4,6 +4,10 @@ title: 3. Adding a resource permission check description: Explains how to add a resource permission check to a Backstage plugin --- +:::info +This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./03-adding-a-resource-permission-check--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + When performing updates (or other operations) on specific [resources](../../references/glossary.md#resource-permission-plugin), the permissions framework allows for the decision to be based on characteristics of the resource itself. This means that it's possible to write policies that (for example) allow the operation for users that own a resource, and deny the operation otherwise. ## Creating the update permission @@ -68,9 +72,7 @@ const permissionIntegrationRouter = createPermissionIntegrationRouter({ router.put('/todos', async (req, res) => { /* highlight-add-start */ - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); /* highlight-add-end */ if (!isTodoUpdateRequest(req.body)) { @@ -80,9 +82,7 @@ router.put('/todos', async (req, res) => { const decision = ( await permissions.authorize( [{ permission: todoListUpdatePermission, resourceRef: req.body.id }], - { - token, - }, + { credentials }, ) )[0]; @@ -146,7 +146,7 @@ export const rules = { isOwner }; :::note Note -To support custom rules defined by Backstage integrators, you must export `createTodoListPermissionRule` from the backend package and provide some way for custom rules to be passed in before the backend starts, likely via `createRouter`. +To support custom rules defined by Backstage integrators, you must export `createTodoListPermissionRule` from the backend package and provide some way for custom rules to be passed in before the backend starts, likely via `extension point`. ::: diff --git a/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data--old.md b/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data--old.md new file mode 100644 index 0000000000..cca6899ef6 --- /dev/null +++ b/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data--old.md @@ -0,0 +1,193 @@ +--- +id: 04-authorizing-access-to-paginated-data--old +title: 4. Authorizing access to paginated data +description: Explains how to authorize access to paginated data in a Backstage plugin +--- + +:::info +This documentation is written for the old backend which has been replaced by [the new backend system](../../backend-system/index.md), being the default since Backstage [version 1.24](../../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./04-authorizing-access-to-paginated-data.md) instead. Otherwise, [consider migrating](../../backend-system/building-backends/08-migrating.md)! +::: + +Authorizing `GET /todos` is similar to the update endpoint, in that it should be possible to authorize access based on the characteristics of each resource. However, we'll need to authorize a list of resources for this endpoint. + +One possible solution may leverage the batching functionality to authorize all of the todos, and then returning only the ones for which the decision was `ALLOW`: + +```ts +router.get('/todos', async (req, res) => { + /* highlight-add-next-line */ + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); + + /* highlight-remove-next-line */ + res.json(getAll()); + /* highlight-add-start */ + const items = getAll(); + const decisions = await permissions.authorize( + items.map(({ id }) => ({ + permission: todoListReadPermission, + resourceRef: id, + })), + { credentials }, + ); + + const filteredItems = decisions.filter( + decision => decision.result === AuthorizeResult.ALLOW, + ); + res.json(filteredItems); + /* highlight-add-end */ +}); +``` + +This approach will work for simple cases, but it has a downside: it forces us to retrieve all the elements upfront and authorize them one by one. This forces the plugin implementation to handle concerns like pagination, which is currently handled by the data source. + +To avoid this situation, the permissions framework has support for filtering items in the data source itself. In this part of the tutorial, we'll describe the steps required to use that behavior. + +:::note Note + +In order to perform authorization filtering in this way, the data source must allow filters to be logically combined with AND, OR, and NOT operators. The conditional decisions returned by the permissions framework use a [nested object](https://backstage.io/docs/reference/plugin-permission-common.permissioncriteria) to combine conditions. If you're implementing a filter API from scratch, we recommend using the same shape for ease of interoperability. If not, you'll need to implement a function which transforms the nested object into your own format. + +::: + +## Creating the read permission + +Let's add another permission to the plugin. + +```ts title="plugins/todo-list-backend/src/service/permissions.ts" +import { createPermission } from '@backstage/plugin-permission-common'; + +export const TODO_LIST_RESOURCE_TYPE = 'todo-item'; + +export const todoListCreatePermission = createPermission({ + name: 'todo.list.create', + attributes: { action: 'create' }, +}); + +export const todoListUpdatePermission = createPermission({ + name: 'todo.list.update', + attributes: { action: 'update' }, + resourceType: TODO_LIST_RESOURCE_TYPE, +}); + +/* highlight-add-start */ +export const todoListReadPermission = createPermission({ + name: 'todos.list.read', + attributes: { action: 'read' }, + resourceType: TODO_LIST_RESOURCE_TYPE, +}); +/* highlight-add-end */ + +export const todoListPermissions = [ + todoListCreatePermission, + todoListUpdatePermission, + /* highlight-add-start */ + todoListReadPermission, + /* highlight-add-end */ +]; +``` + +## Using conditional policy decisions + +So far we've only used the `PermissionsService.authorize` method, which will evaluate conditional decisions before returning a result. In this step, we want to evaluate conditional decisions within our plugin, so we'll use `PermissionsService.authorizeConditional` instead. + +```ts title="plugins/todo-list-backend/src/service/router.ts" +/* highlight-remove-next-line */ +import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; +/* highlight-add-start */ +import { + createPermissionIntegrationRouter, + createConditionTransformer, + ConditionTransformer, +} from '@backstage/plugin-permission-node'; +/* highlight-add-end */ +/* highlight-remove-next-line */ +import { add, getAll, getTodo, update } from './todos'; +/* highlight-add-next-line */ +import { add, getAll, getTodo, TodoFilter, update } from './todos'; +import { + TODO_LIST_RESOURCE_TYPE, + todoListCreatePermission, + todoListUpdatePermission, + /* highlight-add-next-line */ + todoListReadPermission, +} from './permissions'; + +// ... + +const permissionIntegrationRouter = createPermissionIntegrationRouter({ + /* highlight-remove-next-line */ + permissions: [todoListCreatePermission, todoListUpdatePermission], + /* highlight-add-next-line */ + permissions: [todoListCreatePermission, todoListUpdatePermission, todoListReadPermission], + getResources: async resourceRefs => { + return resourceRefs.map(getTodo); + }, + resourceType: TODO_LIST_RESOURCE_TYPE, + rules: Object.values(rules), +}); + +// ... + +/* highlight-add-next-line */ +const transformConditions: ConditionTransformer = createConditionTransformer(Object.values(rules)); + +/* highlight-remove-next-line */ +router.get('/todos', async (_req, res) => { +/* highlight-add-start */ +router.get('/todos', async (req, res) => { + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); + + const decision = ( + await permissions.authorizeConditional([{ permission: todoListReadPermission }], { + credentials, + }) + )[0]; + + if (decision.result === AuthorizeResult.DENY) { + throw new NotAllowedError('Unauthorized'); + } + + if (decision.result === AuthorizeResult.CONDITIONAL) { + const filter = transformConditions(decision.conditions); + res.json(getAll(filter)); + } else { + res.json(getAll()); + } +/* highlight-add-end */ + /* highlight-remove-next-line */ + res.json(getAll()); +}); +``` + +To make the process of handling conditional decisions easier, the permission framework provides a `createConditionTransformer` helper. This function accepts an array of permission rules, and returns a transformer function which converts the conditions to the format needed by the plugin using the `toQuery` method defined on each rule. + +Since `TodoFilter` used in our plugin matches the structure of the conditions object, we can directly pass the output of our condition transformer. If the filters were structured differently, we'd need to transform it further before passing it to the api. + +## Test the authorized read endpoint + +Let's update our permission policy to return a conditional result whenever a `todoListReadPermission` permission is received. In this case, we can reuse the decision returned for the `todosListCreate` permission. + +```ts title="packages/backend/src/plugins/permission.ts" +import { + todoListCreatePermission, + todoListUpdatePermission, + /* highlight-add-next-line */ + todoListReadPermission, +} from '@internal/plugin-todo-list-common'; + +/* highlight-remove-next-line */ +if (isPermission(request.permission, todoListUpdatePermission)) { +/* highlight-add-start */ +if ( + isPermission(request.permission, todoListUpdatePermission) || + isPermission(request.permission, todoListReadPermission) +) { +/* highlight-add-end */ + return createTodoListConditionalDecision( + request.permission, + todoListConditions.isOwner({ + userId: user?.identity.userEntityRef + }), + ); +} +``` + +Once the changes to the permission policy are saved, the UI should show only the todo items you've created. diff --git a/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data.md b/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data.md index 84e86140fc..883884b6e5 100644 --- a/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data.md +++ b/docs/permissions/plugin-authors/04-authorizing-access-to-paginated-data.md @@ -4,6 +4,8 @@ title: 4. Authorizing access to paginated data description: Explains how to authorize access to paginated data in a Backstage plugin --- +This documentation is written for [the new backend system](../../backend-system/index.md) which is the default since Backstage [version 1.24](../../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./04-authorizing-access-to-paginated-data--old.md) instead, and [consider migrating](../../backend-system/building-backends/08-migrating.md)! + Authorizing `GET /todos` is similar to the update endpoint, in that it should be possible to authorize access based on the characteristics of each resource. However, we'll need to authorize a list of resources for this endpoint. One possible solution may leverage the batching functionality to authorize all of the todos, and then returning only the ones for which the decision was `ALLOW`: @@ -11,7 +13,7 @@ One possible solution may leverage the batching functionality to authorize all o ```ts router.get('/todos', async (req, res) => { /* highlight-add-next-line */ - const token = IdentityClient.getBearerToken(req.header('authorization')); + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); /* highlight-remove-next-line */ res.json(getAll()); @@ -22,6 +24,7 @@ router.get('/todos', async (req, res) => { permission: todoListReadPermission, resourceRef: id, })), + { credentials }, ); const filteredItems = decisions.filter( @@ -81,7 +84,7 @@ export const todoListPermissions = [ ## Using conditional policy decisions -So far we've only used the `PermissionEvaluator.authorize` method, which will evaluate conditional decisions before returning a result. In this step, we want to evaluate conditional decisions within our plugin, so we'll use `PermissionEvaluator.authorizeConditional` instead. +So far we've only used the `PermissionsService.authorize` method, which will evaluate conditional decisions before returning a result. In this step, we want to evaluate conditional decisions within our plugin, so we'll use `PermissionsService.authorizeConditional` instead. ```ts title="plugins/todo-list-backend/src/service/router.ts" /* highlight-remove-next-line */ @@ -128,13 +131,11 @@ const transformConditions: ConditionTransformer = createConditionTra router.get('/todos', async (_req, res) => { /* highlight-add-start */ router.get('/todos', async (req, res) => { - const token = getBearerTokenFromAuthorizationHeader( - req.header('authorization'), - ); + const credentials = await httpAuth.credentials(req, { allow: ['user'] }); const decision = ( await permissions.authorizeConditional([{ permission: todoListReadPermission }], { - token, + credentials, }) )[0]; diff --git a/docs/plugins/integrating-search-into-plugins--old.md b/docs/plugins/integrating-search-into-plugins--old.md new file mode 100644 index 0000000000..2729dd3d21 --- /dev/null +++ b/docs/plugins/integrating-search-into-plugins--old.md @@ -0,0 +1,421 @@ +--- +id: integrating-search-into-plugins--old +title: Integrating Search into a plugin +description: How to integrate Search into a Backstage plugin +--- + +:::info +This documentation is written for the old backend which has been replaced by [the new backend system](../backend-system/index.md), being the default since Backstage [version 1.24](../releases/v1.24.0.md). If have migrated to the new backend system, you may want to read [its own article](./integrating-search-into-plugins.md) instead. Otherwise, [consider migrating](../backend-system/building-backends/08-migrating.md)! +::: + +The Backstage Search Platform was designed to give plugin developers the APIs +and interfaces needed to offer search experiences within their plugins, while +abstracting away (and instead empowering application integrators to choose) the +specific underlying search technologies. + +On this page, you'll find concepts and tutorials for leveraging the Backstage +Search Platform in your plugin. + +## Providing data to the search platform + +### Create a collator + +> Knowing what a [collator](../features/search/concepts.md#collators) is will help you as you build it out. + +Imagine you have a plugin that is responsible for storing FAQ snippets in a database. You want other engineers to be able to easily find your questions and answers. So that means you want them to be indexed by the search platform. Lets say the FAQ snippets can be viewed at a URL like `backstage.example.biz/faq-snippets`. + +The search platform provides an interface (`DocumentCollatorFactory` from package `@backstage/plugin-search-common`) that allows you to do exactly that. It works by registering each of your entries as a "document" that later represents one search result each. + +> You can always look at a working example, e.g. [StackOverflowQuestionsCollatorFactory](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts), if you are unsure or want to follow best practices. + +#### 1. Install collator interface dependencies + +We will need the interface `DocumentCollatorFactory` from package `@backstage/plugin-search-common`, so let's add it to your plugins dependencies: + +```sh +# navigate to the plugin directory +# (for this tutorial our plugin lives in the backstage repo, if your plugin lives in a separate repo you need to clone that first) +cd plugins/faq-snippets + +# Create a new branch using Git command-line +git checkout -b tutorials/new-faq-snippets-collator + +# Install the package containing the interface +yarn add @backstage/plugin-search-common +``` + +#### 2. Define your document type + +Before we can start generating documents from our FAQ entries, we first have to define a document type containing all necessary information we need to later display our entry as search result. The package `@backstage/plugin-search-common` we installed earlier contains a type `IndexableDocument` that we can extend. + +Create a new file `plugins/faq-snippets/src/search/collators/FaqSnippetDocument.ts` and paste the following below: + +```ts +import { IndexableDocument } from '@backstage/plugin-search-common'; + +export interface FaqSnippetDocument extends IndexableDocument { + answered_by: string; +} +``` + +#### 3. Use Backstage App configuration + +Your new collator could benefit from using configuration directly from the Backstage `app-config.yaml` file which is located on the project's root folder: + +```yaml +faq: + baseUrl: https://backstage.example.biz/faq-snippets +``` + +#### 4. Implement your collator + +Imagine your FAQs can be retrieved at the URL `https://backstage.example.biz/faq-snippets` with following JSON response format: + +```json +{ + "items": [ + { + "id": 42, + "question": "What is The Answer to the Ultimate Question of Life, the Universe, and Everything?", + "answer": "Forty-two", + "user": "Deep Thought" + } + ] +} +``` + +Below we provide an example implementation of how the FAQ collator factory could look like using our new document type, placed in the `plugins/faq-snippets/src/search/collators/FaqCollatorFactory.ts` file: + +```ts +import fetch from 'cross-fetch'; +import { Logger } from 'winston'; +import { Config } from '@backstage/config'; +import { Readable } from 'stream'; +import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; + +import { FaqDocument } from './FaqDocument'; + +export type FaqCollatorFactoryOptions = { + baseUrl?: string; + logger: Logger; +}; + +export class FaqCollatorFactory implements DocumentCollatorFactory { + private readonly baseUrl: string | undefined; + private readonly logger: Logger; + public readonly type: string = 'faq-snippets'; + + private constructor(options: FaqCollatorFactoryOptions) { + this.baseUrl = options.baseUrl; + this.logger = options.logger; + } + + static fromConfig(config: Config, options: FaqCollatorFactoryOptions) { + const baseUrl = + config.getOptionalString('faq.baseUrl') || + 'https://backstage.example.biz/faq-snippets'; + return new FaqCollatorFactory({ ...options, baseUrl }); + } + + async getCollator() { + return Readable.from(this.execute()); + } + + async *execute(): AsyncGenerator { + if (!this.baseUrl) { + this.logger.error(`No faq.baseUrl configured in your app-config.yaml`); + return; + } + + const response = await fetch(this.baseUrl); + const data = await response.json(); + + for (const faq of data.items) { + yield { + title: faq.question, + location: `/faq-snippets/${faq.id}`, + text: faq.answer, + answered_by: faq.user, + }; + } + } +} +``` + +#### 5. Test your collator + +To verify your implementation works as expected make sure to add tests for it. For your convenience, there is the [`TestPipeline`](https://backstage.io/docs/reference/plugin-search-backend-node.testpipeline) utility that emulates a pipeline into which you can integrate your custom collator. + +Look at [DefaultTechDocsCollatorFactory test](https://github.com/backstage/backstage/blob/de294ce5c410c9eb56da6870a1fab795268f60e3/plugins/techdocs-backend/src/search/DefaultTechDocsCollatorFactory.test.ts), for an example. + +#### 6. Make your plugins collator discoverable for others + +If you want to make your collator discoverable for other adopters, add it to the list of [plugins integrated to search](https://backstage.io/docs/features/search/#plugins-integrated-with-backstage-search). + +## Building a search experience into your plugin + +While the core Search plugin offers components and extensions that empower app +integrators to compose a global search experience, you may find that you want a +narrower search experience just within your plugin. This could be as literal as +an autocomplete-style search bar focused on documents provided by your plugin +(for example, the [TechDocsSearch](https://github.com/backstage/backstage/blob/master/plugins/techdocs/src/search/components/TechDocsSearch.tsx) +component), or as abstract as a widget that presents a list of links that +are contextually related to something else on the page. + +### Search Experience Concepts + +Knowing these high-level concepts will help you as you craft your in-plugin +search experience. + +- All search experiences must be wrapped in a ``, which + is provided by `@backstage/plugin-search-react`. This context keeps track + of state necessary to perform search queries and display any results. As + inputs to the query are updated (e.g. a `term` or `filter` values), the + updated query is executed and `results` are refreshed. Check out the + [SearchContextValue](https://backstage.io/docs/reference/plugin-search-react.searchcontextvalue) + for details. +- The aforementioned state can be modified and/or consumed via the + `useSearch()` hook, also exported by `@backstage/plugin-search-react`. +- For more literal search experiences, reusable components are available + to import and compose into a cohesive experience in your plugin (e.g. + `` or ``). You can see all such + components in [Backstage's storybook](https://backstage.io/storybook/?path=/story/plugins-search-searchbar--default). + +### Search Experience Tutorials + +The following tutorials make use of packages and plugins that you may not yet +have as dependencies for your plugin; be sure to add them before you use them! + +- [`@backstage/plugin-search-react`](https://www.npmjs.com/package/@backstage/plugin-search-react) - A + package containing components, hooks, and types that are shared across all + frontend plugins, including plugins like yours! +- [`@backstage/plugin-search`](https://www.npmjs.com/package/@backstage/plugin-search) - The + main search plugin, used by app integrators to compose global search + experiences. +- [`@backstage/core-components`](https://www.npmjs.com/package/@backstage/core-components) - A + package containing generic components useful for a variety of experiences + built in Backstage. + +#### Improved "404" page experience + +Imagine you have a plugin that allows users to manage _widgets_. Perhaps they +can be viewed at a URL like `backstage.example.biz/widgets/{widgetName}`. +At some point, a widget is renamed, and links to that widget's page from +chat systems, wikis, or browser bookmarks become stale, resulting in errors or +404s. + +What if instead of showing a broken page or the generic "looks like someone +dropped the mic" 404 page, you showed a list of possibly related widgets? + +```javascript +import { Link } from '@backstage/core-components'; +import { SearchResult } from '@backstage/plugin-search'; +import { SearchContextProvider } from '@backstage/plugin-search-react'; + +export const Widget404Page = ({ widgetName }) => { + // Supplying this to runs a pre-filtered search with + // the given widgetName as the search term, focused on search result of type + // "widget" with no other filters. + const preFiltered = { + term: widgetName, + types: ['widget'], + filters: {}, + }; + + return ( + + {/* The component allows us to iterate through results and + display them in whatever way fits best! */} + + {({ results }) => ( + {results.map(({ document }) => ( + + {document.title} + + ))} + )} + + + ); +); +``` + +Not all search experiences require user input! As you can see, it's possible to +leverage the Backstage Search Platform's frontend framework without necessarily +giving users input controls. + +#### Simple search page + +Of course, it's also possible to provide a more fully featured search +experience in your plugin. The simplest way is to leverage reusable components +provided by the `@backstage/plugin-search` package, like this: + +```javascript +import { useProfile } from '@internal/api'; +import { + Content, + ContentHeader, + PageWithHeader, +} from '@backstage/core-components'; +import { SearchBar, SearchResult } from '@backstage/plugin-search'; +import { SearchContextProvider } from '@backstage/plugin-search-react'; + +export const ManageMyWidgets = () => { + const { primaryTeam } = useProfile(); + // In this example, note how we are pre-filtering results down to a specific + // owner field value (the currently logged-in user's team), but allowing the + // search term to be controlled by the user via the component. + const preFiltered = { + types: ['widget'], + term: '', + filters: { + owner: primaryTeam, + }, + }; + + return ( + + + + + + + {/* Render results here, just like above */} + + + + + ); +}; +``` + +#### Custom search control surfaces + +If the reusable search components provided by `@backstage/plugin-search` aren't +adequate, no problem! There's an API in place that you can use to author your +own components to control the various parts of the search context. + +```javascript +import { useSearch } from '@backstage/plugin-search-react'; +import ChipInput from 'material-ui-chip-input'; + +export const CustomChipFilter = ({ name }) => { + const { filters, setFilters } = useSearch(); + const chipValues = filters[name] || []; + + // When a chip value is changed, update the filters value by calling the + // setFilters function from the search context. + const handleChipChange = (chip, index) => { + // There may be filters set for other fields. Be sure to maintain them. + setFilters(prevState => { + const { [name]: filter = [], ...others } = prevState; + + if (index === undefined) { + filter.push(chip); + } else { + filter.splice(index, 1); + } + + return { ...others, [name]: filter }; + }); + }; + + return ( + + ); +}; +``` + +Check out the [SearchContextValue type](https://github.com/backstage/backstage/blob/master/plugins/search-react/src/context/SearchContext.tsx) +for more details on what methods and values are available for manipulating and +reading the search context. + +If you produce something generic and reusable, consider contributing your +component upstream so that all users of the Backstage Search Platform can +benefit. Issues and pull requests welcome. + +#### Custom search results + +Search results throughout Backstage are rendered as lists so that list items can easily be customized; although a [default result list item](https://backstage.io/storybook/?path=/story/plugins-search-defaultresultlistitem--default) is available, plugins are in the best position to provide custom result list items that surface relevant information only known to the plugin. + +The example below imagines `YourCustomSearchResult` as a type of search result that contains associated `tags` which could be rendered as chips below the title/text. + +```tsx +import { Link } from '@backstage/core-components'; +import { useAnalytics } from '@backstage/core-plugin-api'; +import { ResultHighlight } from '@backstage/plugin-search-common'; +import { HighlightedSearchResultText } from '@backstage/plugin-search-react'; + +type CustomSearchResultListItemProps = { + result: YourCustomSearchResult; + rank?: number; + highlight?: ResultHighlight; +}; + +export const CustomSearchResultListItem = ( + props: CustomSearchResultListItemProps, +) => { + const { title, text, location, tags } = props.result; + + const analytics = useAnalytics(); + const handleClick = () => { + analytics.captureEvent('discover', title, { + attributes: { to: location }, + value: props.rank, + }); + }; + + return ( + + + + + ) : ( + title + ) + } + secondary={ + highlight?.fields?.text ? ( + + ) : ( + text + ) + } + /> + {tags && + tags.map((tag: string) => ( + + ))} + + + + + ); +}; +``` + +The optional use of the `` component makes it possible to highlight relevant parts of the result based on the user's search query. + +**Note on Analytics**: In order for app integrators to track and improve search experiences across Backstage, it's important for them to understand when and what users search for, as well as what they click on after searching. When providing a custom result component, it's your responsibility as a plugin developer to instrument it according to search analytics conventions. In particular: + +- You must use the `analytics.captureEvent` method, from the `useAnalytics()` hook (detailed [plugin analytics docs are here](./analytics.md)). +- You must ensure that the action of the event, representing a click on a search result item, is `discover`, and the subject is the `title` of the clicked result. In addition, the `to` attribute should be set to the result's `location`, and the `value` of the event must be set to the `rank` (passed in as a prop). +- You must ensure that the aforementioned `captureEvent` method is called when a user clicks the link; you should further ensure that the `noTrack` prop is added to the link (which disables default link click tracking, in favor of this custom instrumentation). + +For other examples and inspiration on custom result list items, check out the [``](https://github.com/backstage/backstage/blob/c981e83/plugins/stack-overflow/src/search/StackOverflowSearchResultListItem/StackOverflowSearchResultListItem.tsx) or [``](https://github.com/backstage/backstage/blob/c981e83/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx) components. diff --git a/docs/plugins/integrating-search-into-plugins.md b/docs/plugins/integrating-search-into-plugins.md index 28c8b410e3..62b3942537 100644 --- a/docs/plugins/integrating-search-into-plugins.md +++ b/docs/plugins/integrating-search-into-plugins.md @@ -4,6 +4,10 @@ title: Integrating Search into a plugin description: How to integrate Search into a Backstage plugin --- +:::info +This documentation is written for [the new backend system](../backend-system/index.md) which is the default since Backstage [version 1.24](../releases/v1.24.0.md). If you are still on the old backend system, you may want to read [its own article](./integrating-search-into-plugins--old.md) instead, and [consider migrating](../backend-system/building-backends/08-migrating.md)! +::: + The Backstage Search Platform was designed to give plugin developers the APIs and interfaces needed to offer search experiences within their plugins, while abstracting away (and instead empowering application integrators to choose) the @@ -24,34 +28,25 @@ The search platform provides an interface (`DocumentCollatorFactory` from packag > You can always look at a working example, e.g. [StackOverflowQuestionsCollatorFactory](https://github.com/backstage/backstage/blob/master/plugins/search-backend-module-stack-overflow-collator/src/collators/StackOverflowQuestionsCollatorFactory.ts), if you are unsure or want to follow best practices. -#### 1. Install collator interface dependencies +#### 1. Create a collator module package -We will need the interface `DocumentCollatorFactory` from package `@backstage/plugin-search-common`, so let's add it to your plugins dependencies: +In order to add an FAQ collator to the Backstage index registry we have to create a [plugin module](https://backstage.io/docs/backend-system/building-plugins-and-modules/index#modules), and the best way to do this is to create it in a separate package, e.g., `plugins/search-backend-module-faq-snippets-collator`, using the `yarn new` command: + +1. Access your Backstage project root directory and run `yarn new`; +2. When asked about what do you want to create, please select `backend-module` and hit enter; +3. Input `search` as the plugin ID and `faq-snippets-collator` as the module ID; +4. A `search-backend-module-faq-snippets-collator` folder should have been created in your project's "plugins" directory. + +#### 2. Install the collator dependencies + +We will use some libraries in the module, so let's add them to your plugin module dependencies: ```sh -# navigate to the plugin directory -# (for this tutorial our plugin lives in the backstage repo, if your plugin lives in a separate repo you need to clone that first) -cd plugins/faq-snippets - # Create a new branch using Git command-line git checkout -b tutorials/new-faq-snippets-collator # Install the package containing the interface -yarn add @backstage/plugin-search-common -``` - -#### 2. Define your document type - -Before we can start generating documents from our FAQ entries, we first have to define a document type containing all necessary information we need to later display our entry as search result. The package `@backstage/plugin-search-common` we installed earlier contains a type `IndexableDocument` that we can extend. - -Create a new file `plugins/faq-snippets/src/search/collators/FaqSnippetDocument.ts` and paste the following below: - -```ts -import { IndexableDocument } from '@backstage/plugin-search-common'; - -export interface FaqSnippetDocument extends IndexableDocument { - answered_by: string; -} +yarn workspace @internal/backstage-plugin-search-backend-module-faq-snippets-collator add node-fetch @backstage/plugin-search-common @backstage/plugin-search-backend-node ``` #### 3. Use Backstage App configuration @@ -63,7 +58,35 @@ faq: baseUrl: https://backstage.example.biz/faq-snippets ``` -#### 4. Implement your collator +It is optional to define a schedule for the collator to run, or else it defaults to the value in the collator factory code (See [5. Implement the collator factory](#5-implement-the-collator-factory)): + +```yaml +faq: + baseUrl: https://backstage.example.biz/faq-snippets + /* highlight-add-start */ + schedule: + # supports cron, ISO duration, "human duration" as used in code + frequency: { minutes: 30 } + # supports ISO duration, "human duration" as used in code + timeout: { minutes: 3 } + /* highlight-add-end */ +``` + +#### 4. Define the collator document type + +Before we can start generating documents from our FAQ entries, we first have to define a document type containing all necessary information we need to later display our entry as search result. The package `@backstage/plugin-search-common` we installed earlier contains a type `IndexableDocument` that we can extend. + +Create a new file `plugins/search-backend-module-faq-snippets-collator/src/types.ts` and paste the following below: + +```ts +import { IndexableDocument } from '@backstage/plugin-search-common'; + +export interface FaqSnippetDocument extends IndexableDocument { + answered_by: string; +} +``` + +#### 5. Implement the collator factory Imagine your FAQs can be retrieved at the URL `https://backstage.example.biz/faq-snippets` with following JSON response format: @@ -80,52 +103,50 @@ Imagine your FAQs can be retrieved at the URL `https://backstage.example.biz/faq } ``` -Below we provide an example implementation of how the FAQ collator factory could look like using our new document type, placed in the `plugins/faq-snippets/src/search/collators/FaqCollatorFactory.ts` file: +Below we provide an example implementation of how the FAQ collator factory could look like using our new document type, placed in the `plugins/search-backend-module-faq-snippets-collator/src/factory.ts` file: ```ts -import fetch from 'cross-fetch'; -import { Logger } from 'winston'; -import { Config } from '@backstage/config'; +import fetch from 'node-fetch'; import { Readable } from 'stream'; + +import { + LoggerService, + RootConfigService, +} from '@backstage/backend-plugin-api'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; -import { FaqDocument } from './FaqDocument'; +import { FaqSnippetDocument } from './types'; -export type FaqCollatorFactoryOptions = { - baseUrl?: string; - logger: Logger; -}; +const DEFAULT_BASE_URL = 'https://backstage.example.biz/faq-snippets'; -export class FaqCollatorFactory implements DocumentCollatorFactory { - private readonly baseUrl: string | undefined; - private readonly logger: Logger; +export class FaqSnippetsCollatorFactory implements DocumentCollatorFactory { public readonly type: string = 'faq-snippets'; + private readonly baseUrl: string; + private readonly logger: LoggerService; - private constructor(options: FaqCollatorFactoryOptions) { + private constructor(options: { logger: LoggerService; baseUrl: string }) { this.baseUrl = options.baseUrl; this.logger = options.logger; } - static fromConfig(config: Config, options: FaqCollatorFactoryOptions) { - const baseUrl = - config.getOptionalString('faq.baseUrl') || - 'https://backstage.example.biz/faq-snippets'; - return new FaqCollatorFactory({ ...options, baseUrl }); + static fromConfig( + config: RootConfigService, + options: { + logger: LoggerService; + }, + ) { + const baseUrl = config.getOptionalString('faq.baseUrl') ?? DEFAULT_BASE_URL; + return new FaqSnippetsCollatorFactory({ ...options, baseUrl }); } async getCollator() { return Readable.from(this.execute()); } - async *execute(): AsyncGenerator { - if (!this.baseUrl) { - this.logger.error(`No faq.baseUrl configured in your app-config.yaml`); - return; - } - + async *execute(): AsyncGenerator { + this.logger.info(`Fetching faq snippets from ${this.baseUrl}`); const response = await fetch(this.baseUrl); const data = await response.json(); - for (const faq of data.items) { yield { title: faq.question, @@ -138,13 +159,109 @@ export class FaqCollatorFactory implements DocumentCollatorFactory { } ``` -#### 5. Test your collator +#### 6. Implement the collator plugin module + +Now we have to connect the search backend plugin with our FAQ Snippets collator factory, so replace the `module.ts` file with the content below: + +```ts title='plugins/search-backend-module-faq-snippets-collator/src/module.ts' +import { + coreServices, + createBackendModule, + readSchedulerServiceTaskScheduleDefinitionFromConfig, +} from '@backstage/backend-plugin-api'; +import { searchIndexRegistryExtensionPoint } from '@backstage/plugin-search-backend-node/alpha'; +import { FaqSnippetsCollatorFactory } from './factory'; + +export const searchFaqSnippetsCollatorModule = createBackendModule({ + pluginId: 'search', + moduleId: 'faq-snippets-collator', + register(env) { + env.registerInit({ + deps: { + config: coreServices.rootConfig, + logger: coreServices.logger, + scheduler: coreServices.scheduler, + indexRegistry: searchIndexRegistryExtensionPoint, + }, + async init({ config, logger, scheduler, indexRegistry }) { + const defaultSchedule = { + frequency: { minutes: 10 }, + timeout: { minutes: 15 }, + initialDelay: { seconds: 3 }, + }; + + const schedule = config.has('faq.schedule') + ? readSchedulerServiceTaskScheduleDefinitionFromConfig( + config.getConfig('faq.schedule'), + ) + : defaultSchedule; + + indexRegistry.addCollator({ + schedule: scheduler.createScheduledTaskRunner(schedule), + factory: FaqSnippetsCollatorFactory.fromConfig(config, { logger }), + }); + }, + }); + }, +}); +``` + +In the fragment above, the module is registered, and when the Backstage backend initializes it, it adds the FAQ Snippets collator to the search index registry. Now let's export the module as default from the `index.ts` file: + +```ts title='plugins/search-backend-module-faq-snippets-collator/src/index.ts' +export { searchFaqSnippetsCollatorModule as default } from './module'; +``` + +#### 7. Install the collator module + +The newly created module should be added to the backend package dependencies as follows: + +```sh +yarn --cwd packages/backend add @internal/backstage-plugin-search-backend-module-faq-snippets-collator +``` + +After that, install the module on your Backstage backend instance: + +```ts title='packages/backend/src/index.ts' +import { createBackend } from '@backstage/backend-defaults'; +//... +const backend = createBackend(); +// Installing the search backend plugin +backend.add(import('@backstage/plugin-search-backend/alpha')); +// Installing the newly created faq snippets collator module +backend.add( + import( + '@internal/backstage-plugin-search-backend-module-faq-snippets-collator' + ), +); +//... +backend.start(); +``` + +#### 8. Testing the collator code To verify your implementation works as expected make sure to add tests for it. For your convenience, there is the [`TestPipeline`](https://backstage.io/docs/reference/plugin-search-backend-node.testpipeline) utility that emulates a pipeline into which you can integrate your custom collator. Look at [DefaultTechDocsCollatorFactory test](https://github.com/backstage/backstage/blob/de294ce5c410c9eb56da6870a1fab795268f60e3/plugins/techdocs-backend/src/search/DefaultTechDocsCollatorFactory.test.ts), for an example. -#### 6. Make your plugins collator discoverable for others +You can also check out the documentation on [how to test Backstage plugin modules](../backend-system/building-plugins-and-modules/02-testing.md). + +#### 9. Running the collator locally + +Run `yarn dev` 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 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 +``` + +It means that the collator task was started and completed successfully. Visit http://localhost:3000, log in, select the 'All' tab, and type in one of your snippets title in the search box. + +Results should appear for snippets. + +#### 10. Make your plugins collator discoverable for others If you want to make your collator discoverable for other adopters, add it to the list of [plugins integrated to search](https://backstage.io/docs/features/search/#plugins-integrated-with-backstage-search). diff --git a/docs/plugins/url-reader.md b/docs/plugins/url-reader.md deleted file mode 100644 index 9fab0482bb..0000000000 --- a/docs/plugins/url-reader.md +++ /dev/null @@ -1,265 +0,0 @@ ---- -id: url-reader -title: URL Reader -sidebar_label: URL Reader -# prettier-ignore -description: URL Reader is a backend core API responsible for reading files from external locations. ---- - -## Concept - -Some of the core plugins of Backstage have to read files from an external -location. [Software Catalog](../features/software-catalog/index.md) has to read -the [`catalog-info.yaml`](../features/software-catalog/descriptor-format.md) -entity descriptor files to register and track an entity. -[Software Templates](../features/software-templates/index.md) have to download -the template skeleton files before creating a new component. -[TechDocs](../features/techdocs/README.md) has to download the markdown source -files before generating a documentation site. - -Since, the requirement for reading files is so essential for Backstage plugins, -the -[`coreServices.urlReader`](../reference/backend-plugin-api.coreservices.urlreader.md) -package provides a dedicated API for reading from such URL based remote -locations like GitHub, GitLab, Bitbucket, Google Cloud Storage, etc. This is -commonly referred to as "URL Reader". It takes care of making authenticated -requests to the remote host so that private files can be read securely. If users -have [GitHub App based authentication](../integrations/github/github-apps.md) set up, URL Reader even -refreshes the token, to avoid reaching the GitHub API rate limit. - -As a result, plugin authors do not have to worry about any of these problems -when trying to read files. - -## Interface - -When the Backstage backend starts, a new instance of URL Reader is created. You -can see this in the index file of your Backstage backend -i.e.`packages/backend/src/index.ts`. -[Example](https://github.com/backstage/backstage/blob/ebbe91dbe79038a61d35cf6ed2d96e0e0d5a15f3/packages/backend/src/index.ts#L57) - -```ts -// File: packages/backend/src/index.ts - -import { UrlReaders } from '@backstage/backend-common'; - -function makeCreateEnv(config: Config) { - // .... - const reader = UrlReaders.default({ logger: root, config }); - // -} -``` - -This instance contains all the default URL Reader providers -in the backend-defaults package including GitHub, GitLab, Bitbucket, Azure, Google -GCS. As the need arises, more URL Readers are being written to support different -providers. - -The generic interface of a URL Reader instance looks like this. - -```ts -export type UrlReader = { - /* Used to read a single file and return its content. */ - readUrl(url: string, options?: ReadUrlOptions): Promise; - /* Used to read a file tree and download as a directory. */ - readTree(url: string, options?: ReadTreeOptions): Promise; - /* Used to search a file in a tree. */ - search(url: string, options?: SearchOptions): Promise; -}; -``` - -## Using a URL Reader inside a plugin - -The `reader` instance is available in the backend plugin environment and passed -on to all the backend plugins. You can see an -[example](https://github.com/backstage/backstage/blob/b0be185369ebaad22255b7cdf18535d1d4ffd0e7/packages/backend/src/plugins/techdocs.ts#L31). -When any of the methods on this instance is called with a URL, URL Reader -extracts the host for that URL (e.g. `github.com`, `ghe.mycompany.com`, etc.). -Using the -[`@backstage/integration`](https://github.com/backstage/backstage/tree/master/packages/integration) -package, it looks inside the -[`integrations:`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/app-config.yaml#L134-L158) -config of the `app-config.yaml` to find out how to work with the host based on -the configs provided like authentication token, API base URL, etc. - -Make sure your plugin-specific backend file at -`packages/backend/src/plugins/.ts` is forwarding the `reader` instance -passed on as the `PluginEnvironment` to the actual plugin's `createRouter` -function. See how this is done in -[Catalog](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/backend/src/plugins/catalog.ts#L25-L27) -and -[TechDocs](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/backend/src/plugins/techdocs.ts#L31-L36) -backend plugins. - -Once the reader instance is available inside the plugin, one of its methods can -directly be used with a URL. Some example usages - - -- [`readUrl`](https://github.com/backstage/backstage/blob/a7607b5/plugins/catalog-backend/src/modules/codeowners/lib/read.ts#L24-L33) - - Catalog using the `readUrl` method to read the CODEOWNERS file in a repository. -- [`readTree`](https://github.com/backstage/backstage/blob/84a8788/plugins/techdocs-node/src/helpers.ts#L146-L167) - - TechDocs using the `readTree` method to download markdown files in order to - generate the documentation site. -- [`readTree`](https://github.com/backstage/backstage/blob/cb4f0e4/plugins/techdocs-node/src/stages/prepare/url.ts#L51-L73) - - TechDocs using `NotModifiedError` to maintain cache and speed up and limit the - number of requests. -- [`search`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.ts#L88-L108) - - Catalog using the `search` method to find files for a location URL containing - a glob pattern. - -Note that URL Readers which target git-based version control systems may, under -the hood, leverage the ability to create tar archives based on a specific git -commit-ish. A consequence of this is that files and directories configured with -[the `export-ignore` attribute](https://git-scm.com/docs/gitattributes#_creating_an_archive) -via `.gitattributes` will not be visible to the URL reader when using the -`readTree` or `search` methods. - -Be aware of this limitation and ensure that end-users of your plugin are also -aware via, for example, documentation. - -## Writing a new URL Reader - -If the available URL Readers are not sufficient for your use case and you want -to add a new URL Reader for any other provider, you are most welcome to -contribute one! - -Feel free to use the -[GitHub URL Reader](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/backend-common/src/reading/GithubUrlReader.ts) -as a source of inspiration. - -### 1. Add an integration - -The provider for your new URL Reader can also be called an "integration" in -Backstage. The `integrations:` section of your Backstage `app-config.yaml` -config file is supposed to be the place where a Backstage integrator defines the -host URL for the integration, authentication details and other integration -related configurations. - -The `@backstage/integration` package is where most of the integration specific -code lives, so that it is shareable across Backstage. Functions like "read the -integrations config and process it", "construct headers for authenticated -requests to the host" or "convert a plain file URL into its API URL for -downloading the file" would live in this package. - -### 2. Create the URL Reader - -Create a new class which implements the -[`UrlReader` type](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/backend-common/src/reading/types.ts#L21-L28) -inside `@backstage/backend-common`. Create and export a static `factory` method -which reads the integration config and returns a map of host URLs the new reader -should be used for. See the -[GitHub URL Reader](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/backend-common/src/reading/GithubUrlReader.ts#L50-L63) -for example. - -### 3. Implement the methods - -We want to make sure all URL Readers behave in the same way. Hence if possible, -all the methods of the `UrlReader` interface should be implemented. However it -is okay to start by implementing just one of them and create issues for the -remaining. - -#### `readUrl` - -`readUrl` method expects a user-friendly URL, something which can be copied from -the browser naturally when a person is browsing the provider in their browser. - -- ✅ Valid URL : - `https://github.com/backstage/backstage/blob/master/ADOPTERS.md` -- ❌ Not a valid URL : - `https://raw.githubusercontent.com/backstage/backstage/master/ADOPTERS.md` -- ❌ Not a valid URL : `https://github.com/backstage/backstage/ADOPTERS.md` - -Upon receiving the URL, `readUrl` converts the user-friendly URL into an API URL -which can be used to request the provider's API. - -`readUrl` then makes an authenticated request to the provider API and returns the response containing the file's contents and ETag(if the provider supports it). - -#### `readTree` - -`readTree` method also expects user-friendly URLs similar to `read` but the URL -should point to a tree (could be the root of a repository or even a -sub-directory). - -- ✅ Valid URL : `https://github.com/backstage/backstage` -- ✅ Valid URL : `https://github.com/backstage/backstage/blob/master` -- ✅ Valid URL : `https://github.com/backstage/backstage/blob/master/docs` - -Using the provider's API documentation, find out an API endpoint which can be -used to download either a zip or a tarball. You can download the entire tree -(e.g. a repository) and filter out in case the user is expecting only a -sub-tree. But some APIs are smart enough to accept a path and return only a -sub-tree in the downloaded archive. - -#### search - -`search` method expects a glob pattern of a URL and returns a list of files -matching the query. - -- ✅ Valid URL : - `https://github.com/backstage/backstage/blob/master/**/catalog-info.yaml` -- ✅ Valid URL : `https://github.com/backstage/backstage/blob/master/**/*.md` -- ✅ Valid URL : - `https://github.com/backstage/backstage/blob/master/*/package.json` -- ✅ Valid URL : `https://github.com/backstage/backstage/blob/master/READM` - -The core logic of `readTree` can be used here to extract all the files inside -the tree and return the files matching the pattern in the `url`. - -### 4. Add to available URL Readers - -There are two ways to make your new URL Reader available for use. - -You can choose to make it open source, by updating the -[`default` factory](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/backend-common/src/reading/UrlReaders.ts#L62-L81) -method of URL Readers. - -But for something internal which you don't want to make open source, you can -update your `packages/backend/src/index.ts` file and update how the `reader` -instance is created. - -```ts -// File: packages/backend/src/index.ts -const reader = UrlReaders.default({ - logger: root, - config, - // This is where your internal URL Readers would go. - factories: [myCustomReader.factory], -}); -``` - -### 5. Caching - -All of the methods above support an ETag based caching. If the method is called -without an `etag`, the response contains an ETag of the resource (should ideally -forward the ETag returned by the provider). If the method is called with an -`etag`, it first compares the ETag and returns a `NotModifiedError` in case the -resource has not been modified. This approach is very similar to the actual -[`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) and -[`If-None-Match`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) -HTTP headers. - -### 6. Debugging - -When debugging one of the URL Readers, you can straightforward use the -[`reader` instance created](https://github.com/backstage/backstage/blob/ebbe91dbe79038a61d35cf6ed2d96e0e0d5a15f3/packages/backend/src/index.ts#L57) -when the backend starts and call one of the methods with your debugging URL. - -```ts -// File: packages/backend/src/index.ts - -async function main() { - // ... - const createEnv = makeCreateEnv(config); - - const testReader = createEnv('test-url-reader').reader; - const response = await testReader.readUrl( - 'https://github.com/backstage/backstage/blob/master/catalog-info.yaml', - ); - console.log((await response.buffer()).toString()); - // ... -} -``` - -This will be run every time you restart the backend. Note that after any change -in the URL Reader code, you need to stop the backend and restart, since the -`reader` instance is memoized and does not update on hot module reloading. Also, -there are a lot of unit tests written for the URL Readers, which you can make -use of. diff --git a/docs/releases/v1.31.0-next.0-changelog.md b/docs/releases/v1.31.0-next.0-changelog.md new file mode 100644 index 0000000000..7e8b118fff --- /dev/null +++ b/docs/releases/v1.31.0-next.0-changelog.md @@ -0,0 +1,2787 @@ +# Release v1.31.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.31.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.31.0-next.0) + +## @backstage/backend-app-api@0.10.0-next.0 + +### Minor Changes + +- 19ff127: **BREAKING**: The deprecated `identityServiceFactory` and `tokenManagerServiceFactory` have been removed. +- 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 + +- cd38da8: Deprecate the `featureDiscoveryServiceFactory` in favor of using `@backstage/backend-defaults#discoveryFeatureLoader` instead. +- 7f779c7: `auth.externalAccess` should be optional in the config schema +- 51a69b5: Fix feature loaders in CJS double-default nested builds +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/backend-common@0.25.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 + +- 8ba77ed: The `legacyPlugin` and `makeLegacyPlugin` helpers now provide their own shim implementation of the identity and token manager services, as these services are being removed from the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 2e9ec14: Add `pg-format` as a dependency +- 19ff127: Internal refactor to re-declare the token manager service which was removed from `@backstage/backend-plugin-api`, but is still supported in this package for backwards compatibility. +- 66dbf0a: Allow the cache service to accept the human duration format for TTL +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.5.0-next.0 + +### Minor Changes + +- 359fcd7: **BREAKING**: The backwards compatibility with plugins using legacy auth through the token manager service has been removed. This means that instead of falling back to using the old token manager, requests towards plugins that don't support the new auth system will simply fail. Please make sure that all plugins in your deployment are hosted within a backend instance from the new backend system. + +- 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. + +- 19ff127: **BREAKING**: The default backend instance no longer provides implementations for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. + + If you rely on plugins that still require these services, you can add them to your own backend by re-creating the service reference and factory. + + The following can be used to implement the identity service: + + ```ts + import { + coreServices, + createServiceFactory, + createServiceRef, + } from '@backstage/backend-plugin-api'; + import { + DefaultIdentityClient, + IdentityApi, + } from '@backstage/plugin-auth-node'; + + backend.add( + createServiceFactory({ + service: createServiceRef({ id: 'core.identity' }), + deps: { + discovery: coreServices.discovery, + }, + async factory({ discovery }) { + return DefaultIdentityClient.create({ discovery }); + }, + }), + ); + ``` + + The following can be used to implement the token manager service: + + ```ts + import { ServerTokenManager, TokenManager } from '@backstage/backend-common'; + import { createBackend } from '@backstage/backend-defaults'; + import { + coreServices, + createServiceFactory, + createServiceRef, + } from '@backstage/backend-plugin-api'; + + backend.add( + createServiceFactory({ + service: createServiceRef({ id: 'core.tokenManager' }), + deps: { + config: coreServices.rootConfig, + logger: coreServices.rootLogger, + }, + createRootContext({ config, logger }) { + return ServerTokenManager.fromConfig(config, { + logger, + allowDisabledTokenManager: true, + }); + }, + async factory(_deps, tokenManager) { + return tokenManager; + }, + }), + ); + ``` + +### Patch Changes + +- 7f779c7: `auth.externalAccess` should be optional in the config schema + +- 7a72ec8: Exports the `discoveryFeatureLoader` as a replacement for the deprecated `featureDiscoveryService`. + The `discoveryFeatureLoader` is a new backend system [feature loader](https://backstage.io/docs/backend-system/architecture/feature-loaders/) that discovers backend features from the current `package.json` and its dependencies. + Here is an example using the `discoveryFeatureLoader` loader in a new backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { discoveryFeatureLoader } from '@backstage/backend-defaults'; + //... + + const backend = createBackend(); + //... + backend.add(discoveryFeatureLoader); + //... + backend.start(); + ``` + +- 66dbf0a: Allow the cache service to accept the human duration format for TTL + +- 5a8fcb4: Added the option to skip database migrations by setting `skipMigrations: true` in config. This can be done globally in the database config or by plugin id. + +- 0b2a402: Updates to the config schema to match reality + +- Updated dependencies + - @backstage/backend-app-api@0.10.0-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-dynamic-feature-service@0.4.0-next.0 + +### Minor Changes + +- 9080f57: **BREAKING**: `dynamicPluginsServiceFactory` is no longer callable as a function. If you need to provide options to make a custom factory, use `dynamicPluginsSchemasServiceFactoryWithOptions` instead. + +### Patch Changes + +- cd38da8: Deprecate the `dynamicPluginsServiceRef`, `dynamicPluginsServiceFactory` and `dynamicPluginsServiceFactoryWithOptions` in favor of using the `dynamicPluginsFeatureDiscoveryLoader` to discover dynamic features in a new backend system. + + See usage examples below: + + Example using the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + //... + + const backend = createBackend(); + backend.add(dynamicPluginsFeatureDiscoveryLoader); + //... + backend.start(); + ``` + + Passing options to the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + import { myCustomModuleLoader } from './myCustomModuleLoader'; + //... + + const backend = createBackend(); + backend.add( + dynamicPluginsFeatureDiscoveryLoader({ + moduleLoader: myCustomModuleLoader, + }), + ); + //... + backend.start(); + ``` + +- e27f889: Relax type check for a plugin's default export to also accept a BackendFeature defined as a function instead of an object + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- Updated dependencies + - @backstage/backend-app-api@0.10.0-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-app-node@0.1.25-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-backend@0.3.12-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/backend-plugin-api@0.9.0-next.0 + +### Minor Changes + +- 19ff127: **BREAKING**: The deprecated identity and token manager services have been removed. This means that `coreServices.identity` and `coreServices.tokenManager` are gone, along with related types and utilities in other packages. + +- f687050: Removed the following deprecated exports + + - `BackendPluginConfig` use `CreateBackendPluginOptions` + - `BackendModuleConfig` use `CreateBackendModuleOptions` + - `ExtensionPointConfig` use `CreateExtensionPointOptions` + +- 4d82481: Removed deprecated `ServiceFactoryOrFunction` type. + +- 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 + +- cd38da8: Deprecate the `featureDiscoveryServiceRef` in favor of using the new `discoveryFeatureLoader` instead. +- 66dbf0a: Allow the cache service to accept the human duration format for TTL +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/backend-test-utils@0.6.0-next.0 + +### Minor Changes + +- 19ff127: **BREAKING**: Removed service mocks for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. +- 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 + +- 0363bf1: There is a new `mockErrorHandler` utility to help in mocking the error middleware in tests. +- Updated dependencies + - @backstage/backend-app-api@0.10.0-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/frontend-app-api@0.9.0-next.0 + +### Minor Changes + +- 62cce6c: Removed deprecated `icons` property passing to `createApp` and `createSpecializedApp`. Use `IconBundleBlueprint.make` to create extensions instead and include them in the app. + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. + +- f3a2b91: Moved several implementations of built-in APIs from being hardcoded in the app to instead be provided as API extensions. This moves all API-related inputs from the `app` extension to the respective API extensions. For example, extensions created with `ThemeBlueprint` are now attached to the `themes` input of `api:app-theme` rather than the `app` extension. + +- 5446061: Internal refactor following removal of v1 extension support. The app implementation itself still supports v1 extensions at runtime. + +- 98850de: Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. + + ```ts + export const AppThemeApi = ApiBlueprint.makeWithOverrides({ + name: 'app-theme', + inputs: { + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead + replaces: [{ id: 'app', input: 'themes' }], + }), + }, + factory: () { + ... + } + }); + ``` + +- 4a66456: Added the `root` extension the replace the `app` extension as the root of the app. + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/plugin-app@0.1.0-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-plugin-api@0.8.0-next.0 + +### Minor Changes + +- 5446061: **BREAKING**: Removed support for "v1" extensions. This means that it is no longer possible to declare inputs and outputs as objects when using `createExtension`. In addition, all extension creators except for `createComponentExtension` have been removed, use the equivalent blueprint instead. See the [1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations/#130) for more information on this change. +- fec8b57: **BREAKING**: Updated the type parameters for `ExtensionDefinition` and `ExtensionBlueprint` to only have a single object parameter. The base type parameter is exported as `ExtensionDefinitionParameters` and `ExtensionBlueprintParameters` respectively. This is shipped as an immediate breaking change as we expect usage of these types to be rare, and it does not affect the runtime behavior of the API. + + This is a breaking change as it changes the type parameters. Existing usage can generally be updated as follows: + + - `ExtensionDefinition` -> `ExtensionDefinition` + - `ExtensionDefinition` -> `ExtensionDefinition` + - `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig }>` + - `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig, configInput: TConfigInput }>` + + If you need to infer the parameter you can use `ExtensionDefinitionParameters`, for example: + + ```ts + import { + ExtensionDefinition, + ExtensionDefinitionParameters, + } from '@backstage/frontend-plugin-api'; + + function myUtility( + ext: ExtensionDefinition, + ): T['config'] { + // ... + } + ``` + + The same patterns apply to `ExtensionBlueprint`. + + This change is made to improve the readability of API references and ability to evolve the type parameters in the future. + +### Patch Changes + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. + +- f3a2b91: Moved several implementations of built-in APIs from being hardcoded in the app to instead be provided as API extensions. This moves all API-related inputs from the `app` extension to the respective API extensions. For example, extensions created with `ThemeBlueprint` are now attached to the `themes` input of `api:app-theme` rather than the `app` extension. + +- 98850de: Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. + + ```ts + export const AppThemeApi = ApiBlueprint.makeWithOverrides({ + name: 'app-theme', + inputs: { + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead + replaces: [{ id: 'app', input: 'themes' }], + }), + }, + factory: () { + ... + } + }); + ``` + +- 4a66456: A new `apis` parameter has been added to `factory` for extensions. This is a way to access utility APIs without being coupled to the React context. + +- Updated dependencies + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-test-utils@0.2.0-next.0 + +### Minor Changes + +- 5446061: Removed support for testing "v1" extensions, where outputs are defined as an object rather than an array. +- e6e488c: **BREAKING**: The deprecated `.render()` method has been removed from the extension tester. + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 4a66456: Internal update to add support for passing an `ApiRegistry` when creating the node tree +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. +- f6d1874: Added the ability to provide additional `extensions` and `features` to `renderInTestApp` +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/frontend-app-api@0.9.0-next.0 + - @backstage/plugin-app@0.1.0-next.0 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/test-utils@1.6.0-next.0 + +### Minor Changes + +- d47be30: Added the icons option to the renderInTestApp function's TestAppOptions to be forwarded to the icons option of `createApp`. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/plugin-app@0.1.0-next.0 + +### Minor Changes + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/plugin-auth-backend@0.23.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 + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- Updated dependencies + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.0-next.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@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/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.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 + +- ecbc47e: Fix a bug where the signer was checked from the payload instead of the header +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-auth-backend@0.23.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.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/plugin-auth-node@0.5.2-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.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/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@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/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@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/plugin-auth-node@0.5.2-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.2.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/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.2.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/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.2.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/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.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-auth-node@0.5.2-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.2.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 + +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@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/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.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/plugin-auth-node@0.5.2-next.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@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/plugin-auth-backend@0.23.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-okta-provider@0.1.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/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.2.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/plugin-auth-node@0.5.2-next.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.2.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/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@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/plugin-auth-node@0.5.2-next.0 + - @backstage/catalog-model@1.6.0 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.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-openapi-utils@0.1.18-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog-backend-module-gcp@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/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-catalog-backend-module-github-org@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/plugin-catalog-backend-module-github@0.7.3-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.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-catalog-backend-module-gitlab@0.4.2-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.9.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/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-backend-module-logs@0.1.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/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.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-catalog-backend@1.25.3-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.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/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.5.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-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-devtools-backend@0.4.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/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-events-node@0.4.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/plugin-notifications-backend@0.4.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-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-notifications-node@0.2.6-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-notifications-backend-module-email@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 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.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/plugin-permission-node@0.8.3-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-scaffolder@1.25.0-next.0 + +### Minor Changes + +- 5143616: Added EntityOwnerPicker component to the TemplateListPage to allow filtering on owner + +### 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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-scaffolder-react@1.12.0-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.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/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-scaffolder-backend@1.25.0-next.0 + +### Minor Changes + +- 62898bd: `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. + +### Patch Changes + +- c160951: Found the issue during testing the clean up of the workspace for the database implementation. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@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/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@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-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@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-defaults@0.5.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.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 + +- 9e5923d: Added test cases for publish:gerrit action examples +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-scaffolder-backend-module-github@0.5.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-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.5.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-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.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-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.12-next.0 + +## @backstage/plugin-scaffolder-react@1.12.0-next.0 + +### Minor Changes + +- 4512f71: Add `ui:backstage.review.name` option for custom item names on scaffolder review page, and also add support for rendering the `title` property instead of the key name. + +### Patch Changes + +- 3ebb64f: - Fix secret widget field not displaying as required. + - Fix secret widget not able to be required inside nested objects. + - Fix secret widget not able to be disabled. + - Support `minLength` and `maxLength` properties for secret widget. +- 8dd6ef6: Fix an issue where keys with duplicate final key parts are not all displayed in the `ReviewState`. Change the way the keys are formatted to include the full schema path, separated by `>`. +- 9a0672a: Scaffolder review page shows static amount of asterisks for secret fields. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@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-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-react@1.8.0-next.0 + +### Minor Changes + +- 9d66d8c: Make use of the `useApp` hook to retrieve the specified search icon in the SearchBar + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- f26ff99: Slight type tweak to match newer React versions better +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-signals-backend@0.2.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 + +- 3ec5ccb: The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/backend-openapi-utils@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/errors@1.2.4 + +## @backstage/backend-tasks@0.6.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/cli@0.27.1-next.0 + +### Patch Changes + +- 1b5c264: Add `checks: 'read'` for default GitHub app permissions +- Updated dependencies + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/integration@1.14.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/core-compat-api@0.2.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/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## @backstage/create-app@0.5.19-next.0 + +### Patch Changes + +- 019d9ad: Minor dockerfile syntax update +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/dev-utils@1.0.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/app-defaults@1.5.10 + - @backstage/catalog-model@1.6.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + +## @backstage/repo-tools@0.9.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + +## @techdocs/cli@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 + +## @backstage/plugin-api-docs@0.11.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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/plugin-app-backend@0.3.74-next.0 + +### Patch Changes + +- d3f79d1: Fixing dependency metadata with the new `@backstage/plugin-app` package +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-app-node@0.1.25-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-app-node@0.1.25-next.0 + +### Patch Changes + +- d3f79d1: Fixing dependency metadata with the new `@backstage/plugin-app` package +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/config-loader@1.9.0 + +## @backstage/plugin-app-visualizer@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-auth-node@0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog@1.22.1-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- 180a45f: Entity presentation api now only fetches fields that are required to display entity title +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-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-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-catalog-backend@1.25.3-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 53cce86: Fixed an issue with the by-query call, where ordering by a field that does not exist on all entities led to not all results being returned +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/backend-openapi-utils@0.1.18-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-catalog-backend-module-azure@0.2.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.3.2-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.2.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.2.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + +## @backstage/plugin-catalog-backend-module-github@0.7.3-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-backend-module-gitlab@0.4.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- b446954: Remove dependency on backend-common +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.5.3-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 4b28e39: Updated the README to include documentation for the new backend support +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.6.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-graph@0.4.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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.3-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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @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/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-node@1.12.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-react@1.12.4-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/plugin-devtools@0.1.18-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 019d9ad: Minor dockerfile syntax update +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/plugin-events-backend@0.3.12-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-events-backend-module-azure@0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + +## @backstage/plugin-events-backend-module-github@0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-module-gitlab@0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/config@1.2.0 + +## @backstage/plugin-events-backend-test-utils@0.1.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.0-next.0 + +## @backstage/plugin-home@0.7.10-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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-home-react@0.1.16 + +## @backstage/plugin-kubernetes@0.11.14-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- bfc0f42: Make k8s entity content appear on components & resources only by default in new FE system +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-react@0.4.2 + +## @backstage/plugin-kubernetes-backend@0.18.6-next.0 + +### Patch Changes + +- f55f8bf: The `KubernetesBuilder` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-kubernetes-node@0.1.19-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-kubernetes-cluster@0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-react@0.4.2 + +## @backstage/plugin-kubernetes-node@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-notifications@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-signals-react@0.0.5-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-notifications-node@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-notifications-common@0.0.5 + +## @backstage/plugin-org@0.6.29-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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-org-react@0.1.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-permission-backend@0.5.49-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- fcb9356: Deprecated `createRouter` and its router options in favour of the new backend system. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-permission-node@0.8.3-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-proxy-backend@0.5.6-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- d298e6e: Deprecated `createRouter` and its router options in favour of the new backend system. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder-node@0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.0 + - @backstage/backend-test-utils@0.6.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-search@1.4.16-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/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/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend@1.5.17-next.0 + +### Patch Changes + +- 5726390: Deprecate create router as the legacy backend system will no longer be supported. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/backend-openapi-utils@0.1.18-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-catalog@0.2.2-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- 5726390: The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: + + - `DefaultCatalogCollatorFactory`: ; + - `ToolDocumentCollatorFactory`: ; + - `DefaultTechDocsCollatorFactory`: . + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.6-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5726390: Internal refactor to use `LoggerService` and `DatabaseService` instead of the legacy `Logger` and `PluginDatabaseManager` types. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-explore@0.2.2-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- 5726390: The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: + + - `DefaultCatalogCollatorFactory`: ; + - `ToolDocumentCollatorFactory`: ; + - `DefaultTechDocsCollatorFactory`: . + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-pg@0.5.35-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5726390: Internal refactor to use `LoggerService` and `DatabaseService` instead of the legacy `Logger` and `PluginDatabaseManager` types. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-techdocs@0.2.2-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. + +- 5726390: The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: + + - `DefaultCatalogCollatorFactory`: ; + - `ToolDocumentCollatorFactory`: ; + - `DefaultTechDocsCollatorFactory`: . + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-techdocs-node@1.12.11-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-node@1.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-signals@0.0.10-next.0 + +### Patch Changes + +- 5add8e1: Added a `SignalsDisplay` extension to allows the signals plugin to be installed in an app as follows: + + ```tsx + export default app.createRoot( + <> + + + + + + {routes} + + , + ); + ``` + + With this in place you can remove the explicit installation via the `plugins` option for `createApp`. + +- Updated dependencies + - @backstage/plugin-signals-react@0.0.5-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-node@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-signals-react@0.0.5-next.0 + +### Patch Changes + +- 0389801: Fix for `useSignal` returning the inverse value for `isSignalsAvailable`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-techdocs@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 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-search-react@1.8.0-next.0 + - @backstage/plugin-techdocs@1.10.9-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + +## @backstage/plugin-techdocs-backend@1.10.13-next.0 + +### Patch Changes + +- 086c32d: Dedicated token for techdocs cache sync +- 5b679ac: The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-techdocs-node@1.12.11-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration@1.14.0 + - @backstage/integration-react@1.1.30 + +## @backstage/plugin-techdocs-node@1.12.11-next.0 + +### Patch Changes + +- 4417dd4: Fix typo and unify TechDocs casing in doc strings +- 33ebb28: As the `@backstage/backend-common` package is deprecated, we have updated the `techdocs-node` package to stop depending on it. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-react@1.2.8-next.0 + +### Patch Changes + +- 5ee3d27: Fixed issue in useShadowRootElements which could lead to unlimited render loops +- Updated dependencies + - @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/version-bridge@1.0.8 + +## @backstage/plugin-user-settings@0.8.12-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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-signals-react@0.0.5-next.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.24-next.0 + +### Patch Changes + +- 164ce3e: In preparation to stop supporting to the legacy backend system, the `createRouter` function is now deprecated and we strongly recommend you [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) your backend to the new system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 1b98099: Replaced usage of the deprecated identity service with the new HTTP auth service for the new backend system. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.101-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/frontend-app-api@0.9.0-next.0 + - @backstage/plugin-catalog-import@0.12.3-next.0 + - @backstage/plugin-catalog-graph@0.4.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-user-settings@0.8.12-next.0 + - @backstage/plugin-search-react@1.8.0-next.0 + - @backstage/plugin-kubernetes@0.11.14-next.0 + - @backstage/plugin-scaffolder@1.25.0-next.0 + - @backstage/plugin-api-docs@0.11.9-next.0 + - @backstage/plugin-devtools@0.1.18-next.0 + - @backstage/plugin-techdocs@1.10.9-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/plugin-search@1.4.16-next.0 + - @backstage/plugin-home@0.7.10-next.0 + - @backstage/plugin-org@0.6.29-next.0 + - @backstage/plugin-scaffolder-react@1.12.0-next.0 + - @backstage/cli@0.27.1-next.0 + - @backstage/plugin-signals@0.0.10-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.0 + - @backstage/app-defaults@1.5.10 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7 + - @backstage/plugin-notifications@0.3.1-next.0 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-search-common@1.2.14 + +## example-app-next@0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/frontend-app-api@0.9.0-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-import@0.12.3-next.0 + - @backstage/plugin-catalog-graph@0.4.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-user-settings@0.8.12-next.0 + - @backstage/plugin-search-react@1.8.0-next.0 + - @backstage/plugin-kubernetes@0.11.14-next.0 + - @backstage/plugin-scaffolder@1.25.0-next.0 + - @backstage/plugin-api-docs@0.11.9-next.0 + - @backstage/plugin-techdocs@1.10.9-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/plugin-search@1.4.16-next.0 + - @backstage/plugin-home@0.7.10-next.0 + - @backstage/plugin-org@0.6.29-next.0 + - @backstage/plugin-scaffolder-react@1.12.0-next.0 + - @backstage/plugin-app@0.1.0-next.0 + - @backstage/cli@0.27.1-next.0 + - @backstage/plugin-signals@0.0.10-next.0 + - @backstage/plugin-app-visualizer@0.1.10-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.0 + - @backstage/app-defaults@1.5.10 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7 + - @backstage/plugin-notifications@0.3.1-next.0 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-search-common@1.2.14 + +## app-next-example-plugin@0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-components@0.14.10 + +## example-backend@0.0.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.13-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-search-backend@1.5.17-next.0 + - @backstage/plugin-kubernetes-backend@0.18.6-next.0 + - @backstage/plugin-scaffolder-backend@1.25.0-next.0 + - @backstage/plugin-app-backend@0.3.74-next.0 + - @backstage/plugin-signals-backend@0.2.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/plugin-auth-backend@0.23.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-permission-backend@0.5.49-next.0 + - @backstage/plugin-proxy-backend@0.5.6-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.0-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.0-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.0 + - @backstage/plugin-devtools-backend@0.4.0-next.0 + - @backstage/plugin-notifications-backend@0.4.0-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-permission-common@0.8.1 + +## example-backend-legacy@0.2.102-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.13-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-search-backend@1.5.17-next.0 + - @backstage/plugin-kubernetes-backend@0.18.6-next.0 + - @backstage/plugin-scaffolder-backend@1.25.0-next.0 + - @backstage/plugin-app-backend@0.3.74-next.0 + - @backstage/plugin-signals-backend@0.2.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/plugin-auth-backend@0.23.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-backend@0.3.12-next.0 + - @backstage/plugin-permission-backend@0.5.49-next.0 + - @backstage/plugin-proxy-backend@0.5.6-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.6-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.35-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.0 + - @backstage/plugin-devtools-backend@0.4.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-permission-common@0.8.1 + +## e2e-test@0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.19-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.100-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/plugin-techdocs@1.10.9-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/cli@0.27.1-next.0 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/app-defaults@1.5.10 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + +## @internal/plugin-todo-list-backend@1.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/errors@1.2.4 diff --git a/docs/releases/v1.31.0-next.1-changelog.md b/docs/releases/v1.31.0-next.1-changelog.md new file mode 100644 index 0000000000..eb9b11125e --- /dev/null +++ b/docs/releases/v1.31.0-next.1-changelog.md @@ -0,0 +1,2176 @@ +# Release v1.31.0-next.1 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.31.0-next.1](https://backstage.github.io/upgrade-helper/?to=1.31.0-next.1) + +## @backstage/backend-common@0.25.0-next.1 + +### Minor Changes + +- a4bac3c: **BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. +- 988c145: **BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. + + - The deprecated `dropDatabase` function has now been removed, without replacement. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## @backstage/backend-defaults@0.5.0-next.1 + +### Minor Changes + +- a4bac3c: **BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. +- 055b75b: **BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. + + For the `/database` subpath exports: + + - The deprecated `dropDatabase` function has now been removed, without replacement. + - The deprecated `LegacyRootDatabaseService` type has now been removed. + - The return type from `DatabaseManager.forPlugin` is now directly a `DatabaseService`, as arguably expected. + - `DatabaseManager.forPlugin` now requires the `deps` argument, with the logger and lifecycle services. + + For the `/cache` subpath exports: + + - The `PluginCacheManager` type has been removed. You can still import it from `@backstage/backend-common`, but it's deprecated there, and you should move off of that package by migrating fully to the new backend system. + - Accordingly, `CacheManager.forPlugin` immediately returns a `CacheService` instead of a `PluginCacheManager`. The outcome of this is that you no longer need to make the extra `.getClient()` call. The old `CacheManager` with the old behavior still exists on `@backstage/backend-common`, but the above recommendations apply. + +### Patch Changes + +- 622360e: Move down the discovery config to be in the root +- fe6fd8c: Accept `ConfigService` instead of `Config` in constructors/factories +- 5705424: Wrap scheduled tasks from the scheduler core service now in OpenTelemetry spans +- b2a329d: Properly indent the config schema +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-app-api@0.10.0-next.1 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## @backstage/core-compat-api@0.3.0-next.1 + +### Minor Changes + +- 6db849e: **BREAKING**: The `namespace` parameter for API's is now defaulted to the `pluginId` which was discovered. This means that if you're overriding API's by using ID's directly, they might have changed to include the plugin ID too. + +### Patch Changes + +- c816e2d: Added support for new `FrontendPlugin` and `FrontendModule` types. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-app-api@0.9.0-next.1 + +### Minor Changes + +- 7c80650: **BREAKING**: The `createSpecializedApp` function now creates a bare-bones app without any of the default app structure or APIs. To re-introduce this functionality if you need to use `createSpecializedApp` you can install the `app` plugin from `@backstage/plugin-app`. + + In addition, the `createApp` and `CreateAppFeatureLoader` exports are now deprecated as they are being moved to `@backstage/frontend-defaults`, which should be used instead. + +### Patch Changes + +- c816e2d: Added support for new `FrontendPlugin` and `FrontendModule` types. +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead +- Updated dependencies + - @backstage/frontend-defaults@0.1.0-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-defaults@0.1.0-next.0 + +### Minor Changes + +- 7c80650: Initial release of this package, which provides a default app setup through the `createApp` function. This replaces the existing `createApp` method from `@backstage/frontend-app-api`. + +### Patch Changes + +- 7d19cd5: Added a new `CreateAppOptions` type for the `createApp` options. +- 7d19cd5: Added `createPublicSignInApp`, used to creating apps for the public entry point. +- Updated dependencies + - @backstage/frontend-app-api@0.9.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/plugin-app@0.1.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/app-defaults@1.5.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/backend-app-api@0.10.0-next.1 + +### Patch Changes + +- c246372: Updated the error message for missing service dependencies to include the plugin and module IDs. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## @backstage/backend-dynamic-feature-service@0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-app-api@0.10.0-next.1 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.25-next.1 + - @backstage/plugin-events-backend@0.3.12-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/backend-openapi-utils@0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 + +## @backstage/backend-plugin-api@0.9.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/backend-test-utils@0.6.0-next.1 + +### Patch Changes + +- 710f621: Added missing service mock for `mockServices.rootConfig.mock`, and fixed the definition of `mockServices.rootHttpRouter.factory` to not have a duplicate callback. +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-app-api@0.10.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/catalog-client@1.6.7-next.0 + +### Patch Changes + +- 1882cfe: Moved `getEntities` ordering to utilize database instead of having it inside catalog client + + Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. + +- Updated dependencies + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## @backstage/cli@0.27.1-next.1 + +### Patch Changes + +- d2d2313: Add `config.d.ts` files to the list of included file in `tsconfig.json`. + + This allows ESLint to detect issues or deprecations in those files. + +- 97422b0: Update templates to not refer to backend-common + +- f865103: Updated dependency `esbuild` to `^0.23.0`. + +- 569c3f0: Fixed an issue where published frontend packages would end up with an invalid import structure if a single module imported both `.css` and `.svg` files. + +- Updated dependencies + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/integration@1.14.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## @backstage/codemods@0.1.50-next.0 + +### Patch Changes + +- 0894166: Updated dependency `jscodeshift` to `^0.16.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/core-components@0.14.11-next.0 + +### Patch Changes + +- 06b8206: Added `titleComponent` prop to `SignInPage` component to allow further customization of the title using `ReactNode` +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/version-bridge@1.0.8 + +## @backstage/create-app@0.5.19-next.1 + +### Patch Changes + +- d2d2313: Add `config.d.ts` files to the list of included file in `tsconfig.json`. + + This allows ESLint to detect issues or deprecations in those files. + +- 97422b0: Update templates to not refer to backend-common + +- bf370c2: Remove references to the `@backstage/backend-tasks` in versions of the `create-app` package, as it has been deprecated. + +- Updated dependencies + - @backstage/cli-common@0.1.14 + +## @backstage/dev-utils@1.0.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/app-defaults@1.5.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + +## @backstage/frontend-plugin-api@0.8.0-next.1 + +### Patch Changes + +- c816e2d: Added `createFrontendModule` as a replacement for `createExtensionOverrides`, which is now deprecated. + + Deprecated the `BackstagePlugin` and `FrontendFeature` type in favor of `FrontendPlugin` and `FrontendFeature` from `@backstage/frontend-app-api` respectively. + +- 52f9c5a: Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. + + You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. + + ```ts + // Before + createExtensionOverrides({ + extensions: [ + createExtension({ + name: 'my-extension', + namespace: 'my-namespace', + kind: 'test', + ... + }) + ], + }); + + // After + createFrontendModule({ + pluginId: 'my-namespace', + extensions: [ + createExtension({ + name: 'my-extension', + kind: 'test', + ... + }) + ], + }); + ``` + +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## @backstage/frontend-test-utils@0.2.0-next.1 + +### Patch Changes + +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead +- Updated dependencies + - @backstage/frontend-app-api@0.9.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/plugin-app@0.1.0-next.1 + - @backstage/config@1.2.0 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/types@1.1.1 + +## @backstage/repo-tools@0.9.7-next.1 + +### Patch Changes + +- 5c4aa2f: Updated dependency `@useoptic/openapi-utilities` to `^0.55.0`. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + +## @techdocs/cli@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 + +## @backstage/plugin-api-docs@0.11.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/core-plugin-api@1.9.3 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/plugin-app@0.1.0-next.1 + +### Patch Changes + +- 52f9c5a: Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. + + You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. + + ```ts + // Before + createExtensionOverrides({ + extensions: [ + createExtension({ + name: 'my-extension', + namespace: 'my-namespace', + kind: 'test', + ... + }) + ], + }); + + // After + createFrontendModule({ + pluginId: 'my-namespace', + extensions: [ + createExtension({ + name: 'my-extension', + kind: 'test', + ... + }) + ], + }); + ``` + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/plugin-app-backend@0.3.74-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.25-next.1 + +## @backstage/plugin-app-node@0.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config-loader@1.9.0 + +## @backstage/plugin-app-visualizer@0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-auth-backend@0.23.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0-next.1 + - @backstage/plugin-auth-node@0.5.2-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/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-google-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.0-next.1 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0-next.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0-next.1 + +### Patch Changes + +- 8d1fb8d: Throw correct error when email is missing from the claims +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-backend@0.23.0-next.1 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-auth-backend-module-google-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-auth-backend@0.23.0-next.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + +## @backstage/plugin-auth-node@0.5.2-next.1 + +### Patch Changes + +- c46eb0f: Extend the "unable to resolve user identity" message +- 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/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-auth-react@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-catalog@1.22.1-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/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + +## @backstage/plugin-catalog-backend@1.25.3-next.1 + +### Patch Changes + +- 1882cfe: Moved `getEntities` ordering to utilize database instead of having it inside catalog client + + Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/backend-openapi-utils@0.1.18-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-catalog-backend-module-azure@0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.1.18-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.3.2-next.1 + +### Patch Changes + +- 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@1.14.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-catalog-backend-module-gerrit@0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.7.3-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/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.7.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.4.2-next.1 + +### Patch Changes + +- 53b24d9: Internal update to use the new cache manager +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.9.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## @backstage/plugin-catalog-backend-module-logs@0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.6.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-catalog-graph@0.4.9-next.1 + +### Patch Changes + +- da91078: Fixed a bug in the `CatalogGraphPage` component where, after clicking on some nodes, clicking the back button would break the navigation. This issue caused the entire navigation to fail and behaved differently across various browsers. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-compat-api@0.3.0-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + +## @backstage/plugin-catalog-import@0.12.3-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/catalog-client@1.6.7-next.0 + - @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/plugin-catalog-common@1.0.26 + +## @backstage/plugin-catalog-node@1.12.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## @backstage/plugin-catalog-react@1.12.4-next.1 + +### Patch Changes + +- ae9b6cb: Small internal fix to better work with recent `lodash` versions +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-compat-api@0.3.0-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.0 + +### Patch Changes + +- 4f08c85: Show additional info on DevTools unprocessed entities table + + - Location path (so that it's easier to search the failed entity from the YAML URL) + - Time info of last discovery and next refresh time so that users can be aware of it and can sort the errors based on the time. + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + +## @backstage/plugin-config-schema@0.1.59-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + +## @backstage/plugin-devtools@0.1.18-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/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-react@0.4.25 + +## @backstage/plugin-devtools-backend@0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## @backstage/plugin-events-backend@0.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-events-backend-module-azure@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-events-backend-module-gerrit@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-events-backend-module-github@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-events-backend-module-gitlab@0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-events-backend-test-utils@0.1.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-events-node@0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + +## @backstage/plugin-home@0.7.10-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/catalog-client@1.6.7-next.0 + - @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-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-home-react@0.1.17-next.0 + +## @backstage/plugin-home-react@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-kubernetes@0.11.14-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/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-react@0.4.3-next.0 + +## @backstage/plugin-kubernetes-backend@0.18.6-next.1 + +### Patch Changes + +- ca96b66: Skip start without proper config +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-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/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-node@0.1.19-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## @backstage/plugin-kubernetes-cluster@0.0.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-react@0.4.3-next.0 + +## @backstage/plugin-kubernetes-node@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-kubernetes-react@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## @backstage/plugin-notifications@0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-react@0.0.5-next.0 + +## @backstage/plugin-notifications-backend@0.4.0-next.1 + +### Patch Changes + +- f195972: Validate notification link when new notification is created +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-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/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.1 + - @backstage/plugin-signals-node@0.1.11-next.1 + +## @backstage/plugin-notifications-backend-module-email@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 + +## @backstage/plugin-notifications-node@0.2.6-next.1 + +### Patch Changes + +- 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/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.11-next.1 + +## @backstage/plugin-org@0.6.29-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/core-plugin-api@1.9.3 + - @backstage/plugin-catalog-common@1.0.26 + +## @backstage/plugin-org-react@0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + +## @backstage/plugin-permission-backend@0.5.49-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## @backstage/plugin-permission-node@0.8.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## @backstage/plugin-proxy-backend@0.5.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## @backstage/plugin-scaffolder@1.25.0-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/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-scaffolder-react@1.12.0-next.1 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.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/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-scaffolder-backend@1.25.0-next.1 + +### Patch Changes + +- f865103: Updated dependency `esbuild` to `^0.23.0`. +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-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/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.1 + - @backstage/plugin-scaffolder-common@1.5.5 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.12-next.1 + +## @backstage/plugin-scaffolder-node@0.4.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-scaffolder-node-test-utils@0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-test-utils@0.6.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## @backstage/plugin-scaffolder-react@1.12.0-next.1 + +### Patch Changes + +- c2cbe1e: Updated dependency `use-immer` to `^0.10.0`. +- Updated dependencies + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + +## @backstage/plugin-search@1.4.16-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/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + +## @backstage/plugin-search-backend@1.5.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-openapi-utils@0.1.18-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-catalog@0.2.2-next.1 + +### Patch Changes + +- 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/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-elasticsearch@1.5.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-explore@0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-pg@0.5.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-backend-module-techdocs@0.2.2-next.1 + +### Patch Changes + +- 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/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-node@1.12.11-next.1 + +## @backstage/plugin-search-backend-node@1.3.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-search-react@1.8.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.14 + +## @backstage/plugin-signals@0.0.10-next.1 + +### Patch Changes + +- 3e9b1a4: Put a name on the `SignalsDisplay` component extension +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.5-next.0 + +## @backstage/plugin-signals-backend@0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-signals-node@0.1.11-next.1 + +## @backstage/plugin-signals-node@0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## @backstage/plugin-techdocs@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 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-search-react@1.8.0-next.1 + - @backstage/plugin-techdocs@1.10.9-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + +## @backstage/plugin-techdocs-backend@1.10.13-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/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-node@1.12.11-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration@1.14.0 + - @backstage/integration-react@1.1.30 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + +## @backstage/plugin-techdocs-node@1.12.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## @backstage/plugin-techdocs-react@1.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## @backstage/plugin-user-settings@0.8.12-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/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.5-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.2.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-node@0.1.11-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.101-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.1-next.1 + - @backstage/frontend-app-api@0.9.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-graph@0.4.9-next.1 + - @backstage/plugin-scaffolder-react@1.12.0-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.0 + - @backstage/plugin-signals@0.0.10-next.1 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/app-defaults@1.5.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.9-next.1 + - @backstage/plugin-auth-react@0.1.6-next.0 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-import@0.12.3-next.1 + - @backstage/plugin-devtools@0.1.18-next.1 + - @backstage/plugin-home@0.7.10-next.1 + - @backstage/plugin-kubernetes@0.11.14-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.1 + - @backstage/plugin-notifications@0.3.1-next.1 + - @backstage/plugin-org@0.6.29-next.1 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder@1.25.0-next.1 + - @backstage/plugin-search@1.4.16-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + - @backstage/plugin-techdocs@1.10.9-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + - @backstage/plugin-user-settings@0.8.12-next.1 + +## example-app-next@0.0.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.1-next.1 + - @backstage/frontend-defaults@0.1.0-next.0 + - @backstage/frontend-app-api@0.9.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-compat-api@0.3.0-next.1 + - @backstage/plugin-app@0.1.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-graph@0.4.9-next.1 + - @backstage/plugin-scaffolder-react@1.12.0-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.0 + - @backstage/plugin-signals@0.0.10-next.1 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/app-defaults@1.5.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.9-next.1 + - @backstage/plugin-app-visualizer@0.1.10-next.1 + - @backstage/plugin-auth-react@0.1.6-next.0 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-import@0.12.3-next.1 + - @backstage/plugin-home@0.7.10-next.1 + - @backstage/plugin-kubernetes@0.11.14-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.1 + - @backstage/plugin-notifications@0.3.1-next.1 + - @backstage/plugin-org@0.6.29-next.1 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder@1.25.0-next.1 + - @backstage/plugin-search@1.4.16-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + - @backstage/plugin-techdocs@1.10.9-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + - @backstage/plugin-user-settings@0.8.12-next.1 + +## app-next-example-plugin@0.0.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-components@0.14.11-next.0 + +## example-backend@0.0.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/plugin-scaffolder-backend@1.25.0-next.1 + - @backstage/plugin-notifications-backend@0.4.0-next.1 + - @backstage/plugin-kubernetes-backend@0.18.6-next.1 + - @backstage/plugin-techdocs-backend@1.10.13-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-app-backend@0.3.74-next.1 + - @backstage/plugin-auth-backend@0.23.0-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.0-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.0-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.1 + - @backstage/plugin-devtools-backend@0.4.0-next.1 + - @backstage/plugin-permission-backend@0.5.49-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-proxy-backend@0.5.6-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.1 + - @backstage/plugin-search-backend@1.5.17-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.1 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-signals-backend@0.2.0-next.1 + +## example-backend-legacy@0.2.102-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/plugin-scaffolder-backend@1.25.0-next.1 + - @backstage/plugin-kubernetes-backend@0.18.6-next.1 + - @backstage/plugin-techdocs-backend@1.10.13-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-app-backend@0.3.74-next.1 + - @backstage/plugin-auth-backend@0.23.0-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-devtools-backend@0.4.0-next.1 + - @backstage/plugin-events-backend@0.3.12-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-backend@0.5.49-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-proxy-backend@0.5.6-next.1 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.0-next.1 + - @backstage/plugin-search-backend@1.5.17-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.6-next.1 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.35-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-signals-backend@0.2.0-next.1 + - @backstage/plugin-signals-node@0.1.11-next.1 + +## e2e-test@0.2.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.19-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## techdocs-cli-embedded-app@0.2.100-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.1-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/app-defaults@1.5.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-techdocs@1.10.9-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + +## @internal/plugin-todo-list@1.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + +## @internal/plugin-todo-list-backend@1.0.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 diff --git a/docs/tooling/cli/03-commands.md b/docs/tooling/cli/03-commands.md index a6652bd036..913a71f514 100644 --- a/docs/tooling/cli/03-commands.md +++ b/docs/tooling/cli/03-commands.md @@ -326,7 +326,7 @@ Options: ## versions\:bump Bump all `@backstage` packages to the latest versions. This checks for updates -in the package registry, and will update entries `package.json` files when necessary. +in the package registry, and will update entries `package.json` files when necessary. See more how this command can be configured and used [for keeping Backstage updated](../../getting-started/keeping-backstage-updated.md). ```text Usage: backstage-cli versions:bump [options] diff --git a/docs/tooling/local-dev/profiling.md b/docs/tooling/local-dev/profiling.md new file mode 100644 index 0000000000..bbc263c3d5 --- /dev/null +++ b/docs/tooling/local-dev/profiling.md @@ -0,0 +1,65 @@ +--- +id: profiling +title: Profiling Backstage +description: Finding performance bottlenecks in your Backstage application +--- + +Profiling can help you find performance bottlenecks in your code. This guide will show you how to profile +both the backend and frontend of your Backstage application. + +# Backend + +To profile the backend, start the backend with the `--inspect` flag: + +```shell +yarn workspace backend start --inspect +# or `yarn workspace example-backend start --inspect` in this repository +``` + +Next you can use the Chrome DevTools to profile the backend by navigating to `chrome://inspect` and +clicking the `Open dedicated DevTools for Node` link. + +In the `Performance` tab, you can start a new recording by clicking the `Start` button. After you +have recorded some data, you can stop the recording by clicking the `Stop` button. The recording +will show you a flame graph of the backend's execution, which can help you identify performance issues. + +You can also use the `Memory` tab to profile the backend's memory usage and find potential memory leaks. + +It's recommended to start profiling with short periods of time to avoid too much data being collected. + +## Stress testing + +To get more out of profiling, you might want to introduce additional load to your application with some tooling. +One such tool is called [AutoCannon](https://www.npmjs.com/package/autocannon) which can be used to stress test the +API endpoints of your application. You can install it globally with `npm install -g autocannon`. + +To be able to access the API endpoints, you must configure a static token for the backend. In your +`app-config.yaml` file, add the following configuration: + +```yaml +backend: + auth: + externalAccess: + - type: static + options: + token: autocannon12345 + subject: autocannon +``` + +See more information in the [Service to Service Auth](../../auth/service-to-service-auth.md) documentation. +To run the stress test, you can use the following command: + +```shell +autocannon -H "Authorization=Bearer autocannon12345" http://localhost:7007/api/catalog/entities +``` + +See more command options in the AutoCannon documentation. + +# Frontend + +Profiling the frontend can be done by using the `React DevTools` extension for Chrome or Firefox. +The extension is available for download from the Chrome Web Store or the Firefox Add-ons website. + +To start profiling, start the application with `yarn dev` and open inspector in the browser. In the +`Profiler` tab (far to the right), click the `Start profiling` button to start recording. After +you have recorded some data by navigating through the page, click the `Stop profiling` button to stop the recording. diff --git a/docs/tutorials/enable-public-entry.md b/docs/tutorials/enable-public-entry.md index 25d7382f13..1ba4983618 100644 --- a/docs/tutorials/enable-public-entry.md +++ b/docs/tutorials/enable-public-entry.md @@ -106,40 +106,12 @@ That's it! If your app uses the new frontend system, you can still use the public entry point feature. The `index-public-experimental.tsx` file does end up looking a bit different in this case: ```tsx title="in packages/app/src/index-public-experimental.tsx" -import React from 'react'; import ReactDOM from 'react-dom/client'; -import { CookieAuthRedirect } from '@backstage/plugin-auth-react'; -import { createApp } from '@backstage/frontend-app-api'; -import { - coreExtensionData, - createExtension, - createExtensionOverrides, - createSignInPageExtension, -} from '@backstage/frontend-plugin-api'; +import { signInPageModule } from './overrides/SignInPage'; +import { createPublicSignInApp } from '@backstage/frontend-defaults'; -const signInPage = createSignInPageExtension({ - name: 'guest', - loader: async () => props => , -}); - -const authRedirectExtension = createExtension({ - namespace: 'app', - name: 'layout', - attachTo: { id: 'app/root', input: 'children' }, - output: { - element: coreExtensionData.reactElement, - }, - factory: () => ({ - element: , - }), -}); - -const app = createApp({ - features: [ - createExtensionOverrides({ - extensions: [signInPage, authRedirectExtension], - }), - ], +const app = createPublicSignInApp({ + features: [signInPageModule], }); ReactDOM.createRoot(document.getElementById('root')!).render(app.createRoot()); diff --git a/microsite/data/plugins/ai-assistant.yaml b/microsite/data/plugins/ai-assistant.yaml index 997846c14b..6ac4b6cd9e 100644 --- a/microsite/data/plugins/ai-assistant.yaml +++ b/microsite/data/plugins/ai-assistant.yaml @@ -1,6 +1,6 @@ --- title: AI Assistant - RAG AI -author: RoadieHQ +author: roadie.io authorUrl: https://roadie.io category: Search description: Query LLMs with contextual information from your catalog. diff --git a/microsite/data/plugins/analytics-module-generic.yaml b/microsite/data/plugins/analytics-module-generic.yaml new file mode 100644 index 0000000000..260319aca6 --- /dev/null +++ b/microsite/data/plugins/analytics-module-generic.yaml @@ -0,0 +1,9 @@ +--- +title: 'Analytics Module: Generic HTTP' +author: Josephine Pfeiffer +authorUrl: https://josie.lol +category: Monitoring +description: Track usage of your Backstage instance using generic POST endpoints. +documentation: https://github.com/pfeifferj/backstage-plugin-analytics-generic/blob/main/README.md +npmPackageName: '@pfeifferj/backstage-plugin-analytics-generic' +addedDate: '2024-08-23' diff --git a/microsite/data/plugins/aws-app-development.yaml b/microsite/data/plugins/aws-app-development.yaml index 47b40b8b3b..5df0598c5e 100644 --- a/microsite/data/plugins/aws-app-development.yaml +++ b/microsite/data/plugins/aws-app-development.yaml @@ -1,10 +1,10 @@ --- -title: OPA on AWS +title: Harmonix on AWS author: Amazon Web Services authorUrl: https://aws.amazon.com/ category: Infrastructure -description: Orchestrate Platforms and Applications (OPA) allows customers to build and manage AWS Apps & Environments within Backstage -documentation: https://opaonaws.io -iconUrl: https://github.com/awslabs/app-development-for-backstage-io-on-aws/blob/main/website/static/img/white_OPA_text02.png?raw=true +description: Harmonix allows customers to build and manage AWS Apps & Environments within Backstage +documentation: https://harmonixonaws.io +iconUrl: https://github.com/awslabs/harmonix/blob/main/docs/images/harmonix-white.png?raw=true npmPackageName: '@aws/plugin-aws-apps-for-backstage' addedDate: '2023-05-10' diff --git a/microsite/data/plugins/github-workflows.yaml b/microsite/data/plugins/github-workflows.yaml index 743e7a5b1b..f80e6f3f29 100644 --- a/microsite/data/plugins/github-workflows.yaml +++ b/microsite/data/plugins/github-workflows.yaml @@ -4,7 +4,7 @@ author: VeeCode Platform authorUrl: https://platform.vee.codes/ category: CI/CD description: The Github Workflows plugin provides an alternative for manually triggering GitHub workflows from within your Backstage component. -documentation: https://platform.vee.codes/plugin/Github%20workflows/ +documentation: https://platform.vee.codes/plugin/github-workflows/ iconUrl: https://veecode-platform.github.io/support/imgs/logo_2.svg npmPackageName: '@veecode-platform/backstage-plugin-github-workflows' tags: diff --git a/microsite/data/plugins/gitlab-pipelines.yaml b/microsite/data/plugins/gitlab-pipelines.yaml index d40419e464..4b77d67e07 100644 --- a/microsite/data/plugins/gitlab-pipelines.yaml +++ b/microsite/data/plugins/gitlab-pipelines.yaml @@ -4,7 +4,7 @@ author: VeeCode Platform authorUrl: https://platform.vee.codes category: CI/CD description: The Gitlab pipelines plugin integrates GitlabCi with its backstage component in a simple way. -documentation: https://platform.vee.codes/plugin/Gitlab%20Pipelines/ +documentation: https://platform.vee.codes/plugin/gitlab-pipelines/ iconUrl: https://veecode-platform.github.io/support/imgs/logo_1.svg npmPackageName: '@veecode-platform/backstage-plugin-gitlab-pipelines' tags: diff --git a/microsite/data/plugins/grafana.yaml b/microsite/data/plugins/grafana.yaml index c26d10b751..0637717466 100644 --- a/microsite/data/plugins/grafana.yaml +++ b/microsite/data/plugins/grafana.yaml @@ -4,9 +4,9 @@ author: K-Phoen authorUrl: https://github.com/K-Phoen category: Monitoring description: Associate alerts and dashboards to components. -documentation: https://github.com/K-Phoen/backstage-plugin-grafana/ +documentation: https://github.com/backstage/community-plugins/blob/main/workspaces/grafana/plugins/grafana/docs/index.md iconUrl: https://avatars.githubusercontent.com/u/7195757?s=200&v=4 -npmPackageName: '@k-phoen/backstage-plugin-grafana' +npmPackageName: '@backstage-community/plugin-grafana' tags: - dashboards - monitoring diff --git a/microsite/data/plugins/gravatar.yaml b/microsite/data/plugins/gravatar.yaml new file mode 100644 index 0000000000..d31c16a155 --- /dev/null +++ b/microsite/data/plugins/gravatar.yaml @@ -0,0 +1,14 @@ +--- +title: Gravatar catalog processor +author: roadie.io +authorUrl: https://roadie.io +category: Catalog +description: The processor generates a Gravatar URL for each user based on their email address and the generated Gravatar URL is added to the spec.profile.picture field of User entities. +documentation: https://github.com/RoadieHQ/roadie-backstage-plugins/blob/main/plugins/backend/catalog-backend-module-gravatar/README.md +iconUrl: https://gravatar.com/avatar/gravatar +npmPackageName: '@roadiehq/catalog-backend-module-gravatar' +tags: + - gravatar + - catalog + - processor +addedDate: '2024-08-26' diff --git a/microsite/data/plugins/hashicorp-terraform.yaml b/microsite/data/plugins/hashicorp-terraform.yaml new file mode 100644 index 0000000000..c254667015 --- /dev/null +++ b/microsite/data/plugins/hashicorp-terraform.yaml @@ -0,0 +1,10 @@ +--- +title: Hashicorp Terraform +author: GlobalLogic UK&I +authorUrl: https://www.globallogic.com +category: Infrastructure +description: Easily view Hashicorp Terraform runs for a specific workspace. +documentation: https://github.com/globallogicuki/globallogic-backstage-plugins/tree/main/plugins/terraform +iconUrl: /img/terraform-logo.svg +npmPackageName: '@globallogicuki/backstage-plugin-terraform' +addedDate: '2024-07-17' diff --git a/microsite/data/plugins/kong-service-manager.yaml b/microsite/data/plugins/kong-service-manager.yaml index 78ff37e36e..2b5f444479 100644 --- a/microsite/data/plugins/kong-service-manager.yaml +++ b/microsite/data/plugins/kong-service-manager.yaml @@ -4,7 +4,7 @@ author: VeeCode Platform authorUrl: https://platform.vee.codes/ category: api-manager description: The Kong Service Manager plugin provides information about the kong service, a list of the routes it has and also offers the possibility of manipulating plugins without leaving the backstage. -documentation: https://platform.vee.codes/plugin/Kong%20Service%20Manager/ +documentation: https://platform.vee.codes/plugin/kong-service-manager/ iconUrl: https://veecode-platform.github.io/support/imgs/logo_3.svg npmPackageName: '@veecode-platform/plugin-kong-service-manager' tags: diff --git a/microsite/data/plugins/kubelog.yaml b/microsite/data/plugins/kubelog.yaml new file mode 100644 index 0000000000..fcadba2978 --- /dev/null +++ b/microsite/data/plugins/kubelog.yaml @@ -0,0 +1,10 @@ +--- +title: Kubelog +author: Julio Fernandez +authorUrl: https://github.com/jfvilas +category: Observability +description: Kubelog provides your Backstage users the ability to view logs of your Kubernetes objects linked to Backstage entities. Security controls can be applied. +documentation: https://github.com/jfvilas/kubelog +iconUrl: https://raw.githubusercontent.com/jfvilas/kubelog/master/src/assets/kubelog-logo.png +npmPackageName: '@jfvilas/plugin-kubelog' +addedDate: 2024-08-25 diff --git a/microsite/data/plugins/kubernetes-gpt-analyzer.yaml b/microsite/data/plugins/kubernetes-gpt-analyzer.yaml index 78bd0fe4c4..e5de961869 100644 --- a/microsite/data/plugins/kubernetes-gpt-analyzer.yaml +++ b/microsite/data/plugins/kubernetes-gpt-analyzer.yaml @@ -4,7 +4,7 @@ author: VeeCode Platform authorUrl: https://platform.vee.codes/ category: Monitoring description: The Kubernetes GPT Analyzer plug-in uses artificial intelligence with the help of k8s-operator to analyze and optimize your Kubernetes entities, improving the management and performance of your cluster. It makes it easier to detect anomalies and suggest best practices. -documentation: https://platform.vee.codes/plugin/Kubernetes%20GPT%20Analyzer/ +documentation: https://platform.vee.codes/plugin/kubernetes-gpt-analyzer/ iconUrl: https://veecode-platform.github.io/support/imgs/logo_4.svg npmPackageName: '@veecode-platform/backstage-plugin-kubernetes-gpt-analyzer' tags: diff --git a/microsite/data/plugins/launchdarkly.yaml b/microsite/data/plugins/launchdarkly.yaml new file mode 100644 index 0000000000..30e4cab685 --- /dev/null +++ b/microsite/data/plugins/launchdarkly.yaml @@ -0,0 +1,9 @@ +--- +title: LaunchDarkly +author: roadie.io +authorUrl: https://roadie.io +category: CI/CD +description: View LaunchDarkly feature flags for your entities in Backstage. +documentation: https://github.com/RoadieHQ/roadie-backstage-plugins/blob/launchdarkly/plugins/frontend/backstage-plugin-launchdarkly/README.md +npmPackageName: '@roadiehq/backstage-plugin-launchdarkly' +addedDate: '2024-07-27' diff --git a/microsite/data/plugins/scaffolder-backend-module-webex.yaml b/microsite/data/plugins/scaffolder-backend-module-webex.yaml new file mode 100644 index 0000000000..f2113b2a8d --- /dev/null +++ b/microsite/data/plugins/scaffolder-backend-module-webex.yaml @@ -0,0 +1,11 @@ +--- +title: Cisco Webex Scaffolder Actions +author: Robert Lindley +authorUrl: https://github.com/Coderrob +category: Scaffolder +description: >- + A Backstage.io plugin that enables sending Webex messages via + Incoming Webhooks within scaffolder templates. +documentation: https://github.com/Coderrob/backstage-plugin-scaffolder-backend-module-webex +npmPackageName: '@coderrob/backstage-plugin-scaffolder-backend-module-webex' +addedDate: '2024-09-04' diff --git a/microsite/docusaurus.config.ts b/microsite/docusaurus.config.ts index 67018c6e33..96edb57dea 100644 --- a/microsite/docusaurus.config.ts +++ b/microsite/docusaurus.config.ts @@ -21,9 +21,38 @@ import { themes } from 'prism-react-renderer'; import type * as Preset from '@docusaurus/preset-classic'; import { Config } from '@docusaurus/types'; +import RedirectPlugin from '@docusaurus/plugin-client-redirects'; + const backstageTheme = themes.vsDark; backstageTheme.plain.backgroundColor = '#232323'; +const useVersionedDocs = require('fs').existsSync('versions.json'); + +// This patches the redirect plugin to ignore the error when it tries to override existing fields. +// This lets us add redirects that only apply to the next docs, while the stable docs still contain the source path. +const PatchedRedirectPlugin: typeof RedirectPlugin = (ctx, opts) => { + const plugin = RedirectPlugin(ctx, opts); + + return { + ...plugin, + async postBuild(...args) { + try { + await plugin.postBuild(...args); + } catch (error) { + if ( + error.message === + 'The redirect plugin is not supposed to override existing files.' + ) { + // Bit of a hack to make sure all remaining redirects are written, since the write uses Promise.all + await new Promise(resolve => setTimeout(resolve, 1000)); + } else { + throw error; + } + } + }, + }; +}; + const config: Config = { title: 'Backstage Software Catalog and Developer Platform', tagline: 'An open source framework for building developer portals', @@ -57,6 +86,26 @@ const config: Config = { editUrl: 'https://github.com/backstage/backstage/edit/master/docs/', path: '../docs', sidebarPath: 'sidebars.json', + ...(useVersionedDocs + ? { + includeCurrentVersion: true, + lastVersion: 'stable', + versions: { + stable: { + label: 'Stable', + path: '/', + banner: 'none', + badge: false, + }, + current: { + label: 'Next', + path: '/next', + banner: 'unreleased', + badge: true, + }, + }, + } + : undefined), }, blog: { path: 'blog', @@ -119,9 +168,11 @@ const config: Config = { }; }, }), - [ - '@docusaurus/plugin-client-redirects', - { + ctx => + PatchedRedirectPlugin(ctx, { + id: '@docusaurus/plugin-client-redirects', + toExtensions: [], + fromExtensions: [], redirects: [ { from: '/docs', @@ -195,9 +246,12 @@ const config: Config = { from: '/docs/local-dev/debugging/', to: '/docs/tooling/local-dev/debugging', }, + { + from: '/docs/plugins/url-reader/', + to: '/docs/backend-system/core-services/url-reader', + }, ], - }, - ], + }), [ 'docusaurus-pushfeedback', { @@ -255,6 +309,14 @@ const config: Config = { label: 'Community', position: 'left', }, + ...(useVersionedDocs + ? [ + { + type: 'docsVersionDropdown', + position: 'right' as const, + }, + ] + : []), ], }, image: 'img/sharing-opengraph.png', diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 79a43e165b..d134486024 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -1,39 +1,4 @@ { - "releases": { - "Release Notes": [ - "releases/v1.30.0", - "releases/v1.29.0", - "releases/v1.28.0", - "releases/v1.27.0", - "releases/v1.26.0", - "releases/v1.25.0", - "releases/v1.24.0", - "releases/v1.23.0", - "releases/v1.22.0", - "releases/v1.21.0", - "releases/v1.20.0", - "releases/v1.19.0", - "releases/v1.18.0", - "releases/v1.17.0", - "releases/v1.16.0", - "releases/v1.15.0", - "releases/v1.14.0", - "releases/v1.13.0", - "releases/v1.12.0", - "releases/v1.11.0", - "releases/v1.10.0", - "releases/v1.9.0", - "releases/v1.8.0", - "releases/v1.7.0", - "releases/v1.6.0", - "releases/v1.5.0", - "releases/v1.4.0", - "releases/v1.3.0", - "releases/v1.2.0", - "releases/v1.1.0", - "releases/v1.0.0" - ] - }, "docs": { "Overview": [ "overview/what-is-backstage", @@ -274,8 +239,7 @@ "items": [ "plugins/proxying", "plugins/backend-plugin", - "plugins/call-existing-api", - "plugins/url-reader" + "plugins/call-existing-api" ] }, { @@ -367,7 +331,8 @@ "label": "Local Development", "items": [ "tooling/local-dev/linking-local-packages", - "tooling/local-dev/debugging" + "tooling/local-dev/debugging", + "tooling/local-dev/profiling" ] }, "tooling/package-metadata" @@ -556,5 +521,40 @@ "contribute/project-structure" ], "References": ["references/glossary"] + }, + "releases": { + "Release Notes": [ + "releases/v1.30.0", + "releases/v1.29.0", + "releases/v1.28.0", + "releases/v1.27.0", + "releases/v1.26.0", + "releases/v1.25.0", + "releases/v1.24.0", + "releases/v1.23.0", + "releases/v1.22.0", + "releases/v1.21.0", + "releases/v1.20.0", + "releases/v1.19.0", + "releases/v1.18.0", + "releases/v1.17.0", + "releases/v1.16.0", + "releases/v1.15.0", + "releases/v1.14.0", + "releases/v1.13.0", + "releases/v1.12.0", + "releases/v1.11.0", + "releases/v1.10.0", + "releases/v1.9.0", + "releases/v1.8.0", + "releases/v1.7.0", + "releases/v1.6.0", + "releases/v1.5.0", + "releases/v1.4.0", + "releases/v1.3.0", + "releases/v1.2.0", + "releases/v1.1.0", + "releases/v1.0.0" + ] } } diff --git a/microsite/static/img/terraform-logo.svg b/microsite/static/img/terraform-logo.svg new file mode 100644 index 0000000000..9ec37bdab4 --- /dev/null +++ b/microsite/static/img/terraform-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/microsite/yarn.lock b/microsite/yarn.lock index f4e48096a2..f37b397a75 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -197,118 +197,117 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.8.3": - version: 7.23.5 - resolution: "@babel/code-frame@npm:7.23.5" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.24.7, @babel/code-frame@npm:^7.8.3": + version: 7.24.7 + resolution: "@babel/code-frame@npm:7.24.7" dependencies: - "@babel/highlight": ^7.23.4 - chalk: ^2.4.2 - checksum: d90981fdf56a2824a9b14d19a4c0e8db93633fd488c772624b4e83e0ceac6039a27cd298a247c3214faa952bf803ba23696172ae7e7235f3b97f43ba278c569a + "@babel/highlight": ^7.24.7 + picocolors: ^1.0.0 + checksum: 830e62cd38775fdf84d612544251ce773d544a8e63df667728cc9e0126eeef14c6ebda79be0f0bc307e8318316b7f58c27ce86702e0a1f5c321d842eb38ffda4 languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.20, @babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/compat-data@npm:7.23.5" - checksum: 06ce244cda5763295a0ea924728c09bae57d35713b675175227278896946f922a63edf803c322f855a3878323d48d0255a2a3023409d2a123483c8a69ebb4744 +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.2, @babel/compat-data@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/compat-data@npm:7.25.4" + checksum: b12a91d27c3731a4b0bdc9312a50b1911f41f7f728aaf0d4b32486e2257fd2cb2d3ea1a295e98449600c48f2c7883a3196ca77cda1cef7d97a10c2e83d037974 languageName: node linkType: hard -"@babel/core@npm:^7.19.6, @babel/core@npm:^7.23.3": - version: 7.23.9 - resolution: "@babel/core@npm:7.23.9" +"@babel/core@npm:^7.21.3, @babel/core@npm:^7.23.3": + version: 7.25.2 + resolution: "@babel/core@npm:7.25.2" dependencies: "@ampproject/remapping": ^2.2.0 - "@babel/code-frame": ^7.23.5 - "@babel/generator": ^7.23.6 - "@babel/helper-compilation-targets": ^7.23.6 - "@babel/helper-module-transforms": ^7.23.3 - "@babel/helpers": ^7.23.9 - "@babel/parser": ^7.23.9 - "@babel/template": ^7.23.9 - "@babel/traverse": ^7.23.9 - "@babel/types": ^7.23.9 + "@babel/code-frame": ^7.24.7 + "@babel/generator": ^7.25.0 + "@babel/helper-compilation-targets": ^7.25.2 + "@babel/helper-module-transforms": ^7.25.2 + "@babel/helpers": ^7.25.0 + "@babel/parser": ^7.25.0 + "@babel/template": ^7.25.0 + "@babel/traverse": ^7.25.2 + "@babel/types": ^7.25.2 convert-source-map: ^2.0.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.3 semver: ^6.3.1 - checksum: 634a511f74db52a5f5a283c1121f25e2227b006c095b84a02a40a9213842489cd82dc7d61cdc74e10b5bcd9bb0a4e28bab47635b54c7e2256d47ab57356e2a76 + checksum: 9a1ef604a7eb62195f70f9370cec45472a08114e3934e3eaaedee8fd754edf0730e62347c7b4b5e67d743ce57b5bb8cf3b92459482ca94d06e06246ef021390a languageName: node linkType: hard -"@babel/generator@npm:^7.23.3, @babel/generator@npm:^7.23.6": - version: 7.23.6 - resolution: "@babel/generator@npm:7.23.6" +"@babel/generator@npm:^7.23.3, @babel/generator@npm:^7.25.0, @babel/generator@npm:^7.25.4": + version: 7.25.5 + resolution: "@babel/generator@npm:7.25.5" dependencies: - "@babel/types": ^7.23.6 - "@jridgewell/gen-mapping": ^0.3.2 - "@jridgewell/trace-mapping": ^0.3.17 + "@babel/types": ^7.25.4 + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 jsesc: ^2.5.1 - checksum: 1a1a1c4eac210f174cd108d479464d053930a812798e09fee069377de39a893422df5b5b146199ead7239ae6d3a04697b45fc9ac6e38e0f6b76374390f91fc6c + checksum: d7713f02536a8144eca810e9b13ae854b05fec462348eaf52e7b50df2c0a312bc43bfff0e8e10d6dd982e8986d61175ac8e67d7358a8b4dad9db4d6733bf0c9c languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" +"@babel/helper-annotate-as-pure@npm:^7.22.5, @babel/helper-annotate-as-pure@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-annotate-as-pure@npm:7.24.7" dependencies: - "@babel/types": ^7.22.5 - checksum: 53da330f1835c46f26b7bf4da31f7a496dee9fd8696cca12366b94ba19d97421ce519a74a837f687749318f94d1a37f8d1abcbf35e8ed22c32d16373b2f6198d + "@babel/types": ^7.24.7 + checksum: 6178566099a6a0657db7a7fa601a54fb4731ca0b8614fbdccfd8e523c210c13963649bc8fdfd53ce7dd14d05e3dda2fb22dea5b30113c488b9eb1a906d60212e languageName: node linkType: hard -"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.5": - version: 7.22.15 - resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.15" +"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.24.7" dependencies: - "@babel/types": ^7.22.15 - checksum: 639c697a1c729f9fafa2dd4c9af2e18568190299b5907bd4c2d0bc818fcbd1e83ffeecc2af24327a7faa7ac4c34edd9d7940510a5e66296c19bad17001cf5c7a + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 71a6158a9fdebffb82fdc400d5555ba8f2e370cea81a0d578155877bdc4db7d5252b75c43b2fdf3f72b3f68348891f99bd35ae315542daad1b7ace8322b1abcb languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.22.5, @babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.23.6": - version: 7.23.6 - resolution: "@babel/helper-compilation-targets@npm:7.23.6" +"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.24.7, @babel/helper-compilation-targets@npm:^7.24.8, @babel/helper-compilation-targets@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-compilation-targets@npm:7.25.2" dependencies: - "@babel/compat-data": ^7.23.5 - "@babel/helper-validator-option": ^7.23.5 - browserslist: ^4.22.2 + "@babel/compat-data": ^7.25.2 + "@babel/helper-validator-option": ^7.24.8 + browserslist: ^4.23.1 lru-cache: ^5.1.1 semver: ^6.3.1 - checksum: c630b98d4527ac8fe2c58d9a06e785dfb2b73ec71b7c4f2ddf90f814b5f75b547f3c015f110a010fd31f76e3864daaf09f3adcd2f6acdbfb18a8de3a48717590 + checksum: aed33c5496cb9db4b5e2d44e26bf8bc474074cc7f7bb5ebe1d4a20fdeb362cb3ba9e1596ca18c7484bcd6e5c3a155ab975e420d520c0ae60df81f9de04d0fd16 languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.22.11, @babel/helper-create-class-features-plugin@npm:^7.22.15, @babel/helper-create-class-features-plugin@npm:^7.22.5": - version: 7.22.15 - resolution: "@babel/helper-create-class-features-plugin@npm:7.22.15" +"@babel/helper-create-class-features-plugin@npm:^7.24.7, @babel/helper-create-class-features-plugin@npm:^7.25.0, @babel/helper-create-class-features-plugin@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/helper-create-class-features-plugin@npm:7.25.4" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-environment-visitor": ^7.22.5 - "@babel/helper-function-name": ^7.22.5 - "@babel/helper-member-expression-to-functions": ^7.22.15 - "@babel/helper-optimise-call-expression": ^7.22.5 - "@babel/helper-replace-supers": ^7.22.9 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 - "@babel/helper-split-export-declaration": ^7.22.6 + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-member-expression-to-functions": ^7.24.8 + "@babel/helper-optimise-call-expression": ^7.24.7 + "@babel/helper-replace-supers": ^7.25.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + "@babel/traverse": ^7.25.4 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 52c500d8d164abb3a360b1b7c4b8fff77bc4a5920d3a2b41ae6e1d30617b0dc0b972c1f5db35b1752007e04a748908b4a99bc872b73549ae837e87dcdde005a3 + checksum: 4544ebda4516eb25efdebd47ca024bd7bdb1eb6e7cc3ad89688c8ef8e889734c2f4411ed78981899c641394f013f246f2af63d92a0e9270f6c453309b4cb89ba languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": - version: 7.22.15 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15" +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.24.7, @babel/helper-create-regexp-features-plugin@npm:^7.25.0, @babel/helper-create-regexp-features-plugin@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.2" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-annotate-as-pure": ^7.24.7 regexpu-core: ^5.3.1 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 0243b8d4854f1dc8861b1029a46d3f6393ad72f366a5a08e36a4648aa682044f06da4c6e87a456260e1e1b33c999f898ba591a0760842c1387bcc93fbf2151a6 + checksum: df55fdc6a1f3090dd37d91347df52d9322d52affa239543808dc142f8fe35e6787e67d8612337668198fac85826fafa9e6772e6c28b7d249ec94e6fafae5da6e languageName: node linkType: hard @@ -327,218 +326,238 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.22.20, @babel/helper-environment-visitor@npm:^7.22.5": - version: 7.22.20 - resolution: "@babel/helper-environment-visitor@npm:7.22.20" - checksum: d80ee98ff66f41e233f36ca1921774c37e88a803b2f7dca3db7c057a5fea0473804db9fb6729e5dbfd07f4bed722d60f7852035c2c739382e84c335661590b69 +"@babel/helper-define-polyfill-provider@npm:^0.6.2": + version: 0.6.2 + resolution: "@babel/helper-define-polyfill-provider@npm:0.6.2" + dependencies: + "@babel/helper-compilation-targets": ^7.22.6 + "@babel/helper-plugin-utils": ^7.22.5 + debug: ^4.1.1 + lodash.debounce: ^4.0.8 + resolve: ^1.14.2 + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 2bba965ea9a4887ddf9c11d51d740ab473bd7597b787d042c325f6a45912dfe908c2d6bb1d837bf82f7e9fa51e6ad5150563c58131d2bb85515e63d971414a9c languageName: node linkType: hard -"@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/helper-function-name@npm:7.23.0" +"@babel/helper-member-expression-to-functions@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" dependencies: - "@babel/template": ^7.22.15 - "@babel/types": ^7.23.0 - checksum: e44542257b2d4634a1f979244eb2a4ad8e6d75eb6761b4cfceb56b562f7db150d134bc538c8e6adca3783e3bc31be949071527aa8e3aab7867d1ad2d84a26e10 + "@babel/traverse": ^7.24.8 + "@babel/types": ^7.24.8 + checksum: bf923d05d81b06857f4ca4fe9c528c9c447a58db5ea39595bb559eae2fce01a8266173db0fd6a2ec129d7bbbb9bb22f4e90008252f7c66b422c76630a878a4bc languageName: node linkType: hard -"@babel/helper-hoist-variables@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-hoist-variables@npm:7.22.5" +"@babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-module-imports@npm:7.24.7" dependencies: - "@babel/types": ^7.22.5 - checksum: 394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 8ac15d96d262b8940bc469052a048e06430bba1296369be695fabdf6799f201dd0b00151762b56012a218464e706bc033f27c07f6cec20c6f8f5fd6543c67054 languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.22.15": - version: 7.23.0 - resolution: "@babel/helper-member-expression-to-functions@npm:7.23.0" +"@babel/helper-module-transforms@npm:^7.24.7, @babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.25.0, @babel/helper-module-transforms@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-module-transforms@npm:7.25.2" dependencies: - "@babel/types": ^7.23.0 - checksum: 494659361370c979ada711ca685e2efe9460683c36db1b283b446122596602c901e291e09f2f980ecedfe6e0f2bd5386cb59768285446530df10c14df1024e75 - languageName: node - linkType: hard - -"@babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.22.5": - version: 7.22.15 - resolution: "@babel/helper-module-imports@npm:7.22.15" - dependencies: - "@babel/types": ^7.22.15 - checksum: ecd7e457df0a46f889228f943ef9b4a47d485d82e030676767e6a2fdcbdaa63594d8124d4b55fd160b41c201025aec01fc27580352b1c87a37c9c6f33d116702 - languageName: node - linkType: hard - -"@babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.23.0, @babel/helper-module-transforms@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/helper-module-transforms@npm:7.23.3" - dependencies: - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-module-imports": ^7.22.15 - "@babel/helper-simple-access": ^7.22.5 - "@babel/helper-split-export-declaration": ^7.22.6 - "@babel/helper-validator-identifier": ^7.22.20 + "@babel/helper-module-imports": ^7.24.7 + "@babel/helper-simple-access": ^7.24.7 + "@babel/helper-validator-identifier": ^7.24.7 + "@babel/traverse": ^7.25.2 peerDependencies: "@babel/core": ^7.0.0 - checksum: 5d0895cfba0e16ae16f3aa92fee108517023ad89a855289c4eb1d46f7aef4519adf8e6f971e1d55ac20c5461610e17213f1144097a8f932e768a9132e2278d71 + checksum: 282d4e3308df6746289e46e9c39a0870819630af5f84d632559171e4fae6045684d771a65f62df3d569e88ccf81dc2def78b8338a449ae3a94bb421aa14fc367 languageName: node linkType: hard -"@babel/helper-optimise-call-expression@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-optimise-call-expression@npm:7.22.5" +"@babel/helper-optimise-call-expression@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-optimise-call-expression@npm:7.24.7" dependencies: - "@babel/types": ^7.22.5 - checksum: c70ef6cc6b6ed32eeeec4482127e8be5451d0e5282d5495d5d569d39eb04d7f1d66ec99b327f45d1d5842a9ad8c22d48567e93fc502003a47de78d122e355f7c + "@babel/types": ^7.24.7 + checksum: 280654eaf90e92bf383d7eed49019573fb35a98c9e992668f701ad099957246721044be2068cf6840cb2299e0ad393705a1981c88c23a1048096a8d59e5f79a3 languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": - version: 7.22.5 - resolution: "@babel/helper-plugin-utils@npm:7.22.5" - checksum: c0fc7227076b6041acd2f0e818145d2e8c41968cc52fb5ca70eed48e21b8fe6dd88a0a91cbddf4951e33647336eb5ae184747ca706817ca3bef5e9e905151ff5 +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.24.8, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": + version: 7.24.8 + resolution: "@babel/helper-plugin-utils@npm:7.24.8" + checksum: 73b1a83ba8bcee21dc94de2eb7323207391715e4369fd55844bb15cf13e3df6f3d13a40786d990e6370bf0f571d94fc31f70dec96c1d1002058258c35ca3767a languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.22.5, @babel/helper-remap-async-to-generator@npm:^7.22.9": - version: 7.22.20 - resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20" +"@babel/helper-remap-async-to-generator@npm:^7.24.7, @babel/helper-remap-async-to-generator@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-remap-async-to-generator@npm:7.25.0" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-wrap-function": ^7.22.20 + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-wrap-function": ^7.25.0 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 2fe6300a6f1b58211dffa0aed1b45d4958506d096543663dba83bd9251fe8d670fa909143a65b45e72acb49e7e20fbdb73eae315d9ddaced467948c3329986e7 + checksum: 47f3065e43fe9d6128ddb4291ffb9cf031935379265fd13de972b5f241943121f7583efb69cd2e1ecf39e3d0f76f047547d56c3fcc2c853b326fad5465da0bd7 languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.22.5, @babel/helper-replace-supers@npm:^7.22.9": - version: 7.22.20 - resolution: "@babel/helper-replace-supers@npm:7.22.20" +"@babel/helper-replace-supers@npm:^7.24.7, @babel/helper-replace-supers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-replace-supers@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-member-expression-to-functions": ^7.22.15 - "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/helper-member-expression-to-functions": ^7.24.8 + "@babel/helper-optimise-call-expression": ^7.24.7 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: a0008332e24daedea2e9498733e3c39b389d6d4512637e000f96f62b797e702ee24a407ccbcd7a236a551590a38f31282829a8ef35c50a3c0457d88218cae639 + checksum: f669fc2487c22d40b808f94b9c3ee41129484d5ef0ba689bdd70f216ff91e10b6b021d2f8cd37e7bdd700235a2a6ae6622526344f064528190383bf661ac65f8 languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-simple-access@npm:7.22.5" +"@babel/helper-simple-access@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-simple-access@npm:7.24.7" dependencies: - "@babel/types": ^7.22.5 - checksum: fe9686714caf7d70aedb46c3cce090f8b915b206e09225f1e4dbc416786c2fdbbee40b38b23c268b7ccef749dd2db35f255338fb4f2444429874d900dede5ad2 + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: ddbf55f9dea1900213f2a1a8500fabfd21c5a20f44dcfa957e4b0d8638c730f88751c77f678644f754f1a1dc73f4eb8b766c300deb45a9daad000e4247957819 languageName: node linkType: hard -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5" +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.24.7" dependencies: - "@babel/types": ^7.22.5 - checksum: 1012ef2295eb12dc073f2b9edf3425661e9b8432a3387e62a8bc27c42963f1f216ab3124228015c748770b2257b4f1fda882ca8fa34c0bf485e929ae5bc45244 + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 11b28fe534ce2b1a67c4d8e51a7b5711a2a0a0cae802f74614eee54cca58c744d9a62f6f60103c41759e81c537d270bfd665bf368a6bea214c6052f2094f8407 languageName: node linkType: hard -"@babel/helper-split-export-declaration@npm:^7.22.6": - version: 7.22.6 - resolution: "@babel/helper-split-export-declaration@npm:7.22.6" +"@babel/helper-string-parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-string-parser@npm:7.24.8" + checksum: 39b03c5119216883878655b149148dc4d2e284791e969b19467a9411fccaa33f7a713add98f4db5ed519535f70ad273cdadfd2eb54d47ebbdeac5083351328ce + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-validator-identifier@npm:7.24.7" + checksum: 6799ab117cefc0ecd35cd0b40ead320c621a298ecac88686a14cffceaac89d80cdb3c178f969861bf5fa5e4f766648f9161ea0752ecfe080d8e89e3147270257 + languageName: node + linkType: hard + +"@babel/helper-validator-option@npm:^7.22.15, @babel/helper-validator-option@npm:^7.24.7, @babel/helper-validator-option@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-validator-option@npm:7.24.8" + checksum: a52442dfa74be6719c0608fee3225bd0493c4057459f3014681ea1a4643cd38b68ff477fe867c4b356da7330d085f247f0724d300582fa4ab9a02efaf34d107c + languageName: node + linkType: hard + +"@babel/helper-wrap-function@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-wrap-function@npm:7.25.0" dependencies: - "@babel/types": ^7.22.5 - checksum: e141cace583b19d9195f9c2b8e17a3ae913b7ee9b8120246d0f9ca349ca6f03cb2c001fd5ec57488c544347c0bb584afec66c936511e447fd20a360e591ac921 + "@babel/template": ^7.25.0 + "@babel/traverse": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 0095b4741704066d1687f9bbd5370bb88c733919e4275e49615f70c180208148ff5f24ab58d186ce92f8f5d28eab034ec6617e9264590cc4744c75302857629c languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/helper-string-parser@npm:7.23.4" - checksum: c0641144cf1a7e7dc93f3d5f16d5327465b6cf5d036b48be61ecba41e1eece161b48f46b7f960951b67f8c3533ce506b16dece576baef4d8b3b49f8c65410f90 - languageName: node - linkType: hard - -"@babel/helper-validator-identifier@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-validator-identifier@npm:7.22.20" - checksum: 136412784d9428266bcdd4d91c32bcf9ff0e8d25534a9d94b044f77fe76bc50f941a90319b05aafd1ec04f7d127cd57a179a3716009ff7f3412ef835ada95bdc - languageName: node - linkType: hard - -"@babel/helper-validator-option@npm:^7.22.15, @babel/helper-validator-option@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/helper-validator-option@npm:7.23.5" - checksum: 537cde2330a8aede223552510e8a13e9c1c8798afee3757995a7d4acae564124fe2bf7e7c3d90d62d3657434a74340a274b3b3b1c6f17e9a2be1f48af29cb09e - languageName: node - linkType: hard - -"@babel/helper-wrap-function@npm:^7.22.20": - version: 7.22.20 - resolution: "@babel/helper-wrap-function@npm:7.22.20" +"@babel/helpers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helpers@npm:7.25.0" dependencies: - "@babel/helper-function-name": ^7.22.5 - "@babel/template": ^7.22.15 - "@babel/types": ^7.22.19 - checksum: 221ed9b5572612aeb571e4ce6a256f2dee85b3c9536f1dd5e611b0255e5f59a3d0ec392d8d46d4152149156a8109f92f20379b1d6d36abb613176e0e33f05fca + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 739e3704ff41a30f5eaac469b553f4d3ab02be6ced083f5925851532dfbd9efc5c347728e77b754ed0b262a4e5e384e60932a62c192d338db7e4b7f3adf9f4a7 languageName: node linkType: hard -"@babel/helpers@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/helpers@npm:7.23.9" +"@babel/highlight@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/highlight@npm:7.24.7" dependencies: - "@babel/template": ^7.23.9 - "@babel/traverse": ^7.23.9 - "@babel/types": ^7.23.9 - checksum: 2678231192c0471dbc2fc403fb19456cc46b1afefcfebf6bc0f48b2e938fdb0fef2e0fe90c8c8ae1f021dae5012b700372e4b5d15867f1d7764616532e4a6324 - languageName: node - linkType: hard - -"@babel/highlight@npm:^7.23.4": - version: 7.23.4 - resolution: "@babel/highlight@npm:7.23.4" - dependencies: - "@babel/helper-validator-identifier": ^7.22.20 + "@babel/helper-validator-identifier": ^7.24.7 chalk: ^2.4.2 js-tokens: ^4.0.0 - checksum: 643acecdc235f87d925979a979b539a5d7d1f31ae7db8d89047269082694122d11aa85351304c9c978ceeb6d250591ccadb06c366f358ccee08bb9c122476b89 + picocolors: ^1.0.0 + checksum: 5cd3a89f143671c4ac129960024ba678b669e6fc673ce078030f5175002d1d3d52bc10b22c5b916a6faf644b5028e9a4bd2bb264d053d9b05b6a98690f1d46f1 languageName: node linkType: hard -"@babel/parser@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/parser@npm:7.23.9" +"@babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/parser@npm:7.25.4" + dependencies: + "@babel/types": ^7.25.4 bin: parser: ./bin/babel-parser.js - checksum: e7cd4960ac8671774e13803349da88d512f9292d7baa952173260d3e8f15620a28a3701f14f709d769209022f9e7b79965256b8be204fc550cfe783cdcabe7c7 + checksum: fe4f083d4ad34f019dd7fad672cd007003004fb0a3df9b7315a5da9a5e8e56c1fed95acab6862e7d76cfccb2e8e364bcc307e9117718e6bb6dfb2e87ad065abf languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.22.15" +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.3": + version: 7.25.3 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.3" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/traverse": ^7.25.3 peerDependencies: "@babel/core": ^7.0.0 - checksum: 8910ca21a7ec7c06f7b247d4b86c97c5aa15ef321518f44f6f490c5912fdf82c605aaa02b90892e375d82ccbedeadfdeadd922c1b836c9dd4c596871bf654753 + checksum: d3dba60f360defe70eb43e35a1b17ea9dd4a99e734249e15be3d5c288019644f96f88d7ff51990118fda0845b4ad50f6d869e0382232b1d8b054d113d4eea7e2 languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.22.15" +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.0" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 - "@babel/plugin-transform-optional-chaining": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: fd56d1e6435f2c008ca9050ea906ff7eedcbec43f532f2bf2e7e905d8bf75bf5e4295ea9593f060394e2c8e45737266ccbf718050bad2dd7be4e7613c60d1b5b + languageName: node + linkType: hard + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 13ed301b108d85867d64226bbc4032b07dd1a23aab68e9e32452c4fe3930f2198bb65bdae9c262c4104bd5e45647bc1830d25d43d356ee9a137edd8d5fab8350 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + "@babel/plugin-transform-optional-chaining": ^7.24.7 peerDependencies: "@babel/core": ^7.13.0 - checksum: fbefedc0da014c37f1a50a8094ce7dbbf2181ae93243f23d6ecba2499b5b20196c2124d6a4dfe3e9e0125798e80593103e456352a4beb4e5c6f7c75efb80fdac + checksum: 07b92878ac58a98ea1fdf6a8b4ec3413ba4fa66924e28b694d63ec5b84463123fbf4d7153b56cf3cedfef4a3482c082fe3243c04f8fb2c041b32b0e29b4a9e21 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/traverse": ^7.25.0 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: c8d08b8d6cc71451ad2a50cf7db72ab5b41c1e5e2e4d56cf6837a25a61270abd682c6b8881ab025f11a552d2024b3780519bb051459ebb71c27aed13d9917663 languageName: node linkType: hard @@ -606,25 +625,25 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.22.5" +"@babel/plugin-syntax-import-assertions@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2b8b5572db04a7bef1e6cd20debf447e4eef7cb012616f5eceb8fa3e23ce469b8f76ee74fd6d1e158ba17a8f58b0aec579d092fb67c5a30e83ccfbc5754916c1 + checksum: c4d67be4eb1d4637e361477dbe01f5b392b037d17c1f861cfa0faa120030e137aab90a9237931b8040fd31d1e5d159e11866fa1165f78beef7a3be876a391a17 languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.22.5" +"@babel/plugin-syntax-import-attributes@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 197b3c5ea2a9649347f033342cb222ab47f4645633695205c0250c6bf2af29e643753b8bb24a2db39948bef08e7c540babfd365591eb57fc110cb30b425ffc47 + checksum: 590dbb5d1a15264f74670b427b8d18527672c3d6c91d7bae7e65f80fd810edbc83d90e68065088644cbad3f2457ed265a54a9956fb789fcb9a5b521822b3a275 languageName: node linkType: hard @@ -650,14 +669,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-syntax-jsx@npm:7.22.5" +"@babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-syntax-jsx@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8829d30c2617ab31393d99cec2978e41f014f4ac6f01a1cecf4c4dd8320c3ec12fdc3ce121126b2d8d32f6887e99ca1a0bad53dedb1e6ad165640b92b24980ce + checksum: 7a5ca629d8ca1e1ee78705a78e58c12920d07ed8006d7e7232b31296a384ff5e41d7b649bde5561196041037bbb9f9715be1d1c20975df87ca204f34ad15b965 languageName: node linkType: hard @@ -749,14 +768,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-syntax-typescript@npm:7.22.5" +"@babel/plugin-syntax-typescript@npm:^7.24.7": + version: 7.25.4 + resolution: "@babel/plugin-syntax-typescript@npm:7.25.4" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8ab7718fbb026d64da93681a57797d60326097fd7cb930380c8bffd9eb101689e90142c760a14b51e8e69c88a73ba3da956cb4520a3b0c65743aee5c71ef360a + checksum: 9b89b8930cd5983f64251d75c9fcdc17a8dc73837d6de12220ff972888ecff4054a6467cf0c423cad242aa96c0f0564a39a0823073728cc02239b80d13f02230 languageName: node linkType: hard @@ -772,468 +791,477 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.22.5" +"@babel/plugin-transform-arrow-functions@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 35abb6c57062802c7ce8bd96b2ef2883e3124370c688bbd67609f7d2453802fb73944df8808f893b6c67de978eb2bcf87bbfe325e46d6f39b5fcb09ece11d01a + checksum: 707c209b5331c7dc79bd326128c6a6640dbd62a78da1653c844db20c4f36bf7b68454f1bc4d2d051b3fde9136fa291f276ec03a071bb00ee653069ff82f91010 languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.22.15" +"@babel/plugin-transform-async-generator-functions@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.4" dependencies: - "@babel/helper-environment-visitor": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-remap-async-to-generator": ^7.22.9 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-remap-async-to-generator": ^7.25.0 "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/traverse": ^7.25.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: fad98786b446ce63bde0d14a221e2617eef5a7bbca62b49d96f16ab5e1694521234cfba6145b830fbf9af16d60a8a3dbf148e8694830bd91796fe333b0599e73 + checksum: 4235444735a1946f8766fe56564a8134c2c36c73e6cf83b3f2ed5624ebc84ff5979506a6a5b39acdb23aa09d442a6af471710ed408ccce533a2c4d2990b9df6a languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.22.5" +"@babel/plugin-transform-async-to-generator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.24.7" dependencies: - "@babel/helper-module-imports": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-remap-async-to-generator": ^7.22.5 + "@babel/helper-module-imports": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-remap-async-to-generator": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b95f23f99dcb379a9f0a1c2a3bbea3f8dc0e1b16dc1ac8b484fe378370169290a7a63d520959a9ba1232837cf74a80e23f6facbe14fd42a3cda6d3c2d7168e62 + checksum: 13704fb3b83effc868db2b71bfb2c77b895c56cb891954fc362e95e200afd523313b0e7cf04ce02f45b05e76017c5b5fa8070c92613727a35131bb542c253a36 languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.22.5" +"@babel/plugin-transform-block-scoped-functions@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 416b1341858e8ca4e524dee66044735956ced5f478b2c3b9bc11ec2285b0c25d7dbb96d79887169eb938084c95d0a89338c8b2fe70d473bd9dc92e5d9db1732c + checksum: 249cdcbff4e778b177245f9652b014ea4f3cd245d83297f10a7bf6d97790074089aa62bcde8c08eb299c5e68f2faed346b587d3ebac44d625ba9a83a4ee27028 languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.22.15": - version: 7.23.0 - resolution: "@babel/plugin-transform-block-scoping@npm:7.23.0" +"@babel/plugin-transform-block-scoping@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-block-scoping@npm:7.25.0" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0cfe925cc3b5a3ad407e2253fab3ceeaa117a4b291c9cb245578880872999bca91bd83ffa0128ae9ca356330702e1ef1dcb26804f28d2cef678239caf629f73e + checksum: b1a8f932f69ad2a47ae3e02b4cedd2a876bfc2ac9cf72a503fd706cdc87272646fe9eed81e068c0fc639647033de29f7fa0c21cddd1da0026f83dbaac97316a8 languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-class-properties@npm:7.22.5" +"@babel/plugin-transform-class-properties@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-class-properties@npm:7.25.4" dependencies: - "@babel/helper-create-class-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.25.4 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b830152dfc2ff2f647f0abe76e6251babdfbef54d18c4b2c73a6bf76b1a00050a5d998dac80dc901a48514e95604324943a9dd39317073fe0928b559e0e0c579 + checksum: b73f7d968639c6c2dfc13f4c5a8fe45cefd260f0faa7890ae12e65d41211072544ff5e128c8b61a86887b29ffd3df8422dbdfbf61648488e71d4bb599c41f4a5 languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-class-static-block@npm:7.22.11" +"@babel/plugin-transform-class-static-block@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-class-static-block@npm:7.24.7" dependencies: - "@babel/helper-create-class-features-plugin": ^7.22.11 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-class-static-block": ^7.14.5 peerDependencies: "@babel/core": ^7.12.0 - checksum: 69f040506fad66f1c6918d288d0e0edbc5c8a07c8b4462c1184ad2f9f08995d68b057126c213871c0853ae0c72afc60ec87492049dfacb20902e32346a448bcb + checksum: 324049263504f18416f1c3e24033baebfafd05480fdd885c8ebe6f2b415b0fc8e0b98d719360f9e30743cc78ac387fabc0b3c6606d2b54135756ffb92963b382 languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-classes@npm:7.22.15" +"@babel/plugin-transform-classes@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-classes@npm:7.25.4" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-compilation-targets": ^7.22.15 - "@babel/helper-environment-visitor": ^7.22.5 - "@babel/helper-function-name": ^7.22.5 - "@babel/helper-optimise-call-expression": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-replace-supers": ^7.22.9 - "@babel/helper-split-export-declaration": ^7.22.6 + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-compilation-targets": ^7.25.2 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-replace-supers": ^7.25.0 + "@babel/traverse": ^7.25.4 globals: ^11.1.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d3f4d0c107dd8a3557ea3575cc777fab27efa92958b41e4a9822f7499725c1f554beae58855de16ddec0a7b694e45f59a26cea8fbde4275563f72f09c6e039a0 + checksum: 0bf20e46eeb691bd60cee5d1b01950fc37accec88018ecace25099f7c8d8509c1ac54d11b8caf9f2157c6945969520642a3bc421159c1a14e80224dc9a7611de languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-computed-properties@npm:7.22.5" +"@babel/plugin-transform-computed-properties@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-computed-properties@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/template": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/template": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c2a77a0f94ec71efbc569109ec14ea2aa925b333289272ced8b33c6108bdbb02caf01830ffc7e49486b62dec51911924d13f3a76f1149f40daace1898009e131 + checksum: 0cf8c1b1e4ea57dec8d4612460d84fd4cdbf71a7499bb61ee34632cf89018a59eee818ffca88a8d99ee7057c20a4257044d7d463fda6daef9bf1db9fa81563cb languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.22.15": - version: 7.23.0 - resolution: "@babel/plugin-transform-destructuring@npm:7.23.0" +"@babel/plugin-transform-destructuring@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-destructuring@npm:7.24.8" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: cd6dd454ccc2766be551e4f8a04b1acc2aa539fa19e5c7501c56cc2f8cc921dd41a7ffb78455b4c4b2f954fcab8ca4561ba7c9c7bd5af9f19465243603d18cc3 + checksum: 0b4bd3d608979a1e5bd97d9d42acd5ad405c7fffa61efac4c7afd8e86ea6c2d91ab2d94b6a98d63919571363fe76e0b03c4ff161f0f60241b895842596e4a999 languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.22.5" +"@babel/plugin-transform-dotall-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.24.7" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-regexp-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 409b658d11e3082c8f69e9cdef2d96e4d6d11256f005772425fb230cc48fd05945edbfbcb709dab293a1a2f01f9c8a5bb7b4131e632b23264039d9f95864b453 + checksum: 67b10fc6abb1f61f0e765288eb4c6d63d1d0f9fc0660e69f6f2170c56fa16bc74e49857afc644beda112b41771cd90cf52df0940d11e97e52617c77c7dcff171 languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.22.5" +"@babel/plugin-transform-duplicate-keys@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: bb1280fbabaab6fab2ede585df34900712698210a3bd413f4df5bae6d8c24be36b496c92722ae676a7a67d060a4624f4d6c23b923485f906bfba8773c69f55b4 + checksum: d1da2ff85ecb56a63f4ccfd9dc9ae69400d85f0dadf44ecddd9e71c6e5c7a9178e74e3a9637555f415a2bb14551e563f09f98534ab54f53d25e8439fdde6ba2d languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-dynamic-import@npm:7.22.11" +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.0" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-regexp-features-plugin": ^7.25.0 + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 608d6b0e77341189508880fd1a9f605a38d0803dd6f678ea3920ab181b17b377f6d5221ae8cf0104c7a044d30d4ddb0366bd064447695671d78457a656bb264f + languageName: node + linkType: hard + +"@babel/plugin-transform-dynamic-import@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.7" + dependencies: + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-dynamic-import": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 78fc9c532210bf9e8f231747f542318568ac360ee6c27e80853962c984283c73da3f8f8aebe83c2096090a435b356b092ed85de617a156cbe0729d847632be45 + checksum: 776509ff62ab40c12be814a342fc56a5cc09b91fb63032b2633414b635875fd7da03734657be0f6db2891fe6e3033b75d5ddb6f2baabd1a02e4443754a785002 languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.22.5" +"@babel/plugin-transform-exponentiation-operator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.24.7" dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-builder-binary-assignment-operator-visitor": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f2d660c1b1d51ad5fec1cd5ad426a52187204068c4158f8c4aa977b31535c61b66898d532603eef21c15756827be8277f724c869b888d560f26d7fe848bb5eae + checksum: 23c84a23eb56589fdd35a3540f9a1190615be069110a2270865223c03aee3ba4e0fc68fe14850800cf36f0712b26e4964d3026235261f58f0405a29fe8dac9b1 languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-export-namespace-from@npm:7.22.11" +"@babel/plugin-transform-export-namespace-from@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-export-namespace-from": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 73af5883a321ed56a4bfd43c8a7de0164faebe619287706896fc6ee2f7a4e69042adaa1338c0b8b4bdb9f7e5fdceb016fb1d40694cb43ca3b8827429e8aac4bf + checksum: 3bd3a10038f10ae0dea1ee42137f3edcf7036b5e9e570a0d1cbd0865f03658990c6c2d84fa2475f87a754e7dc5b46766c16f7ce5c9b32c3040150b6a21233a80 languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-for-of@npm:7.22.15" +"@babel/plugin-transform-for-of@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-for-of@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f395ae7bce31e14961460f56cf751b5d6e37dd27d7df5b1f4e49fec1c11b6f9cf71991c7ffbe6549878591e87df0d66af798cf26edfa4bfa6b4c3dba1fb2f73a + checksum: a53b42dc93ab4b7d1ebd3c695b52be22b3d592f6a3dbdb3dc2fea2c8e0a7e1508fe919864c455cde552aec44ce7518625fccbb70c7063373ca228d884f4f49ea languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-function-name@npm:7.22.5" +"@babel/plugin-transform-function-name@npm:^7.25.1": + version: 7.25.1 + resolution: "@babel/plugin-transform-function-name@npm:7.25.1" dependencies: - "@babel/helper-compilation-targets": ^7.22.5 - "@babel/helper-function-name": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-compilation-targets": ^7.24.8 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/traverse": ^7.25.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: cff3b876357999cb8ae30e439c3ec6b0491a53b0aa6f722920a4675a6dd5b53af97a833051df4b34791fe5b3dd326ccf769d5c8e45b322aa50ee11a660b17845 + checksum: 743f3ea03bbc5a90944849d5a880b6bd9243dddbde581a46952da76e53a0b74c1e2424133fe8129d7a152c1f8c872bcd27e0b6728d7caadabd1afa7bb892e1e0 languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-json-strings@npm:7.22.11" +"@babel/plugin-transform-json-strings@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-json-strings@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-json-strings": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 50665e5979e66358c50e90a26db53c55917f78175127ac2fa05c7888d156d418ffb930ec0a109353db0a7c5f57c756ce01bfc9825d24cbfd2b3ec453f2ed8cba + checksum: 88874d0b7a1ddea66c097fc0abb68801ffae194468aa44b828dde9a0e20ac5d8647943793de86092eabaa2911c96f67a6b373793d4bb9c932ef81b2711c06c2e languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-literals@npm:7.22.5" +"@babel/plugin-transform-literals@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/plugin-transform-literals@npm:7.25.2" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ec37cc2ffb32667af935ab32fe28f00920ec8a1eb999aa6dc6602f2bebd8ba205a558aeedcdccdebf334381d5c57106c61f52332045730393e73410892a9735b + checksum: 70c9bb40e377a306bd8f500899fb72127e527517914466e95dc6bb53fa7a0f51479db244a54a771b5780fc1eab488fedd706669bf11097b81a23c81ab7423eb1 languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.22.11" +"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c664e9798e85afa7f92f07b867682dee7392046181d82f5d21bae6f2ca26dfe9c8375cdc52b7483c3fc09a983c1989f60eff9fbc4f373b0c0a74090553d05739 + checksum: 3367ce0be243704dc6fce23e86a592c4380f01998ee5dd9f94c54b1ef7b971ac6f8a002901eb51599ac6cbdc0d067af8d1a720224fca1c40fde8bb8aab804aac languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.22.5" +"@babel/plugin-transform-member-expression-literals@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ec4b0e07915ddd4fda0142fd104ee61015c208608a84cfa13643a95d18760b1dc1ceb6c6e0548898b8c49e5959a994e46367260176dbabc4467f729b21868504 + checksum: 2720c57aa3bf70576146ba7d6ea03227f4611852122d76d237924f7b008dafc952e6ae61a19e5024f26c665f44384bbd378466f01b6bd1305b3564a3b7fb1a5d languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.22.5": - version: 7.23.0 - resolution: "@babel/plugin-transform-modules-amd@npm:7.23.0" +"@babel/plugin-transform-modules-amd@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-modules-amd@npm:7.24.7" dependencies: - "@babel/helper-module-transforms": ^7.23.0 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-module-transforms": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5d92875170a37b8282d4bcd805f55829b8fab0f9c8d08b53d32a7a0bfdc62b868e489b52d329ae768ecafc0c993eed0ad7a387baa673ac33211390a9f833ab5d + checksum: f1dd0fb2f46c0f8f21076b8c7ccd5b33a85ce6dcb31518ea4c648d9a5bb2474cd4bd87c9b1b752e68591e24b022e334ba0d07631fef2b6b4d8a4b85cf3d581f5 languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.22.15, @babel/plugin-transform-modules-commonjs@npm:^7.23.0": - version: 7.23.0 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.23.0" +"@babel/plugin-transform-modules-commonjs@npm:^7.24.7, @babel/plugin-transform-modules-commonjs@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.8" dependencies: - "@babel/helper-module-transforms": ^7.23.0 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-simple-access": ^7.22.5 + "@babel/helper-module-transforms": ^7.24.8 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-simple-access": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7fb25997194053e167c4207c319ff05362392da841bd9f42ddb3caf9c8798a5d203bd926d23ddf5830fdf05eddc82c2810f40d1287e3a4f80b07eff13d1024b5 + checksum: a4cf95b1639c33382064b44558f73ee5fac023f2a94d16e549d2bb55ceebd5cbc10fcddd505d08cd5bc97f5a64af9fd155512358b7dcf7b1a0082e8945cf21c5 languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.22.11": - version: 7.23.0 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.23.0" +"@babel/plugin-transform-modules-systemjs@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.0" dependencies: - "@babel/helper-hoist-variables": ^7.22.5 - "@babel/helper-module-transforms": ^7.23.0 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-validator-identifier": ^7.22.20 + "@babel/helper-module-transforms": ^7.25.0 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-validator-identifier": ^7.24.7 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2d481458b22605046badea2317d5cc5c94ac3031c2293e34c96f02063f5b02af0979c4da6a8fbc67cc249541575dc9c6d710db6b919ede70b7337a22d9fd57a7 + checksum: fe673bec08564e491847324bb80a1e6edfb229f5c37e58a094d51e95306e7b098e1d130fc43e992d22debd93b9beac74441ffc3f6ea5d78f6b2535896efa0728 languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-modules-umd@npm:7.22.5" +"@babel/plugin-transform-modules-umd@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-modules-umd@npm:7.24.7" dependencies: - "@babel/helper-module-transforms": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-module-transforms": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 46622834c54c551b231963b867adbc80854881b3e516ff29984a8da989bd81665bd70e8cba6710345248e97166689310f544aee1a5773e262845a8f1b3e5b8b4 + checksum: 9ff1c464892efe042952ba778468bda6131b196a2729615bdcc3f24cdc94014f016a4616ee5643c5845bade6ba698f386833e61056d7201314b13a7fd69fac88 languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5" +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.24.7" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-regexp-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0 - checksum: 3ee564ddee620c035b928fdc942c5d17e9c4b98329b76f9cefac65c111135d925eb94ed324064cd7556d4f5123beec79abea1d4b97d1c8a2a5c748887a2eb623 + checksum: f1c6c7b5d60a86b6d7e4dd098798e1d393d55e993a0b57a73b53640c7a94985b601a96bdacee063f809a9a700bcea3a2ff18e98fa561554484ac56b761d774bd languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-new-target@npm:7.22.5" +"@babel/plugin-transform-new-target@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-new-target@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 6b72112773487a881a1d6ffa680afde08bad699252020e86122180ee7a88854d5da3f15d9bca3331cf2e025df045604494a8208a2e63b486266b07c14e2ffbf3 + checksum: 3cb94cd1076b270f768f91fdcf9dd2f6d487f8dbfff3df7ca8d07b915900b86d02769a35ba1407d16fe49499012c8f055e1741299e2c880798b953d942a8fa1b languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.22.11" +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 167babecc8b8fe70796a7b7d34af667ebbf43da166c21689502e5e8cc93180b7a85979c77c9f64b7cce431b36718bd0a6df9e5e0ffea4ae22afb22cfef886372 + checksum: 4a9221356401d87762afbc37a9e8e764afc2daf09c421117537820f8cfbed6876888372ad3a7bcfae2d45c95f026651f050ab4020b777be31d3ffb00908dbdd3 languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-numeric-separator@npm:7.22.11" +"@babel/plugin-transform-numeric-separator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-numeric-separator": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: af064d06a4a041767ec396a5f258103f64785df290e038bba9f0ef454e6c914f2ac45d862bbdad8fac2c7ad47fa4e95356f29053c60c100a0160b02a995fe2a3 + checksum: 561b5f1d08b2c3f92ce849f092751558b5e6cfeb7eb55c79e7375c34dd9c3066dce5e630bb439affef6adcf202b6cbcaaa23870070276fa5bb429c8f5b8c7514 languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.22.15" +"@babel/plugin-transform-object-rest-spread@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.24.7" dependencies: - "@babel/compat-data": ^7.22.9 - "@babel/helper-compilation-targets": ^7.22.15 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-compilation-targets": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-object-rest-spread": ^7.8.3 - "@babel/plugin-transform-parameters": ^7.22.15 + "@babel/plugin-transform-parameters": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 62197a6f12289c1c1bd57f3bed9f0f765ca32390bfe91e0b5561dd94dd9770f4480c4162dec98da094bc0ba99d2c2ebba68de47c019454041b0b7a68ba2ec66d + checksum: 169d257b9800c13e1feb4c37fb05dae84f702e58b342bb76e19e82e6692b7b5337c9923ee89e3916a97c0dd04a3375bdeca14f5e126f110bbacbeb46d1886ca2 languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-object-super@npm:7.22.5" +"@babel/plugin-transform-object-super@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-object-super@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-replace-supers": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-replace-supers": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b71887877d74cb64dbccb5c0324fa67e31171e6a5311991f626650e44a4083e5436a1eaa89da78c0474fb095d4ec322d63ee778b202d33aa2e4194e1ed8e62d7 + checksum: f71e607a830ee50a22fa1a2686524d3339440cf9dea63032f6efbd865cfe4e35000e1e3f3492459e5c986f7c0c07dc36938bf3ce61fc9ba5f8ab732d0b64ab37 languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.22.11" +"@babel/plugin-transform-optional-catch-binding@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f17abd90e1de67c84d63afea29c8021c74abb2794d3a6eeafb0bbe7372d3db32aefca386e392116ec63884537a4a2815d090d26264d259bacc08f6e3ed05294c + checksum: 7229f3a5a4facaab40f4fdfc7faabc157dc38a67d66bed7936599f4bc509e0bff636f847ac2aa45294881fce9cf8a0a460b85d2a465b7b977de9739fce9b18f6 languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.22.15": - version: 7.23.0 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.23.0" +"@babel/plugin-transform-optional-chaining@npm:^7.24.7, @babel/plugin-transform-optional-chaining@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.8" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 "@babel/plugin-syntax-optional-chaining": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f702634f2b97e5260dbec0d4bde05ccb6f4d96d7bfa946481aeacfa205ca846cb6e096a38312f9d51fdbdac1f258f211138c5f7075952e46a5bf8574de6a1329 + checksum: 45e55e3a2fffb89002d3f89aef59c141610f23b60eee41e047380bffc40290b59f64fc649aa7ec5281f73d41b2065410d788acc6afaad2a9f44cad6e8af04442 languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-parameters@npm:7.22.15" +"@babel/plugin-transform-parameters@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-parameters@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 541188bb7d1876cad87687b5c7daf90f63d8208ae83df24acb1e2b05020ad1c78786b2723ca4054a83fcb74fb6509f30c4cacc5b538ee684224261ad5fb047c1 + checksum: ab534b03ac2eff94bc79342b8f39a4584666f5305a6c63c1964afda0b1b004e6b861e49d1683548030defe248e3590d3ff6338ee0552cb90c064f7e1479968c3 languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-private-methods@npm:7.22.5" +"@babel/plugin-transform-private-methods@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-private-methods@npm:7.25.4" dependencies: - "@babel/helper-create-class-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.25.4 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 321479b4fcb6d3b3ef622ab22fd24001e43d46e680e8e41324c033d5810c84646e470f81b44cbcbef5c22e99030784f7cac92f1829974da7a47a60a7139082c3 + checksum: cb1dabfc03e2977990263d65bc8f43a9037dffbb5d9a5f825c00d05447ff68015099408c1531d9dd88f18a41a90f5062dc48f3a1d52b415d2d2ee4827dedff09 languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.22.11": - version: 7.22.11 - resolution: "@babel/plugin-transform-private-property-in-object@npm:7.22.11" +"@babel/plugin-transform-private-property-in-object@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.24.7" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-create-class-features-plugin": ^7.22.11 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-create-class-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-private-property-in-object": ^7.14.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4d029d84901e53c46dead7a46e2990a7bc62470f4e4ca58a0d063394f86652fd58fe4eea1eb941da3669cd536b559b9d058b342b59300026346b7a2a51badac8 + checksum: 8cee9473095305cc787bb653fd681719b49363281feabf677db8a552e8e41c94441408055d7e5fd5c7d41b315e634fa70b145ad0c7c54456216049df4ed57350 languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-property-literals@npm:7.22.5" +"@babel/plugin-transform-property-literals@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-property-literals@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 796176a3176106f77fcb8cd04eb34a8475ce82d6d03a88db089531b8f0453a2fb8b0c6ec9a52c27948bc0ea478becec449893741fc546dfc3930ab927e3f9f2e + checksum: 9aeefc3aab6c6bf9d1fae1cf3a2d38c7d886fd3c6c81b7c608c477f5758aee2e7abf52f32724310fe861da61af934ee2508b78a5b5f234b9740c9134e1c14437 languageName: node linkType: hard -"@babel/plugin-transform-react-constant-elements@npm:^7.18.12": - version: 7.20.2 - resolution: "@babel/plugin-transform-react-constant-elements@npm:7.20.2" +"@babel/plugin-transform-react-constant-elements@npm:^7.21.3": + version: 7.25.1 + resolution: "@babel/plugin-transform-react-constant-elements@npm:7.25.1" dependencies: - "@babel/helper-plugin-utils": ^7.20.2 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7b041b726e7c14b8c26a0dd240defac5f93a1f449371c6bdc5e6b46d581211300cc1a79da4140bdf20347f49e175dcb4f469812399206864024d1fdc81171193 + checksum: 6126abf8bc3980c1e27fd217f8b2f226b20cce9be300eaf9d30548556dd1e906b7daa4580d9ae1dae35eb5ed5c98e7222e0cb91efb0a232d05aae5875dcfe55c languageName: node linkType: hard @@ -1286,26 +1314,26 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.22.10": - version: 7.22.10 - resolution: "@babel/plugin-transform-regenerator@npm:7.22.10" +"@babel/plugin-transform-regenerator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-regenerator@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 regenerator-transform: ^0.15.2 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e13678d62d6fa96f11cb8b863f00e8693491e7adc88bfca3f2820f80cbac8336e7dec3a596eee6a1c4663b7ececc3564f2cd7fb44ed6d4ce84ac2bb7f39ecc6e + checksum: 20c6c3fb6fc9f407829087316653388d311e8c1816b007609bb09aeef254092a7157adace8b3aaa8f34be752503717cb85c88a5fe482180a9b11bcbd676063be languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-reserved-words@npm:7.22.5" +"@babel/plugin-transform-reserved-words@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-reserved-words@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3ffd7dbc425fe8132bfec118b9817572799cab1473113a635d25ab606c1f5a2341a636c04cf6b22df3813320365ed5a965b5eeb3192320a10e4cc2c137bd8bfc + checksum: 3d5876954d5914d7270819479504f30c4bf5452a65c677f44e2dab2db50b3c9d4b47793c45dfad7abf4f377035dd79e4b3f554ae350df9f422201d370ce9f8dd languageName: node linkType: hard @@ -1325,141 +1353,145 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.22.5" +"@babel/plugin-transform-shorthand-properties@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a5ac902c56ea8effa99f681340ee61bac21094588f7aef0bc01dff98246651702e677552fa6d10e548c4ac22a3ffad047dd2f8c8f0540b68316c2c203e56818b + checksum: 7b524245814607188212b8eb86d8c850e5974203328455a30881b4a92c364b93353fae14bc2af5b614ef16300b75b8c1d3b8f3a08355985b4794a7feb240adc3 languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-spread@npm:7.22.5" +"@babel/plugin-transform-spread@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-spread@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5587f0deb60b3dfc9b274e269031cc45ec75facccf1933ea2ea71ced9fd3ce98ed91bb36d6cd26817c14474b90ed998c5078415f0eab531caf301496ce24c95c + checksum: 4c4254c8b9cceb1a8f975fa9b92257ddb08380a35c0a3721b8f4b9e13a3d82e403af2e0fba577b9f2452dd8f06bc3dea71cc53b1e2c6af595af5db52a13429d6 languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.22.5" +"@babel/plugin-transform-sticky-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 63b2c575e3e7f96c32d52ed45ee098fb7d354b35c2223b8c8e76840b32cc529ee0c0ceb5742fd082e56e91e3d82842a367ce177e82b05039af3d602c9627a729 + checksum: 118fc7a7ebf7c20411b670c8a030535fdfe4a88bc5643bb625a584dbc4c8a468da46430a20e6bf78914246962b0f18f1b9d6a62561a7762c4f34a038a5a77179 languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-template-literals@npm:7.22.5" +"@babel/plugin-transform-template-literals@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-template-literals@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 27e9bb030654cb425381c69754be4abe6a7c75b45cd7f962cd8d604b841b2f0fb7b024f2efc1c25cc53f5b16d79d5e8cfc47cacbdaa983895b3aeefa3e7e24ff + checksum: ad44e5826f5a98c1575832dbdbd033adfe683cdff195e178528ead62507564bf02f479b282976cfd3caebad8b06d5fd7349c1cdb880dec3c56daea4f1f179619 languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.22.5" +"@babel/plugin-transform-typeof-symbol@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.8" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 82a53a63ffc3010b689ca9a54e5f53b2718b9f4b4a9818f36f9b7dba234f38a01876680553d2716a645a61920b5e6e4aaf8d4a0064add379b27ca0b403049512 + checksum: 8663a8e7347cedf181001d99c88cf794b6598c3d82f324098510fe8fb8bd22113995526a77aa35a3cc5d70ffd0617a59dd0d10311a9bf0e1a3a7d3e59b900c00 languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/plugin-transform-typescript@npm:7.22.15" +"@babel/plugin-transform-typescript@npm:^7.24.7": + version: 7.25.2 + resolution: "@babel/plugin-transform-typescript@npm:7.25.2" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-create-class-features-plugin": ^7.22.15 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/plugin-syntax-typescript": ^7.22.5 + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-create-class-features-plugin": ^7.25.0 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + "@babel/plugin-syntax-typescript": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c5d96cdbf0e1512707aa1c1e3ac6b370a25fd9c545d26008ce44eb13a47bd7fd67a1eb799c98b5ccc82e33a345fda55c0055e1fe3ed97646ed405dd13020b226 + checksum: b0267128d93560a4350919f7230a3b497e20fb8611d9f04bb3560d6b38877305ccad4c40903160263361c6930a84dbcb5b21b8ea923531bda51f67bffdc2dd0b languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.22.10": - version: 7.22.10 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.22.10" +"@babel/plugin-transform-unicode-escapes@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 807f40ed1324c8cb107c45358f1903384ca3f0ef1d01c5a3c5c9b271c8d8eec66936a3dcc8d75ddfceea9421420368c2e77ae3adef0a50557e778dfe296bf382 + checksum: 4af0a193e1ddea6ff82b2b15cc2501b872728050bd625740b813c8062fec917d32d530ff6b41de56c15e7296becdf3336a58db81f5ca8e7c445c1306c52f3e01 languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.22.5" +"@babel/plugin-transform-unicode-property-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.24.7" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-regexp-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2495e5f663cb388e3d888b4ba3df419ac436a5012144ac170b622ddfc221f9ea9bdba839fa2bc0185cb776b578030666406452ec7791cbf0e7a3d4c88ae9574c + checksum: aae13350c50973f5802ca7906d022a6a0cc0e3aebac9122d0450bbd51e78252d4c2032ad69385e2759fcbdd3aac5d571bd7e26258907f51f8e1a51b53be626c2 languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.22.5" +"@babel/plugin-transform-unicode-regex@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.24.7" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-regexp-features-plugin": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 6b5d1404c8c623b0ec9bd436c00d885a17d6a34f3f2597996343ddb9d94f6379705b21582dfd4cec2c47fd34068872e74ab6b9580116c0566b3f9447e2a7fa06 + checksum: 1cb4e70678906e431da0a05ac3f8350025fee290304ad7482d9cfaa1ca67b2e898654de537c9268efbdad5b80d3ebadf42b4a88ea84609bd8a4cce7b11b48afd languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.22.5" +"@babel/plugin-transform-unicode-sets-regex@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.25.4" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-regexp-features-plugin": ^7.25.2 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0 - checksum: c042070f980b139547f8b0179efbc049ac5930abec7fc26ed7a41d89a048d8ab17d362200e204b6f71c3c20d6991a0e74415e1a412a49adc8131c2a40c04822e + checksum: 6d1a7e9fdde4ffc9a81c0e3f261b96a9a0dfe65da282ec96fe63b36c597a7389feac638f1df2a8a4f8c9128337bba8e984f934e9f19077930f33abf1926759ea languageName: node linkType: hard -"@babel/preset-env@npm:^7.19.4, @babel/preset-env@npm:^7.22.9": - version: 7.22.20 - resolution: "@babel/preset-env@npm:7.22.20" +"@babel/preset-env@npm:^7.20.2, @babel/preset-env@npm:^7.22.9": + version: 7.25.4 + resolution: "@babel/preset-env@npm:7.25.4" dependencies: - "@babel/compat-data": ^7.22.20 - "@babel/helper-compilation-targets": ^7.22.15 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-validator-option": ^7.22.15 - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.22.15 - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.22.15 + "@babel/compat-data": ^7.25.4 + "@babel/helper-compilation-targets": ^7.25.2 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-validator-option": ^7.24.8 + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ^7.25.3 + "@babel/plugin-bugfix-safari-class-field-initializer-scope": ^7.25.0 + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.25.0 + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.24.7 + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.25.0 "@babel/plugin-proposal-private-property-in-object": 7.21.0-placeholder-for-preset-env.2 "@babel/plugin-syntax-async-generators": ^7.8.4 "@babel/plugin-syntax-class-properties": ^7.12.13 "@babel/plugin-syntax-class-static-block": ^7.14.5 "@babel/plugin-syntax-dynamic-import": ^7.8.3 "@babel/plugin-syntax-export-namespace-from": ^7.8.3 - "@babel/plugin-syntax-import-assertions": ^7.22.5 - "@babel/plugin-syntax-import-attributes": ^7.22.5 + "@babel/plugin-syntax-import-assertions": ^7.24.7 + "@babel/plugin-syntax-import-attributes": ^7.24.7 "@babel/plugin-syntax-import-meta": ^7.10.4 "@babel/plugin-syntax-json-strings": ^7.8.3 "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 @@ -1471,64 +1503,64 @@ __metadata: "@babel/plugin-syntax-private-property-in-object": ^7.14.5 "@babel/plugin-syntax-top-level-await": ^7.14.5 "@babel/plugin-syntax-unicode-sets-regex": ^7.18.6 - "@babel/plugin-transform-arrow-functions": ^7.22.5 - "@babel/plugin-transform-async-generator-functions": ^7.22.15 - "@babel/plugin-transform-async-to-generator": ^7.22.5 - "@babel/plugin-transform-block-scoped-functions": ^7.22.5 - "@babel/plugin-transform-block-scoping": ^7.22.15 - "@babel/plugin-transform-class-properties": ^7.22.5 - "@babel/plugin-transform-class-static-block": ^7.22.11 - "@babel/plugin-transform-classes": ^7.22.15 - "@babel/plugin-transform-computed-properties": ^7.22.5 - "@babel/plugin-transform-destructuring": ^7.22.15 - "@babel/plugin-transform-dotall-regex": ^7.22.5 - "@babel/plugin-transform-duplicate-keys": ^7.22.5 - "@babel/plugin-transform-dynamic-import": ^7.22.11 - "@babel/plugin-transform-exponentiation-operator": ^7.22.5 - "@babel/plugin-transform-export-namespace-from": ^7.22.11 - "@babel/plugin-transform-for-of": ^7.22.15 - "@babel/plugin-transform-function-name": ^7.22.5 - "@babel/plugin-transform-json-strings": ^7.22.11 - "@babel/plugin-transform-literals": ^7.22.5 - "@babel/plugin-transform-logical-assignment-operators": ^7.22.11 - "@babel/plugin-transform-member-expression-literals": ^7.22.5 - "@babel/plugin-transform-modules-amd": ^7.22.5 - "@babel/plugin-transform-modules-commonjs": ^7.22.15 - "@babel/plugin-transform-modules-systemjs": ^7.22.11 - "@babel/plugin-transform-modules-umd": ^7.22.5 - "@babel/plugin-transform-named-capturing-groups-regex": ^7.22.5 - "@babel/plugin-transform-new-target": ^7.22.5 - "@babel/plugin-transform-nullish-coalescing-operator": ^7.22.11 - "@babel/plugin-transform-numeric-separator": ^7.22.11 - "@babel/plugin-transform-object-rest-spread": ^7.22.15 - "@babel/plugin-transform-object-super": ^7.22.5 - "@babel/plugin-transform-optional-catch-binding": ^7.22.11 - "@babel/plugin-transform-optional-chaining": ^7.22.15 - "@babel/plugin-transform-parameters": ^7.22.15 - "@babel/plugin-transform-private-methods": ^7.22.5 - "@babel/plugin-transform-private-property-in-object": ^7.22.11 - "@babel/plugin-transform-property-literals": ^7.22.5 - "@babel/plugin-transform-regenerator": ^7.22.10 - "@babel/plugin-transform-reserved-words": ^7.22.5 - "@babel/plugin-transform-shorthand-properties": ^7.22.5 - "@babel/plugin-transform-spread": ^7.22.5 - "@babel/plugin-transform-sticky-regex": ^7.22.5 - "@babel/plugin-transform-template-literals": ^7.22.5 - "@babel/plugin-transform-typeof-symbol": ^7.22.5 - "@babel/plugin-transform-unicode-escapes": ^7.22.10 - "@babel/plugin-transform-unicode-property-regex": ^7.22.5 - "@babel/plugin-transform-unicode-regex": ^7.22.5 - "@babel/plugin-transform-unicode-sets-regex": ^7.22.5 + "@babel/plugin-transform-arrow-functions": ^7.24.7 + "@babel/plugin-transform-async-generator-functions": ^7.25.4 + "@babel/plugin-transform-async-to-generator": ^7.24.7 + "@babel/plugin-transform-block-scoped-functions": ^7.24.7 + "@babel/plugin-transform-block-scoping": ^7.25.0 + "@babel/plugin-transform-class-properties": ^7.25.4 + "@babel/plugin-transform-class-static-block": ^7.24.7 + "@babel/plugin-transform-classes": ^7.25.4 + "@babel/plugin-transform-computed-properties": ^7.24.7 + "@babel/plugin-transform-destructuring": ^7.24.8 + "@babel/plugin-transform-dotall-regex": ^7.24.7 + "@babel/plugin-transform-duplicate-keys": ^7.24.7 + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ^7.25.0 + "@babel/plugin-transform-dynamic-import": ^7.24.7 + "@babel/plugin-transform-exponentiation-operator": ^7.24.7 + "@babel/plugin-transform-export-namespace-from": ^7.24.7 + "@babel/plugin-transform-for-of": ^7.24.7 + "@babel/plugin-transform-function-name": ^7.25.1 + "@babel/plugin-transform-json-strings": ^7.24.7 + "@babel/plugin-transform-literals": ^7.25.2 + "@babel/plugin-transform-logical-assignment-operators": ^7.24.7 + "@babel/plugin-transform-member-expression-literals": ^7.24.7 + "@babel/plugin-transform-modules-amd": ^7.24.7 + "@babel/plugin-transform-modules-commonjs": ^7.24.8 + "@babel/plugin-transform-modules-systemjs": ^7.25.0 + "@babel/plugin-transform-modules-umd": ^7.24.7 + "@babel/plugin-transform-named-capturing-groups-regex": ^7.24.7 + "@babel/plugin-transform-new-target": ^7.24.7 + "@babel/plugin-transform-nullish-coalescing-operator": ^7.24.7 + "@babel/plugin-transform-numeric-separator": ^7.24.7 + "@babel/plugin-transform-object-rest-spread": ^7.24.7 + "@babel/plugin-transform-object-super": ^7.24.7 + "@babel/plugin-transform-optional-catch-binding": ^7.24.7 + "@babel/plugin-transform-optional-chaining": ^7.24.8 + "@babel/plugin-transform-parameters": ^7.24.7 + "@babel/plugin-transform-private-methods": ^7.25.4 + "@babel/plugin-transform-private-property-in-object": ^7.24.7 + "@babel/plugin-transform-property-literals": ^7.24.7 + "@babel/plugin-transform-regenerator": ^7.24.7 + "@babel/plugin-transform-reserved-words": ^7.24.7 + "@babel/plugin-transform-shorthand-properties": ^7.24.7 + "@babel/plugin-transform-spread": ^7.24.7 + "@babel/plugin-transform-sticky-regex": ^7.24.7 + "@babel/plugin-transform-template-literals": ^7.24.7 + "@babel/plugin-transform-typeof-symbol": ^7.24.8 + "@babel/plugin-transform-unicode-escapes": ^7.24.7 + "@babel/plugin-transform-unicode-property-regex": ^7.24.7 + "@babel/plugin-transform-unicode-regex": ^7.24.7 + "@babel/plugin-transform-unicode-sets-regex": ^7.25.4 "@babel/preset-modules": 0.1.6-no-external-plugins - "@babel/types": ^7.22.19 - babel-plugin-polyfill-corejs2: ^0.4.5 - babel-plugin-polyfill-corejs3: ^0.8.3 - babel-plugin-polyfill-regenerator: ^0.5.2 - core-js-compat: ^3.31.0 + babel-plugin-polyfill-corejs2: ^0.4.10 + babel-plugin-polyfill-corejs3: ^0.10.6 + babel-plugin-polyfill-regenerator: ^0.6.1 + core-js-compat: ^3.37.1 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 99357a5cb30f53bacdc0d1cd6dff0f052ea6c2d1ba874d969bba69897ef716e87283e84a59dc52fb49aa31fd1b6f55ed756c64c04f5678380700239f6030b881 + checksum: 752be43f0b78a2eefe5007076aed3d21b505e1c09d134b61e7de8838f1bbb1e7af81023d39adb14b6eae23727fb5a9fd23f8115a44df043319be22319be17913 languageName: node linkType: hard @@ -1561,18 +1593,18 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:^7.18.6, @babel/preset-typescript@npm:^7.22.5": - version: 7.23.0 - resolution: "@babel/preset-typescript@npm:7.23.0" +"@babel/preset-typescript@npm:^7.21.0, @babel/preset-typescript@npm:^7.22.5": + version: 7.24.7 + resolution: "@babel/preset-typescript@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-validator-option": ^7.22.15 - "@babel/plugin-syntax-jsx": ^7.22.5 - "@babel/plugin-transform-modules-commonjs": ^7.23.0 - "@babel/plugin-transform-typescript": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-validator-option": ^7.24.7 + "@babel/plugin-syntax-jsx": ^7.24.7 + "@babel/plugin-transform-modules-commonjs": ^7.24.7 + "@babel/plugin-transform-typescript": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3d5fce83e83f11c07e0ea13542bca181abb3b482b8981ec9c64e6add9d7beed3c54d063dc4bc9fd383165c71114a245abef89a289680833c5a8552fe3e7c4407 + checksum: 12929b24757f3bd6548103475f86478eda4c872bc7cefd920b29591eee8f4a4f350561d888e133d632d0c9402b8615fdcec9138e5127a6567dcb22f804ff207f languageName: node linkType: hard @@ -1602,43 +1634,40 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/template@npm:7.23.9" +"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/template@npm:7.25.0" dependencies: - "@babel/code-frame": ^7.23.5 - "@babel/parser": ^7.23.9 - "@babel/types": ^7.23.9 - checksum: 6e67414c0f7125d7ecaf20c11fab88085fa98a96c3ef10da0a61e962e04fdf3a18a496a66047005ddd1bb682a7cc7842d556d1db2f3f3f6ccfca97d5e445d342 + "@babel/code-frame": ^7.24.7 + "@babel/parser": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 3f2db568718756d0daf2a16927b78f00c425046b654cd30b450006f2e84bdccaf0cbe6dc04994aa1f5f6a4398da2f11f3640a4d3ee31722e43539c4c919c817b languageName: node linkType: hard -"@babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.23.9": - version: 7.23.9 - resolution: "@babel/traverse@npm:7.23.9" +"@babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.1, @babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.25.3, @babel/traverse@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/traverse@npm:7.25.4" dependencies: - "@babel/code-frame": ^7.23.5 - "@babel/generator": ^7.23.6 - "@babel/helper-environment-visitor": ^7.22.20 - "@babel/helper-function-name": ^7.23.0 - "@babel/helper-hoist-variables": ^7.22.5 - "@babel/helper-split-export-declaration": ^7.22.6 - "@babel/parser": ^7.23.9 - "@babel/types": ^7.23.9 + "@babel/code-frame": ^7.24.7 + "@babel/generator": ^7.25.4 + "@babel/parser": ^7.25.4 + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.4 debug: ^4.3.1 globals: ^11.1.0 - checksum: a932f7aa850e158c00c97aad22f639d48c72805c687290f6a73e30c5c4957c07f5d28310c9bf59648e2980fe6c9d16adeb2ff92a9ca0f97fa75739c1328fc6c3 + checksum: 3b6d879b9d843b119501585269b3599f047011ae21eb7820d00aef62fc3a2bcdaf6f4cdf2679795a2d7c0b6b5d218974916e422f08dea08613dc42188ef21e4b languageName: node linkType: hard -"@babel/types@npm:^7.20.0, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.6, @babel/types@npm:^7.23.9, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.23.9 - resolution: "@babel/types@npm:7.23.9" +"@babel/types@npm:^7.21.3, @babel/types@npm:^7.22.15, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.4, @babel/types@npm:^7.4.4": + version: 7.25.4 + resolution: "@babel/types@npm:7.25.4" dependencies: - "@babel/helper-string-parser": ^7.23.4 - "@babel/helper-validator-identifier": ^7.22.20 + "@babel/helper-string-parser": ^7.24.8 + "@babel/helper-validator-identifier": ^7.24.7 to-fast-properties: ^2.0.0 - checksum: 0a9b008e9bfc89beb8c185e620fa0f8ed6c771f1e1b2e01e1596870969096fec7793898a1d64a035176abf1dd13e2668ee30bf699f2d92c210a8128f4b151e65 + checksum: 497f8b583c54a92a59c3ec542144695064cd5c384fcca46ba1aa301d5e5dd6c1d011f312ca024cb0f9c956da07ae82fb4c348c31a30afa31a074c027720d2aa8 languageName: node linkType: hard @@ -1689,9 +1718,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/core@npm:3.2.1, @docusaurus/core@npm:^3.1.1": - version: 3.2.1 - resolution: "@docusaurus/core@npm:3.2.1" +"@docusaurus/core@npm:3.5.2, @docusaurus/core@npm:^3.1.1": + version: 3.5.2 + resolution: "@docusaurus/core@npm:3.5.2" dependencies: "@babel/core": ^7.23.3 "@babel/generator": ^7.23.3 @@ -1703,14 +1732,12 @@ __metadata: "@babel/runtime": ^7.22.6 "@babel/runtime-corejs3": ^7.22.6 "@babel/traverse": ^7.22.8 - "@docusaurus/cssnano-preset": 3.2.1 - "@docusaurus/logger": 3.2.1 - "@docusaurus/mdx-loader": 3.2.1 - "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-common": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 - "@svgr/webpack": ^6.5.1 + "@docusaurus/cssnano-preset": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 autoprefixer: ^10.4.14 babel-loader: ^9.1.3 babel-plugin-dynamic-import-node: ^2.3.3 @@ -1724,8 +1751,8 @@ __metadata: copy-webpack-plugin: ^11.0.0 core-js: ^3.31.1 css-loader: ^6.8.1 - css-minimizer-webpack-plugin: ^4.2.2 - cssnano: ^5.1.15 + css-minimizer-webpack-plugin: ^5.0.1 + cssnano: ^6.1.2 del: ^6.1.1 detect-port: ^1.5.1 escape-html: ^1.0.3 @@ -1745,7 +1772,7 @@ __metadata: prompts: ^2.4.2 react-dev-utils: ^12.0.1 react-helmet-async: ^1.3.0 - react-loadable: "npm:@docusaurus/react-loadable@5.5.2" + react-loadable: "npm:@docusaurus/react-loadable@6.0.0" react-loadable-ssr-addon-v5-slorber: ^1.0.1 react-router: ^5.3.4 react-router-config: ^5.1.1 @@ -1764,43 +1791,44 @@ __metadata: webpack-merge: ^5.9.0 webpackbar: ^5.0.2 peerDependencies: + "@mdx-js/react": ^3.0.0 react: ^18.0.0 react-dom: ^18.0.0 bin: docusaurus: bin/docusaurus.mjs - checksum: 9267f08b41240cb9d399abbd8a41ff66e0082551284325db3f17fcce9643bef81d06564797a7cc4c528fe8bde2858c20666e74a0308f3ecc80f3be1dbee14bb5 + checksum: 6c6282a75931f0f8f8f8768232b4436ff8679ae12b619f7bd01e0d83aa346e24ab0d9cecac034f9dc95c55059997efdd963d052d3e429583bfb8d3b54ab750d3 languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/cssnano-preset@npm:3.2.1" +"@docusaurus/cssnano-preset@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/cssnano-preset@npm:3.5.2" dependencies: - cssnano-preset-advanced: ^5.3.10 - postcss: ^8.4.26 - postcss-sort-media-queries: ^4.4.1 + cssnano-preset-advanced: ^6.1.2 + postcss: ^8.4.38 + postcss-sort-media-queries: ^5.2.0 tslib: ^2.6.0 - checksum: ee23a1229d23732d936fe1d68732d1305abf0132b43a398336fee500504a3e7566d3b0c6222f89f565e24e68e00e353765e0cbbab5611a3b35ecf88305558b6d + checksum: 4bb1fae3741e14cbbdb64c1b0707435970838bf219831234a70cf382e6811ffac1cadf733d5e1fe7c278e7b2a9e533bfa802a5212b22ec46edd703208cf49f92 languageName: node linkType: hard -"@docusaurus/logger@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/logger@npm:3.2.1" +"@docusaurus/logger@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/logger@npm:3.5.2" dependencies: chalk: ^4.1.2 tslib: ^2.6.0 - checksum: 9d5db5253eda98871563faddb5318bcb6b17ddf5882ababad4803d526917844819751e84ee8028e794fd5507646db6409f9041fd7f41b7f7971015df11cc6376 + checksum: 7cbdcf54acd6e7787ca5a10b9c884be4b9e8fdae837862c66550a0bf3d02737f72c3188b2bddd61da6d8530eb2eb2b646ea599a79416e33c4998f1a87d2f6a8c languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/mdx-loader@npm:3.2.1" +"@docusaurus/mdx-loader@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/mdx-loader@npm:3.5.2" dependencies: - "@docusaurus/logger": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/logger": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 "@mdx-js/mdx": ^3.0.0 "@slorber/remark-comment": ^1.0.0 escape-html: ^1.0.3 @@ -1825,38 +1853,37 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 4609faf2d8b76085a3aa86ac5ca4ac3b3420e3cfd796f1b39c46f368c82b3db0db5b1308646cf35fdad0a1f6f088d367116eb0e2a8c3fa728ed886ee37516476 + checksum: 36186c2f3487631757b24ba3a21575d2253ca1e6ada82d556bf323da7ae7637c0880eb388bf375e207bc5f26dcd8b58cc76d763e6c2caf6ed80f88748444ce8d languageName: node linkType: hard -"@docusaurus/module-type-aliases@npm:3.2.1, @docusaurus/module-type-aliases@npm:^3.1.1": - version: 3.2.1 - resolution: "@docusaurus/module-type-aliases@npm:3.2.1" +"@docusaurus/module-type-aliases@npm:3.5.2, @docusaurus/module-type-aliases@npm:^3.1.1": + version: 3.5.2 + resolution: "@docusaurus/module-type-aliases@npm:3.5.2" dependencies: - "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/types": 3.2.1 + "@docusaurus/types": 3.5.2 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" "@types/react-router-dom": "*" react-helmet-async: "*" - react-loadable: "npm:@docusaurus/react-loadable@5.5.2" + react-loadable: "npm:@docusaurus/react-loadable@6.0.0" peerDependencies: react: "*" react-dom: "*" - checksum: 37b4a40f9afebbe76e350c10c857737b544c141a988462436904ae16993a52e4429018d406e2f55ad57a533e5a108dd7cdb903434abb84721deeec0d5f195d80 + checksum: 0161db859d459bb25ac162f0c509fb1316dfb403a9e89f325a9bc7d9f35ae1825b9703a435777903ba93de827d4413b189bbd0c03018ac13d66b50633302ea80 languageName: node linkType: hard "@docusaurus/plugin-client-redirects@npm:^3.1.1": - version: 3.2.1 - resolution: "@docusaurus/plugin-client-redirects@npm:3.2.1" + version: 3.5.2 + resolution: "@docusaurus/plugin-client-redirects@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/logger": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-common": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 eta: ^2.2.0 fs-extra: ^11.1.1 lodash: ^4.17.21 @@ -1864,22 +1891,23 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 84f031a9f660028cf745ad4f3b8ea8820e34fdabed75321b06a8145078b3b8c496369c902dc3f46a2bb973cfaaa433474a9891bd836494ff72c65258fa67b64c + checksum: 040aa829e819a43cb8d30f6c776c27a303080a4cb2fc2c398266fe9ecbd006dc53c6dd862ebcf4f74d0547042c4df6c4bbf080b3702be6df18c95b95c3e38f1d languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/plugin-content-blog@npm:3.2.1" +"@docusaurus/plugin-content-blog@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-content-blog@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/logger": 3.2.1 - "@docusaurus/mdx-loader": 3.2.1 - "@docusaurus/types": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-common": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 - cheerio: ^1.0.0-rc.12 + "@docusaurus/core": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 + cheerio: 1.0.0-rc.12 feed: ^4.2.2 fs-extra: ^11.1.1 lodash: ^4.17.21 @@ -1890,24 +1918,26 @@ __metadata: utility-types: ^3.10.0 webpack: ^5.88.1 peerDependencies: + "@docusaurus/plugin-content-docs": "*" react: ^18.0.0 react-dom: ^18.0.0 - checksum: d95147a28aad832cd2dc39af634e1902a8a36f958dd2ff5fa6eaa47b574b58df42609a64da823951826f647337ad35c1f1c8be8a0a085913e192936f38839413 + checksum: c5997b9d86ccf939998f9d56e65491ecf9e677d8425e95a79b3b428041d4dfc4ecb03a18ef595777c3ad5bd65f4a2dd30d99cb6f1b411161bf7cd32027ecc6d5 languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/plugin-content-docs@npm:3.2.1" +"@docusaurus/plugin-content-docs@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-content-docs@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/logger": 3.2.1 - "@docusaurus/mdx-loader": 3.2.1 - "@docusaurus/module-type-aliases": 3.2.1 - "@docusaurus/types": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-common": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/module-type-aliases": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 "@types/react-router-config": ^5.0.7 combine-promises: ^1.1.0 fs-extra: ^11.1.1 @@ -1919,168 +1949,156 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: c182466c3ff513b36a8975a3899b07ffc4b227ab45ef69eacc0a77119d6f0cd6a0727a3e886cfcf4a56e4f522f64e1e6a2647ddc57eb8493b93c03240b1d9b39 + checksum: fb7ba7f8a6741b14bbe8db0bf1b12ff7a24d12c40d8276f32b9b393881d74bfed3bed4f1e5b0756cac0e43c4bd8106094d5cf6a3c527400e9713283fc3832dab languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/plugin-content-pages@npm:3.2.1" +"@docusaurus/plugin-content-pages@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-content-pages@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/mdx-loader": 3.2.1 - "@docusaurus/types": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 fs-extra: ^11.1.1 tslib: ^2.6.0 webpack: ^5.88.1 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 3cce99f8aa863b97cbb54a50b448073222a0678528b09f5bec2196e73ec4740f412f8675ed05d283ff672756a5d3005f7a1e4d8c8f882cd0d6d5691cbccb604c + checksum: 8b3f1040e8ec006c9431508e73ef3f61cd5759bece3770189f7d52609f91bd156c9b18d0608f9cb14c456a1d1823be6633c573d5eee7cf9bd142b0f978c7a745 languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/plugin-debug@npm:3.2.1" +"@docusaurus/plugin-debug@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-debug@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/types": 3.2.1 - "@docusaurus/utils": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 fs-extra: ^11.1.1 react-json-view-lite: ^1.2.0 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: b3fb1c8935463afb97f233042692c247d4147c03e18ef9fb37fbf0c46d4adaefa4af0d5c357025992dadfe7b83a9fd3754946b8947bfb8b9535dca390a3668d0 + checksum: a839e6c3a595ea202fdd7fbce638ab8df26ba73a8c7ead8c04d1bbb509ebe34e9633e7fe9eb54a7a733e93a03d74a60df4d9f6597b9621ff464280d4dd71db34 languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/plugin-google-analytics@npm:3.2.1" +"@docusaurus/plugin-google-analytics@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-google-analytics@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/types": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: e1e881fd6adbe408029257d526759b9217f7d70e5e068c7e9241a5f0c3050b0fa46acfeb4f8a23c3f36e1739d0a3d810642d69c6648ff6801ce13b646e44e6c1 + checksum: 0b8c4d21333d40c2509d6ef807caaf69f085010c5deac514ab34f53b5486fd76766c90213dc98976a6c4d66fdfa14bf6b05594e51e8a53ec60c2a3fa08fd9a83 languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/plugin-google-gtag@npm:3.2.1" +"@docusaurus/plugin-google-gtag@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-google-gtag@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/types": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 "@types/gtag.js": ^0.0.12 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: b7758289d8453e98baf95d41e754c1e4c8fd5b1c000ba444c4bdf13fc97674a3cddf3215b6406266729e23898641b5bae297c5422c5bd079ef04773fa5a15c1b + checksum: 5d53c2483c8c7e3a8e842bd091a774d4041f0e165d216b3c02f031a224a77258c9456e8b2acd0500b4a0eff474a83c1b82803628db9d4b132514409936c68ac4 languageName: node linkType: hard -"@docusaurus/plugin-google-tag-manager@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/plugin-google-tag-manager@npm:3.2.1" +"@docusaurus/plugin-google-tag-manager@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-google-tag-manager@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/types": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 82355aed046b12ce0fead68339e24a3c6f2f517bc2b80c9c26c502cc49d86c1b6d0f797d5269d1d5e73ac78fd748c8a2f4528f7f3feee1137ae8e73876426426 + checksum: 9a6fc2ca54ea677c6edfd78f4f392d7d9ae86afd085fcda96d5ac41efa441352c25a2519595d9d15fb9b838e2ae39837f0daf02e2406c5cd56199ae237bd7b7a languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/plugin-sitemap@npm:3.2.1" +"@docusaurus/plugin-sitemap@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/plugin-sitemap@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/logger": 3.2.1 - "@docusaurus/types": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-common": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 fs-extra: ^11.1.1 sitemap: ^7.1.1 tslib: ^2.6.0 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: b2e4c4fddd0fbdd4a6a4c93a0f9c16b1294162146eb9911ce378f33d70396f08dfa98d92aed133bba2a8df2b1710c257bf00c0657933ee6cd9c5edb36c8054dc + checksum: 26b6bceb7ab87fe7f6f666742d1e81de32cdacc5aaa3d45d91002c7d64e3258f3d0aac87c6b0d442eaf34ede2af4b7521b50737f2e8e2718daff6fce10230213 languageName: node linkType: hard "@docusaurus/preset-classic@npm:^3.1.1": - version: 3.2.1 - resolution: "@docusaurus/preset-classic@npm:3.2.1" + version: 3.5.2 + resolution: "@docusaurus/preset-classic@npm:3.5.2" dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/plugin-content-blog": 3.2.1 - "@docusaurus/plugin-content-docs": 3.2.1 - "@docusaurus/plugin-content-pages": 3.2.1 - "@docusaurus/plugin-debug": 3.2.1 - "@docusaurus/plugin-google-analytics": 3.2.1 - "@docusaurus/plugin-google-gtag": 3.2.1 - "@docusaurus/plugin-google-tag-manager": 3.2.1 - "@docusaurus/plugin-sitemap": 3.2.1 - "@docusaurus/theme-classic": 3.2.1 - "@docusaurus/theme-common": 3.2.1 - "@docusaurus/theme-search-algolia": 3.2.1 - "@docusaurus/types": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/plugin-content-blog": 3.5.2 + "@docusaurus/plugin-content-docs": 3.5.2 + "@docusaurus/plugin-content-pages": 3.5.2 + "@docusaurus/plugin-debug": 3.5.2 + "@docusaurus/plugin-google-analytics": 3.5.2 + "@docusaurus/plugin-google-gtag": 3.5.2 + "@docusaurus/plugin-google-tag-manager": 3.5.2 + "@docusaurus/plugin-sitemap": 3.5.2 + "@docusaurus/theme-classic": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/theme-search-algolia": 3.5.2 + "@docusaurus/types": 3.5.2 peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 343c896f22bffbda9db4af7d652588f353c5f60336e545eb07be0dfe9bc29ca04a3978d88d5a8b3fa7caafc56a48b341349ffd08006885fa0d4de216cfdc5401 + checksum: ec578e62b3b13b1874b14235a448a913c2d2358ea9b9d9c60bb250be468ab62387c88ec44e1ee82ad5b3d7243306e31919888a80eae62e5e8eab0ae12194bf69 languageName: node linkType: hard -"@docusaurus/react-loadable@npm:5.5.2, react-loadable@npm:@docusaurus/react-loadable@5.5.2": - version: 5.5.2 - resolution: "@docusaurus/react-loadable@npm:5.5.2" +"@docusaurus/theme-classic@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-classic@npm:3.5.2" dependencies: - "@types/react": "*" - prop-types: ^15.6.2 - peerDependencies: - react: "*" - checksum: 930fb9e2936412a12461f210acdc154a433283921ca43ac3fc3b84cb6c12eb738b3a3719373022bf68004efeb1a928dbe36c467d7a1f86454ed6241576d936e7 - languageName: node - linkType: hard - -"@docusaurus/theme-classic@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/theme-classic@npm:3.2.1" - dependencies: - "@docusaurus/core": 3.2.1 - "@docusaurus/mdx-loader": 3.2.1 - "@docusaurus/module-type-aliases": 3.2.1 - "@docusaurus/plugin-content-blog": 3.2.1 - "@docusaurus/plugin-content-docs": 3.2.1 - "@docusaurus/plugin-content-pages": 3.2.1 - "@docusaurus/theme-common": 3.2.1 - "@docusaurus/theme-translations": 3.2.1 - "@docusaurus/types": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-common": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/module-type-aliases": 3.5.2 + "@docusaurus/plugin-content-blog": 3.5.2 + "@docusaurus/plugin-content-docs": 3.5.2 + "@docusaurus/plugin-content-pages": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/theme-translations": 3.5.2 + "@docusaurus/types": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 "@mdx-js/react": ^3.0.0 clsx: ^2.0.0 copy-text-to-clipboard: ^3.2.0 - infima: 0.2.0-alpha.43 + infima: 0.2.0-alpha.44 lodash: ^4.17.21 nprogress: ^0.2.0 postcss: ^8.4.26 @@ -2093,21 +2111,18 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 7b38e47e9334ba6ad84f6432ec9ae81caad7f6c630b2a332617b0f32f1559b0e56f3d8857c732da62d1d7213ad0f493853bf18b1707a2f8d8bcccef32f1d81a1 + checksum: 6c415b01ad24bb43eb166e2b780a84356ff14a627627f6a541c2803832d56c4f9409a5636048693d2d24804f59c2cc7bda925d9ef999a8276fe125477d2b2e1e languageName: node linkType: hard -"@docusaurus/theme-common@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/theme-common@npm:3.2.1" +"@docusaurus/theme-common@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-common@npm:3.5.2" dependencies: - "@docusaurus/mdx-loader": 3.2.1 - "@docusaurus/module-type-aliases": 3.2.1 - "@docusaurus/plugin-content-blog": 3.2.1 - "@docusaurus/plugin-content-docs": 3.2.1 - "@docusaurus/plugin-content-pages": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-common": 3.2.1 + "@docusaurus/mdx-loader": 3.5.2 + "@docusaurus/module-type-aliases": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -2117,24 +2132,25 @@ __metadata: tslib: ^2.6.0 utility-types: ^3.10.0 peerDependencies: + "@docusaurus/plugin-content-docs": "*" react: ^18.0.0 react-dom: ^18.0.0 - checksum: 13de70293476e05f1b52c2d99a1b26c73bf99ac92aba3c8ddc413b5336725d2b54c56c167d12244fdb0b518ee9cdecbbfb3258fb8cc91272e9b795361b131fbb + checksum: c78ec7f6035abc920a2a0bc1ad78920178a5452538a3a70794eca8d4b976725f6ccc464ee3092afd31ca59b4e061ad4c21cdce7f5e10b06567075814b2fc2002 languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/theme-search-algolia@npm:3.2.1" +"@docusaurus/theme-search-algolia@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-search-algolia@npm:3.5.2" dependencies: "@docsearch/react": ^3.5.2 - "@docusaurus/core": 3.2.1 - "@docusaurus/logger": 3.2.1 - "@docusaurus/plugin-content-docs": 3.2.1 - "@docusaurus/theme-common": 3.2.1 - "@docusaurus/theme-translations": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-validation": 3.2.1 + "@docusaurus/core": 3.5.2 + "@docusaurus/logger": 3.5.2 + "@docusaurus/plugin-content-docs": 3.5.2 + "@docusaurus/theme-common": 3.5.2 + "@docusaurus/theme-translations": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-validation": 3.5.2 algoliasearch: ^4.18.0 algoliasearch-helper: ^3.13.3 clsx: ^2.0.0 @@ -2146,30 +2162,30 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: befbb86bf309f2b770ae21bc1d5c91eb6e840a5a72858cdfd3b21dbabadd1738d6d427ada7745f9d3424bb1a6e01839e20bf35c15a4c13d59b63d259e52de5df + checksum: e945e3001996477597bfad074eaef074cf4c5365ed3076c3109130a2252b266e4e2fac46904a0626eedeff23b9ac11e7b985cc71f5485ede52d3ddf379b7959b languageName: node linkType: hard -"@docusaurus/theme-translations@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/theme-translations@npm:3.2.1" +"@docusaurus/theme-translations@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/theme-translations@npm:3.5.2" dependencies: fs-extra: ^11.1.1 tslib: ^2.6.0 - checksum: 43bdb90d143576d2e8eb56bfe2c9daa0e4250cdb2dcfd10096b86466e6ee253548ac5ef2f9a4986a5bc9a573d118fe4695ee5004f0ef00b57b720dac7f124337 + checksum: dc523c74a13fb8552c03e547c6de1c21881d899cc74bf088a2bed716e0ef1a4ceba2726c43656d87fff60413ca191f5ea946b182e4ae4129c14da832b5194d82 languageName: node linkType: hard "@docusaurus/tsconfig@npm:^3.1.1": - version: 3.2.1 - resolution: "@docusaurus/tsconfig@npm:3.2.1" - checksum: ea3c28b79b0de069c50f7b3a67d3ff682b6ded2ef02d2c7a4c2eaeddc8fcf79c9d9f5e60fbd2966cf3d247fbb8f63897b80a61fdd8b485c745a12eb684ae241a + version: 3.5.2 + resolution: "@docusaurus/tsconfig@npm:3.5.2" + checksum: 808a17eaf422ae9a948c6558dd1e92d4700b067ead3a63a84049c6845bf94f84e311cd0e4d517047fe9ea057efe393bb22c2d5c92d727d06c9f895e971f2c3ea languageName: node linkType: hard -"@docusaurus/types@npm:3.2.1, @docusaurus/types@npm:^3.1.1": - version: 3.2.1 - resolution: "@docusaurus/types@npm:3.2.1" +"@docusaurus/types@npm:3.5.2, @docusaurus/types@npm:^3.1.1": + version: 3.5.2 + resolution: "@docusaurus/types@npm:3.5.2" dependencies: "@mdx-js/mdx": ^3.0.0 "@types/history": ^4.7.11 @@ -2183,13 +2199,13 @@ __metadata: peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 4f19e162bff627675df160ae5c33c6063646050c4de5c9698018fbd9d198300b9ce7a7333e4d1b369b42cfa42296dc9fb36547e4e37664d594deb08639e6b620 + checksum: e39451b7b08673ad5e1551ee6e4286f90f2554cf9ba245abfa56670550f48afca9c57b01c10ffa21dacb734c0fcd067150eeb2b1c1ebb1692f1f538b1eed0029 languageName: node linkType: hard -"@docusaurus/utils-common@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/utils-common@npm:3.2.1" +"@docusaurus/utils-common@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/utils-common@npm:3.5.2" dependencies: tslib: ^2.6.0 peerDependencies: @@ -2197,31 +2213,33 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: bc0b7e74bc29134dbdb7fbc2e8f9f39f0f460923a07d0ccd7f0542088e92c47faf06bdbd253b7ba2b9250b0869118a3b7bf3faa3a075a2a35f5f8545eb3345f2 + checksum: 9d550c89663d4271456ae0832c82a1691207ccc95e21df3a05a4bd6bbd2624bb9e3ab7327d939c04b2023378987bcf99321b2c37be1af214852832f65d6db14a languageName: node linkType: hard -"@docusaurus/utils-validation@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/utils-validation@npm:3.2.1" +"@docusaurus/utils-validation@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/utils-validation@npm:3.5.2" dependencies: - "@docusaurus/logger": 3.2.1 - "@docusaurus/utils": 3.2.1 - "@docusaurus/utils-common": 3.2.1 + "@docusaurus/logger": 3.5.2 + "@docusaurus/utils": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + fs-extra: ^11.2.0 joi: ^17.9.2 js-yaml: ^4.1.0 + lodash: ^4.17.21 tslib: ^2.6.0 - checksum: c7b5142083c8e4798c7f6aa1f7a06bc2e93e8e08a8a7a2c5eaf24aa6939e12e401f180f02164764805c40ec0f7179479e0ee98a935c2cb77037ca73ab33d80fd + checksum: 5966e6d0e8f26292c629899f13b545501b53b345b0e2291bb47aaa80d7c9c5cf155e15a4ecd073a4095ee7c83c6db3612e0a34f81a8187fd20410b1aeb92d731 languageName: node linkType: hard -"@docusaurus/utils@npm:3.2.1": - version: 3.2.1 - resolution: "@docusaurus/utils@npm:3.2.1" +"@docusaurus/utils@npm:3.5.2": + version: 3.5.2 + resolution: "@docusaurus/utils@npm:3.5.2" dependencies: - "@docusaurus/logger": 3.2.1 - "@docusaurus/utils-common": 3.2.1 - "@svgr/webpack": ^6.5.1 + "@docusaurus/logger": 3.5.2 + "@docusaurus/utils-common": 3.5.2 + "@svgr/webpack": ^8.1.0 escape-string-regexp: ^4.0.0 file-loader: ^6.2.0 fs-extra: ^11.1.1 @@ -2237,13 +2255,14 @@ __metadata: shelljs: ^0.8.5 tslib: ^2.6.0 url-loader: ^4.1.1 + utility-types: ^3.10.0 webpack: ^5.88.1 peerDependencies: "@docusaurus/types": "*" peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: ea862b178e303b49e644e77a663df6e42909632022918b77dc1ee69c4de46dde3f210052b1063e96a820e1443141f70e44aa51372f2bf9cfde65e080ea639889 + checksum: 0e0f4fc65ed076d4e4b551ecb61447b7c2468060d1655afff314515844ae34dc0546f467f53bff535f3144afc109e974da27fadb7c678a5d19966bed9e7a27c4 languageName: node linkType: hard @@ -2270,51 +2289,51 @@ __metadata: languageName: node linkType: hard -"@jest/schemas@npm:^29.0.0": - version: 29.0.0 - resolution: "@jest/schemas@npm:29.0.0" +"@jest/schemas@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/schemas@npm:29.6.3" dependencies: - "@sinclair/typebox": ^0.24.1 - checksum: 41355c78f09eb1097e57a3c5d0ca11c9099e235e01ea5fa4e3953562a79a6a9296c1d300f1ba50ca75236048829e056b00685cd2f1ff8285e56fd2ce01249acb + "@sinclair/typebox": ^0.27.8 + checksum: 910040425f0fc93cd13e68c750b7885590b8839066dfa0cd78e7def07bbb708ad869381f725945d66f2284de5663bbecf63e8fdd856e2ae6e261ba30b1687e93 languageName: node linkType: hard -"@jest/types@npm:^29.3.1": - version: 29.3.1 - resolution: "@jest/types@npm:29.3.1" +"@jest/types@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/types@npm:29.6.3" dependencies: - "@jest/schemas": ^29.0.0 + "@jest/schemas": ^29.6.3 "@types/istanbul-lib-coverage": ^2.0.0 "@types/istanbul-reports": ^3.0.0 "@types/node": "*" "@types/yargs": ^17.0.8 chalk: ^4.0.0 - checksum: 6f9faf27507b845ff3839c1adc6dbd038d7046d03d37e84c9fc956f60718711a801a5094c7eeee6b39ccf42c0ab61347fdc0fa49ab493ae5a8efd2fd41228ee8 + checksum: a0bcf15dbb0eca6bdd8ce61a3fb055349d40268622a7670a3b2eb3c3dbafe9eb26af59938366d520b86907b9505b0f9b29b85cec11579a9e580694b87cd90fcc languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.2": - version: 0.3.2 - resolution: "@jridgewell/gen-mapping@npm:0.3.2" +"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" dependencies: - "@jridgewell/set-array": ^1.0.1 + "@jridgewell/set-array": ^1.2.1 "@jridgewell/sourcemap-codec": ^1.4.10 - "@jridgewell/trace-mapping": ^0.3.9 - checksum: 1832707a1c476afebe4d0fbbd4b9434fdb51a4c3e009ab1e9938648e21b7a97049fa6009393bdf05cab7504108413441df26d8a3c12193996e65493a4efb6882 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: ff7a1764ebd76a5e129c8890aa3e2f46045109dabde62b0b6c6a250152227647178ff2069ea234753a690d8f3c4ac8b5e7b267bbee272bffb7f3b0a370ab6e52 languageName: node linkType: hard -"@jridgewell/resolve-uri@npm:3.1.0": - version: 3.1.0 - resolution: "@jridgewell/resolve-uri@npm:3.1.0" - checksum: b5ceaaf9a110fcb2780d1d8f8d4a0bfd216702f31c988d8042e5f8fbe353c55d9b0f55a1733afdc64806f8e79c485d2464680ac48a0d9fcadb9548ee6b81d267 +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 83b85f72c59d1c080b4cbec0fef84528963a1b5db34e4370fa4bd1e3ff64a0d80e0cee7369d11d73c704e0286fb2865b530acac7a871088fbe92b5edf1000870 languageName: node linkType: hard -"@jridgewell/set-array@npm:^1.0.1": - version: 1.1.2 - resolution: "@jridgewell/set-array@npm:1.1.2" - checksum: 69a84d5980385f396ff60a175f7177af0b8da4ddb81824cb7016a9ef914eee9806c72b6b65942003c63f7983d4f39a5c6c27185bbca88eb4690b62075602e28e +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 languageName: node linkType: hard @@ -2328,20 +2347,20 @@ __metadata: languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.10": - version: 1.4.14 - resolution: "@jridgewell/sourcemap-codec@npm:1.4.14" - checksum: 61100637b6d173d3ba786a5dff019e1a74b1f394f323c1fee337ff390239f053b87266c7a948777f4b1ee68c01a8ad0ab61e5ff4abb5a012a0b091bec391ab97 +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": + version: 1.5.0 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.0" + checksum: 05df4f2538b3b0f998ea4c1cd34574d0feba216fa5d4ccaef0187d12abf82eafe6021cec8b49f9bb4d90f2ba4582ccc581e72986a5fcf4176ae0cfeb04cf52ec languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9": - version: 0.3.18 - resolution: "@jridgewell/trace-mapping@npm:0.3.18" +"@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.9": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" dependencies: - "@jridgewell/resolve-uri": 3.1.0 - "@jridgewell/sourcemap-codec": 1.4.14 - checksum: 0572669f855260808c16fe8f78f5f1b4356463b11d3f2c7c0b5580c8ba1cbf4ae53efe9f627595830856e57dbac2325ac17eb0c3dd0ec42102e6f227cc289c02 + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 9d3c40d225e139987b50c48988f8717a54a8c994d8a948ee42e1412e08988761d0754d7d10b803061cc3aebf35f92a5dbbab493bd0e1a9ef9e89a2130e83ba34 languageName: node linkType: hard @@ -2499,10 +2518,10 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.24.1": - version: 0.24.51 - resolution: "@sinclair/typebox@npm:0.24.51" - checksum: fd0d855e748ef767eb19da1a60ed0ab928e91e0f358c1dd198d600762c0015440b15755e96d1176e2a0db7e09c6a64ed487828ee10dd0c3e22f61eb09c478cd0 +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 languageName: node linkType: hard @@ -2540,248 +2559,248 @@ __metadata: languageName: node linkType: hard -"@svgr/babel-plugin-add-jsx-attribute@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:6.5.1" +"@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:8.0.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: cab83832830a57735329ed68f67c03b57ca21fa037b0134847b0c5c0ef4beca89956d7dacfbf7b2a10fd901e7009e877512086db2ee918b8c69aee7742ae32c0 + checksum: 3fc8e35d16f5abe0af5efe5851f27581225ac405d6a1ca44cda0df064cddfcc29a428c48c2e4bef6cebf627c9ac2f652a096030edb02cf5a120ce28d3c234710 languageName: node linkType: hard -"@svgr/babel-plugin-remove-jsx-attribute@npm:*": - version: 6.5.0 - resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:6.5.0" +"@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7a4dfc1345f5855b010684e9c5301731842bf91d72b82ce5cc4c82c80b94de1036e447a8a00fb306a6dd575cb4c640d8ce3cfee6607ddbb804796a77284c7f22 + checksum: ff992893c6c4ac802713ba3a97c13be34e62e6d981c813af40daabcd676df68a72a61bd1e692bb1eda3587f1b1d700ea462222ae2153bb0f46886632d4f88d08 languageName: node linkType: hard -"@svgr/babel-plugin-remove-jsx-empty-expression@npm:*": - version: 6.5.0 - resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:6.5.0" +"@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3e173f720d530f9f71f8506f3eb78583eec3d87d66e385efe1ef3b3ebfc4e3680ec30f36414726de6a163e99ca69f54886022967e49476dea522267e1986936e + checksum: 0fb691b63a21bac00da3aa2dccec50d0d5a5b347ff408d60803b84410d8af168f2656e4ba1ee1f24dab0ae4e4af77901f2928752bb0434c1f6788133ec599ec8 languageName: node linkType: hard -"@svgr/babel-plugin-replace-jsx-attribute-value@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:6.5.1" +"@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:8.0.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b7d2125758e766e1ebd14b92216b800bdc976959bc696dbfa1e28682919147c1df4bb8b1b5fd037d7a83026e27e681fea3b8d3741af8d3cf4c9dfa3d412125df + checksum: 1edda65ef4f4dd8f021143c8ec276a08f6baa6f733b8e8ee2e7775597bf6b97afb47fdeefd579d6ae6c959fe2e634f55cd61d99377631212228c8cfb351b8921 languageName: node linkType: hard -"@svgr/babel-plugin-svg-dynamic-title@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:6.5.1" +"@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:8.0.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0fd42ebf127ae9163ef341e84972daa99bdcb9e6ed3f83aabd95ee173fddc43e40e02fa847fbc0a1058cf5549f72b7960a2c5e22c3e4ac18f7e3ac81277852ae + checksum: 876cec891488992e6a9aebb8155e2bea4ec461b4718c51de36e988e00e271c6d9d01ef6be17b9effd44b2b3d7db0b41c161a5904a46ae6f38b26b387ad7f3709 languageName: node linkType: hard -"@svgr/babel-plugin-svg-em-dimensions@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:6.5.1" +"@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:8.0.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c1550ee9f548526fa66fd171e3ffb5696bfc4e4cd108a631d39db492c7410dc10bba4eb5a190e9df824bf806130ccc586ae7d2e43c547e6a4f93bbb29a18f344 + checksum: be0e2d391164428327d9ec469a52cea7d93189c6b0e2c290999e048f597d777852f701c64dca44cd45b31ed14a7f859520326e2e4ad7c3a4545d0aa235bc7e9a languageName: node linkType: hard -"@svgr/babel-plugin-transform-react-native-svg@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:6.5.1" +"@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:8.1.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4c924af22b948b812629e80efb90ad1ec8faae26a232d8ca8a06b46b53e966a2c415a57806a3ff0ea806a622612e546422719b69ec6839717a7755dac19171d9 + checksum: 85b434a57572f53bd2b9f0606f253e1fcf57b4a8c554ec3f2d43ed17f50d8cae200cb3aaf1ec9d626e1456e8b135dce530ae047eb0bed6d4bf98a752d6640459 languageName: node linkType: hard -"@svgr/babel-plugin-transform-svg-component@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/babel-plugin-transform-svg-component@npm:6.5.1" +"@svgr/babel-plugin-transform-svg-component@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/babel-plugin-transform-svg-component@npm:8.0.0" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e496bb5ee871feb6bcab250b6e067322da7dd5c9c2b530b41e5586fe090f86611339b49d0a909c334d9b24cbca0fa755c949a2526c6ad03c6b5885666874cf5f + checksum: 04e2023d75693eeb0890341c40e449881184663056c249be7e5c80168e4aabb0fadd255e8d5d2dbf54b8c2a6e700efba994377135bfa4060dc4a2e860116ef8c languageName: node linkType: hard -"@svgr/babel-preset@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/babel-preset@npm:6.5.1" +"@svgr/babel-preset@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/babel-preset@npm:8.1.0" dependencies: - "@svgr/babel-plugin-add-jsx-attribute": ^6.5.1 - "@svgr/babel-plugin-remove-jsx-attribute": "*" - "@svgr/babel-plugin-remove-jsx-empty-expression": "*" - "@svgr/babel-plugin-replace-jsx-attribute-value": ^6.5.1 - "@svgr/babel-plugin-svg-dynamic-title": ^6.5.1 - "@svgr/babel-plugin-svg-em-dimensions": ^6.5.1 - "@svgr/babel-plugin-transform-react-native-svg": ^6.5.1 - "@svgr/babel-plugin-transform-svg-component": ^6.5.1 + "@svgr/babel-plugin-add-jsx-attribute": 8.0.0 + "@svgr/babel-plugin-remove-jsx-attribute": 8.0.0 + "@svgr/babel-plugin-remove-jsx-empty-expression": 8.0.0 + "@svgr/babel-plugin-replace-jsx-attribute-value": 8.0.0 + "@svgr/babel-plugin-svg-dynamic-title": 8.0.0 + "@svgr/babel-plugin-svg-em-dimensions": 8.0.0 + "@svgr/babel-plugin-transform-react-native-svg": 8.1.0 + "@svgr/babel-plugin-transform-svg-component": 8.0.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 9f124be39a8e64f909162f925b3a63ddaa5a342a5e24fc0b7f7d9d4d7f7e3b916596c754fb557dc259928399cad5366a27cb231627a0d2dcc4b13ac521cf05af + checksum: 3a67930f080b8891e1e8e2595716b879c944d253112bae763dce59807ba23454d162216c8d66a0a0e3d4f38a649ecd6c387e545d1e1261dd69a68e9a3392ee08 languageName: node linkType: hard -"@svgr/core@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/core@npm:6.5.1" +"@svgr/core@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/core@npm:8.1.0" dependencies: - "@babel/core": ^7.19.6 - "@svgr/babel-preset": ^6.5.1 - "@svgr/plugin-jsx": ^6.5.1 + "@babel/core": ^7.21.3 + "@svgr/babel-preset": 8.1.0 camelcase: ^6.2.0 - cosmiconfig: ^7.0.1 - checksum: fd6d6d5da5aeb956703310480b626c1fb3e3973ad9fe8025efc1dcf3d895f857b70d100c63cf32cebb20eb83c9607bafa464c9436e18fe6fe4fafdc73ed6b1a5 + cosmiconfig: ^8.1.3 + snake-case: ^3.0.4 + checksum: da4a12865c7dc59829d58df8bd232d6c85b7115fda40da0d2f844a1a51886e2e945560596ecfc0345d37837ac457de86a931e8b8d8550e729e0c688c02250d8a languageName: node linkType: hard -"@svgr/hast-util-to-babel-ast@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/hast-util-to-babel-ast@npm:6.5.1" +"@svgr/hast-util-to-babel-ast@npm:8.0.0": + version: 8.0.0 + resolution: "@svgr/hast-util-to-babel-ast@npm:8.0.0" dependencies: - "@babel/types": ^7.20.0 + "@babel/types": ^7.21.3 entities: ^4.4.0 - checksum: 37923cce1b3f4e2039077b0c570b6edbabe37d1cf1a6ee35e71e0fe00f9cffac450eec45e9720b1010418131a999cb0047331ba1b6d1d2c69af1b92ac785aacf + checksum: 88401281a38bbc7527e65ff5437970414391a86158ef4b4046c89764c156d2d39ecd7cce77be8a51994c9fb3249170cb1eb8b9128b62faaa81743ef6ed3534ab languageName: node linkType: hard -"@svgr/plugin-jsx@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/plugin-jsx@npm:6.5.1" +"@svgr/plugin-jsx@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/plugin-jsx@npm:8.1.0" dependencies: - "@babel/core": ^7.19.6 - "@svgr/babel-preset": ^6.5.1 - "@svgr/hast-util-to-babel-ast": ^6.5.1 + "@babel/core": ^7.21.3 + "@svgr/babel-preset": 8.1.0 + "@svgr/hast-util-to-babel-ast": 8.0.0 svg-parser: ^2.0.4 peerDependencies: - "@svgr/core": ^6.0.0 - checksum: 42f22847a6bdf930514d7bedd3c5e1fd8d53eb3594779f9db16cb94c762425907c375cd8ec789114e100a4d38068aca6c7ab5efea4c612fba63f0630c44cc859 + "@svgr/core": "*" + checksum: 0418a9780753d3544912ee2dad5d2cf8d12e1ba74df8053651b3886aeda54d5f0f7d2dece0af5e0d838332c4f139a57f0dabaa3ca1afa4d1a765efce6a7656f2 languageName: node linkType: hard -"@svgr/plugin-svgo@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/plugin-svgo@npm:6.5.1" +"@svgr/plugin-svgo@npm:8.1.0": + version: 8.1.0 + resolution: "@svgr/plugin-svgo@npm:8.1.0" dependencies: - cosmiconfig: ^7.0.1 - deepmerge: ^4.2.2 - svgo: ^2.8.0 + cosmiconfig: ^8.1.3 + deepmerge: ^4.3.1 + svgo: ^3.0.2 peerDependencies: "@svgr/core": "*" - checksum: cd2833530ac0485221adc2146fd992ab20d79f4b12eebcd45fa859721dd779483158e11dfd9a534858fe468416b9412416e25cbe07ac7932c44ed5fa2021c72e + checksum: 59d9d214cebaacca9ca71a561f463d8b7e5a68ca9443e4792a42d903acd52259b1790c0680bc6afecc3f00a255a6cbd7ea278a9f625bac443620ea58a590c2d0 languageName: node linkType: hard -"@svgr/webpack@npm:^6.5.1": - version: 6.5.1 - resolution: "@svgr/webpack@npm:6.5.1" +"@svgr/webpack@npm:^8.1.0": + version: 8.1.0 + resolution: "@svgr/webpack@npm:8.1.0" dependencies: - "@babel/core": ^7.19.6 - "@babel/plugin-transform-react-constant-elements": ^7.18.12 - "@babel/preset-env": ^7.19.4 + "@babel/core": ^7.21.3 + "@babel/plugin-transform-react-constant-elements": ^7.21.3 + "@babel/preset-env": ^7.20.2 "@babel/preset-react": ^7.18.6 - "@babel/preset-typescript": ^7.18.6 - "@svgr/core": ^6.5.1 - "@svgr/plugin-jsx": ^6.5.1 - "@svgr/plugin-svgo": ^6.5.1 - checksum: d10582eb4fa82a5b6d314cb49f2c640af4fd3a60f5b76095d2b14e383ef6a43a6f4674b68774a21787dbde69dec0a251cfcfc3f9a96c82754ba5d5c6daf785f0 + "@babel/preset-typescript": ^7.21.0 + "@svgr/core": 8.1.0 + "@svgr/plugin-jsx": 8.1.0 + "@svgr/plugin-svgo": 8.1.0 + checksum: c6eec5b0cf2fb2ecd3a7a362d272eda35330b17c76802a3481f499b5d07ff8f87b31d2571043bff399b051a1767b1e2e499dbf186104d1c06d76f9f1535fac01 languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-arm64@npm:1.5.29" +"@swc/core-darwin-arm64@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-darwin-arm64@npm:1.7.23" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-x64@npm:1.5.29" +"@swc/core-darwin-x64@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-darwin-x64@npm:1.7.23" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.29" +"@swc/core-linux-arm-gnueabihf@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.23" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-gnu@npm:1.5.29" +"@swc/core-linux-arm64-gnu@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-arm64-gnu@npm:1.7.23" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-musl@npm:1.5.29" +"@swc/core-linux-arm64-musl@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-arm64-musl@npm:1.7.23" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-gnu@npm:1.5.29" +"@swc/core-linux-x64-gnu@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-x64-gnu@npm:1.7.23" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-musl@npm:1.5.29" +"@swc/core-linux-x64-musl@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-x64-musl@npm:1.7.23" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-arm64-msvc@npm:1.5.29" +"@swc/core-win32-arm64-msvc@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-win32-arm64-msvc@npm:1.7.23" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-ia32-msvc@npm:1.5.29" +"@swc/core-win32-ia32-msvc@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-win32-ia32-msvc@npm:1.7.23" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-x64-msvc@npm:1.5.29" +"@swc/core-win32-x64-msvc@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-win32-x64-msvc@npm:1.7.23" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.5.29 - resolution: "@swc/core@npm:1.5.29" + version: 1.7.23 + resolution: "@swc/core@npm:1.7.23" dependencies: - "@swc/core-darwin-arm64": 1.5.29 - "@swc/core-darwin-x64": 1.5.29 - "@swc/core-linux-arm-gnueabihf": 1.5.29 - "@swc/core-linux-arm64-gnu": 1.5.29 - "@swc/core-linux-arm64-musl": 1.5.29 - "@swc/core-linux-x64-gnu": 1.5.29 - "@swc/core-linux-x64-musl": 1.5.29 - "@swc/core-win32-arm64-msvc": 1.5.29 - "@swc/core-win32-ia32-msvc": 1.5.29 - "@swc/core-win32-x64-msvc": 1.5.29 + "@swc/core-darwin-arm64": 1.7.23 + "@swc/core-darwin-x64": 1.7.23 + "@swc/core-linux-arm-gnueabihf": 1.7.23 + "@swc/core-linux-arm64-gnu": 1.7.23 + "@swc/core-linux-arm64-musl": 1.7.23 + "@swc/core-linux-x64-gnu": 1.7.23 + "@swc/core-linux-x64-musl": 1.7.23 + "@swc/core-win32-arm64-msvc": 1.7.23 + "@swc/core-win32-ia32-msvc": 1.7.23 + "@swc/core-win32-x64-msvc": 1.7.23 "@swc/counter": ^0.1.3 - "@swc/types": ^0.1.8 + "@swc/types": ^0.1.12 peerDependencies: "@swc/helpers": "*" dependenciesMeta: @@ -2808,7 +2827,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 19e3f8525ce4f4d9f6f3f62825b1f13e1e76146390930b6d5e663c0bb2c5e95ef3bf30268110d1444ea92b99dd95bfe5a3c6e2a3c0dd79291505dc7da1ed3dab + checksum: a21e9a67d305ad9b49b6def9f9698b374db6c15b2ded5e5cf29390221181fc6b91bfa317b53fd41d9cca989d85b79bbbca5ab27635df1e0232cad4681f618fa5 languageName: node linkType: hard @@ -2819,12 +2838,12 @@ __metadata: languageName: node linkType: hard -"@swc/types@npm:^0.1.8": - version: 0.1.8 - resolution: "@swc/types@npm:0.1.8" +"@swc/types@npm:^0.1.12": + version: 0.1.12 + resolution: "@swc/types@npm:0.1.12" dependencies: "@swc/counter": ^0.1.3 - checksum: e564d0e37b0e28546973c6d50c7a179395912a97168d695cfe9cf1051199c8b828680cdafcb8d43948f76d3703873bafb88dfb5bc2dfe0596b4ad18fcaf90c80 + checksum: cf7f89e46f859864075d7965582baea9c5f98830f45b1046251568c9bdf1ca484b1bf37f6d3c32b7c82ecf8cd5df89d22f05268c391819c44e49911bb1a8e71a languageName: node linkType: hard @@ -3045,9 +3064,9 @@ __metadata: linkType: hard "@types/luxon@npm:^3.0.0": - version: 3.3.8 - resolution: "@types/luxon@npm:3.3.8" - checksum: 026711b4aefc01c6e233e359c693b6d4c0873acc3f52a08661ea3751b2cf3e34d1ce1d5b0b99b0e40a059a2a3755acc20498d37db5f9a5a4f0f330cdf72db3db + version: 3.4.2 + resolution: "@types/luxon@npm:3.4.2" + checksum: 6f92d5bd02e89f310395753506bcd9cef3a56f5940f7a50db2a2b9822bce753553ac767d143cb5b4f9ed5ddd4a84e64f89ff538082ceb4d18739af7781b56925 languageName: node linkType: hard @@ -3553,7 +3572,7 @@ __metadata: languageName: node linkType: hard -"ajv-keywords@npm:^5.0.0": +"ajv-keywords@npm:^5.1.0": version: 5.1.0 resolution: "ajv-keywords@npm:5.1.0" dependencies: @@ -3576,15 +3595,15 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.8.0": - version: 8.11.2 - resolution: "ajv@npm:8.11.2" +"ajv@npm:^8.0.0, ajv@npm:^8.9.0": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" dependencies: - fast-deep-equal: ^3.1.1 + fast-deep-equal: ^3.1.3 + fast-uri: ^3.0.1 json-schema-traverse: ^1.0.0 require-from-string: ^2.0.2 - uri-js: ^4.2.2 - checksum: 53435bf79ee7d1eabba8085962dba4c08d08593334b304db7772887f0b7beebc1b3d957432f7437ed4b60e53b5d966a57b439869890209c50fed610459999e3e + checksum: 1797bf242cfffbaf3b870d13565bd1716b73f214bb7ada9a497063aada210200da36e3ed40237285f3255acc4feeae91b1fb183625331bad27da95973f7253d9 languageName: node linkType: hard @@ -3765,21 +3784,21 @@ __metadata: languageName: node linkType: hard -"autoprefixer@npm:^10.4.12, autoprefixer@npm:^10.4.14": - version: 10.4.16 - resolution: "autoprefixer@npm:10.4.16" +"autoprefixer@npm:^10.4.14, autoprefixer@npm:^10.4.19": + version: 10.4.20 + resolution: "autoprefixer@npm:10.4.20" dependencies: - browserslist: ^4.21.10 - caniuse-lite: ^1.0.30001538 - fraction.js: ^4.3.6 + browserslist: ^4.23.3 + caniuse-lite: ^1.0.30001646 + fraction.js: ^4.3.7 normalize-range: ^0.1.2 - picocolors: ^1.0.0 + picocolors: ^1.0.1 postcss-value-parser: ^4.2.0 peerDependencies: postcss: ^8.1.0 bin: autoprefixer: bin/autoprefixer - checksum: 45fad7086495048dacb14bb7b00313e70e135b5d8e8751dcc60548889400763705ab16fc2d99ea628b44c3472698fb0e39598f595ba28409c965ab159035afde + checksum: 187cec2ec356631932b212f76dc64f4419c117fdb2fb9eeeb40867d38ba5ca5ba734e6ceefc9e3af4eec8258e60accdf5cbf2b7708798598fde35cdc3de562d6 languageName: node linkType: hard @@ -3805,16 +3824,28 @@ __metadata: languageName: node linkType: hard -"babel-plugin-polyfill-corejs2@npm:^0.4.5": - version: 0.4.5 - resolution: "babel-plugin-polyfill-corejs2@npm:0.4.5" +"babel-plugin-polyfill-corejs2@npm:^0.4.10, babel-plugin-polyfill-corejs2@npm:^0.4.5": + version: 0.4.11 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.11" dependencies: "@babel/compat-data": ^7.22.6 - "@babel/helper-define-polyfill-provider": ^0.4.2 + "@babel/helper-define-polyfill-provider": ^0.6.2 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 - checksum: 33a8e06aa54e2858d211c743d179f0487b03222f9ca1bfd7c4865bca243fca942a3358cb75f6bb894ed476cbddede834811fbd6903ff589f055821146f053e1a + checksum: f098353ce7c7dde1a1d2710858e01b471e85689110c9e37813e009072347eb8c55d5f84d20d3bf1cab31755f20078ba90f8855fdc4686a9daa826a95ff280bd7 + languageName: node + linkType: hard + +"babel-plugin-polyfill-corejs3@npm:^0.10.6": + version: 0.10.6 + resolution: "babel-plugin-polyfill-corejs3@npm:0.10.6" + dependencies: + "@babel/helper-define-polyfill-provider": ^0.6.2 + core-js-compat: ^3.38.0 + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: f762f29f7acca576897c63149c850f0a72babd3fb9ea436a2e36f0c339161c4b912a77828541d8188ce8a91e50965c6687120cf36071eabb1b7aa92f279e2164 languageName: node linkType: hard @@ -3841,6 +3872,17 @@ __metadata: languageName: node linkType: hard +"babel-plugin-polyfill-regenerator@npm:^0.6.1": + version: 0.6.2 + resolution: "babel-plugin-polyfill-regenerator@npm:0.6.2" + dependencies: + "@babel/helper-define-polyfill-provider": ^0.6.2 + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 150233571072b6b3dfe946242da39cba8587b7f908d1c006f7545fc88b0e3c3018d445739beb61e7a75835f0c2751dbe884a94ff9b245ec42369d9267e0e1b3f + languageName: node + linkType: hard + "backstage-microsite@workspace:.": version: 0.0.0-use.local resolution: "backstage-microsite@workspace:." @@ -3997,7 +4039,7 @@ __metadata: languageName: node linkType: hard -"braces@npm:^3.0.2, braces@npm:~3.0.2": +"braces@npm:^3.0.3, braces@npm:~3.0.2": version: 3.0.3 resolution: "braces@npm:3.0.3" dependencies: @@ -4006,17 +4048,17 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.14.5, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.22.1, browserslist@npm:^4.22.2": - version: 4.22.3 - resolution: "browserslist@npm:4.22.3" +"browserslist@npm:^4.0.0, browserslist@npm:^4.14.5, browserslist@npm:^4.18.1, browserslist@npm:^4.23.0, browserslist@npm:^4.23.1, browserslist@npm:^4.23.3": + version: 4.23.3 + resolution: "browserslist@npm:4.23.3" dependencies: - caniuse-lite: ^1.0.30001580 - electron-to-chromium: ^1.4.648 - node-releases: ^2.0.14 - update-browserslist-db: ^1.0.13 + caniuse-lite: ^1.0.30001646 + electron-to-chromium: ^1.5.4 + node-releases: ^2.0.18 + update-browserslist-db: ^1.1.0 bin: browserslist: cli.js - checksum: e62b17348e92143fe58181b02a6a97c4a98bd812d1dc9274673a54f73eec53dbed1c855ebf73e318ee00ee039f23c9a6d0e7629d24f3baef08c7a5b469742d57 + checksum: 7906064f9970aeb941310b2fcb8b4ace4a1b50aa657c986677c6f1553a8cabcc94ee9c5922f715baffbedaa0e6cf0831b6fed7b059dde6873a4bfadcbe069c7e languageName: node linkType: hard @@ -4142,10 +4184,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001538, caniuse-lite@npm:^1.0.30001580": - version: 1.0.30001587 - resolution: "caniuse-lite@npm:1.0.30001587" - checksum: fb50aa9beaaae42f9feae92ce038f6ff71e97510f024ef1bef2666f3adcfd36d6c59e5675442e5fe795575193f71bc826cb7721d4b0f6d763e82d193bea57863 +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001646": + version: 1.0.30001653 + resolution: "caniuse-lite@npm:1.0.30001653" + checksum: 289cf06c26a46f3e6460ccd5feffa788ab0ab35d306898c48120c65cfb11959bfa560e9f739393769b4fd01150c69b0747ad3ad5ec3abf3dfafd66df3c59254e languageName: node linkType: hard @@ -4233,7 +4275,7 @@ __metadata: languageName: node linkType: hard -"cheerio@npm:^1.0.0-rc.12": +"cheerio@npm:1.0.0-rc.12": version: 1.0.0-rc.12 resolution: "cheerio@npm:1.0.0-rc.12" dependencies: @@ -4390,7 +4432,7 @@ __metadata: languageName: node linkType: hard -"colord@npm:^2.9.1": +"colord@npm:^2.9.3": version: 2.9.3 resolution: "colord@npm:2.9.3" checksum: 95d909bfbcfd8d5605cbb5af56f2d1ce2b323990258fd7c0d2eb0e6d3bb177254d7fb8213758db56bb4ede708964f78c6b992b326615f81a18a6aaf11d64c650 @@ -4602,12 +4644,12 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.32.2": - version: 3.33.0 - resolution: "core-js-compat@npm:3.33.0" +"core-js-compat@npm:^3.32.2, core-js-compat@npm:^3.37.1, core-js-compat@npm:^3.38.0": + version: 3.38.1 + resolution: "core-js-compat@npm:3.38.1" dependencies: - browserslist: ^4.22.1 - checksum: 83ae54008c09b8e0ae3c59457039866c342c7e28b0d30eebb638a5b51c01432e63fe97695c90645cbc6a8b073a4f9a8b0e75f0818bbf8b4b054e01f4c17d3181 + browserslist: ^4.23.3 + checksum: a0a5673bcd59f588f0cd0b59cdacd4712b82909738a87406d334dd412eb3d273ae72b275bdd8e8fef63fca9ef12b42ed651be139c7c44c8a1acb423c8906992e languageName: node linkType: hard @@ -4645,20 +4687,7 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^7.0.1": - version: 7.1.0 - resolution: "cosmiconfig@npm:7.1.0" - dependencies: - "@types/parse-json": ^4.0.0 - import-fresh: ^3.2.1 - parse-json: ^5.0.0 - path-type: ^4.0.0 - yaml: ^1.10.0 - checksum: c53bf7befc1591b2651a22414a5e786cd5f2eeaa87f3678a3d49d6069835a9d8d1aef223728e98aa8fec9a95bf831120d245096db12abe019fecb51f5696c96f - languageName: node - linkType: hard - -"cosmiconfig@npm:^8.2.0": +"cosmiconfig@npm:^8.1.3, cosmiconfig@npm:^8.2.0": version: 8.3.6 resolution: "cosmiconfig@npm:8.3.6" dependencies: @@ -4695,12 +4724,12 @@ __metadata: languageName: node linkType: hard -"css-declaration-sorter@npm:^6.3.1": - version: 6.3.1 - resolution: "css-declaration-sorter@npm:6.3.1" +"css-declaration-sorter@npm:^7.2.0": + version: 7.2.0 + resolution: "css-declaration-sorter@npm:7.2.0" peerDependencies: postcss: ^8.0.9 - checksum: ff0d9989ee21ec4c42430b9bb86c43f973ed5024d68f30edc1e3fb07a22828ce3c3e5b922019f2ccbff606722e43c407c5c76e3cddac523ac4afcb31e4b2601c + checksum: 69b2f63a1c7c593123fabcbb353618ed01eb75f6404da9321328fbb30d603d89c47195129fadf1dc316e1406a0881400b324c2bded9438c47196e1c96ec726dd languageName: node linkType: hard @@ -4722,16 +4751,16 @@ __metadata: languageName: node linkType: hard -"css-minimizer-webpack-plugin@npm:^4.2.2": - version: 4.2.2 - resolution: "css-minimizer-webpack-plugin@npm:4.2.2" +"css-minimizer-webpack-plugin@npm:^5.0.1": + version: 5.0.1 + resolution: "css-minimizer-webpack-plugin@npm:5.0.1" dependencies: - cssnano: ^5.1.8 - jest-worker: ^29.1.2 - postcss: ^8.4.17 - schema-utils: ^4.0.0 - serialize-javascript: ^6.0.0 - source-map: ^0.6.1 + "@jridgewell/trace-mapping": ^0.3.18 + cssnano: ^6.0.1 + jest-worker: ^29.4.3 + postcss: ^8.4.24 + schema-utils: ^4.0.1 + serialize-javascript: ^6.0.1 peerDependencies: webpack: ^5.0.0 peerDependenciesMeta: @@ -4747,7 +4776,7 @@ __metadata: optional: true lightningcss: optional: true - checksum: 5417e76a445f35832aa96807c835b8e92834a6cd285b1b788dfe3ca0fa90fec7eb2dd6efa9d3649f9d8244b99b7da2d065951603b94918e8f6a366a5049cacdd + checksum: 10055802c61d1ae72584eac03b6bd221ecbefde11d337be44a5459d8de075b38f91b80949f95cd0c3a10295615ee013f82130bfac5fe9b5b3e8e75531f232680 languageName: node linkType: hard @@ -4777,13 +4806,23 @@ __metadata: languageName: node linkType: hard -"css-tree@npm:^1.1.2, css-tree@npm:^1.1.3": - version: 1.1.3 - resolution: "css-tree@npm:1.1.3" +"css-tree@npm:^2.3.1": + version: 2.3.1 + resolution: "css-tree@npm:2.3.1" dependencies: - mdn-data: 2.0.14 - source-map: ^0.6.1 - checksum: 79f9b81803991b6977b7fcb1588799270438274d89066ce08f117f5cdb5e20019b446d766c61506dd772c839df84caa16042d6076f20c97187f5abe3b50e7d1f + mdn-data: 2.0.30 + source-map-js: ^1.0.1 + checksum: 493cc24b5c22b05ee5314b8a0d72d8a5869491c1458017ae5ed75aeb6c3596637dbe1b11dac2548974624adec9f7a1f3a6cf40593dc1f9185eb0e8279543fbc0 + languageName: node + linkType: hard + +"css-tree@npm:~2.2.0": + version: 2.2.1 + resolution: "css-tree@npm:2.2.1" + dependencies: + mdn-data: 2.0.28 + source-map-js: ^1.0.1 + checksum: b94aa8cc2f09e6f66c91548411fcf74badcbad3e150345074715012d16333ce573596ff5dfca03c2a87edf1924716db765120f94247e919d72753628ba3aba27 languageName: node linkType: hard @@ -4803,89 +4842,90 @@ __metadata: languageName: node linkType: hard -"cssnano-preset-advanced@npm:^5.3.10": - version: 5.3.10 - resolution: "cssnano-preset-advanced@npm:5.3.10" +"cssnano-preset-advanced@npm:^6.1.2": + version: 6.1.2 + resolution: "cssnano-preset-advanced@npm:6.1.2" dependencies: - autoprefixer: ^10.4.12 - cssnano-preset-default: ^5.2.14 - postcss-discard-unused: ^5.1.0 - postcss-merge-idents: ^5.1.1 - postcss-reduce-idents: ^5.2.0 - postcss-zindex: ^5.1.0 + autoprefixer: ^10.4.19 + browserslist: ^4.23.0 + cssnano-preset-default: ^6.1.2 + postcss-discard-unused: ^6.0.5 + postcss-merge-idents: ^6.0.3 + postcss-reduce-idents: ^6.0.3 + postcss-zindex: ^6.0.2 peerDependencies: - postcss: ^8.2.15 - checksum: d21cb382aea2f35c9eaa50686280bbd5158260edf73020731364b03bae0d887292da51ed0b20b369f51d2573ee8c02c695f604647b839a9ca746be8a44c3bb5b + postcss: ^8.4.31 + checksum: cf70e27915947412730abb3075587efb66bcea58d7f1b906a7225bb4a40c9ca40150251a2ac33363d4f55bbdeb9ba000c242fa6244ee36cba2477ac07fbbe791 languageName: node linkType: hard -"cssnano-preset-default@npm:^5.2.14": - version: 5.2.14 - resolution: "cssnano-preset-default@npm:5.2.14" +"cssnano-preset-default@npm:^6.1.2": + version: 6.1.2 + resolution: "cssnano-preset-default@npm:6.1.2" dependencies: - css-declaration-sorter: ^6.3.1 - cssnano-utils: ^3.1.0 - postcss-calc: ^8.2.3 - postcss-colormin: ^5.3.1 - postcss-convert-values: ^5.1.3 - postcss-discard-comments: ^5.1.2 - postcss-discard-duplicates: ^5.1.0 - postcss-discard-empty: ^5.1.1 - postcss-discard-overridden: ^5.1.0 - postcss-merge-longhand: ^5.1.7 - postcss-merge-rules: ^5.1.4 - postcss-minify-font-values: ^5.1.0 - postcss-minify-gradients: ^5.1.1 - postcss-minify-params: ^5.1.4 - postcss-minify-selectors: ^5.2.1 - postcss-normalize-charset: ^5.1.0 - postcss-normalize-display-values: ^5.1.0 - postcss-normalize-positions: ^5.1.1 - postcss-normalize-repeat-style: ^5.1.1 - postcss-normalize-string: ^5.1.0 - postcss-normalize-timing-functions: ^5.1.0 - postcss-normalize-unicode: ^5.1.1 - postcss-normalize-url: ^5.1.0 - postcss-normalize-whitespace: ^5.1.1 - postcss-ordered-values: ^5.1.3 - postcss-reduce-initial: ^5.1.2 - postcss-reduce-transforms: ^5.1.0 - postcss-svgo: ^5.1.0 - postcss-unique-selectors: ^5.1.1 + browserslist: ^4.23.0 + css-declaration-sorter: ^7.2.0 + cssnano-utils: ^4.0.2 + postcss-calc: ^9.0.1 + postcss-colormin: ^6.1.0 + postcss-convert-values: ^6.1.0 + postcss-discard-comments: ^6.0.2 + postcss-discard-duplicates: ^6.0.3 + postcss-discard-empty: ^6.0.3 + postcss-discard-overridden: ^6.0.2 + postcss-merge-longhand: ^6.0.5 + postcss-merge-rules: ^6.1.1 + postcss-minify-font-values: ^6.1.0 + postcss-minify-gradients: ^6.0.3 + postcss-minify-params: ^6.1.0 + postcss-minify-selectors: ^6.0.4 + postcss-normalize-charset: ^6.0.2 + postcss-normalize-display-values: ^6.0.2 + postcss-normalize-positions: ^6.0.2 + postcss-normalize-repeat-style: ^6.0.2 + postcss-normalize-string: ^6.0.2 + postcss-normalize-timing-functions: ^6.0.2 + postcss-normalize-unicode: ^6.1.0 + postcss-normalize-url: ^6.0.2 + postcss-normalize-whitespace: ^6.0.2 + postcss-ordered-values: ^6.0.2 + postcss-reduce-initial: ^6.1.0 + postcss-reduce-transforms: ^6.0.2 + postcss-svgo: ^6.0.3 + postcss-unique-selectors: ^6.0.4 peerDependencies: - postcss: ^8.2.15 - checksum: d3bbbe3d50c6174afb28d0bdb65b511fdab33952ec84810aef58b87189f3891c34aaa8b6a6101acd5314f8acded839b43513e39a75f91a698ddc985a1b1d9e95 + postcss: ^8.4.31 + checksum: 51d93e52df7141143947dc4695b5087c04b41ea153e4f4c0282ac012b62c7457c6aca244f604ae94fa3b4840903a30a1e7df38f8610e0b304d05e3065375ee56 languageName: node linkType: hard -"cssnano-utils@npm:^3.1.0": - version: 3.1.0 - resolution: "cssnano-utils@npm:3.1.0" +"cssnano-utils@npm:^4.0.2": + version: 4.0.2 + resolution: "cssnano-utils@npm:4.0.2" peerDependencies: - postcss: ^8.2.15 - checksum: 975c84ce9174cf23bb1da1e9faed8421954607e9ea76440cd3bb0c1bea7e17e490d800fca5ae2812d1d9e9d5524eef23ede0a3f52497d7ccc628e5d7321536f2 + postcss: ^8.4.31 + checksum: f04c6854e75d847c7a43aff835e003d5bc7387ddfc476f0ad3a2d63663d0cec41047d46604c1717bf6b5a8e24e54bb519e465ff78d62c7e073c7cbe2279bebaf languageName: node linkType: hard -"cssnano@npm:^5.1.15, cssnano@npm:^5.1.8": - version: 5.1.15 - resolution: "cssnano@npm:5.1.15" +"cssnano@npm:^6.0.1, cssnano@npm:^6.1.2": + version: 6.1.2 + resolution: "cssnano@npm:6.1.2" dependencies: - cssnano-preset-default: ^5.2.14 - lilconfig: ^2.0.3 - yaml: ^1.10.2 + cssnano-preset-default: ^6.1.2 + lilconfig: ^3.1.1 peerDependencies: - postcss: ^8.2.15 - checksum: ca9e1922178617c66c2f1548824b2c7af2ecf69cc3a187fc96bf8d29251c2e84d9e4966c69cf64a2a6a057a37dff7d6d057bc8a2a0957e6ea382e452ae9d0bbb + postcss: ^8.4.31 + checksum: 65aad92c5ee0089ffd4cd933c18c65edbf7634f7c3cd833a499dc948aa7e4168be22130dfe83bde07fcdc87f7c45a02d09040b7f439498208bc90b8d5a9abcc8 languageName: node linkType: hard -"csso@npm:^4.2.0": - version: 4.2.0 - resolution: "csso@npm:4.2.0" +"csso@npm:^5.0.5": + version: 5.0.5 + resolution: "csso@npm:5.0.5" dependencies: - css-tree: ^1.1.2 - checksum: 380ba9663da3bcea58dee358a0d8c4468bb6539be3c439dc266ac41c047217f52fd698fb7e4b6b6ccdfb8cf53ef4ceed8cc8ceccb8dfca2aa628319826b5b998 + css-tree: ~2.2.0 + checksum: 0ad858d36bf5012ed243e9ec69962a867509061986d2ee07cc040a4b26e4d062c00d4c07e5ba8d430706ceb02dd87edd30a52b5937fd45b1b6f2119c4993d59a languageName: node linkType: hard @@ -4942,10 +4982,10 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^4.2.2": - version: 4.2.2 - resolution: "deepmerge@npm:4.2.2" - checksum: a8c43a1ed8d6d1ed2b5bf569fa4c8eb9f0924034baf75d5d406e47e157a451075c4db353efea7b6bcc56ec48116a8ce72fccf867b6e078e7c561904b5897530b +"deepmerge@npm:^4.2.2, deepmerge@npm:^4.3.1": + version: 4.3.1 + resolution: "deepmerge@npm:4.3.1" + checksum: 2024c6a980a1b7128084170c4cf56b0fd58a63f2da1660dcfe977415f27b17dbe5888668b59d0b063753f3220719d5e400b7f113609489c90160bb9a5518d052 languageName: node linkType: hard @@ -5239,10 +5279,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.648": - version: 1.4.665 - resolution: "electron-to-chromium@npm:1.4.665" - checksum: 6c863300909a2712a79bd8a00ff2d3747fb72edf3dfda892449aabd42a12448e8e215e318d628421bbdfc7e4e3bc1fb38a81bbd530a71036bb86a75868e9eb8a +"electron-to-chromium@npm:^1.5.4": + version: 1.5.13 + resolution: "electron-to-chromium@npm:1.5.13" + checksum: f18ac84dd3bf9a200654a6a9292b9ec4bced0cf9bd26cec9941b775f4470c581c9d043e70b37a124d9752dcc0f47fc96613d52b2defd8e59632852730cb418b9 languageName: node linkType: hard @@ -5351,10 +5391,10 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.1.1": - version: 3.1.1 - resolution: "escalade@npm:3.1.1" - checksum: a3e2a99f07acb74b3ad4989c48ca0c3140f69f923e56d0cba0526240ee470b91010f9d39001f2a4a313841d237ede70a729e92125191ba5d21e74b106800b133 +"escalade@npm:^3.1.1, escalade@npm:^3.1.2": + version: 3.1.2 + resolution: "escalade@npm:3.1.2" + checksum: 1ec0977aa2772075493002bdbd549d595ff6e9393b1cb0d7d6fcaf78c750da0c158f180938365486f75cb69fba20294351caddfce1b46552a7b6c3cde52eaa02 languageName: node linkType: hard @@ -5648,6 +5688,13 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.0.1 + resolution: "fast-uri@npm:3.0.1" + checksum: 106143ff83705995225dcc559411288f3337e732bb2e264e79788f1914b6bd8f8bc3683102de60b15ba00e6ebb443633cabac77d4ebc5cb228c47cf955e199ff + languageName: node + linkType: hard + "fast-url-parser@npm:1.1.3": version: 1.1.3 resolution: "fast-url-parser@npm:1.1.3" @@ -5837,10 +5884,10 @@ __metadata: languageName: node linkType: hard -"fraction.js@npm:^4.3.6": - version: 4.3.6 - resolution: "fraction.js@npm:4.3.6" - checksum: e96ae77e64ebfd442d3a5a01a3f0637b0663fc2440bcf2841b3ad9341ba24c81fb2e3e7142e43ef7d088558c6b3f8609df135b201adc7a1c674aea6a71384162 +"fraction.js@npm:^4.3.7": + version: 4.3.7 + resolution: "fraction.js@npm:4.3.7" + checksum: e1553ae3f08e3ba0e8c06e43a3ab20b319966dfb7ddb96fd9b5d0ee11a66571af7f993229c88ebbb0d4a816eb813a24ed48207b140d442a8f76f33763b8d1f3f languageName: node linkType: hard @@ -5851,14 +5898,14 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^11.1.1": - version: 11.1.1 - resolution: "fs-extra@npm:11.1.1" +"fs-extra@npm:^11.1.1, fs-extra@npm:^11.2.0": + version: 11.2.0 + resolution: "fs-extra@npm:11.2.0" dependencies: graceful-fs: ^4.2.0 jsonfile: ^6.0.1 universalify: ^2.0.0 - checksum: fb883c68245b2d777fbc1f2082c9efb084eaa2bbf9fddaa366130d196c03608eebef7fb490541276429ee1ca99f317e2d73e96f5ca0999eefedf5a624ae1edfd + checksum: b12e42fa40ba47104202f57b8480dd098aa931c2724565e5e70779ab87605665594e76ee5fb00545f772ab9ace167fe06d2ab009c416dc8c842c5ae6df7aa7e8 languageName: node linkType: hard @@ -6649,7 +6696,7 @@ __metadata: languageName: node linkType: hard -"import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": +"import-fresh@npm:^3.1.0, import-fresh@npm:^3.3.0": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" dependencies: @@ -6687,10 +6734,10 @@ __metadata: languageName: node linkType: hard -"infima@npm:0.2.0-alpha.43": - version: 0.2.0-alpha.43 - resolution: "infima@npm:0.2.0-alpha.43" - checksum: fc5f79240e940eddd750439511767092ccb4051e5e91d253ec7630a9e7ce691812da3aa0f05e46b4c0a95dbfadeae5714fd0073f8d2df12e5aaff0697a1d6aa2 +"infima@npm:0.2.0-alpha.44": + version: 0.2.0-alpha.44 + resolution: "infima@npm:0.2.0-alpha.44" + checksum: e9871f4056c0c8b311fcd32e2864d23a8f6807af5ff32d3c4d8271ad9971b5a7ea5016787a6b215893bb3e9f5f14326816bc05151d576dd375b0d79279cdfa8b languageName: node linkType: hard @@ -7066,17 +7113,17 @@ __metadata: languageName: node linkType: hard -"jest-util@npm:^29.3.1": - version: 29.3.1 - resolution: "jest-util@npm:29.3.1" +"jest-util@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-util@npm:29.7.0" dependencies: - "@jest/types": ^29.3.1 + "@jest/types": ^29.6.3 "@types/node": "*" chalk: ^4.0.0 ci-info: ^3.2.0 graceful-fs: ^4.2.9 picomatch: ^2.2.3 - checksum: f67c60f062b94d21cb60e84b3b812d64b7bfa81fe980151de5c17a74eb666042d0134e2e756d099b7606a1fcf1d633824d2e58197d01d76dde1e2dc00dfcd413 + checksum: 042ab4980f4ccd4d50226e01e5c7376a8556b472442ca6091a8f102488c0f22e6e8b89ea874111d2328a2080083bf3225c86f3788c52af0bd0345a00eb57a3ca languageName: node linkType: hard @@ -7091,15 +7138,15 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^29.1.2": - version: 29.3.1 - resolution: "jest-worker@npm:29.3.1" +"jest-worker@npm:^29.4.3": + version: 29.7.0 + resolution: "jest-worker@npm:29.7.0" dependencies: "@types/node": "*" - jest-util: ^29.3.1 + jest-util: ^29.7.0 merge-stream: ^2.0.0 supports-color: ^8.0.0 - checksum: 38687fcbdc2b7ddc70bbb5dfc703ae095b46b3c7f206d62ecdf5f4d16e336178e217302138f3b906125576bb1cfe4cfe8d43681276fa5899d138ed9422099fb3 + checksum: 30fff60af49675273644d408b650fc2eb4b5dcafc5a0a455f238322a8f9d8a98d847baca9d51ff197b6747f54c7901daa2287799230b856a0f48287d131f8c13 languageName: node linkType: hard @@ -7279,10 +7326,10 @@ __metadata: languageName: node linkType: hard -"lilconfig@npm:^2.0.3": - version: 2.0.6 - resolution: "lilconfig@npm:2.0.6" - checksum: 40a3cd72f103b1be5975f2ac1850810b61d4053e20ab09be8d3aeddfe042187e1ba70b4651a7e70f95efa1642e7dc8b2ae395b317b7d7753b241b43cef7c0f7d +"lilconfig@npm:^3.1.1": + version: 3.1.2 + resolution: "lilconfig@npm:3.1.2" + checksum: 4e8b83ddd1d0ad722600994e6ba5d858ddca14f0587aa6b9c8185e17548149b5e13d4d583d811e9e9323157fa8c6a527e827739794c7502b59243c58e210b8c3 languageName: node linkType: hard @@ -7469,9 +7516,9 @@ __metadata: linkType: hard "luxon@npm:^3.0.0": - version: 3.4.4 - resolution: "luxon@npm:3.4.4" - checksum: 36c1f99c4796ee4bfddf7dc94fa87815add43ebc44c8934c924946260a58512f0fd2743a629302885df7f35ccbd2d13f178c15df046d0e3b6eb71db178f1c60c + version: 3.5.0 + resolution: "luxon@npm:3.5.0" + checksum: f290fe5788c8e51e748744f05092160d4be12150dca70f9fadc0d233e53d60ce86acd82e7d909a114730a136a77e56f0d3ebac6141bbb82fd310969a4704825b languageName: node linkType: hard @@ -7766,10 +7813,17 @@ __metadata: languageName: node linkType: hard -"mdn-data@npm:2.0.14": - version: 2.0.14 - resolution: "mdn-data@npm:2.0.14" - checksum: 9d0128ed425a89f4cba8f787dca27ad9408b5cb1b220af2d938e2a0629d17d879a34d2cb19318bdb26c3f14c77dd5dfbae67211f5caaf07b61b1f2c5c8c7dc16 +"mdn-data@npm:2.0.28": + version: 2.0.28 + resolution: "mdn-data@npm:2.0.28" + checksum: f51d587a6ebe8e426c3376c74ea6df3e19ec8241ed8e2466c9c8a3904d5d04397199ea4f15b8d34d14524b5de926d8724ae85207984be47e165817c26e49e0aa + languageName: node + linkType: hard + +"mdn-data@npm:2.0.30": + version: 2.0.30 + resolution: "mdn-data@npm:2.0.30" + checksum: d6ac5ac7439a1607df44b22738ecf83f48e66a0874e4482d6424a61c52da5cde5750f1d1229b6f5fa1b80a492be89465390da685b11f97d62b8adcc6e88189aa languageName: node linkType: hard @@ -8316,12 +8370,12 @@ __metadata: linkType: hard "micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": - version: 4.0.5 - resolution: "micromatch@npm:4.0.5" + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" dependencies: - braces: ^3.0.2 + braces: ^3.0.3 picomatch: ^2.3.1 - checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc + checksum: 79920eb634e6f400b464a954fcfa589c4e7c7143209488e44baf627f9affc8b1e306f41f4f0deedde97e69cb725920879462d3e750ab3bd3c1aed675bb3a8966 languageName: node linkType: hard @@ -8556,12 +8610,12 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.6": - version: 3.3.6 - resolution: "nanoid@npm:3.3.6" +"nanoid@npm:^3.3.7": + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" bin: nanoid: bin/nanoid.cjs - checksum: 7d0eda657002738aa5206107bd0580aead6c95c460ef1bdd0b1a87a9c7ae6277ac2e9b945306aaa5b32c6dcb7feaf462d0f552e7f8b5718abfc6ead5c94a71b3 + checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2 languageName: node linkType: hard @@ -8628,10 +8682,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.14": - version: 2.0.14 - resolution: "node-releases@npm:2.0.14" - checksum: 59443a2f77acac854c42d321bf1b43dea0aef55cd544c6a686e9816a697300458d4e82239e2d794ea05f7bbbc8a94500332e2d3ac3f11f52e4b16cbe638b3c41 +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: ef55a3d853e1269a6d6279b7692cd6ff3e40bc74947945101138745bfdc9a5edabfe72cb19a31a8e45752e1910c4c65c77d931866af6357f242b172b7283f5b3 languageName: node linkType: hard @@ -8660,13 +8714,6 @@ __metadata: languageName: node linkType: hard -"normalize-url@npm:^6.0.1": - version: 6.1.0 - resolution: "normalize-url@npm:6.1.0" - checksum: 4a4944631173e7d521d6b80e4c85ccaeceb2870f315584fa30121f505a6dfd86439c5e3fdd8cd9e0e291290c41d0c3599f0cb12ab356722ed242584c30348e50 - languageName: node - linkType: hard - "normalize-url@npm:^8.0.0": version: 8.0.0 resolution: "normalize-url@npm:8.0.0" @@ -9084,10 +9131,10 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0": - version: 1.0.0 - resolution: "picocolors@npm:1.0.0" - checksum: a2e8092dd86c8396bdba9f2b5481032848525b3dc295ce9b57896f931e63fc16f79805144321f72976383fc249584672a75cc18d6777c6b757603f372f745981 +"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1": + version: 1.0.1 + resolution: "picocolors@npm:1.0.1" + checksum: fa68166d1f56009fc02a34cdfd112b0dd3cf1ef57667ac57281f714065558c01828cdf4f18600ad6851cbe0093952ed0660b1e0156bddf2184b6aaf5817553a5 languageName: node linkType: hard @@ -9116,88 +9163,88 @@ __metadata: languageName: node linkType: hard -"postcss-calc@npm:^8.2.3": - version: 8.2.4 - resolution: "postcss-calc@npm:8.2.4" +"postcss-calc@npm:^9.0.1": + version: 9.0.1 + resolution: "postcss-calc@npm:9.0.1" dependencies: - postcss-selector-parser: ^6.0.9 + postcss-selector-parser: ^6.0.11 postcss-value-parser: ^4.2.0 peerDependencies: postcss: ^8.2.2 - checksum: 314b4cebb0c4ed0cf8356b4bce71eca78f5a7842e6a3942a3bba49db168d5296b2bd93c3f735ae1c616f2651d94719ade33becc03c73d2d79c7394fb7f73eabb + checksum: 7327ed83bfec544ab8b3e38353baa72ff6d04378b856db4ad82dbd68ce0b73668867ef182b5d4025f9dd9aa9c64aacc50cd1bd9db8d8b51ccc4cb97866b9d72b languageName: node linkType: hard -"postcss-colormin@npm:^5.3.1": - version: 5.3.1 - resolution: "postcss-colormin@npm:5.3.1" +"postcss-colormin@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-colormin@npm:6.1.0" dependencies: - browserslist: ^4.21.4 + browserslist: ^4.23.0 caniuse-api: ^3.0.0 - colord: ^2.9.1 + colord: ^2.9.3 postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: e5778baab30877cd1f51e7dc9d2242a162aeca6360a52956acd7f668c5bc235c2ccb7e4df0370a804d65ebe00c5642366f061db53aa823f9ed99972cebd16024 + postcss: ^8.4.31 + checksum: 55a1525de345d953bc7f32ecaa5ee6275ef0277c27d1f97ff06a1bd1a2fedf7f254e36dc1500621f1df20c25a6d2485a74a0b527d8ff74eb90726c76efe2ac8e languageName: node linkType: hard -"postcss-convert-values@npm:^5.1.3": - version: 5.1.3 - resolution: "postcss-convert-values@npm:5.1.3" +"postcss-convert-values@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-convert-values@npm:6.1.0" dependencies: - browserslist: ^4.21.4 + browserslist: ^4.23.0 postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: df48cdaffabf9737f9cfdc58a3dc2841cf282506a7a944f6c70236cff295d3a69f63de6e0935eeb8a9d3f504324e5b4e240abc29e21df9e35a02585d3060aeb5 + postcss: ^8.4.31 + checksum: 43e9f66af9bdec3c76695f9dde36885abc01f662c370c490b45d895459caab2c5792f906f3ddad107129133e41485a65634da7f699eef916a636e47f6a37a299 languageName: node linkType: hard -"postcss-discard-comments@npm:^5.1.2": - version: 5.1.2 - resolution: "postcss-discard-comments@npm:5.1.2" +"postcss-discard-comments@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-discard-comments@npm:6.0.2" peerDependencies: - postcss: ^8.2.15 - checksum: abfd064ebc27aeaf5037643dd51ffaff74d1fa4db56b0523d073ace4248cbb64ffd9787bd6924b0983a9d0bd0e9bf9f10d73b120e50391dc236e0d26c812fa2a + postcss: ^8.4.31 + checksum: c1731ccc8d1e3d910412a61395988d3033365e6532d9e5432ad7c74add8c9dcb0af0c03d4e901bf0d2b59ea4e7297a0c77a547ff2ed1b1cc065559cc0de43b4e languageName: node linkType: hard -"postcss-discard-duplicates@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-discard-duplicates@npm:5.1.0" +"postcss-discard-duplicates@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-discard-duplicates@npm:6.0.3" peerDependencies: - postcss: ^8.2.15 - checksum: 88d6964201b1f4ed6bf7a32cefe68e86258bb6e42316ca01d9b32bdb18e7887d02594f89f4a2711d01b51ea6e3fcca8c54be18a59770fe5f4521c61d3eb6ca35 + postcss: ^8.4.31 + checksum: 308e3fb84c35e4703532de1efa5d6e8444cc5f167d0e40f42d7ea3fa3a37d9d636fd10729847d078e0c303eee16f8548d14b6f88a3fce4e38a2b452648465175 languageName: node linkType: hard -"postcss-discard-empty@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-discard-empty@npm:5.1.1" +"postcss-discard-empty@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-discard-empty@npm:6.0.3" peerDependencies: - postcss: ^8.2.15 - checksum: 970adb12fae5c214c0768236ad9a821552626e77dedbf24a8213d19cc2c4a531a757cd3b8cdd3fc22fb1742471b8692a1db5efe436a71236dec12b1318ee8ff4 + postcss: ^8.4.31 + checksum: bad305572faa066026a295faab37e718cee096589ab827b19c990c55620b2b2a1ce9f0145212651737a66086db01b2676c1927bbb8408c5f9cb42686d5959f00 languageName: node linkType: hard -"postcss-discard-overridden@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-discard-overridden@npm:5.1.0" +"postcss-discard-overridden@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-discard-overridden@npm:6.0.2" peerDependencies: - postcss: ^8.2.15 - checksum: d64d4a545aa2c81b22542895cfcddc787d24119f294d35d29b0599a1c818b3cc51f4ee80b80f5a0a09db282453dd5ac49f104c2117cc09112d0ac9b40b499a41 + postcss: ^8.4.31 + checksum: a38e0fe7a36f83cb9b73c1ba9ee2a48cf93c69ec0ea5753935824ffb71e958e58ae0393171c0f3d0014a397469d09bbb0d56bb5ab80f0280722967e2e273aebb languageName: node linkType: hard -"postcss-discard-unused@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-discard-unused@npm:5.1.0" +"postcss-discard-unused@npm:^6.0.5": + version: 6.0.5 + resolution: "postcss-discard-unused@npm:6.0.5" dependencies: - postcss-selector-parser: ^6.0.5 + postcss-selector-parser: ^6.0.16 peerDependencies: - postcss: ^8.2.15 - checksum: 5c09403a342a065033f5f22cefe6b402c76c2dc0aac31a736a2062d82c2a09f0ff2525b3df3a0c6f4e0ffc7a0392efd44bfe7f9d018e4cae30d15b818b216622 + postcss: ^8.4.31 + checksum: 7962640773240186de38125f142a6555b7f9b2493c4968e0f0b11c6629b2bf43ac70b9fc4ee78aa732d82670ad8bf802b2febc9a9864b022eb68530eded26836 languageName: node linkType: hard @@ -9215,89 +9262,89 @@ __metadata: languageName: node linkType: hard -"postcss-merge-idents@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-merge-idents@npm:5.1.1" +"postcss-merge-idents@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-merge-idents@npm:6.0.3" dependencies: - cssnano-utils: ^3.1.0 + cssnano-utils: ^4.0.2 postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: ed8a673617ea6ae3e15d69558063cb1a5eeee01732f78cdc0196ab910324abc30828724ab8dfc4cda27e8c0077542e25688470f829819a2604625a673387ec72 + postcss: ^8.4.31 + checksum: b45780d6d103b8e45a580032747ee6e1842f81863672341a6b4961397e243ca896217bf1f3ee732376a766207d5f610ba8924cf08cf6d5bbd4b093133fd05d70 languageName: node linkType: hard -"postcss-merge-longhand@npm:^5.1.7": - version: 5.1.7 - resolution: "postcss-merge-longhand@npm:5.1.7" +"postcss-merge-longhand@npm:^6.0.5": + version: 6.0.5 + resolution: "postcss-merge-longhand@npm:6.0.5" dependencies: postcss-value-parser: ^4.2.0 - stylehacks: ^5.1.1 + stylehacks: ^6.1.1 peerDependencies: - postcss: ^8.2.15 - checksum: 81c3fc809f001b9b71a940148e242bdd6e2d77713d1bfffa15eb25c1f06f6648d5e57cb21645746d020a2a55ff31e1740d2b27900442913a9d53d8a01fb37e1b + postcss: ^8.4.31 + checksum: 9ae5acf47dc0c1f494684ae55672d55bba7f5ee11c9c0f266aabd7c798e9f7394c6096363cd95685fd21ef088740389121a317772cf523ca22c915009bca2617 languageName: node linkType: hard -"postcss-merge-rules@npm:^5.1.4": - version: 5.1.4 - resolution: "postcss-merge-rules@npm:5.1.4" +"postcss-merge-rules@npm:^6.1.1": + version: 6.1.1 + resolution: "postcss-merge-rules@npm:6.1.1" dependencies: - browserslist: ^4.21.4 + browserslist: ^4.23.0 caniuse-api: ^3.0.0 - cssnano-utils: ^3.1.0 - postcss-selector-parser: ^6.0.5 + cssnano-utils: ^4.0.2 + postcss-selector-parser: ^6.0.16 peerDependencies: - postcss: ^8.2.15 - checksum: 8ab6a569babe6cb412d6612adee74f053cea7edb91fa013398515ab36754b1fec830d68782ed8cdfb44cffdc6b78c79eab157bff650f428aa4460d3f3857447e + postcss: ^8.4.31 + checksum: 43f60a1c88806491cf752ae7871676de0e7a2a9d6d2fc6bc894068cc35a910a63d30f7c7d79545e0926c8b3a9ec583e5e8357203c40b5bad5ff58133b0c900f6 languageName: node linkType: hard -"postcss-minify-font-values@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-minify-font-values@npm:5.1.0" +"postcss-minify-font-values@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-minify-font-values@npm:6.1.0" dependencies: postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: 35e858fa41efa05acdeb28f1c76579c409fdc7eabb1744c3bd76e895bb9fea341a016746362a67609688ab2471f587202b9a3e14ea28ad677754d663a2777ece + postcss: ^8.4.31 + checksum: 985e4dd2f89220a4442a822aad7dff016ab58a9dbb7bbca9d01c2d07d5a1e7d8c02e1c6e836abb4c9b4e825b4b80d99ee1f5899e74bf0d969095037738e6e452 languageName: node linkType: hard -"postcss-minify-gradients@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-minify-gradients@npm:5.1.1" +"postcss-minify-gradients@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-minify-gradients@npm:6.0.3" dependencies: - colord: ^2.9.1 - cssnano-utils: ^3.1.0 + colord: ^2.9.3 + cssnano-utils: ^4.0.2 postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: 27354072a07c5e6dab36731103b94ca2354d4ed3c5bc6aacfdf2ede5a55fa324679d8fee5450800bc50888dbb5e9ed67569c0012040c2be128143d0cebb36d67 + postcss: ^8.4.31 + checksum: 89b95088c3830f829f6d4636d1be4d4f13300bf9f1577c48c25169c81e11ec0026760b9abb32112b95d2c622f09d3b737f4d2975a7842927ccb567e1002ef7b3 languageName: node linkType: hard -"postcss-minify-params@npm:^5.1.4": - version: 5.1.4 - resolution: "postcss-minify-params@npm:5.1.4" +"postcss-minify-params@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-minify-params@npm:6.1.0" dependencies: - browserslist: ^4.21.4 - cssnano-utils: ^3.1.0 + browserslist: ^4.23.0 + cssnano-utils: ^4.0.2 postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: bd63e2cc89edcf357bb5c2a16035f6d02ef676b8cede4213b2bddd42626b3d428403849188f95576fc9f03e43ebd73a29bf61d33a581be9a510b13b7f7f100d5 + postcss: ^8.4.31 + checksum: 1e1cc3057d9bcc532c70e40628e96e3aea0081d8072dffe983a270a8cd59c03ac585e57d036b70e43d4ee725f274a05a6a8efac5a715f448284e115c13f82a46 languageName: node linkType: hard -"postcss-minify-selectors@npm:^5.2.1": - version: 5.2.1 - resolution: "postcss-minify-selectors@npm:5.2.1" +"postcss-minify-selectors@npm:^6.0.4": + version: 6.0.4 + resolution: "postcss-minify-selectors@npm:6.0.4" dependencies: - postcss-selector-parser: ^6.0.5 + postcss-selector-parser: ^6.0.16 peerDependencies: - postcss: ^8.2.15 - checksum: 6fdbc84f99a60d56b43df8930707da397775e4c36062a106aea2fd2ac81b5e24e584a1892f4baa4469fa495cb87d1422560eaa8f6c9d500f9f0b691a5f95bab5 + postcss: ^8.4.31 + checksum: 150221a84422ca7627c67ee691ee51e0fe2c3583c8108801e9fc93d3be8b538c2eb04fcfdc908270d7eeaeaf01594a20b81311690a873efccb8a23aeafe1c354 languageName: node linkType: hard @@ -9345,192 +9392,191 @@ __metadata: languageName: node linkType: hard -"postcss-normalize-charset@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-charset@npm:5.1.0" +"postcss-normalize-charset@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-charset@npm:6.0.2" peerDependencies: - postcss: ^8.2.15 - checksum: e79d92971fc05b8b3c9b72f3535a574e077d13c69bef68156a0965f397fdf157de670da72b797f57b0e3bac8f38155b5dd1735ecab143b9cc4032d72138193b4 + postcss: ^8.4.31 + checksum: 5b8aeb17d61578a8656571cd5d5eefa8d4ee7126a99a41fdd322078002a06f2ae96f649197b9c01067a5f3e38a2e4b03e0e3fda5a0ec9e3d7ad056211ce86156 languageName: node linkType: hard -"postcss-normalize-display-values@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-display-values@npm:5.1.0" +"postcss-normalize-display-values@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-display-values@npm:6.0.2" dependencies: postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: b6eb7b9b02c3bdd62bbc54e01e2b59733d73a1c156905d238e178762962efe0c6f5104544da39f32cade8a4fb40f10ff54b63a8ebfbdff51e8780afb9fbdcf86 + postcss: ^8.4.31 + checksum: da30a9394b0e4a269ccad8d240693a6cd564bcc60e24db67caee00f70ddfbc070ad76faed64c32e6eec9ed02e92565488b7879d4fd6c40d877c290eadbb0bb28 languageName: node linkType: hard -"postcss-normalize-positions@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-normalize-positions@npm:5.1.1" +"postcss-normalize-positions@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-positions@npm:6.0.2" dependencies: postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: d9afc233729c496463c7b1cdd06732469f401deb387484c3a2422125b46ec10b4af794c101f8c023af56f01970b72b535e88373b9058ecccbbf88db81662b3c4 + postcss: ^8.4.31 + checksum: 44fb77583fae4d71b76e38226cf770570876bcf5af6940dc9aeac7a7e2252896b361e0249044766cff8dad445f925378f06a005d6541597573c20e599a62b516 languageName: node linkType: hard -"postcss-normalize-repeat-style@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-normalize-repeat-style@npm:5.1.1" +"postcss-normalize-repeat-style@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-repeat-style@npm:6.0.2" dependencies: postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: 2c6ad2b0ae10a1fda156b948c34f78c8f1e185513593de4d7e2480973586675520edfec427645fa168c337b0a6b3ceca26f92b96149741ca98a9806dad30d534 + postcss: ^8.4.31 + checksum: bebdac63bec6777ead3e265fc12527b261cf8d0da1b7f0abb12bda86fd53b7058e4afe392210ac74dac012e413bb1c2a46a1138c89f82b8bf70b81711f620f8c languageName: node linkType: hard -"postcss-normalize-string@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-string@npm:5.1.0" +"postcss-normalize-string@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-string@npm:6.0.2" dependencies: postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: 6e549c6e5b2831e34c7bdd46d8419e2278f6af1d5eef6d26884a37c162844e60339340c57e5e06058cdbe32f27fc6258eef233e811ed2f71168ef2229c236ada + postcss: ^8.4.31 + checksum: 5e8e253c528b542accafc142846fb33643c342a787c86e5b68c6287c7d8f63c5ae7d4d3fc28e3daf80821cc26a91add135e58bdd62ff9c735fca65d994898c7d languageName: node linkType: hard -"postcss-normalize-timing-functions@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-timing-functions@npm:5.1.0" +"postcss-normalize-timing-functions@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-timing-functions@npm:6.0.2" dependencies: postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: da550f50e90b0b23e17b67449a7d1efd1aa68288e66d4aa7614ca6f5cc012896be1972b7168eee673d27da36504faccf7b9f835c0f7e81243f966a42c8c030aa + postcss: ^8.4.31 + checksum: 1970f5aad04be11f99d51c59e27debb6fd7b49d0fa4a8879062b42c82113f8e520a284448727add3b54de85deefb8bd5fe554f618406586e9ad8fc9d060609f1 languageName: node linkType: hard -"postcss-normalize-unicode@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-normalize-unicode@npm:5.1.1" +"postcss-normalize-unicode@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-normalize-unicode@npm:6.1.0" dependencies: - browserslist: ^4.21.4 + browserslist: ^4.23.0 postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: 4c24d26cc9f4b19a9397db4e71dd600dab690f1de8e14a3809e2aa1452dbc3791c208c38a6316bbc142f29e934fdf02858e68c94038c06174d78a4937e0f273c + postcss: ^8.4.31 + checksum: 69ef35d06242061f0c504c128b83752e0f8daa30ebb26734de7d090460910be0b2efd8b17b1d64c3c85b95831a041faad9ad0aaba80e239406a79cfad3d63568 languageName: node linkType: hard -"postcss-normalize-url@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-normalize-url@npm:5.1.0" - dependencies: - normalize-url: ^6.0.1 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 3bd4b3246d6600230bc827d1760b24cb3101827ec97570e3016cbe04dc0dd28f4dbe763245d1b9d476e182c843008fbea80823061f1d2219b96f0d5c724a24c0 - languageName: node - linkType: hard - -"postcss-normalize-whitespace@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-normalize-whitespace@npm:5.1.1" +"postcss-normalize-url@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-url@npm:6.0.2" dependencies: postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: 12d8fb6d1c1cba208cc08c1830959b7d7ad447c3f5581873f7e185f99a9a4230c43d3af21ca12c818e4690a5085a95b01635b762ad4a7bef69d642609b4c0e19 + postcss: ^8.4.31 + checksum: bef51a18bbfee4fbf0381fec3c91e6c0dace36fca053bbd5f228e653d2732b6df3985525d79c4f7fc89f840ed07eb6d226e9d7503ecdc6f16d6d80cacae9df33 languageName: node linkType: hard -"postcss-ordered-values@npm:^5.1.3": - version: 5.1.3 - resolution: "postcss-ordered-values@npm:5.1.3" - dependencies: - cssnano-utils: ^3.1.0 - postcss-value-parser: ^4.2.0 - peerDependencies: - postcss: ^8.2.15 - checksum: 6f3ca85b6ceffc68aadaf319d9ee4c5ac16d93195bf8cba2d1559b631555ad61941461cda6d3909faab86e52389846b2b36345cff8f0c3f4eb345b1b8efadcf9 - languageName: node - linkType: hard - -"postcss-reduce-idents@npm:^5.2.0": - version: 5.2.0 - resolution: "postcss-reduce-idents@npm:5.2.0" +"postcss-normalize-whitespace@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-normalize-whitespace@npm:6.0.2" dependencies: postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: f0d644c86e160dd36ee4dd924ab7d6feacac867c87702e2f98f96b409430a62de4fec2dfc3c8731bda4e14196e29a752b4558942f0af2a3e6cd7f1f4b173db8e + postcss: ^8.4.31 + checksum: 6081eb3a4b305749eec02c00a95c2d236336a77ee636bb1d939f18d5dfa5ba82b7cf7fa072e83f9133d0bc984276596af3fe468bdd67c742ce69e9c63dbc218d languageName: node linkType: hard -"postcss-reduce-initial@npm:^5.1.2": - version: 5.1.2 - resolution: "postcss-reduce-initial@npm:5.1.2" +"postcss-ordered-values@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-ordered-values@npm:6.0.2" dependencies: - browserslist: ^4.21.4 + cssnano-utils: ^4.0.2 + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: c3d96177b4ffa43754e835e30c40043cc75ab1e95eb6c55ac8723eb48c13a12e986250e63d96619bbbd1a098876a1c0c1b3b7a8e1de1108a009cf7aa0beac834 + languageName: node + linkType: hard + +"postcss-reduce-idents@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-reduce-idents@npm:6.0.3" + dependencies: + postcss-value-parser: ^4.2.0 + peerDependencies: + postcss: ^8.4.31 + checksum: 1feff316838f947386c908f50807cf1b9589fd09b8e8df633a01f2640af5492833cc892448938ceba10ab96826c44767b8f2e1569d587579423f2db81202f7c7 + languageName: node + linkType: hard + +"postcss-reduce-initial@npm:^6.1.0": + version: 6.1.0 + resolution: "postcss-reduce-initial@npm:6.1.0" + dependencies: + browserslist: ^4.23.0 caniuse-api: ^3.0.0 peerDependencies: - postcss: ^8.2.15 - checksum: 55db697f85231a81f1969d54c894e4773912d9ddb914f9b03d2e73abc4030f2e3bef4d7465756d0c1acfcc2c2d69974bfb50a972ab27546a7d68b5a4fc90282b + postcss: ^8.4.31 + checksum: 39e4034ffbf62a041b66944c5cebc4b17f656e76b97568f7f6230b0b886479e5c75b02ae4ba48c472cb0bde47489f9ed1fe6110ae8cff0d7b7165f53c2d64a12 languageName: node linkType: hard -"postcss-reduce-transforms@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-reduce-transforms@npm:5.1.0" +"postcss-reduce-transforms@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-reduce-transforms@npm:6.0.2" dependencies: postcss-value-parser: ^4.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: 0c6af2cba20e3ff63eb9ad045e634ddfb9c3e5c0e614c020db2a02f3aa20632318c4ede9e0c995f9225d9a101e673de91c0a6e10bb2fa5da6d6c75d15a55882f + postcss: ^8.4.31 + checksum: c424cc554eb5d253b7687b64925a13fc16759f058795d223854f5a20d9bca641b5f25d0559d03287e63f07a4629c24ac78156adcf604483fcad3c51721da0a08 languageName: node linkType: hard -"postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4, postcss-selector-parser@npm:^6.0.5, postcss-selector-parser@npm:^6.0.9": - version: 6.0.11 - resolution: "postcss-selector-parser@npm:6.0.11" +"postcss-selector-parser@npm:^6.0.11, postcss-selector-parser@npm:^6.0.16, postcss-selector-parser@npm:^6.0.2, postcss-selector-parser@npm:^6.0.4": + version: 6.1.2 + resolution: "postcss-selector-parser@npm:6.1.2" dependencies: cssesc: ^3.0.0 util-deprecate: ^1.0.2 - checksum: 0b01aa9c2d2c8dbeb51e9b204796b678284be9823abc8d6d40a8b16d4149514e922c264a8ed4deb4d6dbced564b9be390f5942c058582d8656351516d6c49cde + checksum: ce9440fc42a5419d103f4c7c1847cb75488f3ac9cbe81093b408ee9701193a509f664b4d10a2b4d82c694ee7495e022f8f482d254f92b7ffd9ed9dea696c6f84 languageName: node linkType: hard -"postcss-sort-media-queries@npm:^4.4.1": - version: 4.4.1 - resolution: "postcss-sort-media-queries@npm:4.4.1" +"postcss-sort-media-queries@npm:^5.2.0": + version: 5.2.0 + resolution: "postcss-sort-media-queries@npm:5.2.0" dependencies: - sort-css-media-queries: 2.1.0 + sort-css-media-queries: 2.2.0 peerDependencies: - postcss: ^8.4.16 - checksum: 70b42e479bb1d15d8628678eefefd547d309e33e64262fe437630fe62d8e4b3adcae7f2b48ef8da9d3173576d4af109a9ffa9514573db1281deef324f5ea166f + postcss: ^8.4.23 + checksum: d4a976a64b53234762cc35c06ce97c1684bd7a64ead17e84c2047676c7307945be7c005235e6aac7c4620e1f835d6ba1a7dcf018ab7fe0a47657c62c96ad9f35 languageName: node linkType: hard -"postcss-svgo@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-svgo@npm:5.1.0" +"postcss-svgo@npm:^6.0.3": + version: 6.0.3 + resolution: "postcss-svgo@npm:6.0.3" dependencies: postcss-value-parser: ^4.2.0 - svgo: ^2.7.0 + svgo: ^3.2.0 peerDependencies: - postcss: ^8.2.15 - checksum: d86eb5213d9f700cf5efe3073799b485fb7cacae0c731db3d7749c9c2b1c9bc85e95e0baeca439d699ff32ea24815fc916c4071b08f67ed8219df229ce1129bd + postcss: ^8.4.31 + checksum: 1a7d1c8dea555884a7791e28ec2c22ea92331731067584ff5a23042a0e615f88fefde04e1140f11c262a728ef9fab6851423b40b9c47f9ae05353bd3c0ff051a languageName: node linkType: hard -"postcss-unique-selectors@npm:^5.1.1": - version: 5.1.1 - resolution: "postcss-unique-selectors@npm:5.1.1" +"postcss-unique-selectors@npm:^6.0.4": + version: 6.0.4 + resolution: "postcss-unique-selectors@npm:6.0.4" dependencies: - postcss-selector-parser: ^6.0.5 + postcss-selector-parser: ^6.0.16 peerDependencies: - postcss: ^8.2.15 - checksum: 637e7b786e8558265775c30400c54b6b3b24d4748923f4a39f16a65fd0e394f564ccc9f0a1d3c0e770618a7637a7502ea1d0d79f731d429cb202255253c23278 + postcss: ^8.4.31 + checksum: b09df9943b4e858e88b30f3d279ce867a0490df806f1f947d286b0a4e95ba923f1229c385e5bf365f4f124f1edccda41ec18ccad4ba8798d829279d6dc971203 languageName: node linkType: hard @@ -9541,23 +9587,23 @@ __metadata: languageName: node linkType: hard -"postcss-zindex@npm:^5.1.0": - version: 5.1.0 - resolution: "postcss-zindex@npm:5.1.0" +"postcss-zindex@npm:^6.0.2": + version: 6.0.2 + resolution: "postcss-zindex@npm:6.0.2" peerDependencies: - postcss: ^8.2.15 - checksum: 8581e0ee552622489dcb9fb9609a3ccc261a67a229ba91a70bd138fe102a2d04cedb14642b82b673d4cac7b559ef32574f2dafde2ff7816eecac024d231c5ead + postcss: ^8.4.31 + checksum: 394119e47b0fb098dc53d1bcf71b5500ab29605fe106526b2e81290bff179174ee00a82a4d4be5a42d4ef4138e8a3d6aabeef3b06cf7cb15b851848c8585d53b languageName: node linkType: hard -"postcss@npm:^8.4.17, postcss@npm:^8.4.21, postcss@npm:^8.4.26": - version: 8.4.31 - resolution: "postcss@npm:8.4.31" +"postcss@npm:^8.4.21, postcss@npm:^8.4.24, postcss@npm:^8.4.26, postcss@npm:^8.4.38": + version: 8.4.41 + resolution: "postcss@npm:8.4.41" dependencies: - nanoid: ^3.3.6 - picocolors: ^1.0.0 - source-map-js: ^1.0.2 - checksum: 1d8611341b073143ad90486fcdfeab49edd243377b1f51834dc4f6d028e82ce5190e4f11bb2633276864503654fb7cab28e67abdc0fbf9d1f88cad4a0ff0beea + nanoid: ^3.3.7 + picocolors: ^1.0.1 + source-map-js: ^1.2.0 + checksum: f865894929eb0f7fc2263811cc853c13b1c75103028b3f4f26df777e27b201f1abe21cb4aa4c2e901c80a04f6fb325ee22979688fe55a70e2ea82b0a517d3b6f languageName: node linkType: hard @@ -9588,14 +9634,14 @@ __metadata: linkType: hard "prism-react-renderer@npm:^2.1.0, prism-react-renderer@npm:^2.3.0": - version: 2.3.1 - resolution: "prism-react-renderer@npm:2.3.1" + version: 2.4.0 + resolution: "prism-react-renderer@npm:2.4.0" dependencies: "@types/prismjs": ^1.26.0 clsx: ^2.0.0 peerDependencies: react: ">=16.0.0" - checksum: b12a7d502c1e764d94f7d3c84aee9cd6fccc676bb7e21dee94d37eb2e7e62e097a343999e1979887cb83a57cbdea48d2046aa74d07bce05caa25f4c296df30b6 + checksum: d15d944a8cbf05f7b04deecd2cf4ffb08229a6027918641b6f046cd8ab24b65ca4ebe4ac8e95a53a7d7cefb1bba8df3ce394fe4f1d75418e34fa92553dc63ef7 languageName: node linkType: hard @@ -9881,6 +9927,17 @@ __metadata: languageName: node linkType: hard +"react-loadable@npm:@docusaurus/react-loadable@6.0.0": + version: 6.0.0 + resolution: "@docusaurus/react-loadable@npm:6.0.0" + dependencies: + "@types/react": "*" + peerDependencies: + react: "*" + checksum: 4c32061b2fc10689d5d8ba11ead71b69e4c8a55fcfeafb551a6747b1a7b496c4f2d8dbb5d023f5cafc2a9aea9d14582bdb324d11e6f9b8c3049d45b74439203f + languageName: node + linkType: hard + "react-router-config@npm:^5.1.1": version: 5.1.1 resolution: "react-router-config@npm:5.1.1" @@ -10387,15 +10444,15 @@ __metadata: linkType: hard "sass@npm:^1.57.1": - version: 1.75.0 - resolution: "sass@npm:1.75.0" + version: 1.78.0 + resolution: "sass@npm:1.78.0" dependencies: chokidar: ">=3.0.0 <4.0.0" immutable: ^4.0.0 source-map-js: ">=0.6.2 <2.0.0" bin: sass: sass.js - checksum: bfb9f5ddb6a2e1fe0c1ba6191cdb17afa7b40c1eb892c7152f6a29ff2b06dc7a510bdb648f8cca0179dcb3965920ebeb8894f0710b0b450a99db563831345033 + checksum: ea856bd224c85d831a5800195750c2dd008d101771d071dbaca886c47fe4f131c30c328755d7a974ad944ba5b3aafa7a9f6010952da306436dcebddb41580e1c languageName: node linkType: hard @@ -10437,15 +10494,15 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.0.0": - version: 4.0.0 - resolution: "schema-utils@npm:4.0.0" +"schema-utils@npm:^4.0.0, schema-utils@npm:^4.0.1": + version: 4.2.0 + resolution: "schema-utils@npm:4.2.0" dependencies: "@types/json-schema": ^7.0.9 - ajv: ^8.8.0 + ajv: ^8.9.0 ajv-formats: ^2.1.1 - ajv-keywords: ^5.0.0 - checksum: c843e92fdd1a5c145dbb6ffdae33e501867f9703afac67bdf35a685e49f85b1dcc10ea250033175a64bd9d31f0555bc6785b8359da0c90bcea30cf6dfbb55a8f + ajv-keywords: ^5.1.0 + checksum: 26a0463d47683258106e6652e9aeb0823bf0b85843039e068b57da1892f7ae6b6b1094d48e9ed5ba5cbe9f7166469d880858b9d91abe8bd249421eb813850cde languageName: node linkType: hard @@ -10730,6 +10787,16 @@ __metadata: languageName: node linkType: hard +"snake-case@npm:^3.0.4": + version: 3.0.4 + resolution: "snake-case@npm:3.0.4" + dependencies: + dot-case: ^3.0.4 + tslib: ^2.0.3 + checksum: 0a7a79900bbb36f8aaa922cf111702a3647ac6165736d5dc96d3ef367efc50465cac70c53cd172c382b022dac72ec91710608e5393de71f76d7142e6fd80e8a3 + languageName: node + linkType: hard + "sockjs@npm:^0.3.24": version: 0.3.24 resolution: "sockjs@npm:0.3.24" @@ -10762,17 +10829,17 @@ __metadata: languageName: node linkType: hard -"sort-css-media-queries@npm:2.1.0": - version: 2.1.0 - resolution: "sort-css-media-queries@npm:2.1.0" - checksum: 25cb8f08b148a2ed83d0bc1cf20ddb888d3dee2a3c986896099a21b28b999d5cca3e46a9ef64381bb36fca0fc820471713f2e8af2729ecc6e108ab2b3b315ea9 +"sort-css-media-queries@npm:2.2.0": + version: 2.2.0 + resolution: "sort-css-media-queries@npm:2.2.0" + checksum: c090c9a27be40f3e50f5f9bc9d85a8af0e2c5152565eca34bdb028d952749bce169bc5abef21a5a385ca6221a0869640c9faf58f082ac46de9085ebdb506291f languageName: node linkType: hard -"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.2": - version: 1.0.2 - resolution: "source-map-js@npm:1.0.2" - checksum: c049a7fc4deb9a7e9b481ae3d424cc793cb4845daa690bc5a05d428bf41bf231ced49b4cf0c9e77f9d42fdb3d20d6187619fc586605f5eabe995a316da8d377c +"source-map-js@npm:>=0.6.2 <2.0.0, source-map-js@npm:^1.0.1, source-map-js@npm:^1.2.0": + version: 1.2.0 + resolution: "source-map-js@npm:1.2.0" + checksum: 791a43306d9223792e84293b00458bf102a8946e7188f3db0e4e22d8d530b5f80a4ce468eb5ec0bf585443ad55ebbd630bf379c98db0b1f317fd902500217f97 languageName: node linkType: hard @@ -10786,7 +10853,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0": +"source-map@npm:^0.6.0, source-map@npm:~0.6.0": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 59ce8640cf3f3124f64ac289012c2b8bd377c238e316fb323ea22fbfe83da07d81e000071d7242cad7a23cd91c7de98e4df8830ec3f133cb6133a5f6e9f67bc2 @@ -10857,13 +10924,6 @@ __metadata: languageName: node linkType: hard -"stable@npm:^0.1.8": - version: 0.1.8 - resolution: "stable@npm:0.1.8" - checksum: 2ff482bb100285d16dd75cd8f7c60ab652570e8952c0bfa91828a2b5f646a0ff533f14596ea4eabd48bb7f4aeea408dce8f8515812b975d958a4cc4fa6b9dfeb - languageName: node - linkType: hard - "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -11010,15 +11070,15 @@ __metadata: languageName: node linkType: hard -"stylehacks@npm:^5.1.1": - version: 5.1.1 - resolution: "stylehacks@npm:5.1.1" +"stylehacks@npm:^6.1.1": + version: 6.1.1 + resolution: "stylehacks@npm:6.1.1" dependencies: - browserslist: ^4.21.4 - postcss-selector-parser: ^6.0.4 + browserslist: ^4.23.0 + postcss-selector-parser: ^6.0.16 peerDependencies: - postcss: ^8.2.15 - checksum: 11175366ef52de65bf06cefba0ddc9db286dc3a1451fd2989e74c6ea47091a02329a4bf6ce10b1a36950056927b6bbbe47c5ab3a1f4c7032df932d010fbde5a2 + postcss: ^8.4.31 + checksum: 7bef69822280a23817caa43969de76d77ba34042e9f1f7baaeda8f22b1d8c20f1f839ad028552c169e158e387830f176feccd0324b07ef6ec657cba1dd0b2466 languageName: node linkType: hard @@ -11063,20 +11123,20 @@ __metadata: languageName: node linkType: hard -"svgo@npm:^2.7.0, svgo@npm:^2.8.0": - version: 2.8.0 - resolution: "svgo@npm:2.8.0" +"svgo@npm:^3.0.2, svgo@npm:^3.2.0": + version: 3.3.2 + resolution: "svgo@npm:3.3.2" dependencies: "@trysound/sax": 0.2.0 commander: ^7.2.0 - css-select: ^4.1.3 - css-tree: ^1.1.3 - csso: ^4.2.0 + css-select: ^5.1.0 + css-tree: ^2.3.1 + css-what: ^6.1.0 + csso: ^5.0.5 picocolors: ^1.0.0 - stable: ^0.1.8 bin: - svgo: bin/svgo - checksum: b92f71a8541468ffd0b81b8cdb36b1e242eea320bf3c1a9b2c8809945853e9d8c80c19744267eb91cabf06ae9d5fff3592d677df85a31be4ed59ff78534fa420 + svgo: ./bin/svgo + checksum: a3f8aad597dec13ab24e679c4c218147048dc1414fe04e99447c5f42a6e077b33d712d306df84674b5253b98c9b84dfbfb41fdd08552443b04946e43d03e054e languageName: node linkType: hard @@ -11449,17 +11509,17 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.13": - version: 1.0.13 - resolution: "update-browserslist-db@npm:1.0.13" +"update-browserslist-db@npm:^1.1.0": + version: 1.1.0 + resolution: "update-browserslist-db@npm:1.1.0" dependencies: - escalade: ^3.1.1 - picocolors: ^1.0.0 + escalade: ^3.1.2 + picocolors: ^1.0.1 peerDependencies: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 1e47d80182ab6e4ad35396ad8b61008ae2a1330221175d0abd37689658bdb61af9b705bfc41057fd16682474d79944fb2d86767c5ed5ae34b6276b9bed353322 + checksum: 7b74694d96f0c360f01b702e72353dc5a49df4fe6663d3ee4e5c628f061576cddf56af35a3a886238c01dd3d8f231b7a86a8ceaa31e7a9220ae31c1c1238e562 languageName: node linkType: hard @@ -11944,7 +12004,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^1.10.0, yaml@npm:^1.10.2, yaml@npm:^1.7.2": +"yaml@npm:^1.7.2": version: 1.10.2 resolution: "yaml@npm:1.10.2" checksum: ce4ada136e8a78a0b08dc10b4b900936912d15de59905b2bf415b4d33c63df1d555d23acb2a41b23cf9fb5da41c256441afca3d6509de7247daa062fd2c5ea5f diff --git a/mkdocs.yml b/mkdocs.yml index 33c9af3286..4d4d039756 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -138,7 +138,6 @@ nav: - Proxying: 'plugins/proxying.md' - Backend plugin: 'plugins/backend-plugin.md' - Call existing API: 'plugins/call-existing-api.md' - - URL Reader: 'plugins/url-reader.md' - Testing: - Testing with Jest: 'plugins/testing.md' - Publishing: @@ -183,6 +182,7 @@ nav: - Local Development: - Linking in Local Packages: 'tooling/local-dev/linking-local-packages.md' - Debugging Backstage: 'tooling/local-dev/debugging.md' + - Profiling Backstage: 'tooling/local-dev/profiling.md' - Package Metadata: 'tooling/package-metadata.md' - Deployment: - Deploying Backstage: 'deployment/index.md' diff --git a/package.json b/package.json index 740f7a412f..4028f7bacd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.30.0", + "version": "1.31.0-next.1", "private": true, "repository": { "type": "git", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 72c172e395..449f249236 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/app-defaults +## 1.5.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.25 + ## 1.5.10 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index ee21affccf..0e0cb11cbe 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.5.10", + "version": "1.5.11-next.0", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index af5b4a5c24..68879cd7aa 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,21 @@ # app-next-example-plugin +## 0.0.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-components@0.14.11-next.0 + +## 0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-components@0.14.10 + ## 0.0.14 ### Patch Changes diff --git a/packages/app-next-example-plugin/api-report.md b/packages/app-next-example-plugin/api-report.md index 4698edec6b..06d325b844 100644 --- a/packages/app-next-example-plugin/api-report.md +++ b/packages/app-next-example-plugin/api-report.md @@ -4,44 +4,43 @@ ```ts import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; // @public (undocumented) -const examplePlugin: BackstagePlugin< +const examplePlugin: FrontendPlugin< {}, {}, { - 'page:example': ExtensionDefinition< - { + 'page:example': ExtensionDefinition<{ + kind: 'page'; + namespace: undefined; + name: undefined; + config: { path: string | undefined; - }, - { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - {}, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: {}; + }>; } >; export default examplePlugin; diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index 5bb8318e2b..89e2d353f6 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.14", + "version": "0.0.15-next.1", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 5d3a1d5a3c..8ddcaad4b3 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,94 @@ # example-app-next +## 0.0.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.1-next.1 + - @backstage/frontend-defaults@0.1.0-next.0 + - @backstage/frontend-app-api@0.9.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-compat-api@0.3.0-next.1 + - @backstage/plugin-app@0.1.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-graph@0.4.9-next.1 + - @backstage/plugin-scaffolder-react@1.12.0-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.0 + - @backstage/plugin-signals@0.0.10-next.1 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/app-defaults@1.5.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.9-next.1 + - @backstage/plugin-app-visualizer@0.1.10-next.1 + - @backstage/plugin-auth-react@0.1.6-next.0 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-import@0.12.3-next.1 + - @backstage/plugin-home@0.7.10-next.1 + - @backstage/plugin-kubernetes@0.11.14-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.1 + - @backstage/plugin-notifications@0.3.1-next.1 + - @backstage/plugin-org@0.6.29-next.1 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder@1.25.0-next.1 + - @backstage/plugin-search@1.4.16-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + - @backstage/plugin-techdocs@1.10.9-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + - @backstage/plugin-user-settings@0.8.12-next.1 + +## 0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/frontend-app-api@0.9.0-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-import@0.12.3-next.0 + - @backstage/plugin-catalog-graph@0.4.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-user-settings@0.8.12-next.0 + - @backstage/plugin-search-react@1.8.0-next.0 + - @backstage/plugin-kubernetes@0.11.14-next.0 + - @backstage/plugin-scaffolder@1.25.0-next.0 + - @backstage/plugin-api-docs@0.11.9-next.0 + - @backstage/plugin-techdocs@1.10.9-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/plugin-search@1.4.16-next.0 + - @backstage/plugin-home@0.7.10-next.0 + - @backstage/plugin-org@0.6.29-next.0 + - @backstage/plugin-scaffolder-react@1.12.0-next.0 + - @backstage/plugin-app@0.1.0-next.0 + - @backstage/cli@0.27.1-next.0 + - @backstage/plugin-signals@0.0.10-next.0 + - @backstage/plugin-app-visualizer@0.1.10-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.0 + - @backstage/app-defaults@1.5.10 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7 + - @backstage/plugin-notifications@0.3.1-next.0 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-search-common@1.2.14 + ## 0.0.14 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index fa37cce5c8..0b31445e4b 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.14", + "version": "0.0.15-next.1", "private": true, "repository": { "type": "git", @@ -21,9 +21,11 @@ "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/frontend-app-api": "workspace:^", + "@backstage/frontend-defaults": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", "@backstage/integration-react": "workspace:^", "@backstage/plugin-api-docs": "workspace:^", + "@backstage/plugin-app": "workspace:^", "@backstage/plugin-app-visualizer": "workspace:^", "@backstage/plugin-auth-react": "workspace:^", "@backstage/plugin-catalog": "workspace:^", @@ -53,16 +55,12 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@octokit/rest": "^19.0.3", - "@vitejs/plugin-react": "^4.0.4", "history": "^5.0.0", "react": "^18.0.2", "react-dom": "^18.0.2", "react-router": "^6.3.0", "react-router-dom": "^6.3.0", "react-use": "^17.2.4", - "vite": "^4.4.9", - "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.22.0", "zen-observable": "^0.10.0" }, "devDependencies": { diff --git a/packages/app-next/src/App.tsx b/packages/app-next/src/App.tsx index 18b91409e1..0d686cd5a5 100644 --- a/packages/app-next/src/App.tsx +++ b/packages/app-next/src/App.tsx @@ -26,8 +26,8 @@ import homePlugin, { import { coreExtensionData, createExtension, - createExtensionOverrides, ApiBlueprint, + createFrontendModule, } from '@backstage/frontend-plugin-api'; import { techdocsPlugin, @@ -45,11 +45,10 @@ import { createApiFactory, configApiRef } from '@backstage/core-plugin-api'; import { ScmAuth, ScmIntegrationsApi, - scmAuthApiRef, scmIntegrationsApiRef, } from '@backstage/integration-react'; import kubernetesPlugin from '@backstage/plugin-kubernetes/alpha'; -import { signInPageOverrides } from './overrides/SignInPage'; +import { signInPageModule } from './overrides/SignInPage'; import { convertLegacyPlugin } from '@backstage/core-compat-api'; import { convertLegacyPageExtension } from '@backstage/core-compat-api'; import { convertLegacyEntityContentExtension } from '@backstage/plugin-catalog-react/alpha'; @@ -97,34 +96,48 @@ const convertedTechdocsPlugin = convertLegacyPlugin(techdocsPlugin, { ], }); -const homePageExtension = createExtension({ - name: 'myhomepage', - attachTo: { id: 'page:home', input: 'props' }, - output: [coreExtensionData.reactElement, titleExtensionDataRef], - factory() { - return [ - coreExtensionData.reactElement(homePage), - titleExtensionDataRef('just a title'), - ]; - }, -}); - -const scmAuthExtension = ApiBlueprint.make({ - namespace: scmAuthApiRef.id, - params: { - factory: ScmAuth.createDefaultApiFactory(), - }, -}); - -const scmIntegrationApi = ApiBlueprint.make({ - namespace: scmIntegrationsApiRef.id, - params: { - factory: createApiFactory({ - api: scmIntegrationsApiRef, - deps: { configApi: configApiRef }, - factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), +const customHomePageModule = createFrontendModule({ + pluginId: 'home', + extensions: [ + createExtension({ + name: 'my-home-page', + attachTo: { id: 'page:home', input: 'props' }, + output: [coreExtensionData.reactElement, titleExtensionDataRef], + factory() { + return [ + coreExtensionData.reactElement(homePage), + titleExtensionDataRef('just a title'), + ]; + }, }), - }, + ], +}); + +const scmModule = createFrontendModule({ + pluginId: 'app', + extensions: [ + ApiBlueprint.make({ + name: 'scm-auth', + params: { + factory: ScmAuth.createDefaultApiFactory(), + }, + }), + ApiBlueprint.make({ + name: 'scm-integrations', + params: { + factory: createApiFactory({ + api: scmIntegrationsApiRef, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi), + }), + }, + }), + ], +}); + +const notFoundErrorPageModule = createFrontendModule({ + pluginId: 'app', + extensions: [notFoundErrorPage], }); const collectedLegacyPlugins = convertLegacyApp( @@ -141,16 +154,11 @@ const app = createApp({ homePlugin, appVisualizerPlugin, kubernetesPlugin, - signInPageOverrides, + signInPageModule, + scmModule, + notFoundErrorPageModule, + customHomePageModule, ...collectedLegacyPlugins, - createExtensionOverrides({ - extensions: [ - homePageExtension, - scmAuthExtension, - scmIntegrationApi, - notFoundErrorPage, - ], - }), ], /* Handled through config instead */ // bindRoutes({ bind }) { diff --git a/packages/app-next/src/examples/notFoundErrorPageExtension.tsx b/packages/app-next/src/examples/notFoundErrorPageExtension.tsx index f5108c6c15..458e716910 100644 --- a/packages/app-next/src/examples/notFoundErrorPageExtension.tsx +++ b/packages/app-next/src/examples/notFoundErrorPageExtension.tsx @@ -52,6 +52,7 @@ export function CustomNotFoundErrorPage() { } export default createComponentExtension({ + name: 'not-found-error-page', ref: coreComponentRefs.notFoundErrorPage, loader: { sync: () => CustomNotFoundErrorPage }, }); diff --git a/packages/app-next/src/index-public-experimental.tsx b/packages/app-next/src/index-public-experimental.tsx index 27b2af7d91..f258a660e3 100644 --- a/packages/app-next/src/index-public-experimental.tsx +++ b/packages/app-next/src/index-public-experimental.tsx @@ -14,32 +14,12 @@ * limitations under the License. */ -import React from 'react'; import ReactDOM from 'react-dom/client'; -import { CookieAuthRedirect } from '@backstage/plugin-auth-react'; -import { createApp } from '@backstage/frontend-app-api'; -import { signInPageOverrides } from './overrides/SignInPage'; -import { - coreExtensionData, - createExtension, - createExtensionOverrides, -} from '@backstage/frontend-plugin-api'; +import { signInPageModule } from './overrides/SignInPage'; +import { createPublicSignInApp } from '@backstage/frontend-defaults'; -const authRedirectExtension = createExtension({ - namespace: 'app', - name: 'layout', - attachTo: { id: 'app/root', input: 'children' }, - output: [coreExtensionData.reactElement], - factory: () => [coreExtensionData.reactElement()], -}); - -const app = createApp({ - features: [ - signInPageOverrides, - createExtensionOverrides({ - extensions: [authRedirectExtension], - }), - ], +const app = createPublicSignInApp({ + features: [signInPageModule], }); ReactDOM.createRoot(document.getElementById('root')!).render(app.createRoot()); diff --git a/packages/app-next/src/overrides/SignInPage.tsx b/packages/app-next/src/overrides/SignInPage.tsx index 52dd01fcde..f1e37a241b 100644 --- a/packages/app-next/src/overrides/SignInPage.tsx +++ b/packages/app-next/src/overrides/SignInPage.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { SignInPage } from '@backstage/core-components'; import { SignInPageBlueprint, - createExtensionOverrides, + createFrontendModule, } from '@backstage/frontend-plugin-api'; const signInPage = SignInPageBlueprint.make({ @@ -29,6 +29,7 @@ const signInPage = SignInPageBlueprint.make({ }, }); -export const signInPageOverrides = createExtensionOverrides({ +export const signInPageModule = createFrontendModule({ + pluginId: 'app', extensions: [signInPage], }); diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index f9cebb78e6..4cfd9ca1a8 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,87 @@ # example-app +## 0.2.101-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.1-next.1 + - @backstage/frontend-app-api@0.9.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-graph@0.4.9-next.1 + - @backstage/plugin-scaffolder-react@1.12.0-next.1 + - @backstage/plugin-catalog-unprocessed-entities@0.2.8-next.0 + - @backstage/plugin-signals@0.0.10-next.1 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/app-defaults@1.5.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-api-docs@0.11.9-next.1 + - @backstage/plugin-auth-react@0.1.6-next.0 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-import@0.12.3-next.1 + - @backstage/plugin-devtools@0.1.18-next.1 + - @backstage/plugin-home@0.7.10-next.1 + - @backstage/plugin-kubernetes@0.11.14-next.1 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.1 + - @backstage/plugin-notifications@0.3.1-next.1 + - @backstage/plugin-org@0.6.29-next.1 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder@1.25.0-next.1 + - @backstage/plugin-search@1.4.16-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + - @backstage/plugin-techdocs@1.10.9-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + - @backstage/plugin-user-settings@0.8.12-next.1 + +## 0.2.101-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/frontend-app-api@0.9.0-next.0 + - @backstage/plugin-catalog-import@0.12.3-next.0 + - @backstage/plugin-catalog-graph@0.4.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-user-settings@0.8.12-next.0 + - @backstage/plugin-search-react@1.8.0-next.0 + - @backstage/plugin-kubernetes@0.11.14-next.0 + - @backstage/plugin-scaffolder@1.25.0-next.0 + - @backstage/plugin-api-docs@0.11.9-next.0 + - @backstage/plugin-devtools@0.1.18-next.0 + - @backstage/plugin-techdocs@1.10.9-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/plugin-search@1.4.16-next.0 + - @backstage/plugin-home@0.7.10-next.0 + - @backstage/plugin-org@0.6.29-next.0 + - @backstage/plugin-scaffolder-react@1.12.0-next.0 + - @backstage/cli@0.27.1-next.0 + - @backstage/plugin-signals@0.0.10-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.14-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.15-next.0 + - @backstage/app-defaults@1.5.10 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + - @backstage/plugin-auth-react@0.1.5 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-unprocessed-entities@0.2.7 + - @backstage/plugin-notifications@0.3.1-next.0 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-search-common@1.2.14 + ## 0.2.100 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index c27540f63e..f7dccc1edd 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.100", + "version": "0.2.101-next.1", "backstage": { "role": "frontend" }, @@ -74,16 +74,12 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@octokit/rest": "^19.0.3", - "@vitejs/plugin-react": "^4.0.4", "history": "^5.0.0", "react": "^18.0.2", "react-dom": "^18.0.2", "react-router": "^6.3.0", "react-router-dom": "^6.3.0", "react-use": "^17.2.4", - "vite": "^4.4.9", - "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.22.0", "zen-observable": "^0.10.0" }, "devDependencies": { diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index d741dea098..ba556e8616 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -73,8 +73,7 @@ import { DelayingComponentFieldExtension } from './components/scaffolder/customS import { defaultPreviewTemplate } from './components/scaffolder/defaultPreviewTemplate'; import { searchPage } from './components/search/SearchPage'; import { providers } from './identityProviders'; -import * as plugins from './plugins'; - +import { SignalsDisplay } from '@backstage/plugin-signals'; import { techDocsPage } from './components/techdocs/TechDocsPage'; import { RequirePermission } from '@backstage/plugin-permission-react'; import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; @@ -86,7 +85,6 @@ import { NotificationsPage } from '@backstage/plugin-notifications'; const app = createApp({ apis, - plugins: Object.values(plugins), icons: { // Custom icon example alert: AlarmIcon, @@ -217,6 +215,7 @@ export default app.createRoot( <> + {routes} diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 076892c3b1..9605e30ba3 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/backend-app-api +## 0.10.0-next.1 + +### Patch Changes + +- c246372: Updated the error message for missing service dependencies to include the plugin and module IDs. +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## 0.10.0-next.0 + +### Minor Changes + +- 19ff127: **BREAKING**: The deprecated `identityServiceFactory` and `tokenManagerServiceFactory` have been removed. +- 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 + +- cd38da8: Deprecate the `featureDiscoveryServiceFactory` in favor of using `@backstage/backend-defaults#discoveryFeatureLoader` instead. +- 7f779c7: `auth.externalAccess` should be optional in the config schema +- 51a69b5: Fix feature loaders in CJS double-default nested builds +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.9.0 ### Minor Changes diff --git a/packages/backend-app-api/api-report-alpha.md b/packages/backend-app-api/api-report-alpha.md index 2633321472..163cc325a1 100644 --- a/packages/backend-app-api/api-report-alpha.md +++ b/packages/backend-app-api/api-report-alpha.md @@ -6,7 +6,7 @@ import { FeatureDiscoveryService } from '@backstage/backend-plugin-api/alpha'; import { ServiceFactory } from '@backstage/backend-plugin-api'; -// @alpha (undocumented) +// @alpha @deprecated (undocumented) export const featureDiscoveryServiceFactory: ServiceFactory< FeatureDiscoveryService, 'root', diff --git a/packages/backend-app-api/config.d.ts b/packages/backend-app-api/config.d.ts index 76d22db8b2..b5e56af67c 100644 --- a/packages/backend-app-api/config.d.ts +++ b/packages/backend-app-api/config.d.ts @@ -16,297 +16,12 @@ export interface Config { backend?: { - auth?: { - /** - * This disables the otherwise default auth policy, which requires all - * requests to be authenticated with either user or service credentials. - * - * Disabling this check means that the backend will no longer block - * unauthenticated requests, but instead allow them to pass through to - * plugins. - * - * If permissions are enabled, unauthenticated requests will be treated - * exactly as such, leaving it to the permission policy to determine what - * permissions should be allowed for an unauthenticated identity. Note - * that this will also apply to service-to-service calls between plugins - * unless you configure credentials for service calls. - */ - dangerouslyDisableDefaultAuthPolicy?: boolean; - - /** Controls how to store keys for plugin-to-plugin auth */ - pluginKeyStore?: - | { type: 'database' } - | { - type: 'static'; - static: { - /** - * Must be declared at least once and the first one will be used for signing. - */ - keys: Array<{ - /** - * Path to the public key file in the SPKI format. Should be an absolute path. - */ - publicKeyFile: string; - /** - * Path to the matching private key file in the PKCS#8 format. Should be an absolute path. - * - * The first array entry must specify a private key file, the rest must not. - */ - privateKeyFile?: string; - /** - * ID to uniquely identify this key within the JWK set. - */ - keyId: string; - /** - * JWS "alg" (Algorithm) Header Parameter value. Defaults to ES256. - * Must match the algorithm used to generate the keys in the provided files - */ - algorithm?: string; - }>; - }; - }; - - /** - * Configures methods of external access, ie ways for callers outside of - * the Backstage ecosystem to get authorized for access to APIs that do - * not permit unauthorized access. - */ - externalAccess?: Array< - | { - /** - * This is the legacy service-to-service access method, where a set - * of static keys were shared among plugins and used for symmetric - * signing and verification. These correspond to the old - * `backend.auth.keys` set and retain their behavior for backwards - * compatibility. Please migrate to other access methods when - * possible. - * - * Callers generate JWT tokens with the following payload: - * - * ```json - * { - * "sub": "backstage-plugin", - * "exp": - * } - * ``` - * - * And sign them with HS256, using the base64 decoded secret. The - * tokens are then passed along with requests in the Authorization - * header: - * - * ``` - * Authorization: Bearer eyJhbGciOiJIUzI... - * ``` - */ - type: 'legacy'; - options: { - /** - * Any set of base64 encoded random bytes to be used as both the - * signing and verification key. Should be sufficiently long so as - * not to be easy to guess by brute force. - * - * Can be generated eg using - * - * ```sh - * node -p 'require("crypto").randomBytes(24).toString("base64")' - * ``` - * - * @visibility secret - */ - secret: string; - - /** - * Sets the subject of the principal, when matching this token. - * Useful for debugging and tracking purposes. - */ - subject: string; - }; - /** - * Restricts what types of access that are permitted for this access - * method. If no access restrictions are given, it'll have unlimited - * access. This access restriction applies for the framework level; - * individual plugins may have their own access control mechanisms - * on top of this. - */ - accessRestrictions?: Array<{ - /** - * Permit access to make requests to this plugin. - * - * Can be further refined by setting additional fields below. - */ - plugin: string; - /** - * If given, this method is limited to only performing actions - * with these named permissions in this plugin. - * - * Note that this only applies where permissions checks are - * enabled in the first place. Endpoints that are not protected by - * the permissions system at all, are not affected by this - * setting. - */ - permission?: string | Array; - /** - * If given, this method is limited to only performing actions - * whose permissions have these attributes. - * - * Note that this only applies where permissions checks are - * enabled in the first place. Endpoints that are not protected by - * the permissions system at all, are not affected by this - * setting. - */ - permissionAttribute?: { - /** - * One of more of 'create', 'read', 'update', or 'delete'. - */ - action?: string | Array; - }; - }>; - } - | { - /** - * This access method consists of random static tokens that can be - * handed out to callers. - * - * The tokens are then passed along verbatim with requests in the - * Authorization header: - * - * ``` - * Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW - * ``` - */ - type: 'static'; - options: { - /** - * A raw token that can be any string, but for security reasons - * should be sufficiently long so as not to be easy to guess by - * brute force. - * - * Can be generated eg using - * - * ```sh - * node -p 'require("crypto").randomBytes(24).toString("base64")' - * ``` - * - * Since the tokens can be any string, you are free to add - * additional identifying data to them if you like. For example, - * adding a `freben-local-dev-` prefix for debugging purposes to a - * token that you know will be handed out for use as a personal - * access token during development. - * - * @visibility secret - */ - token: string; - - /** - * Sets the subject of the principal, when matching this token. - * Useful for debugging and tracking purposes. - */ - subject: string; - }; - /** - * Restricts what types of access that are permitted for this access - * method. If no access restrictions are given, it'll have unlimited - * access. This access restriction applies for the framework level; - * individual plugins may have their own access control mechanisms - * on top of this. - */ - accessRestrictions?: Array<{ - /** - * Permit access to make requests to this plugin. - * - * Can be further refined by setting additional fields below. - */ - plugin: string; - /** - * If given, this method is limited to only performing actions - * with these named permissions in this plugin. - * - * Note that this only applies where permissions checks are - * enabled in the first place. Endpoints that are not protected by - * the permissions system at all, are not affected by this - * setting. - */ - permission?: string | Array; - /** - * If given, this method is limited to only performing actions - * whose permissions have these attributes. - * - * Note that this only applies where permissions checks are - * enabled in the first place. Endpoints that are not protected by - * the permissions system at all, are not affected by this - * setting. - */ - permissionAttribute?: { - /** - * One of more of 'create', 'read', 'update', or 'delete'. - */ - action?: string | Array; - }; - }>; - } - | { - /** - * This access method consists of a JWKS endpoint that can be used to - * verify JWT tokens. - * - * Callers generate JWT tokens via 3rd party tooling - * and pass them in the Authorization header: - * - * ``` - * Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW - * ``` - */ - type: 'jwks'; - options: { - /** - * The full URL of the JWKS endpoint. - */ - url: string; - /** - * Sets the algorithm(s) that should be used to verify the JWT tokens. - * The passed JWTs must have been signed using one of the listed algorithms. - */ - algorithm?: string | string[]; - /** - * Sets the issuer(s) that should be used to verify the JWT tokens. - * Passed JWTs must have an `iss` claim which matches one of the specified issuers. - */ - issuer?: string | string[]; - /** - * Sets the audience(s) that should be used to verify the JWT tokens. - * The passed JWTs must have an "aud" claim that matches one of the audiences specified, - * or have no audience specified. - */ - audience?: string | string[]; - /** - * Sets an optional subject prefix. Passes the subject to called plugins. - * Useful for debugging and tracking purposes. - */ - subjectPrefix?: string; - }; - } - >; - }; - packages?: 'all' | { include?: string[]; exclude?: string[] }; - }; - - /** Discovery options. */ - discovery?: { - /** - * Endpoints - * - * A list of target baseUrls and the associated plugins. - */ - endpoints: { - /** - * The target baseUrl to use for the plugin - * - * Can be either a string or an object with internal and external keys. - * Targets with `{{pluginId}}` or `{{ pluginId }} in the url will be replaced with the pluginId. - */ - target: string | { internal: string; external: string }; - /** Array of plugins which use the target baseUrl. */ - plugins: string[]; - }[]; + /** Used by the feature discovery service */ + packages?: + | 'all' + | { + include?: string[]; + exclude?: string[]; + }; }; } diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 27cbb0b916..6582a60515 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-app-api", - "version": "0.9.0", + "version": "0.10.0-next.1", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" @@ -53,7 +53,6 @@ "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/cli-common": "workspace:^", - "@backstage/cli-node": "workspace:^", "@backstage/config": "workspace:^", "@backstage/config-loader": "workspace:^", "@backstage/errors": "workspace:^", @@ -66,7 +65,6 @@ "cors": "^2.8.5", "express": "^4.17.1", "express-promise-router": "^4.1.0", - "fs-extra": "^11.2.0", "helmet": "^6.0.0", "jose": "^5.0.0", "knex": "^3.0.0", @@ -91,7 +89,6 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/compression": "^1.7.0", - "@types/fs-extra": "^11.0.0", "@types/http-errors": "^2.0.0", "@types/minimist": "^1.2.0", "@types/morgan": "^1.9.0", diff --git a/packages/backend-app-api/src/alpha/featureDiscoveryServiceFactory.ts b/packages/backend-app-api/src/alpha/featureDiscoveryServiceFactory.ts index c16a3f6534..05de659083 100644 --- a/packages/backend-app-api/src/alpha/featureDiscoveryServiceFactory.ts +++ b/packages/backend-app-api/src/alpha/featureDiscoveryServiceFactory.ts @@ -15,145 +15,17 @@ */ import { - BackendFeature, - RootConfigService, - RootLoggerService, coreServices, createServiceFactory, } from '@backstage/backend-plugin-api'; -import { - featureDiscoveryServiceRef, - FeatureDiscoveryService, -} from '@backstage/backend-plugin-api/alpha'; -import { resolve as resolvePath, dirname } from 'path'; -import fs from 'fs-extra'; -import { BackstagePackageJson } from '@backstage/cli-node'; +import { featureDiscoveryServiceRef } from '@backstage/backend-plugin-api/alpha'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { PackageDiscoveryService } from '../../../backend-defaults/src/PackageDiscoveryService'; -const DETECTED_PACKAGE_ROLES = [ - 'node-library', - 'backend', - 'backend-plugin', - 'backend-plugin-module', -]; - -/** @internal */ -async function findClosestPackageDir( - searchDir: string, -): Promise { - let path = searchDir; - - // Some confidence check to avoid infinite loop - for (let i = 0; i < 1000; i++) { - const packagePath = resolvePath(path, 'package.json'); - const exists = await fs.pathExists(packagePath); - if (exists) { - return path; - } - - const newPath = dirname(path); - if (newPath === path) { - return undefined; - } - path = newPath; - } - - throw new Error( - `Iteration limit reached when searching for root package.json at ${searchDir}`, - ); -} - -/** @internal */ -class PackageDiscoveryService implements FeatureDiscoveryService { - constructor( - private readonly config: RootConfigService, - private readonly logger: RootLoggerService, - ) {} - - getDependencyNames(path: string) { - const { dependencies } = require(path) as BackstagePackageJson; - const packagesConfig = this.config.getOptional('backend.packages'); - - const dependencyNames = Object.keys(dependencies || {}); - - if (packagesConfig === 'all') { - return dependencyNames; - } - - const includedPackagesConfig = this.config.getOptionalStringArray( - 'backend.packages.include', - ); - - const includedPackages = includedPackagesConfig - ? new Set(includedPackagesConfig) - : dependencyNames; - const excludedPackagesSet = new Set( - this.config.getOptionalStringArray('backend.packages.exclude'), - ); - - return [...includedPackages].filter(name => !excludedPackagesSet.has(name)); - } - - async getBackendFeatures(): Promise<{ features: Array }> { - const packagesConfig = this.config.getOptional('backend.packages'); - if (!packagesConfig || Object.keys(packagesConfig).length === 0) { - return { features: [] }; - } - - const packageDir = await findClosestPackageDir(process.argv[1]); - if (!packageDir) { - throw new Error('Package discovery failed to find package.json'); - } - const dependencyNames = this.getDependencyNames( - resolvePath(packageDir, 'package.json'), - ); - - const features: BackendFeature[] = []; - - for (const name of dependencyNames) { - const depPkg = require(require.resolve(`${name}/package.json`, { - paths: [packageDir], - })) as BackstagePackageJson; - if ( - !depPkg?.backstage?.role || - !DETECTED_PACKAGE_ROLES.includes(depPkg.backstage.role) - ) { - continue; // Not a backstage backend package, ignore - } - - const exportedModulePaths = [ - require.resolve(name, { - paths: [packageDir], - }), - ]; - - // Find modules exported as alpha - try { - exportedModulePaths.push( - require.resolve(`${name}/alpha`, { paths: [packageDir] }), - ); - } catch { - /* ignore */ - } - - for (const modulePath of exportedModulePaths) { - const mod = require(modulePath); - - if (isBackendFeature(mod.default)) { - this.logger.info(`Detected: ${name}`); - features.push(mod.default); - } - if (isBackendFeatureFactory(mod.default)) { - this.logger.info(`Detected: ${name}`); - features.push(mod.default()); - } - } - } - - return { features }; - } -} - -/** @alpha */ +/** + * @alpha + * @deprecated The `featureDiscoveryServiceFactory` is deprecated in favor of using {@link @backstage/backend-defaults#discoveryFeatureLoader} instead. + */ export const featureDiscoveryServiceFactory = createServiceFactory({ service: featureDiscoveryServiceRef, deps: { @@ -164,21 +36,3 @@ export const featureDiscoveryServiceFactory = createServiceFactory({ return new PackageDiscoveryService(config, logger); }, }); - -function isBackendFeature(value: unknown): value is BackendFeature { - return ( - !!value && - ['object', 'function'].includes(typeof value) && - (value as BackendFeature).$$type === '@backstage/BackendFeature' - ); -} - -function isBackendFeatureFactory( - value: unknown, -): value is () => BackendFeature { - return ( - !!value && - typeof value === 'function' && - (value as any).$$type === '@backstage/BackendFeatureFactory' - ); -} diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts index 955e463bb0..b524301f21 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts @@ -577,6 +577,56 @@ describe('BackendInitializer', () => { ); }); + it('should reject plugins with missing dependencies', async () => { + const init = new BackendInitializer(baseFactories); + const ref = createServiceRef({ id: 'a' }); + init.add( + createBackendPlugin({ + pluginId: 'test', + register(reg) { + reg.registerInit({ + deps: { ref }, + async init() {}, + }); + }, + }), + ); + await expect(init.start()).rejects.toThrow( + "Service or extension point dependencies of plugin 'test' are missing for the following ref(s): serviceRef{a}", + ); + }); + + it('should reject modules with missing dependencies', async () => { + const init = new BackendInitializer(baseFactories); + const ref = createServiceRef({ id: 'a' }); + init.add( + createBackendPlugin({ + pluginId: 'test', + register(reg) { + reg.registerInit({ + deps: {}, + async init() {}, + }); + }, + }), + ); + init.add( + createBackendModule({ + pluginId: 'test', + moduleId: 'test-mod', + register(reg) { + reg.registerInit({ + deps: { ref }, + async init() {}, + }); + }, + }), + ); + await expect(init.start()).rejects.toThrow( + "Service or extension point dependencies of module 'test-mod' for plugin 'test' are missing for the following ref(s): serviceRef{a}", + ); + }); + it('should properly load double-default CJS modules', async () => { expect.assertions(3); diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index b2173fb105..7e29276a77 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -93,8 +93,11 @@ export class BackendInitializer { if (missingRefs.size > 0) { const missing = Array.from(missingRefs).join(', '); + const target = moduleId + ? `module '${moduleId}' for plugin '${pluginId}'` + : `plugin '${pluginId}'`; throw new Error( - `No extension point or service available for the following ref(s): ${missing}`, + `Service or extension point dependencies of ${target} are missing for the following ref(s): ${missing}`, ); } @@ -157,6 +160,7 @@ export class BackendInitializer { } const featureDiscovery = await this.#serviceRegistry.get( + // TODO: Let's leave this in place and remove it once the deprecated service is removed. We can do that post-1.0 since it's alpha featureDiscoveryServiceRef, 'root', ); diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 40ba8fb687..2a488efd04 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,58 @@ # @backstage/backend-common +## 0.25.0-next.1 + +### Minor Changes + +- a4bac3c: **BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. +- 988c145: **BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. + + - The deprecated `dropDatabase` function has now been removed, without replacement. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + +## 0.25.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 + +- 8ba77ed: The `legacyPlugin` and `makeLegacyPlugin` helpers now provide their own shim implementation of the identity and token manager services, as these services are being removed from the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 2e9ec14: Add `pg-format` as a dependency +- 19ff127: Internal refactor to re-declare the token manager service which was removed from `@backstage/backend-plugin-api`, but is still supported in this package for backwards compatibility. +- 66dbf0a: Allow the cache service to accept the human duration format for TTL +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + ## 0.24.0 ### Minor Changes diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 7de2731518..1a67d4877f 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -65,10 +65,15 @@ export type CacheClientOptions = CacheServiceOptions; // @public @deprecated (undocumented) export type CacheClientSetOptions = CacheServiceSetOptions; -// Warning: (ae-forgotten-export) The symbol "CacheManager_2" needs to be exported by the entry point index.d.ts -// // @public @deprecated (undocumented) -export class CacheManager extends CacheManager_2 {} +export class CacheManager { + // (undocumented) + forPlugin(pluginId: string): PluginCacheManager; + static fromConfig( + config: RootConfigService, + options?: CacheManagerOptions, + ): CacheManager; +} // Warning: (ae-forgotten-export) The symbol "CacheManagerOptions_2" needs to be exported by the entry point index.d.ts // @@ -157,7 +162,10 @@ export class DatabaseManager implements LegacyRootDatabaseService { // (undocumented) static fromConfig( config: Config, - options?: DatabaseManagerOptions, + options?: { + migrations?: DatabaseService['migrations']; + logger?: LoggerService; + }, ): DatabaseManager; } @@ -173,11 +181,6 @@ export class DockerContainerRunner implements ContainerRunner { runContainer(options: RunContainerOptions): Promise; } -// Warning: (ae-forgotten-export) The symbol "dropDatabase_2" needs to be exported by the entry point index.d.ts -// -// @public @deprecated (undocumented) -export const dropDatabase: typeof dropDatabase_2; - // @public @deprecated export function errorHandler( options?: ErrorHandlerOptions, @@ -274,12 +277,7 @@ export class Git { // @public @deprecated class HostDiscovery implements DiscoveryService { - static fromConfig( - config: Config, - options?: { - basePath?: string; - }, - ): HostDiscovery; + static fromConfig(config: Config): HostDiscovery; // (undocumented) getBaseUrl(pluginId: string): Promise; // (undocumented) @@ -367,10 +365,10 @@ export const legacyPlugin: ( }>, ) => BackendFeature; -// Warning: (ae-forgotten-export) The symbol "LegacyRootDatabaseService_2" needs to be exported by the entry point index.d.ts -// // @public @deprecated (undocumented) -export type LegacyRootDatabaseService = LegacyRootDatabaseService_2; +export type LegacyRootDatabaseService = { + forPlugin(pluginId: string): DatabaseService; +}; // @public @deprecated export function loadBackendConfig(options: { @@ -413,10 +411,10 @@ export function makeLegacyPlugin< // @public @deprecated export function notFoundHandler(): RequestHandler; -// Warning: (ae-forgotten-export) The symbol "PluginCacheManager_2" needs to be exported by the entry point index.d.ts -// // @public @deprecated (undocumented) -export type PluginCacheManager = PluginCacheManager_2; +export type PluginCacheManager = { + getClient(options?: CacheServiceOptions): CacheService; +}; // @public @deprecated (undocumented) export type PluginDatabaseManager = DatabaseService; diff --git a/packages/backend-common/config.d.ts b/packages/backend-common/config.d.ts index ed253dd54d..6146adfe83 100644 --- a/packages/backend-common/config.d.ts +++ b/packages/backend-common/config.d.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { HumanDuration } from '@backstage/types'; + export interface Config { app: { baseUrl: string; // defined in core, but repeated here without doc @@ -180,7 +182,7 @@ export interface Config { | { store: 'memory'; /** An optional default TTL (in milliseconds). */ - defaultTtl?: number; + defaultTtl?: number | HumanDuration; } | { store: 'redis'; @@ -190,7 +192,7 @@ export interface Config { */ connection: string; /** An optional default TTL (in milliseconds). */ - defaultTtl?: number; + defaultTtl?: number | HumanDuration; /** * Whether or not [useRedisSets](https://github.com/jaredwray/keyv/tree/main/packages/redis#useredissets) should be configured to this redis cache. * Defaults to true if unspecified. @@ -205,9 +207,12 @@ export interface Config { */ connection: string; /** An optional default TTL (in milliseconds). */ - defaultTtl?: number; + defaultTtl?: number | HumanDuration; }; + /** + * Properties returned upon CORS requests to the backend, including the app-backend. + */ cors?: { origin?: string | string[]; methods?: string | string[]; @@ -219,6 +224,16 @@ export interface Config { optionsSuccessStatus?: number; }; + /** + * Content Security Policy options. + * + * The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The + * values are on the format that the helmet library expects them, as an + * array of strings. There is also the special value false, which means to + * remove the default value that Backstage puts in place for that policy. + */ + csp?: { [policyId: string]: string[] | false }; + /** * Configuration related to URL reading, used for example for reading catalog info * files, scaffolder templates, and techdocs content. @@ -246,15 +261,5 @@ export interface Config { paths?: string[]; }>; }; - - /** - * Content Security Policy options. - * - * The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The - * values are on the format that the helmet library expects them, as an - * array of strings. There is also the special value false, which means to - * remove the default value that Backstage puts in place for that policy. - */ - csp?: { [policyId: string]: string[] | false }; }; } diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index ce26958aaf..1e052c8eba 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-common", - "version": "0.24.0", + "version": "0.25.0-next.1", "description": "Common functionality library for Backstage backends", "backstage": { "role": "node-library" @@ -107,6 +107,7 @@ "p-limit": "^3.1.0", "path-to-regexp": "^6.2.1", "pg": "^8.11.3", + "pg-format": "^1.0.4", "raw-body": "^2.4.1", "selfsigned": "^2.0.0", "stoppable": "^1.1.0", diff --git a/packages/backend-common/src/deprecated/index.ts b/packages/backend-common/src/deprecated/index.ts index 5dfcd322ed..f769d4db09 100644 --- a/packages/backend-common/src/deprecated/index.ts +++ b/packages/backend-common/src/deprecated/index.ts @@ -23,17 +23,12 @@ import { HostDiscovery as _HostDiscovery } from '../../../backend-defaults/src/e import { CacheManager as _CacheManager } from '../../../backend-defaults/src/entrypoints/cache/CacheManager'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { - type PluginCacheManager as _PluginCacheManager, - type CacheManagerOptions as _CacheManagerOptions, -} from '../../../backend-defaults/src/entrypoints/cache/types'; +import { type CacheManagerOptions as _CacheManagerOptions } from '../../../backend-defaults/src/entrypoints/cache/types'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { - dropDatabase as _dropDatabase, DatabaseManager as _DatabaseManager, type DatabaseManagerOptions as _DatabaseManagerOptions, - type LegacyRootDatabaseService as _LegacyRootDatabaseService, } from '../../../backend-defaults/src/entrypoints/database/DatabaseManager'; import { @@ -48,6 +43,9 @@ import { isChildPath as _isChildPath, LifecycleService, PluginMetadataService, + DatabaseService, + LoggerService, + RootConfigService, } from '@backstage/backend-plugin-api'; export * from './hot'; @@ -98,11 +96,11 @@ export class HostDiscovery implements DiscoveryService { * plugins: [search] * ``` * - * The basePath defaults to `/api`, meaning the default full internal + * The fixed base path is `/api`, meaning the default full internal * path for the `catalog` plugin will be `http://localhost:7007/api/catalog`. */ - static fromConfig(config: Config, options?: { basePath?: string }) { - return new HostDiscovery(_HostDiscovery.fromConfig(config, options)); + static fromConfig(config: Config) { + return new HostDiscovery(_HostDiscovery.fromConfig(config)); } private constructor(private readonly impl: _HostDiscovery) {} @@ -133,7 +131,31 @@ export { HostDiscovery as SingleHostDiscovery }; * @public * @deprecated Use `CacheManager` from the `@backstage/backend-defaults` package instead */ -export class CacheManager extends _CacheManager {} +export class CacheManager { + /** + * Creates a new {@link CacheManager} instance by reading from the `backend` + * config section, specifically the `.cache` key. + * + * @param config - The loaded application configuration. + */ + static fromConfig( + config: RootConfigService, + options: CacheManagerOptions = {}, + ): CacheManager { + return new CacheManager(_CacheManager.fromConfig(config, options)); + } + + private constructor(private readonly _impl: _CacheManager) {} + + forPlugin(pluginId: string): PluginCacheManager { + return { + getClient: options => { + const result = this._impl.forPlugin(pluginId); + return options ? result.withOptions(options) : result; + }, + }; + } +} /** * @public @@ -145,7 +167,9 @@ export type CacheManagerOptions = _CacheManagerOptions; * @public * @deprecated Use `PluginCacheManager` from the `@backstage/backend-defaults` package instead */ -export type PluginCacheManager = _PluginCacheManager; +export type PluginCacheManager = { + getClient(options?: CacheServiceOptions): CacheService; +}; /** * @public @@ -170,14 +194,20 @@ export type CacheClientOptions = CacheServiceOptions; * @deprecated Use `DatabaseManager` from the `@backstage/backend-defaults` package instead */ export class DatabaseManager implements LegacyRootDatabaseService { - private constructor(private readonly _databaseManager: _DatabaseManager) {} + private constructor( + private readonly _databaseManager: _DatabaseManager, + private readonly logger?: LoggerService, + ) {} static fromConfig( config: Config, - options?: DatabaseManagerOptions, + options?: { + migrations?: DatabaseService['migrations']; + logger?: LoggerService; + }, ): DatabaseManager { const _databaseManager = _DatabaseManager.fromConfig(config, options); - return new DatabaseManager(_databaseManager); + return new DatabaseManager(_databaseManager, options?.logger); } forPlugin( @@ -186,7 +216,20 @@ export class DatabaseManager implements LegacyRootDatabaseService { | { lifecycle: LifecycleService; pluginMetadata: PluginMetadataService } | undefined, ): PluginDatabaseManager { - return this._databaseManager.forPlugin(pluginId, deps); + const logger: LoggerService = this.logger ?? { + debug() {}, + info() {}, + warn() {}, + error() {}, + child() { + return this; + }, + }; + const lifecycle: LifecycleService = deps?.lifecycle ?? { + addShutdownHook() {}, + addStartupHook() {}, + }; + return this._databaseManager.forPlugin(pluginId, { logger, lifecycle }); } } @@ -204,15 +247,11 @@ export type PluginDatabaseManager = _PluginDatabaseManager; /** * @public - * @deprecated Use `LegacyRootDatabaseService` from the `@backstage/backend-defaults` package instead + * @deprecated Use `DatabaseManager` from `@backstage/backend-defaults/database` instead, or migrate to the new backend system and use `coreServices.database` */ -export type LegacyRootDatabaseService = _LegacyRootDatabaseService; - -/** - * @public - * @deprecated Use `dropDatabase` from the `@backstage/backend-defaults` package instead - */ -export const dropDatabase = _dropDatabase; +export type LegacyRootDatabaseService = { + forPlugin(pluginId: string): DatabaseService; +}; /** * @public diff --git a/packages/backend-common/src/deprecated/util/DockerContainerRunner.ts b/packages/backend-common/src/deprecated/util/DockerContainerRunner.ts index ea576e4a3a..a9f5fb0432 100644 --- a/packages/backend-common/src/deprecated/util/DockerContainerRunner.ts +++ b/packages/backend-common/src/deprecated/util/DockerContainerRunner.ts @@ -64,11 +64,19 @@ export class DockerContainerRunner implements ContainerRunner { if (pullImage) { await new Promise((resolve, reject) => { this.dockerClient.pull(imageName, pullOptions, (err, stream) => { - if (err) return reject(err); - stream.pipe(logStream, { end: false }); - stream.on('end', () => resolve()); - stream.on('error', (error: Error) => reject(error)); - return undefined; + if (err) { + reject(err); + } else if (!stream) { + reject( + new Error( + 'Unexpeected error: no stream returned from Docker while pulling image', + ), + ); + } else { + stream.pipe(logStream, { end: false }); + stream.on('end', () => resolve()); + stream.on('error', (error: Error) => reject(error)); + } }); }); } @@ -99,7 +107,7 @@ export class DockerContainerRunner implements ContainerRunner { } // Create docker environment variables array - const Env = []; + const Env = new Array(); for (const [key, value] of Object.entries(envVars)) { Env.push(`${key}=${value}`); } diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 64d9b77fba..d9fa0e99f6 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,158 @@ # @backstage/backend-defaults +## 0.5.0-next.1 + +### Minor Changes + +- a4bac3c: **BREAKING**: You can no longer supply a `basePath` option to the host discovery implementation. In the new backend system, the ability to choose this path has been removed anyway at the plugin router level. +- 055b75b: **BREAKING**: Simplifications and cleanup as part of the Backend System 1.0 work. + + For the `/database` subpath exports: + + - The deprecated `dropDatabase` function has now been removed, without replacement. + - The deprecated `LegacyRootDatabaseService` type has now been removed. + - The return type from `DatabaseManager.forPlugin` is now directly a `DatabaseService`, as arguably expected. + - `DatabaseManager.forPlugin` now requires the `deps` argument, with the logger and lifecycle services. + + For the `/cache` subpath exports: + + - The `PluginCacheManager` type has been removed. You can still import it from `@backstage/backend-common`, but it's deprecated there, and you should move off of that package by migrating fully to the new backend system. + - Accordingly, `CacheManager.forPlugin` immediately returns a `CacheService` instead of a `PluginCacheManager`. The outcome of this is that you no longer need to make the extra `.getClient()` call. The old `CacheManager` with the old behavior still exists on `@backstage/backend-common`, but the above recommendations apply. + +### Patch Changes + +- 622360e: Move down the discovery config to be in the root +- fe6fd8c: Accept `ConfigService` instead of `Config` in constructors/factories +- 5705424: Wrap scheduled tasks from the scheduler core service now in OpenTelemetry spans +- b2a329d: Properly indent the config schema +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-app-api@0.10.0-next.1 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## 0.5.0-next.0 + +### Minor Changes + +- 359fcd7: **BREAKING**: The backwards compatibility with plugins using legacy auth through the token manager service has been removed. This means that instead of falling back to using the old token manager, requests towards plugins that don't support the new auth system will simply fail. Please make sure that all plugins in your deployment are hosted within a backend instance from the new backend system. +- 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. + +- 19ff127: **BREAKING**: The default backend instance no longer provides implementations for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. + + If you rely on plugins that still require these services, you can add them to your own backend by re-creating the service reference and factory. + + The following can be used to implement the identity service: + + ```ts + import { + coreServices, + createServiceFactory, + createServiceRef, + } from '@backstage/backend-plugin-api'; + import { + DefaultIdentityClient, + IdentityApi, + } from '@backstage/plugin-auth-node'; + + backend.add( + createServiceFactory({ + service: createServiceRef({ id: 'core.identity' }), + deps: { + discovery: coreServices.discovery, + }, + async factory({ discovery }) { + return DefaultIdentityClient.create({ discovery }); + }, + }), + ); + ``` + + The following can be used to implement the token manager service: + + ```ts + import { ServerTokenManager, TokenManager } from '@backstage/backend-common'; + import { createBackend } from '@backstage/backend-defaults'; + import { + coreServices, + createServiceFactory, + createServiceRef, + } from '@backstage/backend-plugin-api'; + + backend.add( + createServiceFactory({ + service: createServiceRef({ id: 'core.tokenManager' }), + deps: { + config: coreServices.rootConfig, + logger: coreServices.rootLogger, + }, + createRootContext({ config, logger }) { + return ServerTokenManager.fromConfig(config, { + logger, + allowDisabledTokenManager: true, + }); + }, + async factory(_deps, tokenManager) { + return tokenManager; + }, + }), + ); + ``` + +### Patch Changes + +- 7f779c7: `auth.externalAccess` should be optional in the config schema +- 7a72ec8: Exports the `discoveryFeatureLoader` as a replacement for the deprecated `featureDiscoveryService`. + The `discoveryFeatureLoader` is a new backend system [feature loader](https://backstage.io/docs/backend-system/architecture/feature-loaders/) that discovers backend features from the current `package.json` and its dependencies. + Here is an example using the `discoveryFeatureLoader` loader in a new backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { discoveryFeatureLoader } from '@backstage/backend-defaults'; + //... + + const backend = createBackend(); + //... + backend.add(discoveryFeatureLoader); + //... + backend.start(); + ``` + +- 66dbf0a: Allow the cache service to accept the human duration format for TTL +- 5a8fcb4: Added the option to skip database migrations by setting `skipMigrations: true` in config. This can be done globally in the database config or by plugin id. +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/backend-app-api@0.10.0-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + ## 0.4.2 ### Patch Changes diff --git a/packages/backend-defaults/api-report-cache.md b/packages/backend-defaults/api-report-cache.md index 58106430ab..ecda42f983 100644 --- a/packages/backend-defaults/api-report-cache.md +++ b/packages/backend-defaults/api-report-cache.md @@ -4,16 +4,15 @@ ```ts import { CacheService } from '@backstage/backend-plugin-api'; -import { CacheServiceOptions } from '@backstage/backend-plugin-api'; -import { Config } from '@backstage/config'; import { LoggerService } from '@backstage/backend-plugin-api'; +import { RootConfigService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; // @public export class CacheManager { - forPlugin(pluginId: string): PluginCacheManager; + forPlugin(pluginId: string): CacheService; static fromConfig( - config: Config, + config: RootConfigService, options?: CacheManagerOptions, ): CacheManager; } @@ -31,11 +30,5 @@ export const cacheServiceFactory: ServiceFactory< 'singleton' >; -// @public (undocumented) -export interface PluginCacheManager { - // (undocumented) - getClient(options?: CacheServiceOptions): CacheService; -} - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-database.md b/packages/backend-defaults/api-report-database.md index 10de8df1ff..d9e9e9e287 100644 --- a/packages/backend-defaults/api-report-database.md +++ b/packages/backend-defaults/api-report-database.md @@ -3,24 +3,23 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { Config } from '@backstage/config'; import { DatabaseService } from '@backstage/backend-plugin-api'; import { LifecycleService } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; -import { PluginMetadataService } from '@backstage/backend-plugin-api'; +import { RootConfigService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; // @public -export class DatabaseManager implements LegacyRootDatabaseService { +export class DatabaseManager { forPlugin( pluginId: string, - deps?: { + deps: { + logger: LoggerService; lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; }, ): DatabaseService; static fromConfig( - config: Config, + config: RootConfigService, options?: DatabaseManagerOptions, ): DatabaseManager; } @@ -28,7 +27,6 @@ export class DatabaseManager implements LegacyRootDatabaseService { // @public export type DatabaseManagerOptions = { migrations?: DatabaseService['migrations']; - logger?: LoggerService; }; // @public @@ -38,16 +36,5 @@ export const databaseServiceFactory: ServiceFactory< 'singleton' >; -// @public @deprecated -export function dropDatabase( - dbConfig: Config, - ...databaseNames: string[] -): Promise; - -// @public -export type LegacyRootDatabaseService = { - forPlugin(pluginId: string): DatabaseService; -}; - // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/api-report-discovery.md b/packages/backend-defaults/api-report-discovery.md index de60256f02..d168d33a71 100644 --- a/packages/backend-defaults/api-report-discovery.md +++ b/packages/backend-defaults/api-report-discovery.md @@ -3,8 +3,8 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { Config } from '@backstage/config'; import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { RootConfigService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; // @public @@ -16,12 +16,7 @@ export const discoveryServiceFactory: ServiceFactory< // @public export class HostDiscovery implements DiscoveryService { - static fromConfig( - config: Config, - options?: { - basePath?: string; - }, - ): HostDiscovery; + static fromConfig(config: RootConfigService): HostDiscovery; // (undocumented) getBaseUrl(pluginId: string): Promise; // (undocumented) diff --git a/packages/backend-defaults/api-report-urlReader.md b/packages/backend-defaults/api-report-urlReader.md index 73fbcd60ac..f8b8db2954 100644 --- a/packages/backend-defaults/api-report-urlReader.md +++ b/packages/backend-defaults/api-report-urlReader.md @@ -12,7 +12,6 @@ import { AzureIntegration } from '@backstage/integration'; import { BitbucketCloudIntegration } from '@backstage/integration'; import { BitbucketIntegration } from '@backstage/integration'; import { BitbucketServerIntegration } from '@backstage/integration'; -import { Config } from '@backstage/config'; import { GerritIntegration } from '@backstage/integration'; import { GiteaIntegration } from '@backstage/integration'; import { GithubCredentialsProvider } from '@backstage/integration'; @@ -21,6 +20,7 @@ import { GitLabIntegration } from '@backstage/integration'; import { HarnessIntegration } from '@backstage/integration'; import { LoggerService } from '@backstage/backend-plugin-api'; import { Readable } from 'stream'; +import { RootConfigService } from '@backstage/backend-plugin-api'; import { ServiceFactory } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; import { UrlReaderService } from '@backstage/backend-plugin-api'; @@ -360,7 +360,7 @@ export class HarnessUrlReader implements UrlReaderService { // @public export type ReaderFactory = (options: { - config: Config; + config: RootConfigService; logger: LoggerService; treeResponseFactory: ReadTreeResponseFactory; }) => UrlReaderPredicateTuple[]; @@ -442,7 +442,7 @@ export const urlReaderServiceFactory: ServiceFactory< // @public export type UrlReadersOptions = { - config: Config; + config: RootConfigService; logger: LoggerService; factories?: ReaderFactory[]; }; diff --git a/packages/backend-defaults/api-report.md b/packages/backend-defaults/api-report.md index ab9cc5775c..def38beda7 100644 --- a/packages/backend-defaults/api-report.md +++ b/packages/backend-defaults/api-report.md @@ -4,7 +4,11 @@ ```ts import { Backend } from '@backstage/backend-app-api'; +import { BackendFeature } from '@backstage/backend-plugin-api'; // @public (undocumented) export function createBackend(): Backend; + +// @public +export const discoveryFeatureLoader: BackendFeature; ``` diff --git a/packages/backend-defaults/config.d.ts b/packages/backend-defaults/config.d.ts index 1582cf1a39..a8c6e1c290 100644 --- a/packages/backend-defaults/config.d.ts +++ b/packages/backend-defaults/config.d.ts @@ -14,8 +14,51 @@ * limitations under the License. */ +import { HumanDuration } from '@backstage/types'; + export interface Config { + app: { + baseUrl: string; // defined in core, but repeated here without doc + }; + backend?: { + /** + * The full base URL of the backend, as seen from the browser's point of + * view as it makes calls to the backend. + */ + baseUrl: string; + + /** Address that the backend should listen to. */ + listen?: + | string + | { + /** Address of the interface that the backend should bind to. */ + host?: string; + /** Port that the backend should listen to. */ + port?: string | number; + }; + + /** + * HTTPS configuration for the backend. If omitted the backend will serve HTTP. + * + * Setting this to `true` will cause self-signed certificates to be generated, which + * can be useful for local development or other non-production scenarios. + */ + https?: + | true + | { + /** Certificate configuration */ + certificate?: { + /** PEM encoded certificate. Use $file to load in a file */ + cert: string; + /** + * PEM encoded certificate key. Use $file to load in a file. + * @visibility secret + */ + key: string; + }; + }; + /** * Options used by the default auth, httpAuth and userInfo services. */ @@ -330,6 +373,184 @@ export interface Config { } >; }; + + /** Database connection configuration, select base database type using the `client` field */ + database: { + /** Default database client to use */ + client: 'better-sqlite3' | 'sqlite3' | 'pg'; + /** + * Base database connection string, or object with individual connection properties + * @visibility secret + */ + connection: + | string + | { + /** + * Password that belongs to the client User + * @visibility secret + */ + password?: string; + /** + * Other connection settings + */ + [key: string]: unknown; + }; + /** Database name prefix override */ + prefix?: string; + /** + * Whether to ensure the given database exists by creating it if it does not. + * Defaults to true if unspecified. + */ + ensureExists?: boolean; + /** + * Whether to ensure the given database schema exists by creating it if it does not. + * Defaults to false if unspecified. + * + * NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema + */ + ensureSchemaExists?: boolean; + /** + * How plugins databases are managed/divided in the provided database instance. + * + * `database` -> Plugins are each given their own database to manage their schemas/tables. + * + * `schema` -> Plugins will be given their own schema (in the specified/default database) + * to manage their tables. + * + * NOTE: Currently only supported by the `pg` client. + * + * @default database + */ + pluginDivisionMode?: 'database' | 'schema'; + /** Configures the ownership of newly created schemas in pg databases. */ + role?: string; + /** + * Arbitrary config object to pass to knex when initializing + * (https://knexjs.org/#Installation-client). Most notable is the debug + * and asyncStackTraces booleans + */ + knexConfig?: object; + /** Skip running database migrations. */ + skipMigrations?: boolean; + /** Plugin specific database configuration and client override */ + plugin?: { + [pluginId: string]: { + /** Database client override */ + client?: 'better-sqlite3' | 'sqlite3' | 'pg'; + /** + * Database connection string or Knex object override + * @visibility secret + */ + connection?: string | object; + /** + * Whether to ensure the given database exists by creating it if it does not. + * Defaults to base config if unspecified. + */ + ensureExists?: boolean; + /** + * Whether to ensure the given database schema exists by creating it if it does not. + * Defaults to false if unspecified. + * + * NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema + */ + ensureSchemaExists?: boolean; + /** + * Arbitrary config object to pass to knex when initializing + * (https://knexjs.org/#Installation-client). Most notable is the + * debug and asyncStackTraces booleans. + * + * This is merged recursively into the base knexConfig + */ + knexConfig?: object; + /** Configures the ownership of newly created schemas in pg databases. */ + role?: string; + /** Skip running database migrations. */ + skipMigrations?: boolean; + }; + }; + }; + + /** Cache connection configuration, select cache type using the `store` field */ + cache?: + | { + store: 'memory'; + /** An optional default TTL (in milliseconds). */ + defaultTtl?: number | HumanDuration; + } + | { + store: 'redis'; + /** + * A redis connection string in the form `redis://user:pass@host:port`. + * @visibility secret + */ + connection: string; + /** An optional default TTL (in milliseconds). */ + defaultTtl?: number | HumanDuration; + /** + * Whether or not [useRedisSets](https://github.com/jaredwray/keyv/tree/main/packages/redis#useredissets) should be configured to this redis cache. + * Defaults to true if unspecified. + */ + useRedisSets?: boolean; + } + | { + store: 'memcache'; + /** + * A memcache connection string in the form `user:pass@host:port`. + * @visibility secret + */ + connection: string; + /** An optional default TTL (in milliseconds). */ + defaultTtl?: number | HumanDuration; + }; + + cors?: { + origin?: string | string[]; + methods?: string | string[]; + allowedHeaders?: string | string[]; + exposedHeaders?: string | string[]; + credentials?: boolean; + maxAge?: number; + preflightContinue?: boolean; + optionsSuccessStatus?: number; + }; + + /** + * Content Security Policy options. + * + * The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The + * values are on the format that the helmet library expects them, as an + * array of strings. There is also the special value false, which means to + * remove the default value that Backstage puts in place for that policy. + */ + csp?: { [policyId: string]: string[] | false }; + + /** + * Configuration related to URL reading, used for example for reading catalog info + * files, scaffolder templates, and techdocs content. + */ + reading?: { + /** + * A list of targets to allow outgoing requests to. Users will be able to make + * requests on behalf of the backend to the targets that are allowed by this list. + */ + allow?: Array<{ + /** + * A host to allow outgoing requests to, being either a full host or + * a subdomain wildcard pattern with a leading `*`. For example `example.com` + * and `*.example.com` are valid values, `prod.*.example.com` is not. + * The host may also contain a port, for example `example.com:8080`. + */ + host: string; + + /** + * An optional list of paths. In case they are present only targets matching + * any of them will are allowed. You can use trailing slashes to make sure only + * subdirectories are allowed, for example `/mydir/` will allow targets with + * paths like `/mydir/a` but will block paths like `/mydir2`. + */ + paths?: string[]; + }>; + }; }; /** diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 3280a3cf9d..2f157580bb 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.4.2", + "version": "0.5.0-next.1", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" @@ -124,6 +124,7 @@ "@backstage/backend-dev-utils": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/cli-common": "workspace:^", + "@backstage/cli-node": "workspace:^", "@backstage/config": "workspace:^", "@backstage/config-loader": "workspace:^", "@backstage/errors": "workspace:^", diff --git a/packages/backend-defaults/src/PackageDiscoveryService.ts b/packages/backend-defaults/src/PackageDiscoveryService.ts new file mode 100644 index 0000000000..d7d127f4fa --- /dev/null +++ b/packages/backend-defaults/src/PackageDiscoveryService.ts @@ -0,0 +1,170 @@ +/* + * 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 fs from 'fs-extra'; +import { resolve as resolvePath, dirname } from 'path'; + +import { + BackendFeature, + RootConfigService, + RootLoggerService, +} from '@backstage/backend-plugin-api'; +import { FeatureDiscoveryService } from '@backstage/backend-plugin-api/alpha'; +import { BackstagePackageJson } from '@backstage/cli-node'; + +const DETECTED_PACKAGE_ROLES = [ + 'node-library', + 'backend', + 'backend-plugin', + 'backend-plugin-module', +]; + +/** @internal */ +function isBackendFeature(value: unknown): value is BackendFeature { + return ( + !!value && + ['object', 'function'].includes(typeof value) && + (value as BackendFeature).$$type === '@backstage/BackendFeature' + ); +} + +/** @internal */ +function isBackendFeatureFactory( + value: unknown, +): value is () => BackendFeature { + return ( + !!value && + typeof value === 'function' && + (value as any).$$type === '@backstage/BackendFeatureFactory' + ); +} + +/** @internal */ +async function findClosestPackageDir( + searchDir: string, +): Promise { + let path = searchDir; + + // Some confidence check to avoid infinite loop + for (let i = 0; i < 1000; i++) { + const packagePath = resolvePath(path, 'package.json'); + const exists = await fs.pathExists(packagePath); + if (exists) { + return path; + } + + const newPath = dirname(path); + if (newPath === path) { + return undefined; + } + path = newPath; + } + + throw new Error( + `Iteration limit reached when searching for root package.json at ${searchDir}`, + ); +} + +/** @internal */ +export class PackageDiscoveryService implements FeatureDiscoveryService { + constructor( + private readonly config: RootConfigService, + private readonly logger: RootLoggerService, + ) {} + + getDependencyNames(path: string) { + const { dependencies } = require(path) as BackstagePackageJson; + const packagesConfig = this.config.getOptional('backend.packages'); + + const dependencyNames = Object.keys(dependencies || {}); + + if (packagesConfig === 'all') { + return dependencyNames; + } + + const includedPackagesConfig = this.config.getOptionalStringArray( + 'backend.packages.include', + ); + + const includedPackages = includedPackagesConfig + ? new Set(includedPackagesConfig) + : dependencyNames; + const excludedPackagesSet = new Set( + this.config.getOptionalStringArray('backend.packages.exclude'), + ); + + return [...includedPackages].filter(name => !excludedPackagesSet.has(name)); + } + + async getBackendFeatures(): Promise<{ features: Array }> { + const packagesConfig = this.config.getOptional('backend.packages'); + if (!packagesConfig || Object.keys(packagesConfig).length === 0) { + return { features: [] }; + } + + const packageDir = await findClosestPackageDir(process.argv[1]); + if (!packageDir) { + throw new Error('Package discovery failed to find package.json'); + } + const dependencyNames = this.getDependencyNames( + resolvePath(packageDir, 'package.json'), + ); + + const features: BackendFeature[] = []; + + for (const name of dependencyNames) { + const depPkg = require(require.resolve(`${name}/package.json`, { + paths: [packageDir], + })) as BackstagePackageJson; + if ( + !depPkg?.backstage?.role || + !DETECTED_PACKAGE_ROLES.includes(depPkg.backstage.role) + ) { + continue; // Not a backstage backend package, ignore + } + + const exportedModulePaths = [ + require.resolve(name, { + paths: [packageDir], + }), + ]; + + // Find modules exported as alpha + try { + exportedModulePaths.push( + require.resolve(`${name}/alpha`, { paths: [packageDir] }), + ); + } catch { + /* ignore */ + } + + for (const modulePath of exportedModulePaths) { + const mod = require(modulePath); + + if (isBackendFeature(mod.default)) { + this.logger.info(`Detected: ${name}`); + features.push(mod.default); + } + if (isBackendFeatureFactory(mod.default)) { + this.logger.info(`Detected: ${name}`); + features.push(mod.default()); + } + } + } + + return { features }; + } +} diff --git a/packages/backend-defaults/src/discoveryFeatureLoader.ts b/packages/backend-defaults/src/discoveryFeatureLoader.ts new file mode 100644 index 0000000000..dc3c9c1d90 --- /dev/null +++ b/packages/backend-defaults/src/discoveryFeatureLoader.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + coreServices, + createBackendFeatureLoader, +} from '@backstage/backend-plugin-api'; +import { PackageDiscoveryService } from './PackageDiscoveryService'; + +/** + * A loader that discovers backend features from the current package.json and its dependencies. + * + * @public + * + * @example + * Using the `discoveryFeatureLoader` loader in a backend instance: + * ```ts + * //... + * import { createBackend } from '@backstage/backend-defaults'; + * import { discoveryFeatureLoader } from '@backstage/backend-defaults'; + * + * const backend = createBackend(); + * backend.add(discoveryFeatureLoader); + * //... + * backend.start(); + * ``` + */ +export const discoveryFeatureLoader = createBackendFeatureLoader({ + deps: { + config: coreServices.rootConfig, + logger: coreServices.rootLogger, + }, + async loader({ config, logger }) { + const service = new PackageDiscoveryService(config, logger); + const { features } = await service.getBackendFeatures(); + return features; + }, +}); diff --git a/packages/backend-defaults/src/entrypoints/cache/CacheClient.ts b/packages/backend-defaults/src/entrypoints/cache/CacheClient.ts index aba62558d4..f519daa6df 100644 --- a/packages/backend-defaults/src/entrypoints/cache/CacheClient.ts +++ b/packages/backend-defaults/src/entrypoints/cache/CacheClient.ts @@ -22,6 +22,7 @@ import { import { JsonValue } from '@backstage/types'; import { createHash } from 'crypto'; import Keyv from 'keyv'; +import { ttlToMilliseconds } from './types'; export type CacheClientFactory = (options: CacheServiceOptions) => Keyv; @@ -58,7 +59,9 @@ export class DefaultCacheClient implements CacheService { opts: CacheServiceSetOptions = {}, ): Promise { const k = this.getNormalizedKey(key); - await this.#client.set(k, value, opts.ttl); + const ttl = + opts.ttl !== undefined ? ttlToMilliseconds(opts.ttl) : undefined; + await this.#client.set(k, value, ttl); } async delete(key: string): Promise { diff --git a/packages/backend-defaults/src/entrypoints/cache/CacheManager.test.ts b/packages/backend-defaults/src/entrypoints/cache/CacheManager.test.ts index 6eb907764d..997739faa2 100644 --- a/packages/backend-defaults/src/entrypoints/cache/CacheManager.test.ts +++ b/packages/backend-defaults/src/entrypoints/cache/CacheManager.test.ts @@ -52,10 +52,10 @@ describe('CacheManager integration', () => { }), ); - manager.forPlugin('p1').getClient(); - manager.forPlugin('p1').getClient({ defaultTtl: 200 }); - manager.forPlugin('p2').getClient(); - manager.forPlugin('p3').getClient({}); + manager.forPlugin('p1'); + manager.forPlugin('p1').withOptions({ defaultTtl: 200 }); + manager.forPlugin('p2'); + manager.forPlugin('p3').withOptions({}); if (store === 'redis') { // eslint-disable-next-line jest/no-conditional-expect @@ -80,9 +80,11 @@ describe('CacheManager integration', () => { }), ); - const plugin1 = manager.forPlugin('p1').getClient(); - const plugin2a = manager.forPlugin('p2').getClient(); - const plugin2b = manager.forPlugin('p2').getClient({ defaultTtl: 2000 }); + const plugin1 = manager.forPlugin('p1'); + const plugin2a = manager.forPlugin('p2'); + const plugin2b = manager + .forPlugin('p2') + .withOptions({ defaultTtl: 2000 }); await plugin1.set('a', 'plugin1'); await plugin2a.set('a', 'plugin2a'); @@ -93,4 +95,96 @@ describe('CacheManager integration', () => { await expect(plugin2b.get('a')).resolves.toBe('plugin2b'); }, ); + + it.each(caches.eachSupportedId())( + 'supports both milliseconds and human durations throughout, %p', + async cacheId => { + const { store, connection } = await caches.init(cacheId); + + for (const defaultTtl of [200, { milliseconds: 200 }]) { + const manager = CacheManager.fromConfig( + mockServices.rootConfig({ + data: { + backend: { + cache: { + store, + connection, + defaultTtl, + }, + }, + }, + }), + ).forPlugin('p'); + + const defaultClient = manager; + const numberOverrideClient = manager.withOptions({ defaultTtl: 400 }); + const durationOverrideClient = manager.withOptions({ + defaultTtl: { milliseconds: 400 }, + }); + + await defaultClient.set('a', 'x'); + await defaultClient.set('b', 'x'); + await numberOverrideClient.set('c', 'x'); + await durationOverrideClient.set('d', 'x'); + await defaultClient.set('e', 'x', { ttl: 400 }); + await defaultClient.set('f', 'x', { ttl: { milliseconds: 400 } }); + + await expect(defaultClient.get('a')).resolves.toBe('x'); + await expect(defaultClient.get('b')).resolves.toBe('x'); + await expect(defaultClient.get('c')).resolves.toBe('x'); + await expect(defaultClient.get('d')).resolves.toBe('x'); + await expect(defaultClient.get('e')).resolves.toBe('x'); + await expect(defaultClient.get('f')).resolves.toBe('x'); + + await new Promise(resolve => setTimeout(resolve, 50 + 200)); + + await expect(defaultClient.get('a')).resolves.toBeUndefined(); + await expect(defaultClient.get('b')).resolves.toBeUndefined(); + await expect(defaultClient.get('c')).resolves.toBe('x'); + await expect(defaultClient.get('d')).resolves.toBe('x'); + await expect(defaultClient.get('e')).resolves.toBe('x'); + await expect(defaultClient.get('f')).resolves.toBe('x'); + + await new Promise(resolve => setTimeout(resolve, 200)); + + await expect(defaultClient.get('a')).resolves.toBeUndefined(); + await expect(defaultClient.get('b')).resolves.toBeUndefined(); + await expect(defaultClient.get('c')).resolves.toBeUndefined(); + await expect(defaultClient.get('d')).resolves.toBeUndefined(); + await expect(defaultClient.get('e')).resolves.toBeUndefined(); + await expect(defaultClient.get('f')).resolves.toBeUndefined(); + } + }, + ); + + it('rejects invalid defaultTtl', () => { + expect(() => + CacheManager.fromConfig( + mockServices.rootConfig({ + data: { + backend: { + cache: { + store: 'memory', + }, + }, + }, + }), + ), + ).not.toThrow(); + + expect(() => + CacheManager.fromConfig( + mockServices.rootConfig({ + data: { + backend: { + cache: { + store: 'memory', + defaultTtl: 'hello', + }, + }, + }, + }), + ), + ).toThrow(/Invalid configuration backend.cache.defaultTtl/); + }); }); diff --git a/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts b/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts index 873bcf9648..41fe595123 100644 --- a/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts +++ b/packages/backend-defaults/src/entrypoints/cache/CacheManager.ts @@ -15,13 +15,15 @@ */ import { + CacheService, CacheServiceOptions, LoggerService, + RootConfigService, } from '@backstage/backend-plugin-api'; -import { Config } from '@backstage/config'; import Keyv from 'keyv'; import { DefaultCacheClient } from './CacheClient'; -import { CacheManagerOptions, PluginCacheManager } from './types'; +import { CacheManagerOptions, ttlToMilliseconds } from './types'; +import { durationToMilliseconds } from '@backstage/types'; type StoreFactory = (pluginId: string, defaultTtl: number | undefined) => Keyv; @@ -57,13 +59,13 @@ export class CacheManager { * @param config - The loaded application configuration. */ static fromConfig( - config: Config, + config: RootConfigService, options: CacheManagerOptions = {}, ): CacheManager { // If no `backend.cache` config is provided, instantiate the CacheManager // with an in-memory cache client. const store = config.getOptionalString('backend.cache.store') || 'memory'; - const defaultTtl = config.getOptionalNumber('backend.cache.defaultTtl'); + const defaultTtlConfig = config.getOptional('backend.cache.defaultTtl'); const connectionString = config.getOptionalString('backend.cache.connection') || ''; const useRedisSets = @@ -71,6 +73,23 @@ export class CacheManager { const logger = options.logger?.child({ type: 'cacheManager', }); + + let defaultTtl: number | undefined; + if (defaultTtlConfig !== undefined && defaultTtlConfig !== null) { + if (typeof defaultTtlConfig === 'number') { + defaultTtl = defaultTtlConfig; + } else if ( + typeof defaultTtlConfig === 'object' && + !Array.isArray(defaultTtlConfig) + ) { + defaultTtl = durationToMilliseconds(defaultTtlConfig); + } else { + throw new Error( + `Invalid configuration backend.cache.defaultTtl: ${defaultTtlConfig}, expected milliseconds number or HumanDuration object`, + ); + } + } + return new CacheManager( store, connectionString, @@ -107,23 +126,16 @@ export class CacheManager { * @param pluginId - The plugin that the cache manager should be created for. * Plugin names should be unique. */ - forPlugin(pluginId: string): PluginCacheManager { - return { - getClient: (defaultOptions = {}) => { - const clientFactory = (options: CacheServiceOptions) => { - return this.getClientWithTtl( - pluginId, - options.defaultTtl ?? this.defaultTtl, - ); - }; - - return new DefaultCacheClient( - clientFactory(defaultOptions), - clientFactory, - defaultOptions, - ); - }, + forPlugin(pluginId: string): CacheService { + const clientFactory = (options: CacheServiceOptions) => { + const ttl = options.defaultTtl ?? this.defaultTtl; + return this.getClientWithTtl( + pluginId, + ttl !== undefined ? ttlToMilliseconds(ttl) : undefined, + ); }; + + return new DefaultCacheClient(clientFactory({}), clientFactory, {}); } private getClientWithTtl(pluginId: string, ttl: number | undefined): Keyv { diff --git a/packages/backend-defaults/src/entrypoints/cache/cacheServiceFactory.ts b/packages/backend-defaults/src/entrypoints/cache/cacheServiceFactory.ts index f16b306d81..352cde44d7 100644 --- a/packages/backend-defaults/src/entrypoints/cache/cacheServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/cache/cacheServiceFactory.ts @@ -40,6 +40,6 @@ export const cacheServiceFactory = createServiceFactory({ return CacheManager.fromConfig(config, { logger }); }, async factory({ plugin }, manager) { - return manager.forPlugin(plugin.getId()).getClient(); + return manager.forPlugin(plugin.getId()); }, }); diff --git a/packages/backend-defaults/src/entrypoints/cache/index.ts b/packages/backend-defaults/src/entrypoints/cache/index.ts index b16fa56bd2..958fa36091 100644 --- a/packages/backend-defaults/src/entrypoints/cache/index.ts +++ b/packages/backend-defaults/src/entrypoints/cache/index.ts @@ -16,4 +16,4 @@ export { cacheServiceFactory } from './cacheServiceFactory'; export { CacheManager } from './CacheManager'; -export type { CacheManagerOptions, PluginCacheManager } from './types'; +export type { CacheManagerOptions } from './types'; diff --git a/packages/backend-defaults/src/entrypoints/cache/types.ts b/packages/backend-defaults/src/entrypoints/cache/types.ts index ccb3ed5f6d..7260099a0a 100644 --- a/packages/backend-defaults/src/entrypoints/cache/types.ts +++ b/packages/backend-defaults/src/entrypoints/cache/types.ts @@ -15,10 +15,7 @@ */ import { LoggerService } from '@backstage/backend-plugin-api'; -import { - CacheService, - CacheServiceOptions, -} from '@backstage/backend-plugin-api'; +import { HumanDuration, durationToMilliseconds } from '@backstage/types'; /** * Options given when constructing a {@link CacheManager}. @@ -38,9 +35,6 @@ export type CacheManagerOptions = { onError?: (err: Error) => void; }; -/** - * @public - */ -export interface PluginCacheManager { - getClient(options?: CacheServiceOptions): CacheService; +export function ttlToMilliseconds(ttl: number | HumanDuration): number { + return typeof ttl === 'number' ? ttl : durationToMilliseconds(ttl); } diff --git a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.test.ts b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.test.ts index 347ec742c0..26c2d54231 100644 --- a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.test.ts +++ b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.test.ts @@ -17,20 +17,24 @@ import { ConfigReader } from '@backstage/config'; import { DatabaseManagerImpl } from './DatabaseManager'; import { Connector } from './types'; +import { mockServices } from '@backstage/backend-test-utils'; describe('DatabaseManagerImpl', () => { afterEach(() => { jest.clearAllMocks(); }); + const deps = { + logger: mockServices.logger.mock(), + lifecycle: mockServices.lifecycle.mock(), + }; + it('calls the right connector, only once per plugin id', async () => { const connector1 = { getClient: jest.fn(), - dropDatabase: jest.fn(), } satisfies Connector; const connector2 = { getClient: jest.fn(), - dropDatabase: jest.fn(), } satisfies Connector; const impl = new DatabaseManagerImpl( @@ -43,30 +47,28 @@ describe('DatabaseManagerImpl', () => { }, ); - await impl.forPlugin('plugin1').getClient(); + await impl.forPlugin('plugin1', deps).getClient(); expect(connector1.getClient).toHaveBeenCalledTimes(1); - expect(connector1.getClient).toHaveBeenLastCalledWith('plugin1', undefined); + expect(connector1.getClient).toHaveBeenLastCalledWith('plugin1', deps); expect(connector2.getClient).toHaveBeenCalledTimes(0); - await impl.forPlugin('plugin1').getClient(); + await impl.forPlugin('plugin1', deps).getClient(); expect(connector1.getClient).toHaveBeenCalledTimes(1); - expect(connector1.getClient).toHaveBeenLastCalledWith('plugin1', undefined); + expect(connector1.getClient).toHaveBeenLastCalledWith('plugin1', deps); expect(connector2.getClient).toHaveBeenCalledTimes(0); - await impl.forPlugin('plugin2').getClient(); + await impl.forPlugin('plugin2', deps).getClient(); expect(connector1.getClient).toHaveBeenCalledTimes(2); - expect(connector1.getClient).toHaveBeenLastCalledWith('plugin2', undefined); + expect(connector1.getClient).toHaveBeenLastCalledWith('plugin2', deps); expect(connector2.getClient).toHaveBeenCalledTimes(0); }); it('respects per-plugin overridden connectors', async () => { const connector1 = { getClient: jest.fn(), - dropDatabase: jest.fn(), } satisfies Connector; const connector2 = { getClient: jest.fn(), - dropDatabase: jest.fn(), } satisfies Connector; const impl = new DatabaseManagerImpl( @@ -84,39 +86,93 @@ describe('DatabaseManagerImpl', () => { }, ); - await impl.forPlugin('plugin1').getClient(); + await impl.forPlugin('plugin1', deps).getClient(); expect(connector1.getClient).toHaveBeenCalledTimes(1); - expect(connector1.getClient).toHaveBeenLastCalledWith('plugin1', undefined); + expect(connector1.getClient).toHaveBeenLastCalledWith('plugin1', deps); expect(connector2.getClient).toHaveBeenCalledTimes(0); - await impl.forPlugin('plugin2').getClient(); + await impl.forPlugin('plugin2', deps).getClient(); expect(connector1.getClient).toHaveBeenCalledTimes(1); - expect(connector1.getClient).toHaveBeenLastCalledWith('plugin1', undefined); + expect(connector1.getClient).toHaveBeenLastCalledWith('plugin1', deps); expect(connector2.getClient).toHaveBeenCalledTimes(1); - expect(connector2.getClient).toHaveBeenLastCalledWith('plugin2', undefined); + expect(connector2.getClient).toHaveBeenLastCalledWith('plugin2', deps); }); - it('retains the migration skip info', async () => { + it('migration skip options take precedence over config', async () => { const connector = { getClient: jest.fn(), - dropDatabase: jest.fn(), } satisfies Connector; + const impl = new DatabaseManagerImpl( + new ConfigReader({ + client: 'pg', + backend: { + database: { + skipMigrations: true, + plugin: { plugin1: { skipMigrations: true } }, + }, + }, + }), + { + pg: connector, + }, + { migrations: { skip: false } }, + ); + expect((await impl.forPlugin('plugin1', deps)).migrations).toEqual({ + skip: false, + }); + const impl1 = new DatabaseManagerImpl(new ConfigReader({ client: 'pg' }), { pg: connector, }); - const impl2 = new DatabaseManagerImpl( - new ConfigReader({ client: 'pg' }), - { pg: connector }, - { migrations: { skip: true } }, + expect((await impl1.forPlugin('plugin1', deps)).migrations).toEqual({ + skip: false, + }); + }); + + it('plugin can skip migrations using config', async () => { + const connector = { + getClient: jest.fn(), + } satisfies Connector; + + const impl = new DatabaseManagerImpl( + new ConfigReader({ + client: 'pg', + backend: { + database: { plugin: { plugin1: { skipMigrations: true } } }, + }, + }), + { + pg: connector, + }, ); - expect((await impl1.forPlugin('plugin1')).migrations).toEqual({ + expect((await impl.forPlugin('plugin1', deps)).migrations).toEqual({ + skip: true, + }); + expect((await impl.forPlugin('plugin2', deps)).migrations).toEqual({ skip: false, }); - expect((await impl2.forPlugin('plugin1')).migrations).toEqual({ + const impl2 = new DatabaseManagerImpl( + new ConfigReader({ + client: 'pg', + backend: { + database: { + skipMigrations: true, + plugin: { plugin1: { skipMigrations: false } }, + }, + }, + }), + { + pg: connector, + }, + ); + expect((await impl2.forPlugin('plugin1', deps)).migrations).toEqual({ + skip: false, + }); + expect((await impl2.forPlugin('plugin2', deps)).migrations).toEqual({ skip: true, }); }); diff --git a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts index 7e3adf17df..46d4ee8cf7 100644 --- a/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts +++ b/packages/backend-defaults/src/entrypoints/database/DatabaseManager.ts @@ -18,7 +18,7 @@ import { DatabaseService, LifecycleService, LoggerService, - PluginMetadataService, + RootConfigService, } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { stringifyError } from '@backstage/errors'; @@ -42,21 +42,12 @@ function pluginPath(pluginId: string): string { */ export type DatabaseManagerOptions = { migrations?: DatabaseService['migrations']; - logger?: LoggerService; -}; - -/** - * An interface that represents the legacy global DatabaseManager implementation. - * @public - */ -export type LegacyRootDatabaseService = { - forPlugin(pluginId: string): DatabaseService; }; /** * Testable implementation class for {@link DatabaseManager} below. */ -export class DatabaseManagerImpl implements LegacyRootDatabaseService { +export class DatabaseManagerImpl { constructor( private readonly config: Config, private readonly connectors: Record, @@ -73,9 +64,9 @@ export class DatabaseManagerImpl implements LegacyRootDatabaseService { */ forPlugin( pluginId: string, - deps?: { + deps: { + logger: LoggerService; lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; }, ): PluginDatabaseManager { const client = this.getClientType(pluginId).client; @@ -86,8 +77,16 @@ export class DatabaseManagerImpl implements LegacyRootDatabaseService { ); } const getClient = () => this.getDatabase(pluginId, connector, deps); - const migrations = { skip: false, ...this.options?.migrations }; - return { getClient, migrations }; + + const skip = + this.options?.migrations?.skip ?? + this.config.getOptionalBoolean( + `backend.database.plugin.${pluginId}.skipMigrations`, + ) ?? + this.config.getOptionalBoolean('backend.database.skipMigrations') ?? + false; + + return { getClient, migrations: { skip } }; } /** @@ -127,9 +126,9 @@ export class DatabaseManagerImpl implements LegacyRootDatabaseService { private async getDatabase( pluginId: string, connector: Connector, - deps?: { + deps: { + logger: LoggerService; lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; }, ): Promise { if (this.databaseCache.has(pluginId)) { @@ -140,13 +139,19 @@ export class DatabaseManagerImpl implements LegacyRootDatabaseService { this.databaseCache.set(pluginId, clientPromise); if (process.env.NODE_ENV !== 'test') { - clientPromise.then(client => this.startKeepaliveLoop(pluginId, client)); + clientPromise.then(client => + this.startKeepaliveLoop(pluginId, client, deps.logger), + ); } return clientPromise; } - private startKeepaliveLoop(pluginId: string, client: Knex): void { + private startKeepaliveLoop( + pluginId: string, + client: Knex, + logger: LoggerService, + ): void { let lastKeepaliveFailed = false; setInterval(() => { @@ -159,7 +164,7 @@ export class DatabaseManagerImpl implements LegacyRootDatabaseService { (error: unknown) => { if (!lastKeepaliveFailed) { lastKeepaliveFailed = true; - this.options?.logger?.warn( + logger.warn( `Database keepalive failed for plugin ${pluginId}, ${stringifyError( error, )}`, @@ -184,7 +189,7 @@ export class DatabaseManagerImpl implements LegacyRootDatabaseService { * set `prefix` which is used to prefix generated database names if config is * not provided. */ -export class DatabaseManager implements LegacyRootDatabaseService { +export class DatabaseManager { /** * Creates a {@link DatabaseManager} from `backend.database` config. * @@ -192,7 +197,7 @@ export class DatabaseManager implements LegacyRootDatabaseService { * @param options - An optional configuration object. */ static fromConfig( - config: Config, + config: RootConfigService, options?: DatabaseManagerOptions, ): DatabaseManager { const databaseConfig = config.getConfig('backend.database'); @@ -224,31 +229,11 @@ export class DatabaseManager implements LegacyRootDatabaseService { */ forPlugin( pluginId: string, - deps?: { + deps: { + logger: LoggerService; lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; }, ): PluginDatabaseManager { return this.impl.forPlugin(pluginId, deps); } } - -/** - * Helper for deleting databases. - * - * @public - * @deprecated Will be removed in a future release. - */ -export async function dropDatabase( - dbConfig: Config, - ...databaseNames: string[] -): Promise { - const client = dbConfig.getString('client'); - const prefix = dbConfig.getOptionalString('prefix') || 'backstage_plugin_'; - - if (client === 'pg') { - await new PgConnector(dbConfig, prefix).dropDatabase(...databaseNames); - } else if (client === 'mysql' || client === 'mysql2') { - await new MysqlConnector(dbConfig, prefix).dropDatabase(...databaseNames); - } -} diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/mysql.ts b/packages/backend-defaults/src/entrypoints/database/connectors/mysql.ts index b11b659a6d..d5bd88deef 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/mysql.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/mysql.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - LifecycleService, - PluginMetadataService, -} from '@backstage/backend-plugin-api'; +import { LifecycleService, LoggerService } from '@backstage/backend-plugin-api'; import { Config, ConfigReader } from '@backstage/config'; import { InputError } from '@backstage/errors'; import { JsonObject } from '@backstage/types'; @@ -253,9 +250,9 @@ export class MysqlConnector implements Connector { async getClient( pluginId: string, - _deps?: { + _deps: { + logger: LoggerService; lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; }, ): Promise { const pluginConfig = new ConfigReader( @@ -293,10 +290,6 @@ export class MysqlConnector implements Connector { return client; } - async dropDatabase(...databaseNames: string[]): Promise { - return await dropMysqlDatabase(this.config, ...databaseNames); - } - /** * Provides the canonical database name for a given plugin. * diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts index 46b958789d..b5cfffd1f4 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - LifecycleService, - PluginMetadataService, -} from '@backstage/backend-plugin-api'; +import { LifecycleService, LoggerService } from '@backstage/backend-plugin-api'; import { Config, ConfigReader } from '@backstage/config'; import { ForwardedError } from '@backstage/errors'; import { JsonObject } from '@backstage/types'; @@ -261,9 +258,9 @@ export class PgConnector implements Connector { async getClient( pluginId: string, - _deps?: { + _deps: { + logger: LoggerService; lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; }, ): Promise { const pluginConfig = new ConfigReader( @@ -312,10 +309,6 @@ export class PgConnector implements Connector { return client; } - async dropDatabase(...databaseNames: string[]): Promise { - return await dropPgDatabase(this.config, ...databaseNames); - } - /** * Provides the canonical database name for a given plugin. * diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.test.ts b/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.test.ts index 2bd517d373..769d402eda 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.test.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.test.ts @@ -20,11 +20,17 @@ import { buildSqliteDatabaseConfig, createSqliteDatabaseClient, } from './sqlite3'; +import { mockServices } from '@backstage/backend-test-utils'; describe('better-sqlite3', () => { const createConfig = (connection: any) => new ConfigReader({ client: 'better-sqlite3', connection }); + const deps = { + logger: mockServices.logger.mock(), + lifecycle: mockServices.lifecycle.mock(), + }; + describe('buildSqliteDatabaseConfig', () => { it('builds an in-memory connection', () => { expect(buildSqliteDatabaseConfig(createConfig(':memory:'))).toEqual({ @@ -90,7 +96,9 @@ describe('better-sqlite3', () => { describe('createSqliteDatabaseClient', () => { it('creates an in memory knex instance', () => { - expect(createSqliteDatabaseClient(createConfig(':memory:'))).toBeTruthy(); + expect( + createSqliteDatabaseClient('p', createConfig(':memory:'), deps), + ).toBeTruthy(); }); }); }); diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.ts b/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.ts index 97ba6d46fd..67dd9d975f 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/sqlite3.ts @@ -15,10 +15,7 @@ */ import { DevDataStore } from '@backstage/backend-dev-utils'; -import { - LifecycleService, - PluginMetadataService, -} from '@backstage/backend-plugin-api'; +import { LifecycleService, LoggerService } from '@backstage/backend-plugin-api'; import { Config, ConfigReader } from '@backstage/config'; import { JsonObject } from '@backstage/types'; import { ensureDirSync } from 'fs-extra'; @@ -35,12 +32,13 @@ import { mergeDatabaseConfig } from './mergeDatabaseConfig'; * @param overrides - Additional options to merge with the config */ export function createSqliteDatabaseClient( + pluginId: string, dbConfig: Config, - overrides?: Knex.Config, - deps?: { + deps: { + logger: LoggerService; lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; }, + overrides?: Knex.Config, ) { const knexConfig = buildSqliteDatabaseConfig(dbConfig, overrides); const connConfig = knexConfig.connection as Knex.Sqlite3ConnectionConfig; @@ -62,7 +60,7 @@ export function createSqliteDatabaseClient( const devStore = DevDataStore.get(); if (devStore) { - const dataKey = `sqlite3-db-${deps.pluginMetadata.getId()}`; + const dataKey = `sqlite3-db-${pluginId}`; const connectionLoader = async () => { // If seed data is available, use it tconnectionLoader restore the database @@ -180,9 +178,9 @@ export class Sqlite3Connector implements Connector { async getClient( pluginId: string, - deps?: { + deps: { + logger: LoggerService; lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; }, ): Promise { const pluginConfig = new ConfigReader( @@ -202,18 +200,15 @@ export class Sqlite3Connector implements Connector { ); const client = createSqliteDatabaseClient( + pluginId, pluginConfig, - databaseClientOverrides, deps, + databaseClientOverrides, ); return client; } - async dropDatabase(..._databaseNames: string[]): Promise { - // do nothing - } - /** * Provides the canonical database name for a given plugin. * diff --git a/packages/backend-defaults/src/entrypoints/database/databaseServiceFactory.ts b/packages/backend-defaults/src/entrypoints/database/databaseServiceFactory.ts index 3bdf1790f3..167779e807 100644 --- a/packages/backend-defaults/src/entrypoints/database/databaseServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/database/databaseServiceFactory.ts @@ -35,6 +35,7 @@ export const databaseServiceFactory = createServiceFactory({ deps: { config: coreServices.rootConfig, lifecycle: coreServices.lifecycle, + logger: coreServices.logger, pluginMetadata: coreServices.pluginMetadata, }, async createRootContext({ config }) { @@ -48,10 +49,10 @@ export const databaseServiceFactory = createServiceFactory({ }), ); }, - async factory({ pluginMetadata, lifecycle }, databaseManager) { + async factory({ pluginMetadata, lifecycle, logger }, databaseManager) { return databaseManager.forPlugin(pluginMetadata.getId(), { - pluginMetadata, lifecycle, + logger, }); }, }); diff --git a/packages/backend-defaults/src/entrypoints/database/index.ts b/packages/backend-defaults/src/entrypoints/database/index.ts index 7d6221b856..e30d06cbdd 100644 --- a/packages/backend-defaults/src/entrypoints/database/index.ts +++ b/packages/backend-defaults/src/entrypoints/database/index.ts @@ -18,6 +18,4 @@ export { databaseServiceFactory } from './databaseServiceFactory'; export { DatabaseManager, type DatabaseManagerOptions, - type LegacyRootDatabaseService, - dropDatabase, } from './DatabaseManager'; diff --git a/packages/backend-defaults/src/entrypoints/database/types.ts b/packages/backend-defaults/src/entrypoints/database/types.ts index a9cceaa1f9..beded85d65 100644 --- a/packages/backend-defaults/src/entrypoints/database/types.ts +++ b/packages/backend-defaults/src/entrypoints/database/types.ts @@ -14,87 +14,17 @@ * limitations under the License. */ -import { - LifecycleService, - PluginMetadataService, -} from '@backstage/backend-plugin-api'; -import { Config } from '@backstage/config'; +import { LifecycleService, LoggerService } from '@backstage/backend-plugin-api'; import { Knex } from 'knex'; export type { DatabaseService as PluginDatabaseManager } from '@backstage/backend-plugin-api'; -/** - * Manages an underlying Knex database driver. - */ -export interface DatabaseConnector { - /** - * Provides an instance of a knex database connector. - */ - createClient( - dbConfig: Config, - overrides?: Partial, - deps?: { - lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; - }, - ): Knex; - - /** - * Provides a partial knex config sufficient to override a database name. - */ - createNameOverride(name: string): Partial; - - /** - * Provides a partial knex config sufficient to override a PostgreSQL schema - * name within utilizing the `searchPath` knex configuration. - */ - createSchemaOverride?(name: string): Partial; - - /** - * Produces a knex connection config object representing a database connection - * string. - */ - parseConnectionString( - connectionString: string, - client?: string, - ): Knex.StaticConnectionConfig; - - /** - * Performs a side-effect to ensure database names passed in are present. - * - * Calling this function on databases which already exist should do nothing. - * Missing databases should be created if needed. - */ - ensureDatabaseExists?( - dbConfig: Config, - ...databases: Array - ): Promise; - - /** - * Performs a side-effect to ensure schema names passed in are present. - * - * Calling this function on schemas which already exist should do nothing. - * Missing schemas should be created if needed. - */ - ensureSchemaExists?( - dbConfig: Config, - ...schemas: Array - ): Promise; - - /** - * Deletes databases. - */ - dropDatabase?(dbConfig: Config, ...databases: Array): Promise; -} - export interface Connector { getClient( pluginId: string, - deps?: { + deps: { + logger: LoggerService; lifecycle: LifecycleService; - pluginMetadata: PluginMetadataService; }, ): Promise; - - dropDatabase(...databaseNames: string[]): Promise; } diff --git a/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.test.ts b/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.test.ts index 4e6aff5853..e4e30044dd 100644 --- a/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.test.ts +++ b/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.test.ts @@ -54,25 +54,6 @@ describe('HostDiscovery', () => { ); }); - it('can configure the base path', async () => { - const discovery = HostDiscovery.fromConfig( - new ConfigReader({ - backend: { - baseUrl: 'http://localhost:40', - listen: { port: 80, host: 'localhost' }, - }, - }), - { basePath: '/service' }, - ); - - await expect(discovery.getBaseUrl('catalog')).resolves.toBe( - 'http://localhost:80/service/catalog', - ); - await expect(discovery.getExternalBaseUrl('catalog')).resolves.toBe( - 'http://localhost:40/service/catalog', - ); - }); - it.each([ [{ listen: ':80' }, 'http://localhost:80'], [{ listen: ':40', https: true }, 'https://localhost:40'], diff --git a/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.ts b/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.ts index 559dda2aa0..47793c82f7 100644 --- a/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.ts +++ b/packages/backend-defaults/src/entrypoints/discovery/HostDiscovery.ts @@ -15,7 +15,10 @@ */ import { Config } from '@backstage/config'; -import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { + DiscoveryService, + RootConfigService, +} from '@backstage/backend-plugin-api'; import { readHttpServerOptions } from '../rootHttpRouter/http/config'; type Target = string | { internal: string; external: string }; @@ -39,6 +42,7 @@ export class HostDiscovery implements DiscoveryService { * * Can be overridden in config by providing a target and corresponding plugins in `discovery.endpoints`. * eg. + * * ```yaml * discovery: * endpoints: @@ -52,11 +56,11 @@ export class HostDiscovery implements DiscoveryService { * plugins: [search] * ``` * - * The basePath defaults to `/api`, meaning the default full internal + * The fixed base path is `/api`, meaning the default full internal * path for the `catalog` plugin will be `http://localhost:7007/api/catalog`. */ - static fromConfig(config: Config, options?: { basePath?: string }) { - const basePath = options?.basePath ?? '/api'; + static fromConfig(config: RootConfigService) { + const basePath = '/api'; const externalBaseUrl = config .getString('backend.baseUrl') .replace(/\/+$/, ''); diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.test.ts b/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.test.ts index 124acf277b..22c6c90f05 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.test.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/createCredentialsBarrier.test.ts @@ -19,13 +19,11 @@ import express from 'express'; import request from 'supertest'; import { createCredentialsBarrier } from './createCredentialsBarrier'; -import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; -import { MiddlewareFactory } from '../rootHttpRouter/http'; - -const errorMiddleware = MiddlewareFactory.create({ - config: mockServices.rootConfig(), - logger: mockServices.rootLogger(), -}).error(); +import { + mockCredentials, + mockErrorHandler, + mockServices, +} from '@backstage/backend-test-utils'; function setup() { const barrier = createCredentialsBarrier({ @@ -37,7 +35,7 @@ function setup() { const app = express(); app.use(barrier.middleware); - app.use(errorMiddleware); + app.use(mockErrorHandler()); app.get('*', (_req, res) => res.status(200).end()); return { app, barrier }; diff --git a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts index f8d06baf56..5c3af24ab1 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.ts @@ -23,13 +23,15 @@ import { SchedulerServiceTaskRunner, SchedulerServiceTaskScheduleDefinition, } from '@backstage/backend-plugin-api'; -import { Counter, Histogram, metrics } from '@opentelemetry/api'; +import { Counter, Histogram, metrics, trace } from '@opentelemetry/api'; import { Knex } from 'knex'; import { Duration } from 'luxon'; import { LocalTaskWorker } from './LocalTaskWorker'; import { TaskWorker } from './TaskWorker'; import { TaskSettingsV2 } from './types'; -import { validateId } from './util'; +import { TRACER_ID, validateId } from './util'; + +const tracer = trace.getTracer(TRACER_ID); /** * Implements the actual task management. @@ -85,7 +87,7 @@ export class PluginTaskSchedulerImpl implements SchedulerService { const knex = await this.databaseFactory(); const worker = new TaskWorker( task.id, - this.wrapInMetrics(task.fn, { labels: { taskId: task.id, scope } }), + this.instrumentedFunction(task, scope), knex, this.logger.child({ task: task.id }), ); @@ -93,7 +95,7 @@ export class PluginTaskSchedulerImpl implements SchedulerService { } else { const worker = new LocalTaskWorker( task.id, - this.wrapInMetrics(task.fn, { labels: { taskId: task.id, scope } }), + this.instrumentedFunction(task, scope), this.logger.child({ task: task.id }), ); worker.start(settings, { signal: task.signal }); @@ -121,20 +123,33 @@ export class PluginTaskSchedulerImpl implements SchedulerService { return this.allScheduledTasks; } - private wrapInMetrics( - fn: SchedulerServiceTaskFunction, - opts: { labels: Record }, + private instrumentedFunction( + task: SchedulerServiceTaskInvocationDefinition, + scope: string, ): SchedulerServiceTaskFunction { return async abort => { - const labels = { - ...opts.labels, + const labels: Record = { + taskId: task.id, + scope, }; this.counter.add(1, { ...labels, result: 'started' }); const startTime = process.hrtime(); try { - await fn(abort); + await tracer.startActiveSpan(`task ${task.id}`, async span => { + try { + span.setAttributes(labels); + await task.fn(abort); + } catch (error) { + if (error instanceof Error) { + span.recordException(error); + } + throw error; + } finally { + span.end(); + } + }); labels.result = 'completed'; } catch (ex) { labels.result = 'failed'; diff --git a/packages/backend-defaults/src/entrypoints/scheduler/lib/util.ts b/packages/backend-defaults/src/entrypoints/scheduler/lib/util.ts index 70d67a9fbe..c475a20b80 100644 --- a/packages/backend-defaults/src/entrypoints/scheduler/lib/util.ts +++ b/packages/backend-defaults/src/entrypoints/scheduler/lib/util.ts @@ -18,6 +18,8 @@ import { InputError } from '@backstage/errors'; import { Knex } from 'knex'; import { DateTime, Duration } from 'luxon'; +export const TRACER_ID = 'backstage-service-scheduler'; + // Keep the IDs compatible with e.g. Prometheus labels export function validateId(id: string) { if (typeof id !== 'string' || !id.trim()) { diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/UrlReaders.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/UrlReaders.ts index cb496dd702..96e9ed6509 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/UrlReaders.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/UrlReaders.ts @@ -14,8 +14,11 @@ * limitations under the License. */ -import { LoggerService, UrlReaderService } from '@backstage/backend-plugin-api'; -import { Config } from '@backstage/config'; +import { + LoggerService, + RootConfigService, + UrlReaderService, +} from '@backstage/backend-plugin-api'; import { ReaderFactory } from './types'; import { UrlReaderPredicateMux } from './UrlReaderPredicateMux'; import { AzureUrlReader } from './AzureUrlReader'; @@ -40,7 +43,7 @@ import { HarnessUrlReader } from './HarnessUrlReader'; */ export type UrlReadersOptions = { /** Root config object */ - config: Config; + config: RootConfigService; /** Logger used by all the readers */ logger: LoggerService; /** A list of factories used to construct individual readers that match on URLs */ diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/types.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/types.ts index 510b12545f..5afbed178f 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/types.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/types.ts @@ -15,11 +15,11 @@ */ import { Readable } from 'stream'; -import { Config } from '@backstage/config'; import { UrlReaderService, UrlReaderServiceReadTreeResponse, LoggerService, + RootConfigService, } from '@backstage/backend-plugin-api'; /** @@ -40,7 +40,7 @@ export type UrlReaderPredicateTuple = { * @public */ export type ReaderFactory = (options: { - config: Config; + config: RootConfigService; logger: LoggerService; treeResponseFactory: ReadTreeResponseFactory; }) => UrlReaderPredicateTuple[]; diff --git a/packages/backend-defaults/src/index.ts b/packages/backend-defaults/src/index.ts index b00c865524..5f26df8921 100644 --- a/packages/backend-defaults/src/index.ts +++ b/packages/backend-defaults/src/index.ts @@ -21,3 +21,4 @@ */ export { createBackend } from './CreateBackend'; +export { discoveryFeatureLoader } from './discoveryFeatureLoader'; diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index 5828cebe32..e76ed0b504 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,98 @@ # @backstage/backend-dynamic-feature-service +## 0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-app-api@0.10.0-next.1 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.25-next.1 + - @backstage/plugin-events-backend@0.3.12-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## 0.4.0-next.0 + +### Minor Changes + +- 9080f57: **BREAKING**: `dynamicPluginsServiceFactory` is no longer callable as a function. If you need to provide options to make a custom factory, use `dynamicPluginsSchemasServiceFactoryWithOptions` instead. + +### Patch Changes + +- cd38da8: Deprecate the `dynamicPluginsServiceRef`, `dynamicPluginsServiceFactory` and `dynamicPluginsServiceFactoryWithOptions` in favor of using the `dynamicPluginsFeatureDiscoveryLoader` to discover dynamic features in a new backend system. + + See usage examples below: + + Example using the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + //... + + const backend = createBackend(); + backend.add(dynamicPluginsFeatureDiscoveryLoader); + //... + backend.start(); + ``` + + Passing options to the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + + ```ts + import { createBackend } from '@backstage/backend-defaults'; + import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + import { myCustomModuleLoader } from './myCustomModuleLoader'; + //... + + const backend = createBackend(); + backend.add( + dynamicPluginsFeatureDiscoveryLoader({ + moduleLoader: myCustomModuleLoader, + }), + ); + //... + backend.start(); + ``` + +- e27f889: Relax type check for a plugin's default export to also accept a BackendFeature defined as a function instead of an object +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-app-api@0.10.0-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-app-node@0.1.25-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-backend@0.3.12-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + ## 0.3.0 ### Minor Changes diff --git a/packages/backend-dynamic-feature-service/api-report.md b/packages/backend-dynamic-feature-service/api-report.md index 148825dce1..f6972da50b 100644 --- a/packages/backend-dynamic-feature-service/api-report.md +++ b/packages/backend-dynamic-feature-service/api-report.md @@ -112,7 +112,13 @@ export interface DynamicPluginsFactoryOptions { moduleLoader?(logger: LoggerService): ModuleLoader; } -// @public (undocumented) +// @public +export const dynamicPluginsFeatureDiscoveryLoader: (( + options?: DynamicPluginsFactoryOptions, +) => BackendFeature) & + BackendFeature; + +// @public @deprecated (undocumented) export const dynamicPluginsFeatureDiscoveryServiceFactory: ServiceFactory< FeatureDiscoveryService, 'root', @@ -154,19 +160,19 @@ export const dynamicPluginsSchemasServiceFactoryWithOptions: ( options?: DynamicPluginsSchemasOptions, ) => ServiceFactory; -// @public (undocumented) +// @public @deprecated (undocumented) export const dynamicPluginsServiceFactory: ServiceFactory< DynamicPluginProvider, 'root', 'singleton' >; -// @public (undocumented) +// @public @deprecated (undocumented) export const dynamicPluginsServiceFactoryWithOptions: ( options?: DynamicPluginsFactoryOptions, ) => ServiceFactory; -// @public (undocumented) +// @public @deprecated (undocumented) export const dynamicPluginsServiceRef: ServiceRef< DynamicPluginProvider, 'root', diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index ac06fcd8d0..451a373650 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.3.0", + "version": "0.4.0-next.1", "description": "Backstage dynamic feature service", "backstage": { "role": "node-library" diff --git a/packages/backend-dynamic-feature-service/src/manager/index.ts b/packages/backend-dynamic-feature-service/src/manager/index.ts index 542bab68ac..d24a41a7a3 100644 --- a/packages/backend-dynamic-feature-service/src/manager/index.ts +++ b/packages/backend-dynamic-feature-service/src/manager/index.ts @@ -36,6 +36,7 @@ export { dynamicPluginsServiceFactory, dynamicPluginsServiceFactoryWithOptions, dynamicPluginsServiceRef, + dynamicPluginsFeatureDiscoveryLoader, } from './plugin-manager'; export type { 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 40746ff440..fef0b6000d 100644 --- a/packages/backend-dynamic-feature-service/src/manager/plugin-manager.ts +++ b/packages/backend-dynamic-feature-service/src/manager/plugin-manager.ts @@ -30,6 +30,7 @@ import { BackendFeature, LoggerService, coreServices, + createBackendFeatureLoader, createServiceFactory, createServiceRef, } from '@backstage/backend-plugin-api'; @@ -214,6 +215,7 @@ export class DynamicPluginManager implements DynamicPluginProvider { /** * @public + * @deprecated The `featureDiscoveryService` is deprecated in favor of using {@link dynamicPluginsFeatureDiscoveryLoader} instead. */ export const dynamicPluginsServiceRef = createServiceRef( { @@ -231,6 +233,7 @@ export interface DynamicPluginsFactoryOptions { /** * @public + * @deprecated Use {@link dynamicPluginsFeatureDiscoveryLoader} instead. */ export const dynamicPluginsServiceFactoryWithOptions = ( options?: DynamicPluginsFactoryOptions, @@ -253,6 +256,7 @@ export const dynamicPluginsServiceFactoryWithOptions = ( /** * @public + * @deprecated Use {@link dynamicPluginsFeatureDiscoveryLoader} instead. */ export const dynamicPluginsServiceFactory = dynamicPluginsServiceFactoryWithOptions(); @@ -292,6 +296,7 @@ class DynamicPluginsEnabledFeatureDiscoveryService /** * @public + * @deprecated The `featureDiscoveryService` is deprecated in favor of using {@link dynamicPluginsFeatureDiscoveryLoader} instead. */ export const dynamicPluginsFeatureDiscoveryServiceFactory = createServiceFactory({ @@ -305,6 +310,66 @@ export const dynamicPluginsFeatureDiscoveryServiceFactory = }, }); +const dynamicPluginsFeatureDiscoveryLoaderWithOptions = ( + options?: DynamicPluginsFactoryOptions, +) => + createBackendFeatureLoader({ + deps: { + config: coreServices.rootConfig, + logger: coreServices.rootLogger, + }, + async loader({ config, logger }) { + const manager = await DynamicPluginManager.create({ + config, + logger, + preferAlpha: true, + moduleLoader: options?.moduleLoader?.(logger), + }); + const service = new DynamicPluginsEnabledFeatureDiscoveryService(manager); + const { features } = await service.getBackendFeatures(); + return features; + }, + }); + +/** + * A backend feature loader that uses the dynamic plugins system to discover features. + * + * @public + * + * @example + * Using the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + * ```ts + * //... + * import { createBackend } from '@backstage/backend-defaults'; + * import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + * + * const backend = createBackend(); + * backend.add(dynamicPluginsFeatureDiscoveryLoader); + * //... + * backend.start(); + * ``` + * + * @example + * Passing options to the `dynamicPluginsFeatureDiscoveryLoader` loader in a backend instance: + * ```ts + * //... + * import { createBackend } from '@backstage/backend-defaults'; + * import { dynamicPluginsFeatureDiscoveryLoader } from '@backstage/backend-dynamic-feature-service'; + * import { myCustomModuleLoader } from './myCustomModuleLoader'; + * + * const backend = createBackend(); + * backend.add(dynamicPluginsFeatureDiscoveryLoader({ + * moduleLoader: myCustomModuleLoader + * })); + * //... + * backend.start(); + * ``` + */ +export const dynamicPluginsFeatureDiscoveryLoader = Object.assign( + dynamicPluginsFeatureDiscoveryLoaderWithOptions, + dynamicPluginsFeatureDiscoveryLoaderWithOptions(), +); + function isBackendFeature(value: unknown): value is BackendFeature { return ( !!value && diff --git a/packages/backend-legacy/CHANGELOG.md b/packages/backend-legacy/CHANGELOG.md index 3b6a1af6f4..6a3068a37b 100644 --- a/packages/backend-legacy/CHANGELOG.md +++ b/packages/backend-legacy/CHANGELOG.md @@ -1,5 +1,89 @@ # example-backend-legacy +## 0.2.102-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/plugin-scaffolder-backend@1.25.0-next.1 + - @backstage/plugin-kubernetes-backend@0.18.6-next.1 + - @backstage/plugin-techdocs-backend@1.10.13-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-app-backend@0.3.74-next.1 + - @backstage/plugin-auth-backend@0.23.0-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-devtools-backend@0.4.0-next.1 + - @backstage/plugin-events-backend@0.3.12-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-backend@0.5.49-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-proxy-backend@0.5.6-next.1 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.1 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.0-next.1 + - @backstage/plugin-search-backend@1.5.17-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.6-next.1 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.1 + - @backstage/plugin-search-backend-module-pg@0.5.35-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-signals-backend@0.2.0-next.1 + - @backstage/plugin-signals-node@0.1.11-next.1 + +## 0.2.102-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.13-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-search-backend@1.5.17-next.0 + - @backstage/plugin-kubernetes-backend@0.18.6-next.0 + - @backstage/plugin-scaffolder-backend@1.25.0-next.0 + - @backstage/plugin-app-backend@0.3.74-next.0 + - @backstage/plugin-signals-backend@0.2.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/plugin-auth-backend@0.23.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-backend@0.3.12-next.0 + - @backstage/plugin-permission-backend@0.5.49-next.0 + - @backstage/plugin-proxy-backend@0.5.6-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.5.6-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.35-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.0 + - @backstage/plugin-devtools-backend@0.4.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.5.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-permission-common@0.8.1 + ## 0.2.101 ### Patch Changes diff --git a/packages/backend-legacy/package.json b/packages/backend-legacy/package.json index 0bdfa350e9..65e5a46f28 100644 --- a/packages/backend-legacy/package.json +++ b/packages/backend-legacy/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-legacy", - "version": "0.2.101", + "version": "0.2.102-next.1", "backstage": { "role": "backend" }, diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index 0d58c6ad9c..3d62a9d121 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/backend-openapi-utils +## 0.1.18-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 + +## 0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/errors@1.2.4 + ## 0.1.16 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index a64ef674a9..37ae412be6 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-openapi-utils", "description": "OpenAPI typescript support.", - "version": "0.1.16", + "version": "0.1.18-next.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index cb830feb33..5fdf43aaa6 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/backend-plugin-api +## 0.9.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + +## 0.9.0-next.0 + +### Minor Changes + +- 19ff127: **BREAKING**: The deprecated identity and token manager services have been removed. This means that `coreServices.identity` and `coreServices.tokenManager` are gone, along with related types and utilities in other packages. +- f687050: Removed the following deprecated exports + + - `BackendPluginConfig` use `CreateBackendPluginOptions` + - `BackendModuleConfig` use `CreateBackendModuleOptions` + - `ExtensionPointConfig` use `CreateExtensionPointOptions` + +- 4d82481: Removed deprecated `ServiceFactoryOrFunction` type. +- 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 + +- cd38da8: Deprecate the `featureDiscoveryServiceRef` in favor of using the new `discoveryFeatureLoader` instead. +- 66dbf0a: Allow the cache service to accept the human duration format for TTL +- 0b2a402: Updates to the config schema to match reality +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + ## 0.8.0 ### Minor Changes diff --git a/packages/backend-plugin-api/api-report-alpha.md b/packages/backend-plugin-api/api-report-alpha.md index 0f4348336a..dea357502e 100644 --- a/packages/backend-plugin-api/api-report-alpha.md +++ b/packages/backend-plugin-api/api-report-alpha.md @@ -14,7 +14,7 @@ export interface FeatureDiscoveryService { }>; } -// @alpha +// @alpha @deprecated export const featureDiscoveryServiceRef: ServiceRef< FeatureDiscoveryService, 'root', diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 1732998e44..89dfe40dd9 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -162,12 +162,12 @@ export interface CacheService { // @public export type CacheServiceOptions = { - defaultTtl?: number; + defaultTtl?: number | HumanDuration; }; // @public export type CacheServiceSetOptions = { - ttl?: number; + ttl?: number | HumanDuration; }; // @public @@ -514,7 +514,7 @@ export interface RootLoggerService extends LoggerService {} // @public (undocumented) export interface RootServiceFactoryOptions< - TService, // TODO(Rugvip): Can we forward the entire service ref type here instead of forwarding each type arg once the callback form is gone? + TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { diff --git a/packages/backend-plugin-api/config.d.ts b/packages/backend-plugin-api/config.d.ts new file mode 100644 index 0000000000..21122d7238 --- /dev/null +++ b/packages/backend-plugin-api/config.d.ts @@ -0,0 +1,35 @@ +/* + * 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 interface Config { + backend?: { + /** + * An absolute path to a directory that can be used as a working dir, for + * example as scratch space for large operations. + * + * @remarks + * + * Note that this must be an absolute path. + * + * If not set, the operating system's designated temporary directory is + * commonly used, but that is implementation defined per plugin. + * + * Plugins are encouraged to heed this config setting if present, to allow + * deployment in severely locked-down or limited environments. + */ + workingDirectory?: string; + }; +} diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 94793e1e49..322c936b39 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "0.8.0", + "version": "0.9.0-next.1", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" @@ -40,7 +40,8 @@ } }, "files": [ - "dist" + "dist", + "config.d.ts" ], "scripts": { "build": "backstage-cli package build", @@ -67,5 +68,6 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^" - } + }, + "configSchema": "config.d.ts" } diff --git a/packages/backend-plugin-api/src/alpha.ts b/packages/backend-plugin-api/src/alpha.ts index baee739f49..3f26c66fe9 100644 --- a/packages/backend-plugin-api/src/alpha.ts +++ b/packages/backend-plugin-api/src/alpha.ts @@ -27,6 +27,7 @@ export interface FeatureDiscoveryService { /** * An optional service that can be used to dynamically load in additional BackendFeatures at runtime. * @alpha + * @deprecated The `featureDiscoveryServiceRef` is deprecated in favor of using {@link @backstage/backend-defaults#discoveryFeatureLoader} instead. */ export const featureDiscoveryServiceRef = createServiceRef({ diff --git a/packages/backend-plugin-api/src/services/definitions/CacheService.ts b/packages/backend-plugin-api/src/services/definitions/CacheService.ts index 3b13292a58..4c5cfd74b3 100644 --- a/packages/backend-plugin-api/src/services/definitions/CacheService.ts +++ b/packages/backend-plugin-api/src/services/definitions/CacheService.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { JsonValue } from '@backstage/types'; +import { HumanDuration, JsonValue } from '@backstage/types'; /** * Options passed to {@link CacheService.set}. @@ -23,10 +23,10 @@ import { JsonValue } from '@backstage/types'; */ export type CacheServiceSetOptions = { /** - * Optional TTL in milliseconds. Defaults to the TTL provided when the client + * Optional TTL (in milliseconds if given as a number). Defaults to the TTL provided when the client * was set up (or no TTL if none are provided). */ - ttl?: number; + ttl?: number | HumanDuration; }; /** @@ -36,11 +36,11 @@ export type CacheServiceSetOptions = { */ export type CacheServiceOptions = { /** - * An optional default TTL (in milliseconds) to be set when getting a client + * An optional default TTL (in milliseconds if given as a number) to be set when getting a client * instance. If not provided, data will persist indefinitely by default (or * can be configured per entry at set-time). */ - defaultTtl?: number; + defaultTtl?: number | HumanDuration; }; /** diff --git a/packages/backend-plugin-api/src/services/system/types.ts b/packages/backend-plugin-api/src/services/system/types.ts index 9e054ed4a4..a14e388bd0 100644 --- a/packages/backend-plugin-api/src/services/system/types.ts +++ b/packages/backend-plugin-api/src/services/system/types.ts @@ -165,7 +165,7 @@ type ServiceRefsToInstances< /** @public */ export interface RootServiceFactoryOptions< - TService, // TODO(Rugvip): Can we forward the entire service ref type here instead of forwarding each type arg once the callback form is gone? + TService, TInstances extends 'singleton' | 'multiton', TImpl extends TService, TDeps extends { [name in string]: ServiceRef }, diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md deleted file mode 100644 index fbdbff1a8a..0000000000 --- a/packages/backend-tasks/CHANGELOG.md +++ /dev/null @@ -1,1438 +0,0 @@ -# @backstage/backend-tasks - -## 0.6.0 - -### Minor Changes - -- fc24d9e: This package is deprecated and will be removed in a near future, follow the instructions below to stop using it: - - - `TaskScheduler`: Please migrate to the new backend system, and depend on `coreServices.scheduler` from `@backstage/backend-plugin-api` instead, or use `DefaultSchedulerService` from `@backstage/backend-defaults; - - `TaskRunner`: Please import `SchedulerServiceTaskRunner` from `@backstage/backend-plugin-api` instead; - - `TaskFunction`: Please import `SchedulerServiceTaskFunction` from `@backstage/backend-plugin-api` instead; - - `TaskDescriptor`: Please import `SchedulerServiceTaskDescriptor` from `@backstage/backend-plugin-api` instead; - - `TaskInvocationDefinition`: Please import `SchedulerServiceTaskInvocationDefinition` from `@backstage/backend-plugin-api` instead; - - `TaskScheduleDefinition`: Please import `SchedulerServiceTaskFunction` from `@backstage/backend-plugin-api` instead; - - `TaskScheduleDefinitionConfig`: Please import `SchedulerServiceTaskScheduleDefinitionConfig` from `@backstage/backend-plugin-api` instead; - - `PluginTaskScheduler`: Please use `SchedulerService` from `@backstage/backend-plugin-api` instead (most likely via `coreServices.scheduler`); - - `readTaskScheduleDefinitionFromConfig`: Please import `readSchedulerServiceTaskScheduleDefinitionFromConfig` from `@backstage/backend-plugin-api` instead; - - `HumanDuration`: Import `TypesHumanDuration` from `@backstage/types` instead. - -### Patch Changes - -- ba9abf4: The `PluginTaskScheduler` now allows tasks with `frequency: { trigger: 'manual' }`. This means that the task will not be scheduled, but rather run only when manually triggered with `PluginTaskScheduler.triggerTask`. -- Updated dependencies - - @backstage/backend-plugin-api@0.8.0 - - @backstage/backend-common@0.24.0 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.28-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.8.0-next.3 - - @backstage/backend-common@0.23.4-next.3 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.28-next.2 - -### Patch Changes - -- ba9abf4: The `PluginTaskScheduler` now allows tasks with `frequency: { trigger: 'manual' }`. This means that the task will not be scheduled, but rather run only when manually triggered with `PluginTaskScheduler.triggerTask`. -- Updated dependencies - - @backstage/backend-plugin-api@0.8.0-next.2 - - @backstage/backend-common@0.23.4-next.2 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.28-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.7.1-next.1 - - @backstage/backend-common@0.23.4-next.1 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.28-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.23.4-next.0 - - @backstage/backend-plugin-api@0.7.1-next.0 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.27 - -### Patch Changes - -- 083eaf9: Fix bug where ISO durations could no longer be used for schedules -- Updated dependencies - - @backstage/backend-plugin-api@0.7.0 - - @backstage/backend-common@0.23.3 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.27-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.23.3-next.1 - - @backstage/backend-plugin-api@0.6.22-next.1 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.26-next.0 - -### Patch Changes - -- 083eaf9: Fix bug where ISO durations could no longer be used for schedules -- Updated dependencies - - @backstage/backend-plugin-api@0.6.21-next.0 - - @backstage/backend-common@0.23.2-next.0 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.24 - -### Patch Changes - -- 736bc3c: Marked all exports as deprecated and pointed at `@backstage/backend-plugin-api` and `@backstage/backend-defaults` -- ed473cd: Updated the `TaskScheduleDefinitionConfig` deprecated comment to point to `SchedulerServiceTaskScheduleDefinitionConfig` -- 6a576dc: Deprecate the legacy `TaskScheduler.fromConfig` method and stop using the `getVoidlogger` in tests files to reduce the dependency on the soon-to-deprecate `backstage-common` package. -- 1897169: More detailed deprecation messages -- Updated dependencies - - @backstage/backend-common@0.23.0 - - @backstage/backend-plugin-api@0.6.19 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.24-next.3 - -### Patch Changes - -- 1897169: More detailed deprecation messages -- Updated dependencies - - @backstage/backend-plugin-api@0.6.19-next.3 - - @backstage/backend-common@0.23.0-next.3 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.24-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-plugin-api@0.6.19-next.2 - - @backstage/backend-common@0.23.0-next.2 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.24-next.1 - -### Patch Changes - -- ed473cd: Updated the `TaskScheduleDefinitionConfig` deprecated comment to point to `SchedulerServiceTaskScheduleDefinitionConfig` -- Updated dependencies - - @backstage/backend-plugin-api@0.6.19-next.1 - - @backstage/backend-common@0.23.0-next.1 - -## 0.5.24-next.0 - -### Patch Changes - -- 736bc3c: Marked all exports as deprecated and pointed at `@backstage/backend-plugin-api` and `@backstage/backend-defaults` -- 6a576dc: Deprecate the legacy `TaskScheduler.fromConfig` method and stop using the `getVoidlogger` in tests files to reduce the dependency on the soon-to-deprecate `backstage-common` package. -- Updated dependencies - - @backstage/backend-common@0.22.1-next.0 - - @backstage/backend-plugin-api@0.6.19-next.0 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.23 - -### Patch Changes - -- d229dc4: Move path utilities from `backend-common` to the `backend-plugin-api` package. -- Updated dependencies - - @backstage/backend-common@0.22.0 - - @backstage/backend-plugin-api@0.6.18 - -## 0.5.23-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.22.0-next.1 - - @backstage/backend-plugin-api@0.6.18-next.1 - -## 0.5.23-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.8-next.0 - - @backstage/backend-plugin-api@0.6.18-next.0 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.22 - -### Patch Changes - -- d5a1fe1: Replaced winston logger with `LoggerService` -- Updated dependencies - - @backstage/backend-common@0.21.7 - - @backstage/backend-plugin-api@0.6.17 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.22-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.7-next.1 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.22-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.7-next.0 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.21 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.6 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.20 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.5 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.19 - -### Patch Changes - -- 0fb419b: Updated dependency `uuid` to `^9.0.0`. - Updated dependency `@types/uuid` to `^9.0.0`. -- Updated dependencies - - @backstage/backend-common@0.21.4 - - @backstage/config@1.2.0 - - @backstage/errors@1.2.4 - - @backstage/types@1.1.1 - -## 0.5.19-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.4-next.2 - - @backstage/config@1.2.0-next.1 - - @backstage/errors@1.2.4-next.0 - - @backstage/types@1.1.1 - -## 0.5.19-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.2.0-next.1 - - @backstage/backend-common@0.21.4-next.1 - - @backstage/errors@1.2.4-next.0 - - @backstage/types@1.1.1 - -## 0.5.18-next.0 - -### Patch Changes - -- 0fb419b: Updated dependency `uuid` to `^9.0.0`. - Updated dependency `@types/uuid` to `^9.0.0`. -- Updated dependencies - - @backstage/backend-common@0.21.3-next.0 - - @backstage/errors@1.2.4-next.0 - - @backstage/config@1.1.2-next.0 - - @backstage/types@1.1.1 - -## 0.5.15 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- 6707216: The `TaskScheduler.fromConfig` method now accepts the `LegacyRootDatabaseService` interface rather than the full `DatabaseManager` implementation. -- b68248b: Updated dependency `cron` to `^3.0.0`. -- Updated dependencies - - @backstage/backend-common@0.21.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.15-next.3 - -### Patch Changes - -- 6707216: The `TaskScheduler.fromConfig` method now accepts the `LegacyRootDatabaseService` interface rather than the full `DatabaseManager` implementation. -- b68248b: Updated dependency `cron` to `^3.0.0`. -- Updated dependencies - - @backstage/backend-common@0.21.0-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.15-next.2 - -### Patch Changes - -- 9aac2b0: Use `--cwd` as the first `yarn` argument -- Updated dependencies - - @backstage/backend-common@0.21.0-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.15-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.15-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.21.0-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.14 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.14-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.2 - -## 0.5.14-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.14-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.1-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.13 - -### Patch Changes - -- d8f488a: Allow tasks to run more often that the default work check interval, which is 5 seconds. -- 0cbb03b: Fixing regular expression ReDoS with zod packages. Upgrading to latest. ref: https://security.snyk.io/vuln/SNYK-JS-ZOD-5925617 -- Updated dependencies - - @backstage/backend-common@0.20.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.13-next.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.3 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.13-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.2 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.13-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.20.0-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.13-next.0 - -### Patch Changes - -- d8f488aaa8: Allow tasks to run more often that the default work check interval, which is 5 seconds. -- Updated dependencies - - @backstage/backend-common@0.20.0-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.12 - -### Patch Changes - -- 013611b42e: `knex` has been bumped to major version 3 and `better-sqlite3` to major version 9, which deprecate node 16 support. -- Updated dependencies - - @backstage/backend-common@0.19.9 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.12-next.2 - -### Patch Changes - -- [#20570](https://github.com/backstage/backstage/pull/20570) [`013611b42e`](https://github.com/backstage/backstage/commit/013611b42ed457fefa9bb85fddf416cf5e0c1f76) Thanks [@freben](https://github.com/freben)! - `knex` has been bumped to major version 3 and `better-sqlite3` to major version 9, which deprecate node 16 support. - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.2 - -## 0.5.12-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.1 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.12-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.9-next.0 - - @backstage/config@1.1.1 - - @backstage/errors@1.2.3 - - @backstage/types@1.1.1 - -## 0.5.11 - -### Patch Changes - -- 5db102bfdf: Instrument `backend-tasks` with some counters and histograms for duration. - - `backend_tasks.task.runs.count`: Counter with the total number of times a task has been run. - `backend_tasks.task.runs.duration`: Histogram with the run durations for each task. - - Both these metrics have come with `result` `taskId` and `scope` labels for finer grained grouping. - -- ddd76ac98d: Fix bug where backend tasks that are defined with HumanDuration are immediately triggered on application startup -- Updated dependencies - - @backstage/backend-common@0.19.8 - - @backstage/errors@1.2.3 - - @backstage/config@1.1.1 - - @backstage/types@1.1.1 - -## 0.5.11-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.8-next.2 - - @backstage/errors@1.2.3-next.0 - - @backstage/config@1.1.1-next.0 - - @backstage/types@1.1.1 - -## 0.5.10-next.1 - -### Patch Changes - -- 5db102bfdf: Instrument `backend-tasks` with some counters and histograms for duration. - - `backend_tasks.task.runs.count`: Counter with the total number of times a task has been run. - `backend_tasks.task.runs.duration`: Histogram with the run durations for each task. - - Both these metrics have come with `result` `taskId` and `scope` labels for finer grained grouping. - -- ddd76ac98d: Fix bug where backend tasks that are defined with HumanDuration are immediately triggered on application startup -- Updated dependencies - - @backstage/backend-common@0.19.7-next.1 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - - @backstage/types@1.1.1 - -## 0.5.10-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.7-next.0 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - - @backstage/types@1.1.1 - -## 0.5.8 - -### Patch Changes - -- 8fd91547cd0b: When starting a task that existed before, with a faster schedule than it - previously had, the task will now correctly obey the faster schedule - immediately. Before this fix, the new schedule was only obeyed after the next - pending (according to the old schedule) run had completed. -- 62f448edb0b5: Use `readDurationFromConfig` from the config package -- 74604806aae8: Avoid starting task janitor in tests. -- cfc3ca6ce060: Changes needed to support MySQL -- 814feeed7343: Update to handle invalid luxon values -- Updated dependencies - - @backstage/backend-common@0.19.5 - - @backstage/config@1.1.0 - - @backstage/errors@1.2.2 - - @backstage/types@1.1.1 - -## 0.5.8-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/backend-common@0.19.5-next.3 - -## 0.5.8-next.2 - -### Patch Changes - -- 814feeed7343: Update to handle invalid luxon values -- Updated dependencies - - @backstage/config@1.1.0-next.1 - - @backstage/backend-common@0.19.5-next.2 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.5.8-next.1 - -### Patch Changes - -- 62f448edb0b5: Use `readDurationFromConfig` from the config package -- Updated dependencies - - @backstage/config@1.1.0-next.0 - - @backstage/backend-common@0.19.5-next.1 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.5.7-next.0 - -### Patch Changes - -- cfc3ca6ce060: Changes needed to support MySQL -- Updated dependencies - - @backstage/backend-common@0.19.4-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.5.5 - -### Patch Changes - -- dfd1b6b2fc33: Make `readTaskScheduleDefinitionFromConfig` properly handle bad inputs -- Updated dependencies - - @backstage/backend-common@0.19.2 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.5.5-next.2 - -### Patch Changes - -- dfd1b6b2fc33: Make `readTaskScheduleDefinitionFromConfig` properly handle bad inputs -- Updated dependencies - - @backstage/backend-common@0.19.2-next.2 - -## 0.5.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.1 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.5.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.2-next.0 - - @backstage/config@1.0.8 - - @backstage/errors@1.2.1 - - @backstage/types@1.1.0 - -## 0.5.4 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1 - - @backstage/backend-common@0.19.1 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - -## 0.5.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/errors@1.2.1-next.0 - - @backstage/backend-common@0.19.1-next.0 - - @backstage/config@1.0.8 - - @backstage/types@1.1.0 - -## 0.5.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0 - - @backstage/types@1.1.0 - - @backstage/errors@1.2.0 - - @backstage/config@1.0.8 - -## 0.5.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.2.0-next.0 - - @backstage/types@1.0.2 - -## 0.5.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.19.0-next.1 - - @backstage/errors@1.2.0-next.0 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - -## 0.5.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.6-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.5.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.5.2-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.1 - - @backstage/config@1.0.7 - -## 0.5.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.5-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.5.1 - -### Patch Changes - -- 1e4f5e91b8e: Bump `zod` and `zod-to-json-schema` dependencies. -- Updated dependencies - - @backstage/backend-common@0.18.4 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.5.1-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.2 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.5.1-next.1 - -### Patch Changes - -- 1e4f5e91b8e: Bump `zod` and `zod-to-json-schema` dependencies. -- Updated dependencies - - @backstage/backend-common@0.18.4-next.1 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.5.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.4-next.0 - - @backstage/config@1.0.7 - - @backstage/errors@1.1.5 - - @backstage/types@1.0.2 - -## 0.5.0 - -### Minor Changes - -- 1578276708a: add functionality to get descriptions from the scheduler for triggering - -### Patch Changes - -- f0685193efa: Added the adapted query to mysql and sqlite3 databases to not returning warning on logs -- 482dae5de1c: Updated link to docs. -- Updated dependencies - - @backstage/backend-common@0.18.3 - - @backstage/errors@1.1.5 - - @backstage/config@1.0.7 - - @backstage/types@1.0.2 - -## 0.5.0-next.2 - -### Minor Changes - -- 1578276708a: add functionality to get descriptions from the scheduler for triggering - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.3-next.2 - - @backstage/config@1.0.7-next.0 - -## 0.4.4-next.1 - -### Patch Changes - -- 482dae5de1c: Updated link to docs. -- Updated dependencies - - @backstage/errors@1.1.5-next.0 - - @backstage/backend-common@0.18.3-next.1 - - @backstage/config@1.0.7-next.0 - - @backstage/types@1.0.2 - -## 0.4.4-next.0 - -### Patch Changes - -- f0685193ef: Added the adapted query to mysql and sqlite3 databases to not returning warning on logs -- Updated dependencies - - @backstage/backend-common@0.18.3-next.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.4.3 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.4.3-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.2 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.4.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.1 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.4.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.2-next.0 - -## 0.4.1 - -### Patch Changes - -- 3fad4ed40a: Added a new static `TaskScheduler.forPlugin` method. -- b99c030f1b: Minor internal refactor to avoid import cycle issue. -- Updated dependencies - - @backstage/backend-common@0.18.0 - - @backstage/config@1.0.6 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.4.1-next.1 - -### Patch Changes - -- b99c030f1b: Minor internal refactor to avoid import cycle issue. -- Updated dependencies - - @backstage/backend-common@0.18.0-next.1 - - @backstage/config@1.0.6-next.0 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.4.1-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.18.0-next.0 - - @backstage/config@1.0.6-next.0 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - -## 0.4.0 - -### Minor Changes - -- de8a975911: Changed to use native `AbortController` and `AbortSignal` from Node.js, instead - of the one from `node-abort-controller`. This is possible now that the minimum - supported Node.js version of the project is 16. - - Note that their interfaces are very slightly different, but typically not in a - way that matters to consumers. If you see any typescript errors as a direct - result from this, they are compatible with each other in the ways that we - interact with them, and should be possible to type-cast across without ill - effects. - -### Patch Changes - -- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries -- Updated dependencies - - @backstage/backend-common@0.17.0 - - @backstage/errors@1.1.4 - - @backstage/types@1.0.2 - - @backstage/config@1.0.5 - -## 0.4.0-next.3 - -### Patch Changes - -- b05dcd5530: Move the `zod` dependency to a version that does not collide with other libraries -- Updated dependencies - - @backstage/backend-common@0.17.0-next.3 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/types@1.0.2-next.1 - -## 0.4.0-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.2 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - - @backstage/types@1.0.2-next.1 - -## 0.4.0-next.1 - -### Minor Changes - -- de8a975911: Changed to use native `AbortController` and `AbortSignal` from Node.js, instead - of the one from `node-abort-controller`. This is possible now that the minimum - supported Node.js version of the project is 16. - - Note that their interfaces are very slightly different, but typically not in a - way that matters to consumers. If you see any typescript errors as a direct - result from this, they are compatible with each other in the ways that we - interact with them, and should be possible to type-cast across without ill - effects. - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.17.0-next.1 - - @backstage/types@1.0.2-next.1 - - @backstage/config@1.0.5-next.1 - - @backstage/errors@1.1.4-next.1 - -## 0.3.8-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.1-next.0 - - @backstage/types@1.0.2-next.0 - - @backstage/config@1.0.5-next.0 - - @backstage/errors@1.1.4-next.0 - -## 0.3.7 - -### Patch Changes - -- 30e43717c7: Deprecated the `HumanDuration` type, which should now instead be imported from `@backstage/types`. -- Updated dependencies - - @backstage/backend-common@0.16.0 - - @backstage/types@1.0.1 - - @backstage/config@1.0.4 - - @backstage/errors@1.1.3 - -## 0.3.7-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.16.0-next.1 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - - @backstage/types@1.0.1-next.0 - -## 0.3.7-next.0 - -### Patch Changes - -- 30e43717c7: Deprecated the `HumanDuration` type, which should now instead be imported from `@backstage/types`. -- Updated dependencies - - @backstage/backend-common@0.16.0-next.0 - - @backstage/types@1.0.1-next.0 - - @backstage/config@1.0.4-next.0 - - @backstage/errors@1.1.3-next.0 - -## 0.3.6 - -### Patch Changes - -- d4fea86ea3: Added new function `readTaskScheduleDefinitionFromConfig` to read `TaskScheduleDefinition` (aka. schedule) from the `Config`. -- Updated dependencies - - @backstage/backend-common@0.15.2 - - @backstage/config@1.0.3 - - @backstage/errors@1.1.2 - - @backstage/types@1.0.0 - -## 0.3.6-next.2 - -### Patch Changes - -- d4fea86ea3: Added new function `readTaskScheduleDefinitionFromConfig` to read `TaskScheduleDefinition` (aka. schedule) from the `Config`. -- Updated dependencies - - @backstage/backend-common@0.15.2-next.2 - - @backstage/config@1.0.3-next.2 - - @backstage/errors@1.1.2-next.2 - - @backstage/types@1.0.0 - -## 0.3.6-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.1 - - @backstage/config@1.0.3-next.1 - - @backstage/errors@1.1.2-next.1 - - @backstage/types@1.0.0 - -## 0.3.6-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.15.2-next.0 - - @backstage/config@1.0.3-next.0 - - @backstage/errors@1.1.2-next.0 - - @backstage/types@1.0.0 - -## 0.3.5 - -### Patch Changes - -- 243533ecdc: Added support to mysql on some raw queries -- 8872cc735d: Fixed a bug where the database option to skip migrations was ignored. -- Updated dependencies - - @backstage/backend-common@0.15.1 - - @backstage/config@1.0.2 - - @backstage/errors@1.1.1 - -## 0.3.5-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/config@1.0.2-next.0 - - @backstage/errors@1.1.1-next.0 - - @backstage/backend-common@0.15.1-next.3 - -## 0.3.5-next.0 - -### Patch Changes - -- 243533ecdc: Added support to mysql on some raw queries -- 8872cc735d: Fixed a bug where the database option to skip migrations was ignored. -- Updated dependencies - - @backstage/backend-common@0.15.1-next.0 - -## 0.3.4 - -### Patch Changes - -- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/backend-common@0.15.0 - -## 0.3.4-next.0 - -### Patch Changes - -- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/backend-common@0.15.0-next.0 - -## 0.3.3 - -### Patch Changes - -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. -- 679b32172e: Updated dependency `knex` to `^2.0.0`. -- Updated dependencies - - @backstage/backend-common@0.14.1 - - @backstage/errors@1.1.0 - -## 0.3.3-next.3 - -### Patch Changes - -- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. -- Updated dependencies - - @backstage/backend-common@0.14.1-next.3 - -## 0.3.3-next.2 - -### Patch Changes - -- 679b32172e: Updated dependency `knex` to `^2.0.0`. -- Updated dependencies - - @backstage/backend-common@0.14.1-next.2 - -## 0.3.3-next.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.1 - - @backstage/errors@1.1.0-next.0 - -## 0.3.3-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.1-next.0 - -## 0.3.2 - -### Patch Changes - -- fde10d24f6: Allow tasks that fail to retry on a loop emitting a warning log every time it fails with the amount of attempts it has -- f7146b516f: Updated dependency `cron` to `^2.0.0`. - Updated dependency `@types/cron` to `^2.0.0`. -- 7f108513b8: Add error logging when a background task throws an error rather than silently swallowing it. -- Updated dependencies - - @backstage/backend-common@0.14.0 - -## 0.3.2-next.2 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.14.0-next.2 - -## 0.3.2-next.1 - -### Patch Changes - -- f7146b516f: Updated dependency `cron` to `^2.0.0`. - Updated dependency `@types/cron` to `^2.0.0`. -- 7f108513b8: Add error logging when a background task throws an error rather than silently swallowing it. -- Updated dependencies - - @backstage/backend-common@0.13.6-next.1 - -## 0.3.2-next.0 - -### Patch Changes - -- fde10d24f6: Allow tasks that fail to retry on a loop emitting a warning log every time it fails with the amount of attempts it has -- Updated dependencies - - @backstage/backend-common@0.13.6-next.0 - -## 0.3.1 - -### Patch Changes - -- 73480846dd: `TaskScheduleDefinition` has been updated to also accept an options object containing duration information in the form of days, hours, seconds and so on. This allows for scheduling without importing `luxon`. - - ```diff - -import { Duration } from 'luxon'; - // omitted other code - - const schedule = env.scheduler.createScheduledTaskRunner({ - - frequency: Duration.fromObject({ minutes: 10 }), - - timeout: Duration.fromObject({ minutes: 15 }), - + frequency: { minutes: 10 }, - + timeout: { minutes: 15 }, - // omitted other code - }); - ``` - -- cfd779a9bc: Scheduled tasks now have an optional `scope` field. If unset, or having the - value `'global'`, the old behavior with cross-worker locking is retained. If - having the value `'local'`, there is no coordination across workers and the - behavior is more like `setInterval`. This can be used to replace usages of - `runPeriodically` helpers. -- ebbec677e1: Correctly set next run time for tasks -- Updated dependencies - - @backstage/backend-common@0.13.3 - - @backstage/config@1.0.1 - -## 0.3.1-next.1 - -### Patch Changes - -- 73480846dd: `TaskScheduleDefinition` has been updated to also accept an options object containing duration information in the form of days, hours, seconds and so on. This allows for scheduling without importing `luxon`. - - ```diff - -import { Duration } from 'luxon'; - // omitted other code - - const schedule = env.scheduler.createScheduledTaskRunner({ - - frequency: Duration.fromObject({ minutes: 10 }), - - timeout: Duration.fromObject({ minutes: 15 }), - + frequency: { minutes: 10 }, - + timeout: { minutes: 15 }, - // omitted other code - }); - ``` - -- ebbec677e1: Correctly set next run time for tasks -- Updated dependencies - - @backstage/backend-common@0.13.3-next.2 - - @backstage/config@1.0.1-next.0 - -## 0.3.1-next.0 - -### Patch Changes - -- cfd779a9bc: Scheduled tasks now have an optional `scope` field. If unset, or having the - value `'global'`, the old behavior with cross-worker locking is retained. If - having the value `'local'`, there is no coordination across workers and the - behavior is more like `setInterval`. This can be used to replace usages of - `runPeriodically` helpers. -- Updated dependencies - - @backstage/backend-common@0.13.3-next.0 - -## 0.3.0 - -### Minor Changes - -- ab008a0988: Adds the ability to manually trigger tasks which are registered - -### Patch Changes - -- bdd2773202: Refactored the internal `TaskWorker` class to make it easier to test. -- a83babdd63: Fixed the `initialDelay` parameter of tasks to properly make task workers - _always_ wait before the first invocations on startup, not just the very first - time that the task is ever created. This behavior is more in line with - expectations. Callers to not need to update their code. - - Also clarified in the doc comment for the field that this wait applies only on - an individual worker level. That is, if you have a cluster of workers then each - individual machine may postpone its first task invocation by the given amount of - time to leave room for the service to settle, but _other_ workers may still - continue to invoke the task on the regular cadence in the meantime. - -- Updated dependencies - - @backstage/backend-common@0.13.2 - -## 0.3.0-next.2 - -### Patch Changes - -- a83babdd63: Fixed the `initialDelay` parameter of tasks to properly make task workers - _always_ wait before the first invocations on startup, not just the very first - time that the task is ever created. This behavior is more in line with - expectations. Callers to not need to update their code. - - Also clarified in the doc comment for the field that this wait applies only on - an individual worker level. That is, if you have a cluster of workers then each - individual machine may postpone its first task invocation by the given amount of - time to leave room for the service to settle, but _other_ workers may still - continue to invoke the task on the regular cadence in the meantime. - -## 0.3.0-next.1 - -### Minor Changes - -- ab008a0988: Adds the ability to manually trigger tasks which are registered - -### Patch Changes - -- bdd2773202: Refactored the internal `TaskWorker` class to make it easier to test. -- Updated dependencies - - @backstage/backend-common@0.13.2-next.1 - -## 0.2.2-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.13.2-next.0 - -## 0.2.1 - -### Patch Changes - -- efc73db10c: Use `better-sqlite3` instead of `@vscode/sqlite3` -- Updated dependencies - - @backstage/backend-common@0.13.1 - - @backstage/config@1.0.0 - - @backstage/errors@1.0.0 - - @backstage/types@1.0.0 - -## 0.2.0 - -### Minor Changes - -- 9461f73643: **BREAKING**: The `TaskDefinition` type has been removed, and replaced by the equal pair `TaskScheduleDefinition` and `TaskInvocationDefinition`. The interface for `PluginTaskScheduler.scheduleTask` stays effectively unchanged, so this only affects you if you use the actual types directly. - - Added the method `PluginTaskScheduler.createTaskSchedule`, which returns a `TaskSchedule` wrapper that is convenient to pass down into classes that want to control their task invocations while the caller wants to retain control of the actual schedule chosen. - -### Patch Changes - -- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912) -- 7290dda9d4: Relaxed the task ID requirement to now support any non-empty string -- ae2ed04076: Add support for cron syntax to configure task frequency - `TaskScheduleDefinition.frequency` can now be both a `Duration` and an object on the form `{ cron: string }`, where the latter is expected to be on standard crontab format (e.g. `'0 */2 * * *'`). -- Updated dependencies - - @backstage/backend-common@0.13.0 - -## 0.2.0-next.0 - -### Minor Changes - -- 9461f73643: **BREAKING**: The `TaskDefinition` type has been removed, and replaced by the equal pair `TaskScheduleDefinition` and `TaskInvocationDefinition`. The interface for `PluginTaskScheduler.scheduleTask` stays effectively unchanged, so this only affects you if you use the actual types directly. - - Added the method `PluginTaskScheduler.createTaskSchedule`, which returns a `TaskSchedule` wrapper that is convenient to pass down into classes that want to control their task invocations while the caller wants to retain control of the actual schedule chosen. - -### Patch Changes - -- ab7cd7d70e: Do some groundwork for supporting the `better-sqlite3` driver, to maybe eventually replace `@vscode/sqlite3` (#9912) -- 7290dda9d4: Relaxed the task ID requirement to now support any non-empty string -- Updated dependencies - - @backstage/backend-common@0.13.0-next.0 - -## 0.1.10 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.12.0 - -## 0.1.9 - -### Patch Changes - -- dc97845422: Only output janitor logs when actually timing out tasks -- Updated dependencies - - @backstage/backend-common@0.11.0 - -## 0.1.8 - -### Patch Changes - -- Fix for the previous release with missing type declarations. -- Updated dependencies - - @backstage/backend-common@0.10.9 - - @backstage/config@0.1.15 - - @backstage/errors@0.2.2 - - @backstage/types@0.1.3 - -## 0.1.7 - -### Patch Changes - -- c77c5c7eb6: Added `backstage.role` to `package.json` -- Updated dependencies - - @backstage/backend-common@0.10.8 - - @backstage/errors@0.2.1 - - @backstage/config@0.1.14 - - @backstage/types@0.1.2 - -## 0.1.6 - -### Patch Changes - -- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 - - This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 - -- Updated dependencies - - @backstage/backend-common@0.10.7 - -## 0.1.6-next.0 - -### Patch Changes - -- 2441d1cf59: chore(deps): bump `knex` from 0.95.6 to 1.0.2 - - This also replaces `sqlite3` with `@vscode/sqlite3` 5.0.7 - -- Updated dependencies - - @backstage/backend-common@0.10.7-next.0 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6 - -## 0.1.5-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.6-next.0 - -## 0.1.4 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4 - - @backstage/config@0.1.13 - -## 0.1.4-next.0 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.4-next.0 - - @backstage/config@0.1.13-next.0 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies - - @backstage/config@0.1.12 - - @backstage/backend-common@0.10.3 - - @backstage/errors@0.2.0 - -## 0.1.2 - -### Patch Changes - -- e188b37024: Updated README to clarify the following: - - - Dashes cannot be used in the `id`, changed to an underscore in the example - - The `timeout` is required, this was also added to the example - - Added a note about tasks not running as expected for local development using persistent database - -- Updated dependencies - - @backstage/backend-common@0.10.2 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies - - @backstage/backend-common@0.10.0 diff --git a/packages/backend-tasks/README.md b/packages/backend-tasks/README.md deleted file mode 100644 index bdb151dea6..0000000000 --- a/packages/backend-tasks/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# @backstage/backend-tasks - -> [!CAUTION] -> This package is deprecated and will be removed in a near future. - -Common distributed task management for Backstage backends. - -## Usage - -> [!CAUTION] -> Please note that the documentation below is only valid for versions equal to or below `0.5.28-next.3`. -> As this package will be deleted soon, we recommend that you migrate to the new backend system, and depend on `coreServices.scheduler` from `@backstage/backend-plugin-api` instead, or use `DefaultSchedulerService` from `@backstage/backend-defaults`. Here are the [backend](https://backstage.io/docs/backend-system/building-backends/migrating) and [plugin](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating) migration guides. - -Add the library to your backend package: - -```bash -# From your Backstage root directory -yarn --cwd packages/backend add @backstage/backend-tasks -``` - -then make use of its facilities as necessary: - -```typescript -import { TaskScheduler } from '@backstage/backend-tasks'; - -const scheduler = TaskScheduler.fromConfig(rootConfig).forPlugin('my-plugin'); - -await scheduler.scheduleTask({ - id: 'refresh_things', - frequency: { cron: '*/5 * * * *' }, // every 5 minutes, also supports Duration - timeout: { minutes: 15 }, - fn: async () => { - await entityProvider.run(); - }, -}); -``` diff --git a/packages/backend-tasks/api-report.md b/packages/backend-tasks/api-report.md deleted file mode 100644 index c0f9da3a01..0000000000 --- a/packages/backend-tasks/api-report.md +++ /dev/null @@ -1,114 +0,0 @@ -## API Report File for "@backstage/backend-tasks" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { Config } from '@backstage/config'; -import { Duration } from 'luxon'; -import { HumanDuration as HumanDuration_2 } from '@backstage/types'; -import { JsonObject } from '@backstage/types'; -import { LegacyRootDatabaseService } from '@backstage/backend-common'; -import { LoggerService } from '@backstage/backend-plugin-api'; -import { PluginDatabaseManager } from '@backstage/backend-common'; - -// @public @deprecated -export type HumanDuration = HumanDuration_2; - -// @public @deprecated -export interface PluginTaskScheduler { - createScheduledTaskRunner(schedule: TaskScheduleDefinition): TaskRunner; - getScheduledTasks(): Promise; - scheduleTask( - task: TaskScheduleDefinition & TaskInvocationDefinition, - ): Promise; - triggerTask(id: string): Promise; -} - -// @public @deprecated -export function readTaskScheduleDefinitionFromConfig( - config: Config, -): TaskScheduleDefinition; - -// @public @deprecated -export type TaskDescriptor = { - id: string; - scope: 'global' | 'local'; - settings: { - version: number; - } & JsonObject; -}; - -// @public @deprecated -export type TaskFunction = - | ((abortSignal: AbortSignal) => void | Promise) - | (() => void | Promise); - -// @public @deprecated -export interface TaskInvocationDefinition { - fn: TaskFunction; - id: string; - signal?: AbortSignal; -} - -// @public @deprecated -export interface TaskRunner { - run(task: TaskInvocationDefinition): Promise; -} - -// @public @deprecated -export interface TaskScheduleDefinition { - frequency: - | { - cron: string; - } - | Duration - | HumanDuration_2 - /** - * This task will only run when manually triggered with the `triggerTask` method; no automatic - * scheduling. This is useful for locking of global tasks that should not be run concurrently. - */ - | { - trigger: 'manual'; - }; - initialDelay?: Duration | HumanDuration_2; - scope?: 'global' | 'local'; - timeout: Duration | HumanDuration_2; -} - -// @public @deprecated -export interface TaskScheduleDefinitionConfig { - frequency: - | { - cron: string; - } - | string - | HumanDuration_2; - initialDelay?: string | HumanDuration_2; - scope?: 'global' | 'local'; - timeout: string | HumanDuration_2; -} - -// @public @deprecated -export class TaskScheduler { - constructor( - databaseManager: LegacyRootDatabaseService, - logger: LoggerService, - ); - // @deprecated - forPlugin(pluginId: string): PluginTaskScheduler; - // @deprecated (undocumented) - static forPlugin(opts: { - pluginId: string; - databaseManager: PluginDatabaseManager; - logger: LoggerService; - }): PluginTaskScheduler; - // @deprecated (undocumented) - static fromConfig( - config: Config, - options?: { - databaseManager?: LegacyRootDatabaseService; - logger?: LoggerService; - }, - ): TaskScheduler; -} -``` diff --git a/packages/backend-tasks/catalog-info.yaml b/packages/backend-tasks/catalog-info.yaml deleted file mode 100644 index f9b81066e6..0000000000 --- a/packages/backend-tasks/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: backstage-backend-tasks - title: '@backstage/backend-tasks' - description: Common distributed task management library for Backstage backends -spec: - lifecycle: experimental - type: backstage-node-library - owner: maintainers diff --git a/packages/backend-tasks/knip-report.md b/packages/backend-tasks/knip-report.md deleted file mode 100644 index 2661c35327..0000000000 --- a/packages/backend-tasks/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/packages/backend-tasks/migrations/20210928160613_init.js b/packages/backend-tasks/migrations/20210928160613_init.js deleted file mode 100644 index f9900cab11..0000000000 --- a/packages/backend-tasks/migrations/20210928160613_init.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// @ts-check - -/** - * @param {import('knex').Knex} knex - */ -exports.up = async function up(knex) { - // - // tasks - // - await knex.schema.createTable('backstage_backend_tasks__tasks', table => { - table.comment('Tasks used for scheduling work on multiple workers'); - table - .string('id') - .primary() - .notNullable() - .comment('The unique ID of this particular task'); - table - .text('settings_json') - .notNullable() - .comment('JSON serialized object with properties for this task'); - table - .dateTime('next_run_start_at') - .notNullable() - .comment('The next time that the task should be started'); - table - .text('current_run_ticket') - .nullable() - .comment('A unique ticket for the current task run'); - table - .dateTime('current_run_started_at') - .nullable() - .comment('The time that the current task run started'); - table - .dateTime('current_run_expires_at') - .nullable() - .comment('The time that the current task run will time out'); - }); -}; - -/** - * @param {import('knex').Knex} knex - */ -exports.down = async function down(knex) { - // - // tasks - // - await knex.schema.dropTable('backstage_backend_tasks__tasks'); -}; diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json deleted file mode 100644 index f0209c1fa9..0000000000 --- a/packages/backend-tasks/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "@backstage/backend-tasks", - "version": "0.6.0", - "description": "Common distributed task management library for Backstage backends", - "backstage": { - "role": "node-library" - }, - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "keywords": [ - "backstage" - ], - "homepage": "https://backstage.io", - "repository": { - "type": "git", - "url": "https://github.com/backstage/backstage", - "directory": "packages/backend-tasks" - }, - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "files": [ - "dist", - "migrations/**/*.{js,d.ts}" - ], - "scripts": { - "build": "backstage-cli package build", - "clean": "backstage-cli package clean", - "lint": "backstage-cli package lint", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack", - "start": "backstage-cli package start", - "test": "backstage-cli package test" - }, - "dependencies": { - "@backstage/backend-common": "workspace:^", - "@backstage/backend-plugin-api": "workspace:^", - "@backstage/config": "workspace:^", - "@backstage/errors": "workspace:^", - "@backstage/types": "workspace:^", - "@opentelemetry/api": "^1.3.0", - "@types/luxon": "^3.0.0", - "cron": "^3.0.0", - "knex": "^3.0.0", - "lodash": "^4.17.21", - "luxon": "^3.0.0", - "uuid": "^9.0.0", - "zod": "^3.22.4" - }, - "devDependencies": { - "@backstage/backend-test-utils": "workspace:^", - "@backstage/cli": "workspace:^", - "wait-for-expect": "^3.0.2" - } -} diff --git a/packages/backend-tasks/src/database/migrateBackendTasks.ts b/packages/backend-tasks/src/database/migrateBackendTasks.ts deleted file mode 100644 index ae5048fbf7..0000000000 --- a/packages/backend-tasks/src/database/migrateBackendTasks.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { resolvePackagePath } from '@backstage/backend-plugin-api'; -import { Knex } from 'knex'; -import { DB_MIGRATIONS_TABLE } from './tables'; - -export async function migrateBackendTasks(knex: Knex): Promise { - const migrationsDir = resolvePackagePath( - '@backstage/backend-tasks', - 'migrations', - ); - - await knex.migrate.latest({ - directory: migrationsDir, - tableName: DB_MIGRATIONS_TABLE, - }); -} diff --git a/packages/backend-tasks/src/index.ts b/packages/backend-tasks/src/index.ts deleted file mode 100644 index 83c7606700..0000000000 --- a/packages/backend-tasks/src/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Common distributed task management library for Backstage backends - * - * @remarks - * This package is deprecated and will be removed in a near future. - * Please migrate to the new backend system, and depend on `coreServices.scheduler` from `@backstage/backend-plugin-api` instead, or use `DefaultSchedulerService` from `@backstage/backend-defaults`. - * - * @packageDocumentation - */ - -export * from './deprecated'; diff --git a/packages/backend-tasks/src/migrations.test.ts b/packages/backend-tasks/src/migrations.test.ts deleted file mode 100644 index 7583948f71..0000000000 --- a/packages/backend-tasks/src/migrations.test.ts +++ /dev/null @@ -1,123 +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 { Knex } from 'knex'; -import { TestDatabases } from '@backstage/backend-test-utils'; -import fs from 'fs'; - -const migrationsDir = `${__dirname}/../migrations`; -const migrationsFiles = fs.readdirSync(migrationsDir).sort(); - -async function migrateUpOnce(knex: Knex): Promise { - await knex.migrate.up({ directory: migrationsDir }); -} - -async function migrateDownOnce(knex: Knex): Promise { - await knex.migrate.down({ directory: migrationsDir }); -} - -async function migrateUntilBefore(knex: Knex, target: string): Promise { - const index = migrationsFiles.indexOf(target); - if (index === -1) { - throw new Error(`Migration ${target} not found`); - } - for (let i = 0; i < index; i++) { - await migrateUpOnce(knex); - } -} - -jest.setTimeout(60_000); - -describe('migrations', () => { - const databases = TestDatabases.create(); - - it.each(databases.eachSupportedId())( - '20210928160613_init.js, %p', - async databaseId => { - const knex = await databases.init(databaseId); - - await migrateUntilBefore(knex, '20210928160613_init.js'); - await migrateUpOnce(knex); - - await knex('backstage_backend_tasks__tasks').insert({ - id: 'test', - settings_json: '{}', - next_run_start_at: knex.fn.now(), - }); - - await expect(knex('backstage_backend_tasks__tasks')).resolves.toEqual([ - { - id: 'test', - settings_json: '{}', - next_run_start_at: expect.anything(), - current_run_ticket: null, - current_run_started_at: null, - current_run_expires_at: null, - }, - ]); - - await migrateDownOnce(knex); - - // This looks odd - you might expect a .toThrow at the end but that - // actually is flaky for some reason specifically on sqlite when - // performing multiple runs in sequence - await expect(knex('backstage_backend_tasks__tasks')).rejects.toEqual( - expect.anything(), - ); - - await knex.destroy(); - }, - ); - - it.each(databases.eachSupportedId())( - '20240712211735_nullable_next_run.js, %p', - async databaseId => { - const knex = await databases.init(databaseId); - - await migrateUntilBefore(knex, '20240712211735_nullable_next_run.js'); - await migrateUpOnce(knex); - - await knex('backstage_backend_tasks__tasks').insert({ - id: 'test', - settings_json: '{}', - next_run_start_at: knex.raw('null'), - }); - - await expect(knex('backstage_backend_tasks__tasks')).resolves.toEqual([ - { - id: 'test', - settings_json: '{}', - next_run_start_at: null, - current_run_ticket: null, - current_run_started_at: null, - current_run_expires_at: null, - }, - ]); - - await migrateDownOnce(knex); - - await expect( - knex('backstage_backend_tasks__tasks').insert({ - id: 'test', - settings_json: '{}', - next_run_start_at: knex.raw('null'), - }), - ).rejects.toEqual(expect.anything()); - - await knex.destroy(); - }, - ); -}); diff --git a/packages/backend-tasks/src/tasks/LocalTaskWorker.test.ts b/packages/backend-tasks/src/tasks/LocalTaskWorker.test.ts deleted file mode 100644 index d4d3d16067..0000000000 --- a/packages/backend-tasks/src/tasks/LocalTaskWorker.test.ts +++ /dev/null @@ -1,109 +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 { LocalTaskWorker } from './LocalTaskWorker'; -import { mockServices } from '@backstage/backend-test-utils'; - -describe('LocalTaskWorker', () => { - const logger = mockServices.logger.mock(); - - it('runs the happy path (with iso duration) and handles cancellation', async () => { - const fn = jest.fn(); - const controller = new AbortController(); - - const worker = new LocalTaskWorker('a', fn, logger); - worker.start( - { - version: 2, - initialDelayDuration: 'PT0.2S', - cadence: 'PT0.2S', - timeoutAfterDuration: 'PT1S', - }, - { signal: controller.signal }, - ); - - // TODO(freben): Rewrite to fake timers - tried, but it wouldn't work - expect(fn).toHaveBeenCalledTimes(0); - await new Promise(r => setTimeout(r, 100)); - expect(fn).toHaveBeenCalledTimes(0); - await new Promise(r => setTimeout(r, 200)); - expect(fn).toHaveBeenCalledTimes(1); - await new Promise(r => setTimeout(r, 200)); - expect(fn).toHaveBeenCalledTimes(2); - controller.abort(); - await new Promise(r => setTimeout(r, 200)); - expect(fn).toHaveBeenCalledTimes(2); - }); - - it('runs the happy path (with a cron expression) and handles cancellation', async () => { - const fn = jest.fn(); - const controller = new AbortController(); - - // Await until system time is just past a second boundary (since cron is - // wall clock based) - await new Promise(r => setTimeout(r, 1000 - (Date.now() % 1000) + 10)); - - const worker = new LocalTaskWorker('a', fn, logger); - worker.start( - { - version: 2, - initialDelayDuration: 'PT0.2S', - cadence: '* * * * * *', - timeoutAfterDuration: 'PT1S', - }, - { signal: controller.signal }, - ); - - // TODO(freben): Rewrite to fake timers - tried, but it wouldn't work - expect(fn).toHaveBeenCalledTimes(0); - await new Promise(r => setTimeout(r, 100)); - expect(fn).toHaveBeenCalledTimes(0); - await new Promise(r => setTimeout(r, 200)); - expect(fn).toHaveBeenCalledTimes(1); - await new Promise(r => setTimeout(r, 1000)); - expect(fn).toHaveBeenCalledTimes(2); - controller.abort(); - await new Promise(r => setTimeout(r, 1000)); - expect(fn).toHaveBeenCalledTimes(2); - }); - - it('can trigger to abort wait', async () => { - const fn = jest.fn(); - const controller = new AbortController(); - - const worker = new LocalTaskWorker('a', fn, logger); - worker.start( - { - version: 2, - initialDelayDuration: 'PT0.2S', - cadence: 'PT0.2S', - timeoutAfterDuration: 'PT1S', - }, - { signal: controller.signal }, - ); - - // TODO(freben): Rewrite to fake timers - tried, but it wouldn't work - expect(fn).toHaveBeenCalledTimes(0); - await new Promise(r => setTimeout(r, 100)); - expect(fn).toHaveBeenCalledTimes(0); - await new Promise(r => setTimeout(r, 200)); - expect(fn).toHaveBeenCalledTimes(1); - worker.trigger(); - await new Promise(r => setTimeout(r, 10)); - expect(fn).toHaveBeenCalledTimes(2); - controller.abort(); - }); -}); diff --git a/packages/backend-tasks/src/tasks/LocalTaskWorker.ts b/packages/backend-tasks/src/tasks/LocalTaskWorker.ts deleted file mode 100644 index e79acb35f0..0000000000 --- a/packages/backend-tasks/src/tasks/LocalTaskWorker.ts +++ /dev/null @@ -1,154 +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 { ConflictError } from '@backstage/errors'; -import { CronTime } from 'cron'; -import { DateTime, Duration } from 'luxon'; -import { TaskFunction, TaskSettingsV2 } from './types'; -import { delegateAbortController, sleep } from './util'; -import { LoggerService } from '@backstage/backend-plugin-api'; - -/** - * Implements tasks that run locally without cross-host collaboration. - * - * @private - */ -export class LocalTaskWorker { - private abortWait: AbortController | undefined; - - constructor( - private readonly taskId: string, - private readonly fn: TaskFunction, - private readonly logger: LoggerService, - ) {} - - start(settings: TaskSettingsV2, options?: { signal?: AbortSignal }) { - this.logger.info( - `Task worker starting: ${this.taskId}, ${JSON.stringify(settings)}`, - ); - - (async () => { - let attemptNum = 1; - for (;;) { - try { - if (settings.initialDelayDuration) { - await this.sleep( - Duration.fromISO(settings.initialDelayDuration), - options?.signal, - ); - } - - while (!options?.signal?.aborted) { - const startTime = process.hrtime(); - await this.runOnce(settings, options?.signal); - const timeTaken = process.hrtime(startTime); - await this.waitUntilNext( - settings, - (timeTaken[0] + timeTaken[1] / 1e9) * 1000, - options?.signal, - ); - } - - this.logger.info(`Task worker finished: ${this.taskId}`); - attemptNum = 0; - break; - } catch (e) { - attemptNum += 1; - this.logger.warn( - `Task worker failed unexpectedly, attempt number ${attemptNum}, ${e}`, - ); - await sleep(Duration.fromObject({ seconds: 1 })); - } - } - })(); - } - - trigger(): void { - if (!this.abortWait) { - throw new ConflictError(`Task ${this.taskId} is currently running`); - } - this.abortWait.abort(); - } - - /** - * Makes a single attempt at running the task to completion. - */ - private async runOnce( - settings: TaskSettingsV2, - signal?: AbortSignal, - ): Promise { - // Abort the task execution either if the worker is stopped, or if the - // task timeout is hit - const taskAbortController = delegateAbortController(signal); - const timeoutHandle = setTimeout(() => { - taskAbortController.abort(); - }, Duration.fromISO(settings.timeoutAfterDuration).as('milliseconds')); - - try { - await this.fn(taskAbortController.signal); - } catch (e) { - // ignore intentionally - } - - // release resources - clearTimeout(timeoutHandle); - taskAbortController.abort(); - } - - /** - * Sleeps until it's time to run the task again. - */ - private async waitUntilNext( - settings: TaskSettingsV2, - lastRunMillis: number, - signal?: AbortSignal, - ) { - if (signal?.aborted) { - return; - } - - const isCron = !settings.cadence.startsWith('P'); - let dt: number; - - if (isCron) { - const nextRun = +new CronTime(settings.cadence).sendAt().toJSDate(); - dt = nextRun - Date.now(); - } else { - dt = - Duration.fromISO(settings.cadence).as('milliseconds') - lastRunMillis; - } - - dt = Math.max(dt, 0); - - this.logger.debug( - `task: ${this.taskId} will next occur around ${DateTime.now().plus( - Duration.fromMillis(dt), - )}`, - ); - - await this.sleep(Duration.fromMillis(dt), signal); - } - - private async sleep( - duration: Duration, - abortSignal?: AbortSignal, - ): Promise { - this.abortWait = delegateAbortController(abortSignal); - await sleep(duration, this.abortWait.signal); - this.abortWait.abort(); // cleans up resources - this.abortWait = undefined; - } -} diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts deleted file mode 100644 index eca899098f..0000000000 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.test.ts +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - TestDatabaseId, - TestDatabases, - mockServices, -} from '@backstage/backend-test-utils'; -import { ConflictError, NotFoundError } from '@backstage/errors'; -import { Duration } from 'luxon'; -import { migrateBackendTasks } from '../database/migrateBackendTasks'; -import { - parseDuration, - PluginTaskSchedulerImpl, -} from './PluginTaskSchedulerImpl'; - -function defer() { - let resolve = () => {}; - const promise = new Promise(_resolve => { - resolve = _resolve; - }); - return { promise, resolve }; -} - -jest.setTimeout(60_000); - -describe('PluginTaskManagerImpl', () => { - const databases = TestDatabases.create({ - ids: ['POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], - }); - - beforeAll(async () => { - // Make sure all databases are running before mocking timers, in case of testcontainers - await Promise.all( - databases.eachSupportedId().map(([id]) => databases.init(id)), - ); - - jest.useFakeTimers(); - }, 60_000); - - async function init(databaseId: TestDatabaseId) { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - const logger = mockServices.logger.mock(); - const manager = new PluginTaskSchedulerImpl(async () => knex, logger); - return { knex, manager }; - } - - // This is just to test the wrapper code; most of the actual tests are in - // TaskWorker.test.ts - describe('scheduleTask with global scope', () => { - it.each(databases.eachSupportedId())( - 'can run the v1 happy path, %p', - async databaseId => { - const { manager } = await init(databaseId); - - const fn = jest.fn(); - const promise = new Promise(resolve => fn.mockImplementation(resolve)); - await manager.scheduleTask({ - id: 'task1', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromMillis(5000), - fn, - scope: 'global', - }); - - await promise; - expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal)); - }, - ); - - it.each(databases.eachSupportedId())( - 'can run the v2 happy path, %p', - async databaseId => { - const { manager } = await init(databaseId); - - const fn = jest.fn(); - const promise = new Promise(resolve => fn.mockImplementation(resolve)); - await manager.scheduleTask({ - id: 'task2', - timeout: Duration.fromMillis(5000), - frequency: { cron: '* * * * * *' }, - fn, - scope: 'global', - }); - - await promise; - expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal)); - }, - ); - }); - - describe('triggerTask with global scope', () => { - it.each(databases.eachSupportedId())( - 'can manually trigger a task, %p', - async databaseId => { - const { manager } = await init(databaseId); - - const fn = jest.fn(); - const promise = new Promise(resolve => fn.mockImplementation(resolve)); - await manager.scheduleTask({ - id: 'task1', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromObject({ years: 1 }), - initialDelay: Duration.fromObject({ years: 1 }), - fn, - scope: 'global', - }); - - await manager.triggerTask('task1'); - jest.advanceTimersByTime(5000); - - await promise; - expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal)); - }, - ); - - it.each(databases.eachSupportedId())( - 'cant trigger a non-existent task, %p', - async databaseId => { - const { manager } = await init(databaseId); - - const fn = jest.fn(); - await manager.scheduleTask({ - id: 'task1', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromObject({ years: 1 }), - fn, - scope: 'global', - }); - - await expect(() => manager.triggerTask('task2')).rejects.toThrow( - NotFoundError, - ); - }, - ); - - it.each(databases.eachSupportedId())( - 'cant trigger a running task, %p', - async databaseId => { - const { manager } = await init(databaseId); - - const { promise, resolve } = defer(); - - await manager.scheduleTask({ - id: 'task1', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromObject({ years: 1 }), - fn: async () => { - resolve(); - await new Promise(r => setTimeout(r, 20000)); - }, - scope: 'global', - }); - - await promise; - await expect(() => manager.triggerTask('task1')).rejects.toThrow( - ConflictError, - ); - }, - ); - }); - - // This is just to test the wrapper code; most of the actual tests are in - // TaskWorker.test.ts - describe('scheduleTask with local scope', () => { - it('can run the v1 happy path', async () => { - const { manager } = await init('SQLITE_3'); - - const fn = jest.fn(); - const promise = new Promise(resolve => fn.mockImplementation(resolve)); - await manager.scheduleTask({ - id: 'task1', - timeout: { milliseconds: 5000 }, - frequency: { milliseconds: 5000 }, - fn, - scope: 'local', - }); - - await promise; - expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal)); - }, 60_000); - - it('can run the v2 happy path', async () => { - const { manager } = await init('SQLITE_3'); - - const fn = jest.fn(); - const promise = new Promise(resolve => fn.mockImplementation(resolve)); - await manager.scheduleTask({ - id: 'task2', - timeout: Duration.fromMillis(5000), - frequency: { cron: '* * * * * *' }, - fn, - scope: 'local', - }); - - await promise; - expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal)); - }, 60_000); - }); - - describe('triggerTask with local scope', () => { - it('can manually trigger a task', async () => { - const { manager } = await init('SQLITE_3'); - - const fn = jest.fn(); - const promise = new Promise(resolve => fn.mockImplementation(resolve)); - await manager.scheduleTask({ - id: 'task1', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromObject({ years: 1 }), - initialDelay: Duration.fromObject({ years: 1 }), - fn, - scope: 'local', - }); - - await manager.triggerTask('task1'); - jest.advanceTimersByTime(5000); - - await promise; - expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal)); - }, 60_000); - - it('cant trigger a non-existent task', async () => { - const { manager } = await init('SQLITE_3'); - - const fn = jest.fn(); - await manager.scheduleTask({ - id: 'task1', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromObject({ years: 1 }), - fn, - scope: 'local', - }); - - await expect(() => manager.triggerTask('task2')).rejects.toThrow( - NotFoundError, - ); - }, 60_000); - - it('cant trigger a running task', async () => { - const { manager } = await init('SQLITE_3'); - - const { promise, resolve } = defer(); - - await manager.scheduleTask({ - id: 'task1', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromObject({ years: 1 }), - fn: async () => { - resolve(); - await new Promise(r => setTimeout(r, 20000)); - }, - scope: 'local', - }); - - await promise; - await expect(() => manager.triggerTask('task1')).rejects.toThrow( - ConflictError, - ); - }, 60_000); - }); - - // This is just to test the wrapper code; most of the actual tests are in - // TaskWorker.test.ts - describe('createScheduledTaskRunner', () => { - it.each(databases.eachSupportedId())( - 'can run the happy path, %p', - async databaseId => { - const { manager } = await init(databaseId); - - const fn = jest.fn(); - const promise = new Promise(resolve => fn.mockImplementation(resolve)); - await manager - .createScheduledTaskRunner({ - timeout: Duration.fromMillis(5000), - frequency: Duration.fromMillis(5000), - scope: 'global', - }) - .run({ - id: 'task1', - fn, - }); - - await promise; - expect(fn).toHaveBeenCalledWith(expect.any(AbortSignal)); - }, - ); - }); - - describe('can fetch task ids', () => { - it.each(databases.eachSupportedId())( - 'can fetch both global and local task ids, %p', - async databaseId => { - const { manager } = await init(databaseId); - const fn = jest.fn(); - - await manager.scheduleTask({ - id: 'task1', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromMillis(5000), - fn, - scope: 'global', - }); - - await manager.scheduleTask({ - id: 'task2', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromMillis(5000), - fn, - scope: 'local', - }); - - await expect(manager.getScheduledTasks()).resolves.toEqual([ - { - id: 'task1', - scope: 'global', - settings: expect.objectContaining({ cadence: 'PT5S' }), - }, - { - id: 'task2', - scope: 'local', - settings: expect.objectContaining({ cadence: 'PT5S' }), - }, - ]); - }, - ); - }); - - describe('parseDuration', () => { - it('should parse durations', () => { - expect(parseDuration({ milliseconds: 5000 })).toEqual('PT5S'); - expect(parseDuration(Duration.fromMillis(5000))).toEqual('PT5S'); - expect(parseDuration({ cron: '1 * * * *' })).toEqual('1 * * * *'); - expect(parseDuration({ trigger: 'manual' })).toEqual('manual'); - }); - }); -}); diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts deleted file mode 100644 index 0ccc77a6c1..0000000000 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerImpl.ts +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Knex } from 'knex'; -import { Duration } from 'luxon'; -import { LocalTaskWorker } from './LocalTaskWorker'; -import { TaskWorker } from './TaskWorker'; -import { - PluginTaskScheduler, - TaskDescriptor, - TaskFunction, - TaskInvocationDefinition, - TaskRunner, - TaskScheduleDefinition, - TaskSettingsV2, -} from './types'; -import { validateId } from './util'; -import { Counter, Histogram, metrics } from '@opentelemetry/api'; -import { LoggerService } from '@backstage/backend-plugin-api'; - -/** - * Implements the actual task management. - */ -export class PluginTaskSchedulerImpl implements PluginTaskScheduler { - private readonly localTasksById = new Map(); - private readonly allScheduledTasks: TaskDescriptor[] = []; - - private readonly counter: Counter; - private readonly duration: Histogram; - - constructor( - private readonly databaseFactory: () => Promise, - private readonly logger: LoggerService, - ) { - const meter = metrics.getMeter('default'); - this.counter = meter.createCounter('backend_tasks.task.runs.count', { - description: 'Total number of times a task has been run', - }); - this.duration = meter.createHistogram('backend_tasks.task.runs.duration', { - description: 'Histogram of task run durations', - unit: 'seconds', - }); - } - - async triggerTask(id: string): Promise { - const localTask = this.localTasksById.get(id); - if (localTask) { - localTask.trigger(); - return; - } - - const knex = await this.databaseFactory(); - await TaskWorker.trigger(knex, id); - } - - async scheduleTask( - task: TaskScheduleDefinition & TaskInvocationDefinition, - ): Promise { - validateId(task.id); - const scope = task.scope ?? 'global'; - - const settings: TaskSettingsV2 = { - version: 2, - cadence: parseDuration(task.frequency), - initialDelayDuration: - task.initialDelay && parseDuration(task.initialDelay), - timeoutAfterDuration: parseDuration(task.timeout), - }; - - if (scope === 'global') { - const knex = await this.databaseFactory(); - const worker = new TaskWorker( - task.id, - this.wrapInMetrics(task.fn, { labels: { taskId: task.id, scope } }), - knex, - this.logger.child({ task: task.id }), - ); - await worker.start(settings, { signal: task.signal }); - } else { - const worker = new LocalTaskWorker( - task.id, - this.wrapInMetrics(task.fn, { labels: { taskId: task.id, scope } }), - this.logger.child({ task: task.id }), - ); - worker.start(settings, { signal: task.signal }); - this.localTasksById.set(task.id, worker); - } - - this.allScheduledTasks.push({ - id: task.id, - scope: scope, - settings: settings, - }); - } - - createScheduledTaskRunner(schedule: TaskScheduleDefinition): TaskRunner { - return { - run: async task => { - await this.scheduleTask({ ...task, ...schedule }); - }, - }; - } - - async getScheduledTasks(): Promise { - return this.allScheduledTasks; - } - - private wrapInMetrics( - fn: TaskFunction, - opts: { labels: Record }, - ): TaskFunction { - return async abort => { - const labels = { - ...opts.labels, - }; - this.counter.add(1, { ...labels, result: 'started' }); - - const startTime = process.hrtime(); - - try { - await fn(abort); - labels.result = 'completed'; - } catch (ex) { - labels.result = 'failed'; - throw ex; - } finally { - const delta = process.hrtime(startTime); - const endTime = delta[0] + delta[1] / 1e9; - this.counter.add(1, labels); - this.duration.record(endTime, labels); - } - }; - } -} - -export function parseDuration( - frequency: TaskScheduleDefinition['frequency'], -): string { - if ('cron' in frequency) { - return frequency.cron; - } - if ('trigger' in frequency) { - return frequency.trigger; - } - - const parsed = Duration.isDuration(frequency) - ? frequency - : Duration.fromObject(frequency); - - if (!parsed.isValid) { - throw new Error( - `Invalid duration, ${parsed.invalidReason}: ${parsed.invalidExplanation}`, - ); - } - - return parsed.toISO()!; -} diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts deleted file mode 100644 index 93b5d7d189..0000000000 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TestDatabases, mockServices } from '@backstage/backend-test-utils'; -import { Knex } from 'knex'; -import { Duration } from 'luxon'; -import waitForExpect from 'wait-for-expect'; -import { migrateBackendTasks } from '../database/migrateBackendTasks'; -import { DbTasksRow, DB_TASKS_TABLE } from '../database/tables'; -import { PluginTaskSchedulerJanitor } from './PluginTaskSchedulerJanitor'; -import { createTestScopedSignal } from './__testUtils__/createTestScopedSignal'; - -const insertTask = async (knex: Knex, task: DbTasksRow) => { - return knex(DB_TASKS_TABLE) - .insert(task) - .onConflict('id') - .merge(['settings_json']); -}; - -const getTask = async (knex: Knex): Promise => { - return (await knex(DB_TASKS_TABLE))[0]; -}; - -describe('PluginTaskSchedulerJanitor', () => { - const logger = mockServices.logger.mock(); - const databases = TestDatabases.create({ - ids: [ - /* 'MYSQL_8' not supported yet */ - 'POSTGRES_16', - 'POSTGRES_12', - 'SQLITE_3', - 'MYSQL_8', - ], - }); - const testScopedSignal = createTestScopedSignal(); - - jest.setTimeout(60_000); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - it.each(databases.eachSupportedId())( - 'Should update date if current_run_expires_at expires, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const dateYesterday = new Date( - new Date().setDate(new Date().getDate() - 1), - ); - - await insertTask(knex, { - id: 'task1', - settings_json: '', - next_run_start_at: new Date('2023-03-01 00:00:00'), - current_run_ticket: 'ticket', - current_run_started_at: dateYesterday, - current_run_expires_at: dateYesterday, - }); - - const worker = new PluginTaskSchedulerJanitor({ - waitBetweenRuns: Duration.fromObject({ milliseconds: 20 }), - knex, - logger, - }); - - worker.start(testScopedSignal()); - - await waitForExpect(async () => { - await expect(getTask(knex)).resolves.toEqual( - expect.objectContaining({ - id: 'task1', - current_run_ticket: null, - current_run_started_at: null, - current_run_expires_at: null, - }), - ); - }); - }, - ); -}); diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts deleted file mode 100644 index 7b6becab91..0000000000 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Knex } from 'knex'; -import { Duration } from 'luxon'; -import { DB_TASKS_TABLE, DbTasksRow } from '../database/tables'; -import { sleep } from './util'; -import { LoggerService } from '@backstage/backend-plugin-api'; - -/** - * Makes sure to auto-expire and clean up things that time out or for other - * reasons should not be left lingering. - */ -export class PluginTaskSchedulerJanitor { - private readonly knex: Knex; - private readonly waitBetweenRuns: Duration; - private readonly logger: LoggerService; - - constructor(options: { - knex: Knex; - waitBetweenRuns: Duration; - logger: LoggerService; - }) { - this.knex = options.knex; - this.waitBetweenRuns = options.waitBetweenRuns; - this.logger = options.logger; - } - - async start(abortSignal?: AbortSignal) { - while (!abortSignal?.aborted) { - try { - await this.runOnce(); - } catch (e) { - this.logger.warn(`Error while performing janitorial tasks, ${e}`); - } - - await sleep(this.waitBetweenRuns, abortSignal); - } - } - - private async runOnce() { - const dbNull = this.knex.raw('null'); - const configClient = this.knex.client.config.client; - - let tasks: Array<{ id: string }>; - if (configClient.includes('sqlite3') || configClient.includes('mysql')) { - tasks = await this.knex(DB_TASKS_TABLE) - .select('id') - .where('current_run_expires_at', '<', this.knex.fn.now()); - await this.knex(DB_TASKS_TABLE) - .whereIn( - 'id', - tasks.map(t => t.id), - ) - .update({ - current_run_ticket: dbNull, - current_run_started_at: dbNull, - current_run_expires_at: dbNull, - }); - } else { - tasks = await this.knex(DB_TASKS_TABLE) - .where('current_run_expires_at', '<', this.knex.fn.now()) - .update({ - current_run_ticket: dbNull, - current_run_started_at: dbNull, - current_run_expires_at: dbNull, - }) - .returning(['id']); - } - - // In rare cases, knex drivers may ignore "returning", and return the number - // of rows changed instead - if (typeof tasks === 'number') { - if (tasks > 0) { - this.logger.warn(`${tasks} tasks timed out and were lost`); - } - } else { - for (const { id } of tasks) { - this.logger.warn(`Task timed out and was lost: ${id}`); - } - } - } -} diff --git a/packages/backend-tasks/src/tasks/TaskScheduler.test.ts b/packages/backend-tasks/src/tasks/TaskScheduler.test.ts deleted file mode 100644 index 24ce73712f..0000000000 --- a/packages/backend-tasks/src/tasks/TaskScheduler.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { DatabaseManager } from '@backstage/backend-common'; -import { - TestDatabaseId, - TestDatabases, - mockServices, -} from '@backstage/backend-test-utils'; -import { Duration } from 'luxon'; -import waitForExpect from 'wait-for-expect'; -import { TaskScheduler } from './TaskScheduler'; -import { createTestScopedSignal } from './__testUtils__/createTestScopedSignal'; - -jest.setTimeout(60_000); - -describe('TaskScheduler', () => { - const logger = mockServices.logger.mock(); - const databases = TestDatabases.create(); - const testScopedSignal = createTestScopedSignal(); - - async function createDatabase( - databaseId: TestDatabaseId, - ): Promise { - const knex = await databases.init(databaseId); - const databaseManager: Partial = { - forPlugin: () => ({ - getClient: async () => knex, - }), - }; - return databaseManager as DatabaseManager; - } - - it.each(databases.eachSupportedId())( - 'can return a working v1 plugin impl, %p', - async databaseId => { - const database = await createDatabase(databaseId); - const manager = new TaskScheduler(database, logger).forPlugin('test'); - const fn = jest.fn(); - - await manager.scheduleTask({ - id: 'task1', - timeout: Duration.fromMillis(5000), - frequency: Duration.fromMillis(5000), - signal: testScopedSignal(), - fn, - }); - - await waitForExpect(() => { - expect(fn).toHaveBeenCalled(); - }); - }, - ); - - it.each(databases.eachSupportedId())( - 'can return a working v2 plugin impl, %p', - async databaseId => { - const database = await createDatabase(databaseId); - const manager = new TaskScheduler(database, logger).forPlugin('test'); - const fn = jest.fn(); - - await manager.scheduleTask({ - id: 'task2', - timeout: Duration.fromMillis(5000), - frequency: { cron: '* * * * * *' }, - signal: testScopedSignal(), - fn, - }); - - await waitForExpect(() => { - expect(fn).toHaveBeenCalled(); - }); - }, - ); -}); diff --git a/packages/backend-tasks/src/tasks/TaskScheduler.ts b/packages/backend-tasks/src/tasks/TaskScheduler.ts deleted file mode 100644 index ff6fd12017..0000000000 --- a/packages/backend-tasks/src/tasks/TaskScheduler.ts +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - DatabaseManager, - getRootLogger, - LegacyRootDatabaseService, - PluginDatabaseManager, -} from '@backstage/backend-common'; -import { Config } from '@backstage/config'; -import { once } from 'lodash'; -import { Duration } from 'luxon'; -import { migrateBackendTasks } from '../database/migrateBackendTasks'; -import { PluginTaskSchedulerImpl } from './PluginTaskSchedulerImpl'; -import { PluginTaskSchedulerJanitor } from './PluginTaskSchedulerJanitor'; -import { PluginTaskScheduler } from './types'; -import { LoggerService } from '@backstage/backend-plugin-api'; - -/** - * Deals with the scheduling of distributed tasks. - * - * @public - * @deprecated Please migrate to the new backend system, and depend on `coreServices.scheduler` from `@backstage/backend-plugin-api` instead, or use `DefaultSchedulerService` from `@backstage/backend-defaults` - */ -export class TaskScheduler { - /** - * @deprecated - * It is only used by the legacy backend system, and should not be used in the new backend system. - */ - static fromConfig( - config: Config, - options?: { - databaseManager?: LegacyRootDatabaseService; - logger?: LoggerService; - }, - ): TaskScheduler { - const databaseManager = - options?.databaseManager ?? DatabaseManager.fromConfig(config); - const logger = (options?.logger || getRootLogger()).child({ - type: 'taskManager', - }); - return new TaskScheduler(databaseManager, logger); - } - - constructor( - private readonly databaseManager: LegacyRootDatabaseService, - private readonly logger: LoggerService, - ) {} - - /** - * Instantiates a task manager instance for the given plugin. - * - * @param pluginId - The unique ID of the plugin, for example "catalog" - * @returns A {@link PluginTaskScheduler} instance - * @deprecated Please migrate to the new backend system, and depend on `coreServices.scheduler` from `@backstage/backend-plugin-api` instead, or use `DefaultSchedulerService` from `@backstage/backend-defaults` - */ - forPlugin(pluginId: string): PluginTaskScheduler { - return TaskScheduler.forPlugin({ - pluginId, - databaseManager: this.databaseManager.forPlugin(pluginId), - logger: this.logger, - }); - } - - /** - * @deprecated Please migrate to the new backend system, and depend on `coreServices.scheduler` from `@backstage/backend-plugin-api` instead, or use `DefaultSchedulerService` from `@backstage/backend-defaults` - */ - static forPlugin(opts: { - pluginId: string; - databaseManager: PluginDatabaseManager; - logger: LoggerService; - }): PluginTaskScheduler { - const databaseFactory = once(async () => { - const knex = await opts.databaseManager.getClient(); - - if (!opts.databaseManager.migrations?.skip) { - await migrateBackendTasks(knex); - } - - if (process.env.NODE_ENV !== 'test') { - const janitor = new PluginTaskSchedulerJanitor({ - knex, - waitBetweenRuns: Duration.fromObject({ minutes: 1 }), - logger: opts.logger, - }); - janitor.start(); - } - - return knex; - }); - - return new PluginTaskSchedulerImpl(databaseFactory, opts.logger); - } -} diff --git a/packages/backend-tasks/src/tasks/TaskWorker.test.ts b/packages/backend-tasks/src/tasks/TaskWorker.test.ts deleted file mode 100644 index 829d7754f8..0000000000 --- a/packages/backend-tasks/src/tasks/TaskWorker.test.ts +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TestDatabases, mockServices } from '@backstage/backend-test-utils'; -import { Duration, DateTime } from 'luxon'; -import waitForExpect from 'wait-for-expect'; -import { migrateBackendTasks } from '../database/migrateBackendTasks'; -import { DbTasksRow, DB_TASKS_TABLE } from '../database/tables'; -import { TaskWorker } from './TaskWorker'; -import { TaskSettingsV2 } from './types'; -import { createTestScopedSignal } from './__testUtils__/createTestScopedSignal'; - -jest.setTimeout(60_000); - -describe('TaskWorker', () => { - const logger = mockServices.logger.mock(); - const databases = TestDatabases.create(); - const testScopedSignal = createTestScopedSignal(); - - beforeEach(() => { - jest.resetAllMocks(); - }); - - it.each(databases.eachSupportedId())( - 'goes through the expected states, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const fn = jest.fn( - async () => new Promise(resolve => setTimeout(resolve, 50)), - ); - const settings: TaskSettingsV2 = { - version: 2, - cadence: '*/2 * * * * *', - initialDelayDuration: Duration.fromObject({ seconds: 1 }).toISO()!, - timeoutAfterDuration: Duration.fromObject({ minutes: 1 }).toISO()!, - }; - - const worker = new TaskWorker('task1', fn, knex, logger); - await worker.persistTask(settings); - - let row = (await knex(DB_TASKS_TABLE))[0]; - expect(row).toEqual( - expect.objectContaining({ - id: 'task1', - current_run_ticket: null, - current_run_started_at: null, - current_run_expires_at: null, - }), - ); - expect(JSON.parse(row.settings_json)).toEqual({ - version: 2, - cadence: '*/2 * * * * *', - initialDelayDuration: 'PT1S', - timeoutAfterDuration: 'PT1M', - }); - - await expect(worker.findReadyTask()).resolves.toEqual({ - result: 'not-ready-yet', - }); - - await waitForExpect(async () => { - await expect(worker.findReadyTask()).resolves.toEqual({ - result: 'ready', - settings, - }); - }); - - row = (await knex(DB_TASKS_TABLE))[0]; - expect(row).toEqual( - expect.objectContaining({ - id: 'task1', - current_run_ticket: null, - current_run_started_at: null, - current_run_expires_at: null, - }), - ); - - await expect(worker.tryClaimTask('ticket', settings)).resolves.toBe(true); - - row = (await knex(DB_TASKS_TABLE))[0]; - expect(row).toEqual( - expect.objectContaining({ - id: 'task1', - current_run_ticket: 'ticket', - current_run_started_at: expect.anything(), - current_run_expires_at: expect.anything(), - }), - ); - - await expect(worker.tryReleaseTask('ticket', settings)).resolves.toBe( - true, - ); - - row = (await knex(DB_TASKS_TABLE))[0]; - expect(row).toEqual( - expect.objectContaining({ - id: 'task1', - current_run_ticket: null, - current_run_started_at: null, - current_run_expires_at: null, - }), - ); - }, - ); - - it.each(databases.eachSupportedId())( - 'logs error when the task throws, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - jest.spyOn(logger, 'error'); - const fn = jest.fn().mockRejectedValue(new Error('failed')); - const settings: TaskSettingsV2 = { - version: 2, - initialDelayDuration: undefined, - cadence: '* * * * * *', - timeoutAfterDuration: Duration.fromMillis(60000).toISO()!, - }; - const checkFrequency = Duration.fromObject({ milliseconds: 100 }); - const worker = new TaskWorker('task1', fn, knex, logger, checkFrequency); - worker.start(settings, { signal: testScopedSignal() }); - - await waitForExpect(() => { - expect(logger.error).toHaveBeenCalled(); - }); - }, - ); - - it.each(databases.eachSupportedId())( - 'runs tasks more than once even when the task throws, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const fn = jest.fn().mockRejectedValue(new Error('failed')); - const settings: TaskSettingsV2 = { - version: 2, - initialDelayDuration: undefined, - cadence: '* * * * * *', - timeoutAfterDuration: Duration.fromMillis(60000).toISO()!, - }; - const checkFrequency = Duration.fromObject({ milliseconds: 100 }); - const worker = new TaskWorker('task1', fn, knex, logger, checkFrequency); - worker.start(settings, { signal: testScopedSignal() }); - - await waitForExpect(() => { - expect(fn).toHaveBeenCalledTimes(3); - }); - }, - ); - - it.each(databases.eachSupportedId())( - 'does not clobber ticket lock when stolen, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const fn = jest.fn( - async () => new Promise(resolve => setTimeout(resolve, 50)), - ); - const settings: TaskSettingsV2 = { - version: 2, - initialDelayDuration: undefined, - cadence: '* * * * * *', - timeoutAfterDuration: Duration.fromMillis(60000).toISO()!, - }; - - const worker = new TaskWorker('task1', fn, knex, logger); - await worker.persistTask(settings); - - await waitForExpect(async () => { - await expect(worker.findReadyTask()).resolves.toEqual({ - result: 'ready', - settings, - }); - }); - - await expect(worker.tryClaimTask('ticket', settings)).resolves.toBe(true); - - let row = (await knex(DB_TASKS_TABLE))[0]; - expect(row).toEqual( - expect.objectContaining({ - id: 'task1', - current_run_ticket: 'ticket', - current_run_started_at: expect.anything(), - current_run_expires_at: expect.anything(), - }), - ); - - await knex(DB_TASKS_TABLE) - .where('id', '=', 'task1') - .update({ current_run_ticket: 'stolen' }); - - await expect(worker.tryReleaseTask('ticket', settings)).resolves.toBe( - false, - ); - - row = (await knex(DB_TASKS_TABLE))[0]; - expect(row).toEqual( - expect.objectContaining({ - id: 'task1', - current_run_ticket: 'stolen', - current_run_started_at: expect.anything(), - current_run_expires_at: expect.anything(), - }), - ); - }, - ); - - it.each(databases.eachSupportedId())( - 'gracefully handles a disappeared task row, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const fn = jest.fn(async () => {}); - const settings: TaskSettingsV2 = { - version: 2, - initialDelayDuration: undefined, - cadence: '* * * * * *', - timeoutAfterDuration: Duration.fromMillis(60000).toISO()!, - }; - - const worker1 = new TaskWorker('task1', fn, knex, logger); - await worker1.persistTask(settings); - await knex(DB_TASKS_TABLE).where('id', '=', 'task1').delete(); - await expect(worker1.findReadyTask()).resolves.toEqual({ - result: 'abort', - }); - - const worker2 = new TaskWorker('task2', fn, knex, logger); - await worker2.persistTask(settings); - - await waitForExpect(async () => { - await expect(worker2.findReadyTask()).resolves.toEqual({ - result: 'ready', - settings, - }); - }); - - await knex(DB_TASKS_TABLE).where('id', '=', 'task2').delete(); - await expect(worker2.tryClaimTask('ticket', settings)).resolves.toBe( - false, - ); - - const worker3 = new TaskWorker('task3', fn, knex, logger); - await worker3.persistTask(settings); - - await waitForExpect(async () => { - await expect(worker3.findReadyTask()).resolves.toEqual({ - result: 'ready', - settings, - }); - }); - - await expect(worker3.tryClaimTask('ticket', settings)).resolves.toBe( - true, - ); - await knex(DB_TASKS_TABLE).where('id', '=', 'task3').delete(); - await expect(worker3.tryReleaseTask('ticket', settings)).resolves.toBe( - false, - ); - }, - ); - - it.each(databases.eachSupportedId())( - 'respects initialDelayDuration per worker, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const abortFirst = new AbortController(); - const settings: TaskSettingsV2 = { - version: 2, - initialDelayDuration: 'PT0.3S', - cadence: 'PT0.1S', - timeoutAfterDuration: 'PT10S', - }; - - // Start a single worker and make sure it waits and then goes to work - const fn1 = jest.fn(async () => {}); - const worker1 = new TaskWorker( - 'task1', - fn1, - knex, - logger, - Duration.fromMillis(10), - ); - await worker1.start(settings, { signal: abortFirst.signal }); - - expect(fn1).toHaveBeenCalledTimes(0); - await new Promise(resolve => setTimeout(resolve, 250)); - expect(fn1).toHaveBeenCalledTimes(0); - await new Promise(resolve => setTimeout(resolve, 100)); - expect(fn1.mock.calls.length).toBeGreaterThan(0); - - // Start a second worker and make sure it waits but the first worker still works along - const fn2 = jest.fn(); - const promise2 = new Promise(resolve => fn2.mockImplementation(resolve)); - const worker2 = new TaskWorker( - 'task1', - fn2, - knex, - logger, - Duration.fromMillis(10), - ); - await worker2.start(settings, { signal: testScopedSignal() }); - - // We eventually abort the first worker just to make sure that the second - // one for sure will get a go at running the task - setTimeout(() => abortFirst.abort(), 1000); - - const before = fn1.mock.calls.length; - await promise2; - expect(fn1.mock.calls.length).toBeGreaterThan(before); - - await knex.destroy(); - }, - ); - - it.each(databases.eachSupportedId())( - 'next_run_start_at is always the min between schedule changes from cron frequency, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const fn = jest.fn( - async () => new Promise(resolve => setTimeout(resolve, 50)), - ); - const settings: TaskSettingsV2 = { - version: 2, - cadence: '*/15 * * * *', - initialDelayDuration: 'PT2M', - timeoutAfterDuration: 'PT1M', - }; - - const worker = new TaskWorker('task99', fn, knex, logger); - await worker.persistTask(settings); - const row1 = (await knex(DB_TASKS_TABLE))[0]; - - const settings2 = { - ...settings, - cadence: '*/2 * * * *', - initialDelayDuration: 'PT1M', - }; - await worker.persistTask(settings2); - const row2 = (await knex(DB_TASKS_TABLE))[0]; - - expect(row2.next_run_start_at).not.toStrictEqual(row1.next_run_start_at); - - const settings3 = { ...settings }; - await worker.persistTask(settings3); - const row3 = (await knex(DB_TASKS_TABLE))[0]; - - // The new timestamp can basically be 0 or a minute depending on how the - // initialDelayDuration falls right on a cron boundary. This kinda - // contrived check removes a test flakiness based on wall clock time. - expect( - Math.abs( - +new Date(row3.next_run_start_at) - +new Date(row2.next_run_start_at), - ), - ).toBeLessThanOrEqual(60_000); - - await knex.destroy(); - }, - ); - - it.each(databases.eachSupportedId())( - 'next_run_start_at is always the min between schedule changes when using human duration frequency, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const fn = jest.fn( - async () => new Promise(resolve => setTimeout(resolve, 50)), - ); - - const initialSettings: TaskSettingsV2 = { - version: 2, - cadence: 'PT120M', - timeoutAfterDuration: 'PT1M', - }; - - const worker = new TaskWorker('task99', fn, knex, logger); - await worker.persistTask(initialSettings); - // replicate task running, sets next_run_start_at based on cadence - await worker.tryClaimTask('ticket', initialSettings); - await worker.tryReleaseTask('ticket', initialSettings); - - // grab initial row for comparisons later - const rowAfterClaimAndRelease = ( - await knex(DB_TASKS_TABLE) - )[0]; - - const settings: TaskSettingsV2 = { - ...initialSettings, - cadence: 'PT60M', - }; - await worker.persistTask(settings); - const row1 = (await knex(DB_TASKS_TABLE))[0]; - - const rowAfterClaimAndReleaseNextStartAt = DateTime.fromJSDate( - new Date(rowAfterClaimAndRelease.next_run_start_at), - ); - const row1NextStartAt = DateTime.fromJSDate( - new Date(row1.next_run_start_at), - ); - const now = DateTime.now(); - expect( - rowAfterClaimAndReleaseNextStartAt.diff(row1NextStartAt).as('minutes'), - ).toBeCloseTo(60, 1); // ensure that next start at is sooner than initial by one hour - expect(row1NextStartAt.diff(now).as('minutes')).toBeCloseTo(60, 1); // ensure that next start at is later than now by one hour - expect( - rowAfterClaimAndReleaseNextStartAt.diff(now).as('minutes'), - ).toBeCloseTo(120, 1); - - const settings2 = { - ...settings, - }; - await worker.persistTask(settings2); - const row2 = (await knex(DB_TASKS_TABLE))[0]; - - expect(row2.next_run_start_at).toStrictEqual(row1.next_run_start_at); - - await knex.destroy(); - }, - ); - - it.each(databases.eachSupportedId())( - 'next_run_start_at is always the min between schedule changes when using human duration frequency with initial start delay, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const fn = jest.fn( - async () => new Promise(resolve => setTimeout(resolve, 50)), - ); - - const initialSettings: TaskSettingsV2 = { - version: 2, - cadence: 'PT120M', - initialDelayDuration: 'PT2M', - timeoutAfterDuration: 'PT1M', - }; - - const worker = new TaskWorker('task99', fn, knex, logger); - await worker.persistTask(initialSettings); - // replicate task running, sets next_run_start_at based on cadence - await worker.tryClaimTask('ticket', initialSettings); - await worker.tryReleaseTask('ticket', initialSettings); - - // grab initial row for comparisons later - const rowAfterClaimAndRelease = ( - await knex(DB_TASKS_TABLE) - )[0]; - - const settings: TaskSettingsV2 = { - ...initialSettings, - cadence: 'PT60M', - }; - await worker.persistTask(settings); - const row1 = (await knex(DB_TASKS_TABLE))[0]; - - const rowAfterClaimAndReleaseNextStartAt = DateTime.fromJSDate( - new Date(rowAfterClaimAndRelease.next_run_start_at), - ); - const row1NextStartAt = DateTime.fromJSDate( - new Date(row1.next_run_start_at), - ); - const now = DateTime.now(); - expect( - rowAfterClaimAndReleaseNextStartAt.diff(row1NextStartAt).as('minutes'), - ).toBeCloseTo(62, 1); // ensure that next start at is sooner than initial by one hour, plus the 2 minute delay (set my tryReleaseTask) - expect(row1NextStartAt.diff(now).as('minutes')).toBeCloseTo(60, 1); // ensure that next start at is later than now by one hour (2 minute delay doesn't take effect here) - expect( - rowAfterClaimAndReleaseNextStartAt.diff(now).as('minutes'), - ).toBeCloseTo(122, 1); // includes 2 minute start delay (which is persisted from tryReleaseTask) - - const settings2 = { - ...settings, - }; - await worker.persistTask(settings2); - const row2 = (await knex(DB_TASKS_TABLE))[0]; - - expect(row2.next_run_start_at).toStrictEqual(row1.next_run_start_at); - - await knex.destroy(); - }, - ); - - it.each(databases.eachSupportedId())( - 'next_run_start_at is not set for manually-triggered tasks, %p', - async databaseId => { - const knex = await databases.init(databaseId); - await migrateBackendTasks(knex); - - const fn = jest.fn( - async () => new Promise(resolve => setTimeout(resolve, 50)), - ); - - const initialSettings: TaskSettingsV2 = { - version: 2, - cadence: 'manual', - timeoutAfterDuration: 'PT1M', - }; - - const worker = new TaskWorker('task99', fn, knex, logger); - await worker.persistTask(initialSettings); - await worker.tryClaimTask('ticket', initialSettings); - await worker.tryReleaseTask('ticket', initialSettings); - - const row = (await knex(DB_TASKS_TABLE))[0]; - expect(row.next_run_start_at).toBeNull(); - - await knex.destroy(); - }, - ); -}); diff --git a/packages/backend-tasks/src/tasks/TaskWorker.ts b/packages/backend-tasks/src/tasks/TaskWorker.ts deleted file mode 100644 index a50b988522..0000000000 --- a/packages/backend-tasks/src/tasks/TaskWorker.ts +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ConflictError, NotFoundError } from '@backstage/errors'; -import { CronTime } from 'cron'; -import { Knex } from 'knex'; -import { DateTime, Duration } from 'luxon'; -import { v4 as uuid } from 'uuid'; -import { DB_TASKS_TABLE, DbTasksRow } from '../database/tables'; -import { TaskFunction, TaskSettingsV2, taskSettingsV2Schema } from './types'; -import { delegateAbortController, nowPlus, sleep } from './util'; -import { LoggerService } from '@backstage/backend-plugin-api'; - -const DEFAULT_WORK_CHECK_FREQUENCY = Duration.fromObject({ seconds: 5 }); - -/** - * Implements tasks that run across worker hosts, with collaborative locking. - * - * @private - */ -export class TaskWorker { - constructor( - private readonly taskId: string, - private readonly fn: TaskFunction, - private readonly knex: Knex, - private readonly logger: LoggerService, - private readonly workCheckFrequency: Duration = DEFAULT_WORK_CHECK_FREQUENCY, - ) {} - - async start(settings: TaskSettingsV2, options?: { signal?: AbortSignal }) { - try { - await this.persistTask(settings); - } catch (e) { - throw new Error(`Failed to persist task, ${e}`); - } - - this.logger.info( - `Task worker starting: ${this.taskId}, ${JSON.stringify(settings)}`, - ); - - let workCheckFrequency = this.workCheckFrequency; - const isDuration = settings?.cadence.startsWith('P'); - if (isDuration) { - const cadence = Duration.fromISO(settings.cadence); - if (cadence < workCheckFrequency) { - workCheckFrequency = cadence; - } - } - - let attemptNum = 1; - (async () => { - for (;;) { - try { - if (settings.initialDelayDuration) { - await sleep( - Duration.fromISO(settings.initialDelayDuration), - options?.signal, - ); - } - - while (!options?.signal?.aborted) { - const runResult = await this.runOnce(options?.signal); - - if (runResult.result === 'abort') { - break; - } - - await sleep(workCheckFrequency, options?.signal); - } - - this.logger.info(`Task worker finished: ${this.taskId}`); - attemptNum = 0; - break; - } catch (e) { - attemptNum += 1; - this.logger.warn( - `Task worker failed unexpectedly, attempt number ${attemptNum}, ${e}`, - ); - await sleep(Duration.fromObject({ seconds: 1 })); - } - } - })(); - } - - static async trigger(knex: Knex, taskId: string): Promise { - // check if task exists - const rows = await knex(DB_TASKS_TABLE) - .select(knex.raw(1)) - .where('id', '=', taskId); - if (rows.length !== 1) { - throw new NotFoundError(`Task ${taskId} does not exist`); - } - - const updatedRows = await knex(DB_TASKS_TABLE) - .where('id', '=', taskId) - .whereNull('current_run_ticket') - .update({ - next_run_start_at: knex.fn.now(), - }); - if (updatedRows < 1) { - throw new ConflictError(`Task ${taskId} is currently running`); - } - } - - /** - * Makes a single attempt at running the task to completion, if ready. - * - * @returns The outcome of the attempt - */ - private async runOnce( - signal?: AbortSignal, - ): Promise< - | { result: 'not-ready-yet' } - | { result: 'abort' } - | { result: 'failed' } - | { result: 'completed' } - > { - const findResult = await this.findReadyTask(); - if ( - findResult.result === 'not-ready-yet' || - findResult.result === 'abort' - ) { - return findResult; - } - - const taskSettings = findResult.settings; - const ticket = uuid(); - - const claimed = await this.tryClaimTask(ticket, taskSettings); - if (!claimed) { - return { result: 'not-ready-yet' }; - } - - // Abort the task execution either if the worker is stopped, or if the - // task timeout is hit - const taskAbortController = delegateAbortController(signal); - const timeoutHandle = setTimeout(() => { - taskAbortController.abort(); - }, Duration.fromISO(taskSettings.timeoutAfterDuration).as('milliseconds')); - - try { - await this.fn(taskAbortController.signal); - taskAbortController.abort(); // releases resources - } catch (e) { - this.logger.error(e); - await this.tryReleaseTask(ticket, taskSettings); - return { result: 'failed' }; - } finally { - clearTimeout(timeoutHandle); - } - - await this.tryReleaseTask(ticket, taskSettings); - return { result: 'completed' }; - } - - /** - * Perform the initial store of the task info - */ - async persistTask(settings: TaskSettingsV2) { - // Perform an initial parse to ensure that we will definitely be able to - // read it back again. - taskSettingsV2Schema.parse(settings); - - const isManual = settings?.cadence === 'manual'; - const isDuration = settings?.cadence.startsWith('P'); - const isCron = !isManual && !isDuration; - - let startAt: Knex.Raw | undefined; - let nextStartAt: Knex.Raw | undefined; - if (settings.initialDelayDuration) { - startAt = nowPlus( - Duration.fromISO(settings.initialDelayDuration), - this.knex, - ); - } - - if (isCron) { - const time = new CronTime(settings.cadence) - .sendAt() - .minus({ seconds: 1 }) // immediately, if "* * * * * *" - .toUTC(); - - nextStartAt = this.nextRunAtRaw(time); - startAt ||= nextStartAt; - } else if (isManual) { - nextStartAt = this.knex.raw('null'); - startAt ||= nextStartAt; - } else { - startAt ||= this.knex.fn.now(); - nextStartAt = nowPlus(Duration.fromISO(settings.cadence), this.knex); - } - - this.logger.debug(`task: ${this.taskId} configured to run at: ${startAt}`); - - // It's OK if the task already exists; if it does, just replace its - // settings with the new value and start the loop as usual. - const settingsJson = JSON.stringify(settings); - await this.knex(DB_TASKS_TABLE) - .insert({ - id: this.taskId, - settings_json: settingsJson, - next_run_start_at: startAt, - }) - .onConflict('id') - .merge( - this.knex.client.config.client.includes('mysql') - ? { - settings_json: settingsJson, - next_run_start_at: this.knex.raw( - `CASE WHEN ?? < ?? THEN ?? ELSE ?? END`, - [ - nextStartAt, - 'next_run_start_at', - nextStartAt, - 'next_run_start_at', - ], - ), - } - : { - settings_json: this.knex.ref('excluded.settings_json'), - next_run_start_at: this.knex.raw( - `CASE WHEN ?? < ?? THEN ?? ELSE ?? END`, - [ - nextStartAt, - `${DB_TASKS_TABLE}.next_run_start_at`, - nextStartAt, - `${DB_TASKS_TABLE}.next_run_start_at`, - ], - ), - }, - ); - } - - /** - * Check if the task is ready to run - */ - async findReadyTask(): Promise< - | { result: 'not-ready-yet' } - | { result: 'abort' } - | { result: 'ready'; settings: TaskSettingsV2 } - > { - const [row] = await this.knex(DB_TASKS_TABLE) - .where('id', '=', this.taskId) - .select({ - settingsJson: 'settings_json', - ready: this.knex.raw( - `CASE - WHEN next_run_start_at <= ? AND current_run_ticket IS NULL THEN TRUE - ELSE FALSE - END`, - [this.knex.fn.now()], - ), - }); - - if (!row) { - this.logger.info( - 'No longer able to find task; aborting and assuming that it has been unregistered or expired', - ); - return { result: 'abort' }; - } else if (!row.ready) { - return { result: 'not-ready-yet' }; - } - - try { - const obj = JSON.parse(row.settingsJson); - const settings = taskSettingsV2Schema.parse(obj); - return { result: 'ready', settings }; - } catch (e) { - this.logger.info( - `Task "${this.taskId}" is no longer able to parse task settings; aborting and assuming that a ` + - `newer version of the task has been issued and being handled by other workers, ${e}`, - ); - return { result: 'abort' }; - } - } - - /** - * Attempts to claim a task that's ready for execution, on this worker's - * behalf. We should not attempt to perform the work unless the claim really - * goes through. - * - * @param ticket - A globally unique string that changes for each invocation - * @param settings - The settings of the task to claim - * @returns True if it was successfully claimed - */ - async tryClaimTask( - ticket: string, - settings: TaskSettingsV2, - ): Promise { - const startedAt = this.knex.fn.now(); - const expiresAt = settings.timeoutAfterDuration - ? nowPlus(Duration.fromISO(settings.timeoutAfterDuration), this.knex) - : this.knex.raw('null'); - - const rows = await this.knex(DB_TASKS_TABLE) - .where('id', '=', this.taskId) - .whereNull('current_run_ticket') - .update({ - current_run_ticket: ticket, - current_run_started_at: startedAt, - current_run_expires_at: expiresAt, - }); - - return rows === 1; - } - - async tryReleaseTask( - ticket: string, - settings: TaskSettingsV2, - ): Promise { - const isManual = settings?.cadence === 'manual'; - const isDuration = settings?.cadence.startsWith('P'); - const isCron = !isManual && !isDuration; - - let nextRun: Knex.Raw; - if (isCron) { - const time = new CronTime(settings.cadence).sendAt().toUTC(); - this.logger.debug(`task: ${this.taskId} will next occur around ${time}`); - - nextRun = this.nextRunAtRaw(time); - } else if (isManual) { - nextRun = this.knex.raw('null'); - } else { - const dt = Duration.fromISO(settings.cadence).as('seconds'); - this.logger.debug( - `task: ${this.taskId} will next occur around ${DateTime.now().plus({ - seconds: dt, - })}`, - ); - - if (this.knex.client.config.client.includes('sqlite3')) { - nextRun = this.knex.raw( - `max(datetime(next_run_start_at, ?), datetime('now'))`, - [`+${dt} seconds`], - ); - } else if (this.knex.client.config.client.includes('mysql')) { - nextRun = this.knex.raw( - `greatest(next_run_start_at + interval ${dt} second, now())`, - ); - } else { - nextRun = this.knex.raw( - `greatest(next_run_start_at + interval '${dt} seconds', now())`, - ); - } - } - - const rows = await this.knex(DB_TASKS_TABLE) - .where('id', '=', this.taskId) - .where('current_run_ticket', '=', ticket) - .update({ - next_run_start_at: nextRun, - current_run_ticket: this.knex.raw('null'), - current_run_started_at: this.knex.raw('null'), - current_run_expires_at: this.knex.raw('null'), - }); - - return rows === 1; - } - - private nextRunAtRaw(time: DateTime): Knex.Raw { - if (this.knex.client.config.client.includes('sqlite3')) { - return this.knex.raw('datetime(?)', [time.toISO()]); - } else if (this.knex.client.config.client.includes('mysql')) { - return this.knex.raw(`?`, [time.toSQL({ includeOffset: false })]); - } - return this.knex.raw(`?`, [time.toISO()]); - } -} diff --git a/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.test.ts b/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.test.ts deleted file mode 100644 index adeb134611..0000000000 --- a/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.test.ts +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ConfigReader } from '@backstage/config'; -import { HumanDuration } from '@backstage/types'; -import { readTaskScheduleDefinitionFromConfig } from './readTaskScheduleDefinitionFromConfig'; - -describe('readTaskScheduleDefinitionFromConfig', () => { - it('all valid values', () => { - const config = new ConfigReader({ - frequency: { - cron: '0 30 * * * *', - }, - timeout: 'PT3M', - initialDelay: { - minutes: 20, - }, - scope: 'global', - }); - - const result = readTaskScheduleDefinitionFromConfig(config); - - expect((result.frequency as { cron: string }).cron).toBe('0 30 * * * *'); - expect(result.timeout).toEqual({ minutes: 3 }); - expect((result.initialDelay as HumanDuration).minutes).toEqual(20); - expect(result.scope).toBe('global'); - }); - - it('all valid required values', () => { - const config = new ConfigReader({ - frequency: { - cron: '0 30 * * * *', - }, - timeout: 'PT3M', - }); - - const result = readTaskScheduleDefinitionFromConfig(config); - - expect((result.frequency as { cron: string }).cron).toBe('0 30 * * * *'); - expect(result.timeout).toEqual({ minutes: 3 }); - expect(result.initialDelay).toBeUndefined(); - expect(result.scope).toBeUndefined(); - }); - - it('fail without required frequency', () => { - const config = new ConfigReader({ - timeout: 'PT3M', - }); - - expect(() => readTaskScheduleDefinitionFromConfig(config)).toThrow( - "Missing required config value at 'frequency'", - ); - }); - - it('fail without required timeout', () => { - const config = new ConfigReader({ - frequency: 'PT30M', - }); - - expect(() => readTaskScheduleDefinitionFromConfig(config)).toThrow( - "Missing required config value at 'timeout'", - ); - }); - - it('invalid frequency key', () => { - const config = new ConfigReader({ - frequency: { - invalid: 'value', - }, - timeout: 'PT3M', - }); - - expect(() => readTaskScheduleDefinitionFromConfig(config)).toThrow( - "Failed to read duration from config at 'frequency', Error: Needs one or more of 'years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds', 'milliseconds'", - ); - }); - - it('invalid frequency value', () => { - const config = new ConfigReader({ - frequency: { - minutes: 'value', - }, - timeout: 'PT3M', - }); - - expect(() => readTaskScheduleDefinitionFromConfig(config)).toThrow( - "Failed to read duration from config, Error: Unable to convert config value for key 'frequency.minutes' in 'mock-config' to a number", - ); - }); - - it('frequency value with additional invalid prop', () => { - const config = new ConfigReader({ - frequency: { - minutes: 20, - invalid: 'value', - }, - timeout: 'PT3M', - }); - - expect(() => readTaskScheduleDefinitionFromConfig(config)).toThrow( - "Failed to read duration from config at 'frequency', Error: Unknown property 'invalid'; expected one or more of 'years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds', 'milliseconds'", - ); - }); - - it('invalid scope value', () => { - const config = new ConfigReader({ - frequency: { - years: 2, - }, - timeout: 'PT3M', - scope: 'invalid', - }); - - expect(() => readTaskScheduleDefinitionFromConfig(config)).toThrow( - 'Only "global" or "local" are allowed for TaskScheduleDefinition.scope, but got: invalid', - ); - }); -}); diff --git a/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.ts b/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.ts deleted file mode 100644 index 85099d82db..0000000000 --- a/packages/backend-tasks/src/tasks/readTaskScheduleDefinitionFromConfig.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2022 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Config, readDurationFromConfig } from '@backstage/config'; -import { HumanDuration } from '@backstage/types'; -import { TaskScheduleDefinition } from './types'; -import { Duration } from 'luxon'; - -function readDuration(config: Config, key: string): HumanDuration { - if (typeof config.get(key) === 'string') { - const value = config.getString(key); - const duration = Duration.fromISO(value); - if (!duration.isValid) { - throw new Error(`Invalid duration: ${value}`); - } - return duration.toObject(); - } - - return readDurationFromConfig(config, { key }); -} - -function readFrequency( - config: Config, - key: string, -): { cron: string } | Duration | HumanDuration | { trigger: 'manual' } { - const value = config.get(key); - if (typeof value === 'object' && (value as { cron?: string }).cron) { - return value as { cron: string }; - } - if ( - typeof value === 'object' && - (value as { trigger?: string }).trigger === 'manual' - ) { - return { trigger: 'manual' }; - } - - return readDuration(config, key); -} - -/** - * Reads a TaskScheduleDefinition from a Config. - * Expects the config not to be the root config, - * but the config for the definition. - * - * @param config - config for a TaskScheduleDefinition. - * @public - * @deprecated Please import `readSchedulerServiceTaskScheduleDefinitionFromConfig` from `@backstage/backend-plugin-api` instead - */ -export function readTaskScheduleDefinitionFromConfig( - config: Config, -): TaskScheduleDefinition { - const frequency = readFrequency(config, 'frequency'); - const timeout = readDuration(config, 'timeout'); - - const initialDelay = config.has('initialDelay') - ? readDuration(config, 'initialDelay') - : undefined; - - const scope = config.getOptionalString('scope'); - if (scope && !['global', 'local'].includes(scope)) { - throw new Error( - `Only "global" or "local" are allowed for TaskScheduleDefinition.scope, but got: ${scope}`, - ); - } - - return { - frequency, - timeout, - initialDelay, - scope: scope as 'global' | 'local' | undefined, - }; -} diff --git a/packages/backend-tasks/src/tasks/types.ts b/packages/backend-tasks/src/tasks/types.ts deleted file mode 100644 index a0bdbbaa64..0000000000 --- a/packages/backend-tasks/src/tasks/types.ts +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { HumanDuration, JsonObject } from '@backstage/types'; -import { CronTime } from 'cron'; -import { Duration } from 'luxon'; -import { z } from 'zod'; - -/** - * A function that can be called as a scheduled task. - * - * It may optionally accept an abort signal argument. When the signal triggers, - * processing should abort and return as quickly as possible. - * - * @public - * @deprecated Please import `SchedulerServiceTaskFunction` from `@backstage/backend-plugin-api` instead - */ -export type TaskFunction = - | ((abortSignal: AbortSignal) => void | Promise) - | (() => void | Promise); - -/** - * A semi-opaque type to describe an actively scheduled task. - * - * @public - * @deprecated Please import `SchedulerServiceTaskDescriptor` from `@backstage/backend-plugin-api` instead - */ -export type TaskDescriptor = { - /** - * The unique identifier of the task. - */ - id: string; - /** - * The scope of the task. - */ - scope: 'global' | 'local'; - /** - * The settings that control the task flow. This is a semi-opaque structure - * that is mainly there for debugging purposes. Do not make any assumptions - * about the contents of this field. - */ - settings: { version: number } & JsonObject; -}; - -/** - * Options that control the scheduling of a task. - * - * @public - * @deprecated Please import `SchedulerServiceTaskScheduleDefinition` from `@backstage/backend-plugin-api` instead - */ -export interface TaskScheduleDefinition { - /** - * How often you want the task to run. The system does its best to avoid - * overlapping invocations. - * - * @remarks - * - * This is the best effort value; under some circumstances there can be - * deviations. For example, if the task runtime is longer than the frequency - * and the timeout has not been given or not been exceeded yet, the next - * invocation of this task will be delayed until after the previous one - * finishes. - * - * This is a required field. - */ - frequency: - | { - /** - * A crontab style string. - * - * @remarks - * - * Overview: - * - * ``` - * ┌────────────── second (optional) - * │ ┌──────────── minute - * │ │ ┌────────── hour - * │ │ │ ┌──────── day of month - * │ │ │ │ ┌────── month - * │ │ │ │ │ ┌──── day of week - * │ │ │ │ │ │ - * │ │ │ │ │ │ - * * * * * * * - * ``` - */ - cron: string; - } - | Duration - | HumanDuration - /** - * This task will only run when manually triggered with the `triggerTask` method; no automatic - * scheduling. This is useful for locking of global tasks that should not be run concurrently. - */ - | { trigger: 'manual' }; - - /** - * The maximum amount of time that a single task invocation can take, before - * it's considered timed out and gets "released" such that a new invocation - * is permitted to take place (possibly, then, on a different worker). - */ - timeout: Duration | HumanDuration; - - /** - * The amount of time that should pass before the first invocation happens. - * - * @remarks - * - * This can be useful in cold start scenarios to stagger or delay some heavy - * compute jobs. If no value is given for this field then the first invocation - * will happen as soon as possible according to the cadence. - * - * NOTE: This is a per-worker delay. If you have a cluster of workers all - * collaborating on a task that has its `scope` field set to `'global'`, then - * you may still see the task being processed by other long-lived workers, - * while any given single worker is in its initial sleep delay time e.g. after - * a deployment. Therefore, this parameter is not useful for "globally" pausing - * work; its main intended use is for individual machines to get a chance to - * reach some equilibrium at startup before triggering heavy batch workloads. - */ - initialDelay?: Duration | HumanDuration; - - /** - * Sets the scope of concurrency control / locking to apply for invocations of - * this task. - * - * @remarks - * - * When the scope is set to the default value `'global'`, the scheduler will - * attempt to ensure that only one worker machine runs the task at a time, - * according to the given cadence. This means that as the number of worker - * hosts increases, the invocation frequency of this task will not go up. - * Instead, the load is spread randomly across hosts. This setting is useful - * for tasks that access shared resources, for example catalog ingestion tasks - * where you do not want many machines to repeatedly import the same data and - * trample over each other. - * - * When the scope is set to `'local'`, there is no concurrency control across - * hosts. Each host runs the task according to the given cadence similarly to - * `setInterval`, but the runtime ensures that there are no overlapping runs. - * - * @defaultValue 'global' - */ - scope?: 'global' | 'local'; -} - -/** - * Config options for {@link TaskScheduleDefinition} - * that control the scheduling of a task. - * - * @public - * @deprecated Please import `SchedulerServiceTaskScheduleDefinitionConfig` from `@backstage/backend-plugin-api` instead - */ -export interface TaskScheduleDefinitionConfig { - /** - * How often you want the task to run. The system does its best to avoid - * overlapping invocations. - * - * @remarks - * - * This is the best effort value; under some circumstances there can be - * deviations. For example, if the task runtime is longer than the frequency - * and the timeout has not been given or not been exceeded yet, the next - * invocation of this task will be delayed until after the previous one - * finishes. - * - * This is a required field. - */ - frequency: - | { - /** - * A crontab style string. - * - * @remarks - * - * Overview: - * - * ``` - * ┌────────────── second (optional) - * │ ┌──────────── minute - * │ │ ┌────────── hour - * │ │ │ ┌──────── day of month - * │ │ │ │ ┌────── month - * │ │ │ │ │ ┌──── day of week - * │ │ │ │ │ │ - * │ │ │ │ │ │ - * * * * * * * - * ``` - */ - cron: string; - } - | string - | HumanDuration; - - /** - * The maximum amount of time that a single task invocation can take, before - * it's considered timed out and gets "released" such that a new invocation - * is permitted to take place (possibly, then, on a different worker). - */ - timeout: string | HumanDuration; - - /** - * The amount of time that should pass before the first invocation happens. - * - * @remarks - * - * This can be useful in cold start scenarios to stagger or delay some heavy - * compute jobs. If no value is given for this field then the first invocation - * will happen as soon as possible according to the cadence. - * - * NOTE: This is a per-worker delay. If you have a cluster of workers all - * collaborating on a task that has its `scope` field set to `'global'`, then - * you may still see the task being processed by other long-lived workers, - * while any given single worker is in its initial sleep delay time e.g. after - * a deployment. Therefore, this parameter is not useful for "globally" pausing - * work; its main intended use is for individual machines to get a chance to - * reach some equilibrium at startup before triggering heavy batch workloads. - */ - initialDelay?: string | HumanDuration; - - /** - * Sets the scope of concurrency control / locking to apply for invocations of - * this task. - * - * @remarks - * - * When the scope is set to the default value `'global'`, the scheduler will - * attempt to ensure that only one worker machine runs the task at a time, - * according to the given cadence. This means that as the number of worker - * hosts increases, the invocation frequency of this task will not go up. - * Instead, the load is spread randomly across hosts. This setting is useful - * for tasks that access shared resources, for example catalog ingestion tasks - * where you do not want many machines to repeatedly import the same data and - * trample over each other. - * - * When the scope is set to `'local'`, there is no concurrency control across - * hosts. Each host runs the task according to the given cadence similarly to - * `setInterval`, but the runtime ensures that there are no overlapping runs. - * - * @defaultValue 'global' - */ - scope?: 'global' | 'local'; -} - -/** - * Options that apply to the invocation of a given task. - * - * @public - * @deprecated Please import `SchedulerServiceTaskInvocationDefinition` from `@backstage/backend-plugin-api` instead - */ -export interface TaskInvocationDefinition { - /** - * A unique ID (within the scope of the plugin) for the task. - */ - id: string; - - /** - * The actual task function to be invoked regularly. - */ - fn: TaskFunction; - - /** - * An abort signal that, when triggered, will stop the recurring execution of - * the task. - */ - signal?: AbortSignal; -} - -/** - * A previously prepared task schedule, ready to be invoked. - * - * @public - * @deprecated Please import `SchedulerServiceTaskRunner` from `@backstage/backend-plugin-api` instead - */ -export interface TaskRunner { - /** - * Takes the schedule and executes an actual task using it. - * - * @param task - The actual runtime properties of the task - */ - run(task: TaskInvocationDefinition): Promise; -} - -/** - * Deals with the scheduling of distributed tasks, for a given plugin. - * - * @public - * @deprecated Please use `SchedulerService` from `@backstage/backend-plugin-api` instead (most likely via `coreServices.scheduler`) - */ -export interface PluginTaskScheduler { - /** - * Manually triggers a task by ID. - * - * If the task doesn't exist, a NotFoundError is thrown. If the task is - * currently running, a ConflictError is thrown. - * - * @param id - The task ID - */ - triggerTask(id: string): Promise; - - /** - * Schedules a task function for recurring runs. - * - * @remarks - * - * The `scope` task field controls whether to use coordinated exclusive - * invocation across workers, or to just coordinate within the current worker. - * - * This convenience method performs both the scheduling and invocation in one - * go. - * - * @param task - The task definition - */ - scheduleTask( - task: TaskScheduleDefinition & TaskInvocationDefinition, - ): Promise; - - /** - * Creates a scheduled but dormant recurring task, ready to be launched at a - * later time. - * - * @remarks - * - * This method is useful for pre-creating a schedule in outer code to be - * passed into an inner implementation, such that the outer code controls - * scheduling while inner code controls implementation. - * - * @param schedule - The task schedule - */ - createScheduledTaskRunner(schedule: TaskScheduleDefinition): TaskRunner; - - /** - * Returns all scheduled tasks registered to this scheduler. - * - * @remarks - * - * This method is useful for triggering tasks manually using the triggerTask - * functionality. Note that the returned tasks contain only tasks that have - * been initialized in this instance of the scheduler. - * - * @returns Scheduled tasks - */ - getScheduledTasks(): Promise; -} - -function isValidOptionalDurationString(d: string | undefined): boolean { - try { - return !d || Duration.fromISO(d).isValid; - } catch { - return false; - } -} - -function isValidCronFormat(c: string | undefined): boolean { - try { - if (!c) { - return false; - } - // parse cron format to ensure it's a valid format. - // eslint-disable-next-line no-new - new CronTime(c); - return true; - } catch { - return false; - } -} - -function isValidTrigger(t: string): boolean { - return t === 'manual'; -} - -export const taskSettingsV1Schema = z.object({ - version: z.literal(1), - initialDelayDuration: z - .string() - .optional() - .refine(isValidOptionalDurationString, { - message: 'Invalid duration, expecting ISO Period', - }), - recurringAtMostEveryDuration: z - .string() - .refine(isValidOptionalDurationString, { - message: 'Invalid duration, expecting ISO Period', - }), - timeoutAfterDuration: z.string().refine(isValidOptionalDurationString, { - message: 'Invalid duration, expecting ISO Period', - }), -}); - -/** - * The properties that control a scheduled task (version 1). - */ -export type TaskSettingsV1 = z.infer; - -export const taskSettingsV2Schema = z.object({ - version: z.literal(2), - cadence: z - .string() - .refine(isValidCronFormat, { message: 'Invalid cron' }) - .or( - z.string().refine(isValidTrigger, { - message: "Invalid trigger, expecting 'manual'", - }), - ) - .or( - z.string().refine(isValidOptionalDurationString, { - message: 'Invalid duration, expecting ISO Period', - }), - ), - timeoutAfterDuration: z.string().refine(isValidOptionalDurationString, { - message: 'Invalid duration, expecting ISO Period', - }), - initialDelayDuration: z - .string() - .optional() - .refine(isValidOptionalDurationString, { - message: 'Invalid duration, expecting ISO Period', - }), -}); - -/** - * The properties that control a scheduled task (version 2). - */ -export type TaskSettingsV2 = z.infer; diff --git a/packages/backend-tasks/src/tasks/util.test.ts b/packages/backend-tasks/src/tasks/util.test.ts deleted file mode 100644 index e2536abb88..0000000000 --- a/packages/backend-tasks/src/tasks/util.test.ts +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import knexFactory, { Knex } from 'knex'; -import { Duration } from 'luxon'; -import { delegateAbortController, nowPlus, sleep, validateId } from './util'; - -class KnexBuilder { - public build(client: string): Knex { - return knexFactory({ client, useNullAsDefault: true }); - } -} - -describe('util', () => { - describe('validateId', () => { - it.each(['a', 'a_b', 'ab123c_2', 'a!', 'A', 'a-b', 'a.b', '_a', 'a_'])( - 'accepts valid inputs, %p', - async input => { - expect(validateId(input)).toBeUndefined(); - }, - ); - - it.each(['', null, Symbol('a')])( - 'rejects invalid inputs, %p', - async input => { - expect(() => validateId(input as any)).toThrow(); - }, - ); - }); - - describe('sleep', () => { - it('finishes the wait as expected with no signal', async () => { - const ac = new AbortController(); - const start = Date.now(); - await sleep(Duration.fromObject({ seconds: 1 }), ac.signal); - expect(Date.now() - start).toBeGreaterThan(800); - }, 5_000); - - it('aborts properly on the signal', async () => { - const ac = new AbortController(); - const promise = sleep(Duration.fromObject({ seconds: 10 }), ac.signal); - ac.abort(); - await promise; - expect(true).toBe(true); - }, 1_000); - }); - - describe('delegateAbortController', () => { - it('inherits parent abort state', () => { - const parent = new AbortController(); - const child = delegateAbortController(parent.signal); - expect(parent.signal.aborted).toBe(false); - expect(child.signal.aborted).toBe(false); - parent.abort(); - expect(parent.signal.aborted).toBe(true); - expect(child.signal.aborted).toBe(true); - }); - - it('does not inherit from child to parent', () => { - const parent = new AbortController(); - const child = delegateAbortController(parent.signal); - expect(parent.signal.aborted).toBe(false); - expect(child.signal.aborted).toBe(false); - child.abort(); - expect(parent.signal.aborted).toBe(false); - expect(child.signal.aborted).toBe(true); - }); - }); - - describe('nowPlus', () => { - describe('without duration', () => { - const databases = [ - { client: 'sqlite3', expected: 'CURRENT_TIMESTAMP' }, - { client: 'mysql2', expected: 'CURRENT_TIMESTAMP' }, - { client: 'pg', expected: 'CURRENT_TIMESTAMP' }, - ]; - - it.each(databases)('for client $client', ({ client, expected }) => { - const knex = new KnexBuilder().build(client); - const result = nowPlus(undefined, knex); - - expect(result.toString()).toBe(expected); - }); - }); - describe('With duration', () => { - const databases = [ - { client: 'sqlite3', expected: "datetime('now', '20 seconds')" }, - { client: 'mysql2', expected: 'now() + interval 20 second' }, - { client: 'pg', expected: "now() + interval '20 seconds'" }, - ]; - it.each(databases)('for client $client', ({ client, expected }) => { - const duration = Duration.fromObject({ seconds: 20 }); - const knex = new KnexBuilder().build(client); - const result = nowPlus(duration, knex); - - expect(result.toString()).toBe(expected); - }); - }); - }); -}); diff --git a/packages/backend-tasks/src/tasks/util.ts b/packages/backend-tasks/src/tasks/util.ts deleted file mode 100644 index 70d67a9fbe..0000000000 --- a/packages/backend-tasks/src/tasks/util.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { InputError } from '@backstage/errors'; -import { Knex } from 'knex'; -import { DateTime, Duration } from 'luxon'; - -// Keep the IDs compatible with e.g. Prometheus labels -export function validateId(id: string) { - if (typeof id !== 'string' || !id.trim()) { - throw new InputError(`${id} is not a valid ID, expected non-empty string`); - } -} - -export function dbTime(t: Date | string): DateTime { - if (typeof t === 'string') { - return DateTime.fromSQL(t); - } - return DateTime.fromJSDate(t); -} - -export function nowPlus(duration: Duration | undefined, knex: Knex) { - const seconds = duration?.as('seconds') ?? 0; - if (!seconds) { - return knex.fn.now(); - } - - if (knex.client.config.client.includes('sqlite3')) { - return knex.raw(`datetime('now', ?)`, [`${seconds} seconds`]); - } - - if (knex.client.config.client.includes('mysql')) { - return knex.raw(`now() + interval ${seconds} second`); - } - - return knex.raw(`now() + interval '${seconds} seconds'`); -} - -/** - * Sleep for the given duration, but return sooner if the abort signal - * triggers. - * - * @param duration - The amount of time to sleep, at most - * @param abortSignal - An optional abort signal that short circuits the wait - */ -export async function sleep( - duration: Duration, - abortSignal?: AbortSignal, -): Promise { - if (abortSignal?.aborted) { - return; - } - - await new Promise(resolve => { - let timeoutHandle: NodeJS.Timeout | undefined = undefined; - - const done = () => { - if (timeoutHandle) { - clearTimeout(timeoutHandle); - } - abortSignal?.removeEventListener('abort', done); - resolve(); - }; - - timeoutHandle = setTimeout(done, duration.as('milliseconds')); - abortSignal?.addEventListener('abort', done); - }); -} - -/** - * Creates a new AbortController that, in addition to working as a regular - * standalone controller, also gets aborted if the given parent signal - * reaches aborted state. - * - * @param parent - The "parent" signal that can trigger the delegate - */ -export function delegateAbortController(parent?: AbortSignal): AbortController { - const delegate = new AbortController(); - - if (parent) { - if (parent.aborted) { - delegate.abort(); - } else { - const onParentAborted = () => { - delegate.abort(); - }; - - const onChildAborted = () => { - parent.removeEventListener('abort', onParentAborted); - }; - - parent.addEventListener('abort', onParentAborted, { once: true }); - delegate.signal.addEventListener('abort', onChildAborted, { once: true }); - } - } - - return delegate; -} diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 2b11e31fb9..28ee376101 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/backend-test-utils +## 0.6.0-next.1 + +### Patch Changes + +- 710f621: Added missing service mock for `mockServices.rootConfig.mock`, and fixed the definition of `mockServices.rootHttpRouter.factory` to not have a duplicate callback. +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-app-api@0.10.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.6.0-next.0 + +### Minor Changes + +- 19ff127: **BREAKING**: Removed service mocks for the identity and token manager services, which have been removed from `@backstage/backend-plugin-api`. +- 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 + +- 0363bf1: There is a new `mockErrorHandler` utility to help in mocking the error middleware in tests. +- Updated dependencies + - @backstage/backend-app-api@0.10.0-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.5.0 ### Minor Changes diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 109ddbece3..2bea998596 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -3,8 +3,10 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +/// /// /// +/// import { AuthService } from '@backstage/backend-plugin-api'; import { Backend } from '@backstage/backend-app-api'; @@ -18,6 +20,7 @@ import { BackstageUserPrincipal } from '@backstage/backend-plugin-api'; import { CacheService } from '@backstage/backend-plugin-api'; import { DatabaseService } from '@backstage/backend-plugin-api'; import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { ErrorRequestHandler } from 'express'; import { EventsService } from '@backstage/plugin-events-node'; import { ExtendedHttpServer } from '@backstage/backend-defaults/rootHttpRouter'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; @@ -28,10 +31,11 @@ import Keyv from 'keyv'; import { Knex } from 'knex'; import { LifecycleService } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; +import { ParamsDictionary } from 'express-serve-static-core'; +import { ParsedQs } from 'qs'; import { PermissionsService } from '@backstage/backend-plugin-api'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { RootHealthService } from '@backstage/backend-plugin-api'; -import { RootHttpRouterFactoryOptions } from '@backstage/backend-defaults/rootHttpRouter'; import { RootHttpRouterService } from '@backstage/backend-plugin-api'; import { RootLifecycleService } from '@backstage/backend-plugin-api'; import { RootLoggerService } from '@backstage/backend-plugin-api'; @@ -137,6 +141,15 @@ export interface MockDirectoryContentOptions { shouldReadAsText?: boolean | ((path: string, buffer: Buffer) => boolean); } +// @public +export function mockErrorHandler(): ErrorRequestHandler< + ParamsDictionary, + any, + any, + ParsedQs, + Record +>; + // @public (undocumented) export namespace mockServices { // (undocumented) @@ -253,6 +266,10 @@ export namespace mockServices { factory: ( options?: Options | undefined, ) => ServiceFactory; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace rootHealth { @@ -266,10 +283,7 @@ export namespace mockServices { // (undocumented) export namespace rootHttpRouter { const // (undocumented) - factory: () => (( - options?: RootHttpRouterFactoryOptions | undefined, - ) => ServiceFactory) & - ServiceFactory; + factory: () => ServiceFactory; const // (undocumented) mock: ( partialImpl?: Partial | undefined, diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 682ec3067e..a84aca9b52 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "0.5.0", + "version": "0.6.0-next.1", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" @@ -55,7 +55,10 @@ "@backstage/types": "workspace:^", "@keyv/memcache": "^1.3.5", "@keyv/redis": "^2.5.3", + "@types/express": "^4.17.6", + "@types/express-serve-static-core": "^4.17.5", "@types/keyv": "^4.2.0", + "@types/qs": "^6.9.6", "better-sqlite3": "^11.0.0", "cookie": "^0.6.0", "express": "^4.17.1", diff --git a/packages/backend-test-utils/src/index.ts b/packages/backend-test-utils/src/index.ts index d1d80bf387..d8e0e2c4a6 100644 --- a/packages/backend-test-utils/src/index.ts +++ b/packages/backend-test-utils/src/index.ts @@ -25,3 +25,4 @@ export * from './database'; export * from './msw'; export * from './filesystem'; export * from './next'; +export { mockErrorHandler } from './util'; diff --git a/packages/backend-test-utils/src/next/services/mockServices.test.ts b/packages/backend-test-utils/src/next/services/mockServices.test.ts new file mode 100644 index 0000000000..80d6e4c6f1 --- /dev/null +++ b/packages/backend-test-utils/src/next/services/mockServices.test.ts @@ -0,0 +1,32 @@ +/* + * 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 { coreServices } from '@backstage/backend-plugin-api'; +import { mockServices } from './mockServices'; + +describe('mockServices', () => { + const coreServiceKeys = Object.keys(coreServices).filter( + key => key !== 'pluginMetadata', + ) as Array; + + it.each(coreServiceKeys)('should have mock implementations for %s', key => { + expect(mockServices[key]).toBeDefined(); + expect(mockServices[key].mock).toEqual(expect.any(Function)); + expect(mockServices[key].mock()).toEqual(expect.any(Object)); + expect(mockServices[key].factory).toEqual(expect.any(Function)); + expect(mockServices[key].factory()).toEqual(expect.any(Object)); + }); +}); diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index d3ec8fb18d..8b0f196399 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -141,6 +141,24 @@ export namespace mockServices { coreServices.rootConfig, rootConfig, ); + export const mock = simpleMock(coreServices.rootConfig, () => ({ + get: jest.fn(), + getBoolean: jest.fn(), + getConfig: jest.fn(), + getConfigArray: jest.fn(), + getNumber: jest.fn(), + getOptional: jest.fn(), + getOptionalBoolean: jest.fn(), + getOptionalConfig: jest.fn(), + getOptionalConfigArray: jest.fn(), + getOptionalNumber: jest.fn(), + getOptionalString: jest.fn(), + getOptionalStringArray: jest.fn(), + getString: jest.fn(), + getStringArray: jest.fn(), + has: jest.fn(), + keys: jest.fn(), + })); } export function rootLogger(options?: rootLogger.Options): LoggerService { @@ -341,7 +359,7 @@ export namespace mockServices { } export namespace rootHttpRouter { - export const factory = () => rootHttpRouterServiceFactory; + export const factory = () => rootHttpRouterServiceFactory(); export const mock = simpleMock(coreServices.rootHttpRouter, () => ({ use: jest.fn(), })); diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts index 7bf3887c93..812e234828 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts @@ -334,4 +334,78 @@ describe('TestBackend', () => { "Unable to determine the plugin ID of extension point(s) 'a'. Tested extension points must be depended on by one or more tested modules.", ); }); + + it('should forward errors from plugins', async () => { + await expect( + startTestBackend({ + features: [ + createBackendPlugin({ + pluginId: 'test', + register(reg) { + reg.registerInit({ + deps: {}, + async init() { + throw new Error('nah'); + }, + }); + }, + }), + ], + }), + ).rejects.toThrow("Plugin 'test' startup failed; caused by Error: nah"); + }); + + it('should forward errors from modules', async () => { + await expect( + startTestBackend({ + features: [ + createBackendModule({ + pluginId: 'test', + moduleId: 'tester', + register(reg) { + reg.registerInit({ + deps: {}, + async init() { + throw new Error('nah'); + }, + }); + }, + }), + ], + }), + ).rejects.toThrow( + "Module 'tester' for plugin 'test' startup failed; caused by Error: nah", + ); + }); + + it('should forward errors from plugin register', async () => { + await expect( + startTestBackend({ + features: [ + createBackendPlugin({ + pluginId: 'test', + register() { + throw new Error('nah'); + }, + }), + ], + }), + ).rejects.toThrow('nah'); + }); + + it('should forward errors from module register', async () => { + await expect( + startTestBackend({ + features: [ + createBackendModule({ + pluginId: 'test', + moduleId: 'tester', + register() { + throw new Error('nah'); + }, + }), + ], + }), + ).rejects.toThrow('nah'); + }); }); diff --git a/packages/backend-tasks/src/setupTests.ts b/packages/backend-test-utils/src/util/errorHandler.ts similarity index 57% rename from packages/backend-tasks/src/setupTests.ts rename to packages/backend-test-utils/src/util/errorHandler.ts index 76619a2542..f534823f50 100644 --- a/packages/backend-tasks/src/setupTests.ts +++ b/packages/backend-test-utils/src/util/errorHandler.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,16 @@ * limitations under the License. */ -import { TestDatabases } from '@backstage/backend-test-utils'; -import { Settings } from 'luxon'; +import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter'; +import { mockServices } from '../next'; -// TS still thinks that methods can return null / placeholders, but we still want to throw as soon as possible when things go wrong -Settings.throwOnInvalid = true; - -TestDatabases.setDefaults({ - ids: ['MYSQL_8', 'POSTGRES_16', 'POSTGRES_12', 'SQLITE_3'], -}); +/** + * A mock for error handler middleware that can be used in router tests. + * @public + */ +export function mockErrorHandler() { + return MiddlewareFactory.create({ + config: mockServices.rootConfig(), + logger: mockServices.rootLogger(), + }).error(); +} diff --git a/packages/backend-test-utils/src/util/index.ts b/packages/backend-test-utils/src/util/index.ts index a6cdc621d4..621c36ba8f 100644 --- a/packages/backend-test-utils/src/util/index.ts +++ b/packages/backend-test-utils/src/util/index.ts @@ -14,4 +14,5 @@ * limitations under the License. */ +export { mockErrorHandler } from './errorHandler'; export { isDockerDisabledForTests } from './isDockerDisabledForTests'; diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 8c856f53ca..e5555f42a0 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,77 @@ # example-backend +## 0.0.30-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/plugin-scaffolder-backend@1.25.0-next.1 + - @backstage/plugin-notifications-backend@0.4.0-next.1 + - @backstage/plugin-kubernetes-backend@0.18.6-next.1 + - @backstage/plugin-techdocs-backend@1.10.13-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-app-backend@0.3.74-next.1 + - @backstage/plugin-auth-backend@0.23.0-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.0-next.1 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0-next.1 + - @backstage/plugin-catalog-backend-module-openapi@0.2.0-next.1 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.1 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.1 + - @backstage/plugin-devtools-backend@0.4.0-next.1 + - @backstage/plugin-permission-backend@0.5.49-next.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-proxy-backend@0.5.6-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.1 + - @backstage/plugin-search-backend@1.5.17-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.1 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-signals-backend@0.2.0-next.1 + +## 0.0.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-backend@1.10.13-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-search-backend@1.5.17-next.0 + - @backstage/plugin-kubernetes-backend@0.18.6-next.0 + - @backstage/plugin-scaffolder-backend@1.25.0-next.0 + - @backstage/plugin-app-backend@0.3.74-next.0 + - @backstage/plugin-signals-backend@0.2.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.0 + - @backstage/plugin-search-backend-module-explore@0.2.2-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/plugin-auth-backend@0.23.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-permission-backend@0.5.49-next.0 + - @backstage/plugin-proxy-backend@0.5.6-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.0-next.0 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.4.0-next.0 + - @backstage/plugin-catalog-backend-module-openapi@0.2.0-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.0 + - @backstage/plugin-catalog-backend-module-unprocessed@0.5.0-next.0 + - @backstage/plugin-devtools-backend@0.4.0-next.0 + - @backstage/plugin-notifications-backend@0.4.0-next.0 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-permission-common@0.8.1 + ## 0.0.29 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 570a545741..d177e1c975 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.29", + "version": "0.0.30-next.1", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -57,9 +57,10 @@ "@backstage/plugin-search-backend-node": "workspace:^", "@backstage/plugin-signals-backend": "workspace:^", "@backstage/plugin-techdocs-backend": "workspace:^", - "@opentelemetry/auto-instrumentations-node": "^0.43.0", - "@opentelemetry/exporter-prometheus": "^0.50.0", - "@opentelemetry/sdk-node": "^0.50.0" + "@opentelemetry/auto-instrumentations-node": "^0.50.0", + "@opentelemetry/exporter-prometheus": "^0.53.0", + "@opentelemetry/sdk-node": "^0.53.0", + "example-app": "link:../app" }, "devDependencies": { "@backstage/cli": "workspace:^" diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index 9ed8a50b91..cf175a3d23 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/catalog-client +## 1.6.7-next.0 + +### Patch Changes + +- 1882cfe: Moved `getEntities` ordering to utilize database instead of having it inside catalog client + + Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. + +- Updated dependencies + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + ## 1.6.6 ### Patch Changes diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index 29c1d3049c..b0568e0b0d 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/catalog-client", - "version": "1.6.6", + "version": "1.6.7-next.0", "description": "An isomorphic client for the catalog backend", "backstage": { "role": "common-library" diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 2440f043d7..2e7912b69a 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -18,7 +18,6 @@ import { CompoundEntityRef, Entity, parseEntityRef, - stringifyEntityRef, stringifyLocationRef, } from '@backstage/catalog-model'; import { ResponseError } from '@backstage/errors'; @@ -142,35 +141,7 @@ export class CatalogClient implements CatalogApi { options, ), ); - - // do not sort entities, if order is provided - if (encodedOrder.length) { - return { items: entities }; - } - - const refCompare = (a: Entity, b: Entity) => { - // in case field filtering is used, these fields might not be part of the response - if ( - a.metadata?.name === undefined || - a.kind === undefined || - b.metadata?.name === undefined || - b.kind === undefined - ) { - return 0; - } - - const aRef = stringifyEntityRef(a); - const bRef = stringifyEntityRef(b); - if (aRef < bRef) { - return -1; - } - if (aRef > bRef) { - return 1; - } - return 0; - }; - - return { items: entities.sort(refCompare) }; + return { items: entities }; } /** diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index ec823ef23e..05a9574f3a 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/cli +## 0.27.1-next.1 + +### Patch Changes + +- d2d2313: Add `config.d.ts` files to the list of included file in `tsconfig.json`. + + This allows ESLint to detect issues or deprecations in those files. + +- 97422b0: Update templates to not refer to backend-common +- f865103: Updated dependency `esbuild` to `^0.23.0`. +- 569c3f0: Fixed an issue where published frontend packages would end up with an invalid import structure if a single module imported both `.css` and `.svg` files. +- Updated dependencies + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/integration@1.14.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + +## 0.27.1-next.0 + +### Patch Changes + +- 1b5c264: Add `checks: 'read'` for default GitHub app permissions +- Updated dependencies + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/eslint-plugin@0.1.8 + - @backstage/integration@1.14.0 + - @backstage/release-manifests@0.0.11 + - @backstage/types@1.1.1 + ## 0.27.0 ### Minor Changes diff --git a/packages/cli/config/eslint-factory.js b/packages/cli/config/eslint-factory.js index 96d8478ec0..856068eef9 100644 --- a/packages/cli/config/eslint-factory.js +++ b/packages/cli/config/eslint-factory.js @@ -277,7 +277,7 @@ function createConfigForRole(dir, role, extraConfig = {}) { restrictedSrcSyntax: [ { message: - "`__dirname` doesn't refer to the same dir in production builds, try `resolvePackagePath()` from `@backstage/backend-common` instead.", + "`__dirname` doesn't refer to the same dir in production builds, try `resolvePackagePath()` from `@backstage/backend-plugin-api` instead.", selector: 'Identifier[name="__dirname"]', }, ...(extraConfig.restrictedSrcSyntax ?? []), diff --git a/packages/cli/config/webpack-public-path.js b/packages/cli/config/webpack-public-path.js new file mode 100644 index 0000000000..3e14e96eb9 --- /dev/null +++ b/packages/cli/config/webpack-public-path.js @@ -0,0 +1,31 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This script is used to pick up and set the public path of the Webpack bundle +// at runtime. The meta tag is injected by the app build, but only present in +// the `index.html.tmpl` file. The runtime value of the meta tag is populated by +// the app backend, when it templates the final `index.html` file. +// +// This is needed for additional chunks to use the correct public path, and it +// is not possible to set the `__webpack_public_path__` variable outside of the +// build itself. The Webpack output also does not read any tags or +// similar, this seems to be the only way to dynamically configure the public +// path at runtime. +const el = document.querySelector('meta[name="backstage-public-path"]'); +const path = el?.getAttribute('content'); +if (path) { + __webpack_public_path__ = path; +} diff --git a/packages/cli/package.json b/packages/cli/package.json index c3f70bcbf4..130ad8c213 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/cli", - "version": "0.27.0", + "version": "0.27.1-next.1", "description": "CLI for developing Backstage plugins and apps", "backstage": { "role": "cli" @@ -91,7 +91,7 @@ "css-loader": "^6.5.1", "ctrlc-windows": "^2.1.0", "diff": "^5.0.0", - "esbuild": "^0.21.0", + "esbuild": "^0.23.0", "esbuild-loader": "^4.0.0", "eslint": "^8.6.0", "eslint-config-prettier": "^9.0.0", @@ -130,6 +130,7 @@ "pirates": "^4.0.6", "postcss": "^8.1.0", "process": "^0.11.10", + "raw-loader": "^4.0.2", "react-dev-utils": "^12.0.0-next.60", "react-refresh": "^0.14.0", "recursive-readdir": "^2.2.2", @@ -182,13 +183,9 @@ "@types/tar": "^6.1.1", "@types/terser-webpack-plugin": "^5.0.4", "@types/yarnpkg__lockfile": "^1.1.4", - "@vitejs/plugin-react": "^4.0.4", "del": "^7.0.0", "msw": "^1.0.0", - "nodemon": "^3.0.1", - "vite": "^4.4.9", - "vite-plugin-html": "^3.2.0", - "vite-plugin-node-polyfills": "^0.22.0" + "nodemon": "^3.0.1" }, "peerDependencies": { "@vitejs/plugin-react": "^4.0.4", diff --git a/packages/cli/src/commands/create-github-app/GithubCreateAppServer.ts b/packages/cli/src/commands/create-github-app/GithubCreateAppServer.ts index 70b8c0ca53..b1825ad996 100644 --- a/packages/cli/src/commands/create-github-app/GithubCreateAppServer.ts +++ b/packages/cli/src/commands/create-github-app/GithubCreateAppServer.ts @@ -114,10 +114,16 @@ export class GithubCreateAppServer { default_events: ['create', 'delete', 'push', 'repository'], default_permissions: { metadata: 'read', - ...(this.permissions.includes('members') && { members: 'read' }), - ...(this.permissions.includes('read') && { contents: 'read' }), + ...(this.permissions.includes('members') && { + members: 'read', + }), + ...(this.permissions.includes('read') && { + contents: 'read', + checks: 'read', + }), ...(this.permissions.includes('write') && { contents: 'write', + checks: 'read', actions: 'write', }), }, diff --git a/packages/cli/src/commands/create-github-app/index.ts b/packages/cli/src/commands/create-github-app/index.ts index 6b3e732f18..681b471c91 100644 --- a/packages/cli/src/commands/create-github-app/index.ts +++ b/packages/cli/src/commands/create-github-app/index.ts @@ -22,6 +22,7 @@ import { paths } from '../../lib/paths'; import { GithubCreateAppServer } from './GithubCreateAppServer'; import fetch from 'node-fetch'; import openBrowser from 'react-dev-utils/openBrowser'; + // This is an experimental command that at this point does not support GitHub Enterprise // due to lacking support for creating apps from manifests. // https://docs.github.com/en/free-pro-team@latest/developers/apps/creating-a-github-app-from-a-manifest diff --git a/packages/cli/src/commands/repo/list-deprecations.ts b/packages/cli/src/commands/repo/list-deprecations.ts index 69fe51f78e..772038025a 100644 --- a/packages/cli/src/commands/repo/list-deprecations.ts +++ b/packages/cli/src/commands/repo/list-deprecations.ts @@ -17,7 +17,7 @@ import chalk from 'chalk'; import { ESLint } from 'eslint'; import { OptionValues } from 'commander'; -import { join as joinPath, relative as relativePath } from 'path'; +import { relative as relativePath } from 'path'; import { PackageGraph } from '@backstage/cli-node'; import { paths } from '../../lib/paths'; @@ -45,7 +45,7 @@ export async function command(opts: OptionValues) { const deprecations = []; for (const [index, pkg] of packages.entries()) { - const results = await eslint.lintFiles(joinPath(pkg.dir, 'src')); + const results = await eslint.lintFiles(pkg.dir); for (const result of results) { for (const message of result.messages) { if (message.ruleId !== 'deprecation/deprecation') { diff --git a/packages/cli/src/lib/builder/config.ts b/packages/cli/src/lib/builder/config.ts index 8beb2cbb1e..a514158e9b 100644 --- a/packages/cli/src/lib/builder/config.ts +++ b/packages/cli/src/lib/builder/config.ts @@ -118,6 +118,7 @@ export async function makeRollupConfigs( ), output, onwarn, + makeAbsoluteExternalsRelative: false, preserveEntrySignatures: 'strict', // All module imports are always marked as external external: (source, importer, isResolved) => diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index da7b378fbd..a64bc0fcd8 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -198,6 +198,19 @@ export async function createConfig( }, }), ); + plugins.push( + new HtmlWebpackPlugin({ + meta: { + 'backstage-app-mode': options?.appMode ?? 'public', + // This is added to be written in the later step, and finally read by the extra entry point + 'backstage-public-path': '<%= publicPath %>/', + }, + minify: false, + publicPath: '<%= publicPath %>', + filename: 'index.html.tmpl', + template: `raw-loader!${paths.targetHtml}`, + }), + ); } if (options.moduleFederation) { @@ -341,7 +354,11 @@ export async function createConfig( }, devtool: isDev ? 'eval-cheap-module-source-map' : 'source-map', context: paths.targetPath, - entry: [...(options.additionalEntryPoints ?? []), paths.targetEntry], + entry: [ + require.resolve('@backstage/cli/config/webpack-public-path'), + ...(options.additionalEntryPoints ?? []), + paths.targetEntry, + ], resolve: { extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx', '.json', '.wasm'], mainFields: ['browser', 'module', 'main'], diff --git a/packages/cli/src/lib/bundler/server.ts b/packages/cli/src/lib/bundler/server.ts index 259f3263eb..d73bcc662e 100644 --- a/packages/cli/src/lib/bundler/server.ts +++ b/packages/cli/src/lib/bundler/server.ts @@ -54,6 +54,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be const { name } = await fs.readJson(libPaths.resolveTarget('package.json')); let webpackServer: WebpackDevServer | undefined = undefined; + // @ts-ignore let viteServer: import('vite').ViteDevServer | undefined = undefined; let latestFrontendAppConfigs: AppConfig[] = []; diff --git a/packages/cli/src/lib/bundler/transforms.ts b/packages/cli/src/lib/bundler/transforms.ts index 302b2fbe68..17a6a0c191 100644 --- a/packages/cli/src/lib/bundler/transforms.ts +++ b/packages/cli/src/lib/bundler/transforms.ts @@ -14,12 +14,12 @@ * limitations under the License. */ -import { ModuleOptions, WebpackPluginInstance } from 'webpack'; +import { RuleSetRule, WebpackPluginInstance } from 'webpack'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import { svgrTemplate } from '../svgrTemplate'; type Transforms = { - loaders: ModuleOptions['rules']; + loaders: RuleSetRule[]; plugins: WebpackPluginInstance[]; }; diff --git a/packages/cli/templates/default-backend-module/package.json.hbs b/packages/cli/templates/default-backend-module/package.json.hbs index db8b8749b3..7e82e047ce 100644 --- a/packages/cli/templates/default-backend-module/package.json.hbs +++ b/packages/cli/templates/default-backend-module/package.json.hbs @@ -29,7 +29,6 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "{{versionQuery '@backstage/backend-common'}}", "@backstage/backend-plugin-api": "{{versionQuery '@backstage/backend-plugin-api'}}" }, "devDependencies": { diff --git a/packages/cli/templates/default-backend-plugin/package.json.hbs b/packages/cli/templates/default-backend-plugin/package.json.hbs index b05d1a844b..6c25562c21 100644 --- a/packages/cli/templates/default-backend-plugin/package.json.hbs +++ b/packages/cli/templates/default-backend-plugin/package.json.hbs @@ -28,7 +28,6 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "{{versionQuery '@backstage/backend-common'}}", "@backstage/backend-defaults": "{{versionQuery '@backstage/backend-defaults'}}", "@backstage/backend-plugin-api": "{{versionQuery '@backstage/backend-plugin-api'}}", "express": "{{versionQuery 'express' '4.17.1'}}", diff --git a/packages/cli/templates/scaffolder-module/package.json.hbs b/packages/cli/templates/scaffolder-module/package.json.hbs index df4bf352f4..a6e6b5c5bc 100644 --- a/packages/cli/templates/scaffolder-module/package.json.hbs +++ b/packages/cli/templates/scaffolder-module/package.json.hbs @@ -32,7 +32,6 @@ "@backstage/plugin-scaffolder-node": "{{versionQuery '@backstage/plugin-scaffolder-node'}}" }, "devDependencies": { - "@backstage/backend-common": "{{versionQuery '@backstage/backend-common'}}", "@backstage/cli": "{{versionQuery '@backstage/cli'}}" }, "files": [ diff --git a/packages/cli/templates/scaffolder-module/src/actions/example/example.test.ts b/packages/cli/templates/scaffolder-module/src/actions/example/example.test.ts index 242f93c2f3..d0e5374f3f 100644 --- a/packages/cli/templates/scaffolder-module/src/actions/example/example.test.ts +++ b/packages/cli/templates/scaffolder-module/src/actions/example/example.test.ts @@ -1,6 +1,5 @@ import { PassThrough } from 'stream'; import { createAcmeExampleAction } from './example'; -import { getVoidLogger } from '@backstage/backend-common'; describe('acme:example', () => { afterEach(() => { @@ -10,15 +9,14 @@ describe('acme:example', () => { it('should call action', async () => { const action = createAcmeExampleAction(); - const logger = getVoidLogger(); - jest.spyOn(logger, 'info'); + const logger = { info: jest.fn() }; await action.handler({ input: { myParameter: 'test', }, workspacePath: '/tmp', - logger, + logger: logger as any, logStream: new PassThrough(), output: jest.fn(), createTemporaryDirectory() { diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index 2a47e34b54..c93a71fe38 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/codemods +## 0.1.50-next.0 + +### Patch Changes + +- 0894166: Updated dependency `jscodeshift` to `^0.16.0`. +- Updated dependencies + - @backstage/cli-common@0.1.14 + ## 0.1.49 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 6bab6f3df8..38d32dfc74 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/codemods", - "version": "0.1.49", + "version": "0.1.50-next.0", "description": "A collection of codemods for Backstage projects", "backstage": { "role": "cli" @@ -46,7 +46,7 @@ "@backstage/cli-common": "workspace:^", "chalk": "^4.0.0", "commander": "^12.0.0", - "jscodeshift": "^0.15.0", + "jscodeshift": "^0.16.0", "jscodeshift-add-imports": "^1.0.10" }, "devDependencies": { diff --git a/packages/core-app-api/src/app/defaultConfigLoader.test.ts b/packages/core-app-api/src/app/defaultConfigLoader.test.tsx similarity index 67% rename from packages/core-app-api/src/app/defaultConfigLoader.test.ts rename to packages/core-app-api/src/app/defaultConfigLoader.test.tsx index c70ec3fbff..44d93aa625 100644 --- a/packages/core-app-api/src/app/defaultConfigLoader.test.ts +++ b/packages/core-app-api/src/app/defaultConfigLoader.test.tsx @@ -14,7 +14,10 @@ * limitations under the License. */ +import React from 'react'; +import { render } from '@testing-library/react'; import { defaultConfigLoaderSync } from './defaultConfigLoader'; +import { ConfigReader } from '@backstage/config'; (process as any).env = { NODE_ENV: 'test' }; const anyEnv = process.env as any; @@ -53,6 +56,45 @@ describe('defaultConfigLoaderSync', () => { ]); }); + it('loads config from script tags and ignore static config', () => { + anyEnv.APP_CONFIG = []; + + render( + , + ); + + const configs = (defaultConfigLoaderSync as any)('{"my":"runtime-config"}'); + expect(configs).toEqual([ + { data: { my: 'config' }, context: 'a' }, + { data: { my: 'override-config' }, context: 'b' }, + ]); + expect(ConfigReader.fromConfigs(configs).get('my')).toBe('override-config'); + }); + + it('loads config from all script tags in order', () => { + anyEnv.APP_CONFIG = []; + + render( + <> + + + , + ); + + const configs = (defaultConfigLoaderSync as any)('{"my":"runtime-config"}'); + expect(configs).toEqual([ + { data: { my: 'config' }, context: 'a' }, + { data: { my: 'override-config' }, context: 'b' }, + ]); + expect(ConfigReader.fromConfigs(configs).get('my')).toBe('override-config'); + }); + it('fails to load invalid missing config', () => { expect(() => defaultConfigLoaderSync()).toThrow( 'No static configuration provided', diff --git a/packages/core-app-api/src/app/defaultConfigLoader.ts b/packages/core-app-api/src/app/defaultConfigLoader.ts index 301b64a865..bfcef390ec 100644 --- a/packages/core-app-api/src/app/defaultConfigLoader.ts +++ b/packages/core-app-api/src/app/defaultConfigLoader.ts @@ -49,9 +49,36 @@ export function defaultConfigLoaderSync( } const configs = appConfig.slice() as unknown as AppConfig[]; - // Avoiding this string also being replaced at runtime - if ( + // Check if we have any config script tags, otherwise fall back to injected config + const configScripts = document.querySelectorAll( + 'script[type="backstage.io/config"]', + ); + if (configScripts.length > 0) { + for (const el of configScripts) { + try { + const content = el.textContent; + if (!content) { + throw new Error('tag is empty'); + } + let data; + try { + data = JSON.parse(content); + } catch (error) { + throw new Error(`failed to parse config; ${error}`); + } + if (!Array.isArray(data)) { + throw new Error('data is not an array'); + } + configs.push(...data); + } catch (error) { + throw new Error( + `Failed to load config from script tag, ${error.message}`, + ); + } + } + } else if ( runtimeConfigJson !== + // Avoiding this string also being replaced at runtime '__app_injected_runtime_config__'.toLocaleUpperCase('en-US') ) { try { diff --git a/packages/core-compat-api/CHANGELOG.md b/packages/core-compat-api/CHANGELOG.md index 35849d453c..62a77898bd 100644 --- a/packages/core-compat-api/CHANGELOG.md +++ b/packages/core-compat-api/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/core-compat-api +## 0.3.0-next.1 + +### Minor Changes + +- 6db849e: **BREAKING**: The `namespace` parameter for API's is now defaulted to the `pluginId` which was discovered. This means that if you're overriding API's by using ID's directly, they might have changed to include the plugin ID too. + +### Patch Changes + +- c816e2d: Added support for new `FrontendPlugin` and `FrontendModule` types. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## 0.2.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/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + ## 0.2.8 ### Patch Changes diff --git a/packages/core-compat-api/api-report.md b/packages/core-compat-api/api-report.md index 75b91cc055..ddb3bc6bf4 100644 --- a/packages/core-compat-api/api-report.md +++ b/packages/core-compat-api/api-report.md @@ -9,12 +9,13 @@ import { AnalyticsEvent } from '@backstage/core-plugin-api'; import { AnalyticsEvent as AnalyticsEvent_2 } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { BackstagePlugin as BackstagePlugin_2 } from '@backstage/frontend-plugin-api'; import { ComponentType } from 'react'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; +import { ExtensionOverrides } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/core-plugin-api'; import { ExternalRouteRef as ExternalRouteRef_2 } from '@backstage/frontend-plugin-api'; -import { FrontendFeature } from '@backstage/frontend-plugin-api'; +import { FrontendModule } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { default as React_2 } from 'react'; import { ReactNode } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; @@ -28,7 +29,7 @@ export function compatWrapper(element: ReactNode): React_2.JSX.Element; // @public (undocumented) export function convertLegacyApp( rootElement: React_2.JSX.Element, -): FrontendFeature[]; +): (FrontendPlugin | FrontendModule | ExtensionOverrides)[]; // @public (undocumented) export function convertLegacyPageExtension( @@ -37,15 +38,15 @@ export function convertLegacyPageExtension( name?: string; defaultPath?: string; }, -): ExtensionDefinition; +): ExtensionDefinition; // @public (undocumented) export function convertLegacyPlugin( legacyPlugin: BackstagePlugin, options: { - extensions: ExtensionDefinition[]; + extensions: ExtensionDefinition[]; }, -): BackstagePlugin_2; +): FrontendPlugin; // @public export function convertLegacyRouteRef( diff --git a/packages/core-compat-api/package.json b/packages/core-compat-api/package.json index 5af7d1b960..a54cb8f20f 100644 --- a/packages/core-compat-api/package.json +++ b/packages/core-compat-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/core-compat-api", - "version": "0.2.8", + "version": "0.3.0-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx index f3e2baee38..0319628b14 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.test.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.test.tsx @@ -31,15 +31,15 @@ import { Navigate, Route, Routes } from 'react-router-dom'; import { collectLegacyRoutes } from './collectLegacyRoutes'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { toInternalBackstagePlugin } from '../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +import { toInternalFrontendPlugin } from '../../frontend-plugin-api/src/wiring/createFrontendPlugin'; import { createPlugin, createRoutableExtension, createRouteRef, useApp, } from '@backstage/core-plugin-api'; -import { createSpecializedApp } from '@backstage/frontend-app-api'; -import { render, screen } from '@testing-library/react'; +import { screen } from '@testing-library/react'; +import { renderInTestApp } from '@backstage/frontend-test-utils'; describe('collectLegacyRoutes', () => { it('should collect legacy routes', () => { @@ -55,7 +55,7 @@ describe('collectLegacyRoutes', () => { expect( collected.map(p => ({ id: p.id, - extensions: toInternalBackstagePlugin(p).extensions.map(e => ({ + extensions: toInternalFrontendPlugin(p).extensions.map(e => ({ id: e.id, attachTo: e.attachTo, disabled: e.disabled, @@ -73,7 +73,7 @@ describe('collectLegacyRoutes', () => { defaultConfig: {}, }, { - id: 'api:plugin.scoringdata.service', + id: 'api:score-card/plugin.scoringdata.service', attachTo: { id: 'root', input: 'apis' }, disabled: false, }, @@ -89,7 +89,7 @@ describe('collectLegacyRoutes', () => { defaultConfig: {}, }, { - id: 'api:plugin.stackstorm.service', + id: 'api:stackstorm/plugin.stackstorm.service', attachTo: { id: 'root', input: 'apis' }, disabled: false, }, @@ -111,7 +111,7 @@ describe('collectLegacyRoutes', () => { defaultConfig: {}, }, { - id: 'api:plugin.puppetdb.service', + id: 'api:puppetDb/plugin.puppetdb.service', attachTo: { id: 'root', input: 'apis' }, disabled: false, }, @@ -158,7 +158,7 @@ describe('collectLegacyRoutes', () => { expect( collected.map(p => ({ id: p.id, - extensions: toInternalBackstagePlugin(p).extensions.map(e => ({ + extensions: toInternalFrontendPlugin(p).extensions.map(e => ({ id: e.id, attachTo: e.attachTo, disabled: e.disabled, @@ -209,7 +209,7 @@ describe('collectLegacyRoutes', () => { disabled: false, }, { - id: 'api:plugin.catalog.service', + id: 'api:catalog/plugin.catalog.service', attachTo: { id: 'root', input: 'apis', @@ -218,7 +218,7 @@ describe('collectLegacyRoutes', () => { disabled: false, }, { - id: 'api:catalog-react.starred-entities', + id: 'api:catalog/catalog-react.starred-entities', attachTo: { id: 'root', input: 'apis', @@ -227,7 +227,7 @@ describe('collectLegacyRoutes', () => { disabled: false, }, { - id: 'api:plugin.catalog.entity-presentation', + id: 'api:catalog/plugin.catalog.entity-presentation', attachTo: { id: 'root', input: 'apis', @@ -241,7 +241,7 @@ describe('collectLegacyRoutes', () => { id: 'score-card', extensions: [ { - id: 'api:plugin.scoringdata.service', + id: 'api:score-card/plugin.scoringdata.service', attachTo: { id: 'root', input: 'apis' }, disabled: false, }, @@ -262,7 +262,15 @@ describe('collectLegacyRoutes', () => { component: () => Promise.resolve(() => { const app = useApp(); - return
plugins: {app.getPlugins().map(p => p.getId())}
; + return ( +
+ plugins:{' '} + {app + .getPlugins() + .map(p => p.getId()) + .join(', ')} +
+ ); }), }), ); @@ -273,10 +281,10 @@ describe('collectLegacyRoutes', () => {
, ); - render(createSpecializedApp({ features }).createRoot()); + renderInTestApp(
, { features }); await expect( - screen.findByText('plugins: test'), + screen.findByText('plugins: app, test'), ).resolves.toBeInTheDocument(); }); diff --git a/packages/core-compat-api/src/collectLegacyRoutes.tsx b/packages/core-compat-api/src/collectLegacyRoutes.tsx index c5cb13b6e1..43e66ce859 100644 --- a/packages/core-compat-api/src/collectLegacyRoutes.tsx +++ b/packages/core-compat-api/src/collectLegacyRoutes.tsx @@ -106,7 +106,7 @@ function visitRouteChildren(options: { parentExtensionId: string; context: { pluginId: string; - extensions: ExtensionDefinition[]; + extensions: ExtensionDefinition[]; getUniqueName: () => string; discoverPlugin: (plugin: LegacyBackstagePlugin) => void; }; @@ -159,7 +159,7 @@ export function collectLegacyRoutes( ): BackstagePlugin[] { const pluginExtensions = new Map< LegacyBackstagePlugin, - ExtensionDefinition[] + ExtensionDefinition[] >(); const getUniqueName = (() => { @@ -268,7 +268,10 @@ export function collectLegacyRoutes( extensions: [ ...extensions, ...Array.from(plugin.getApis()).map(factory => - ApiBlueprint.make({ namespace: factory.api.id, params: { factory } }), + ApiBlueprint.make({ + name: factory.api.id, + params: { factory }, + }), ), ], routes: convertLegacyRouteRefs(plugin.routes ?? {}), diff --git a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx index 445f42124f..0f9ccfb2ad 100644 --- a/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx +++ b/packages/core-compat-api/src/compatWrapper/BackwardsCompatProvider.tsx @@ -22,7 +22,7 @@ import { AppContextProvider } from '../../../core-app-api/src/app/AppContext'; import { RouteResolver } from '../../../core-plugin-api/src/routing/useRouteRef'; import { createFrontendPlugin as createNewPlugin, - BackstagePlugin as NewBackstagePlugin, + FrontendPlugin as NewFrontendPlugin, appTreeApiRef, componentsApiRef, coreComponentRefs, @@ -47,11 +47,11 @@ import { convertLegacyRouteRef } from '../convertLegacyRouteRef'; // Make sure that we only convert each new plugin instance to its legacy equivalent once const legacyPluginStore = getOrCreateGlobalSingleton( 'legacy-plugin-compatibility-store', - () => new WeakMap(), + () => new WeakMap(), ); export function toLegacyPlugin( - plugin: NewBackstagePlugin, + plugin: NewFrontendPlugin, ): LegacyBackstagePlugin { let legacy = legacyPluginStore.get(plugin); if (legacy) { @@ -83,7 +83,7 @@ export function toLegacyPlugin( } // TODO: Currently a very naive implementation, may need some more work -function toNewPlugin(plugin: LegacyBackstagePlugin): NewBackstagePlugin { +function toNewPlugin(plugin: LegacyBackstagePlugin): NewFrontendPlugin { return createNewPlugin({ id: plugin.getId(), }); diff --git a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx index 2e6b127070..18846e0f21 100644 --- a/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx +++ b/packages/core-compat-api/src/compatWrapper/compatWrapper.test.tsx @@ -42,35 +42,39 @@ import { renderInTestApp as renderInOldTestApp } from '@backstage/test-utils'; describe('BackwardsCompatProvider', () => { it('should convert the app context', () => { // TODO(Rugvip): Replace with the new renderInTestApp once it's available, and have some plugins - createExtensionTester( - createExtension({ - attachTo: { id: 'ignored', input: 'ignored' }, - output: [coreExtensionData.reactElement], - factory() { - function Component() { - const app = useApp(); - return ( -
- plugins: - {app - .getPlugins() - .map(p => p.getId()) - .join(', ')} - {'\n'} - components: {Object.keys(app.getComponents()).join(', ')} - {'\n'} - icons: {Object.keys(app.getSystemIcons()).join(', ')} -
- ); - } + renderInNewTestApp( + createExtensionTester( + createExtension({ + attachTo: { id: 'ignored', input: 'ignored' }, + output: [coreExtensionData.reactElement], + factory() { + function Component() { + const app = useApp(); + return ( +
+ plugins:{' '} + {app + .getPlugins() + .map(p => p.getId()) + .join(', ')} + {'\n'} + components: {Object.keys(app.getComponents()).join(', ')} + {'\n'} + icons: {Object.keys(app.getSystemIcons()).join(', ')} +
+ ); + } - return [coreExtensionData.reactElement(compatWrapper())]; - }, - }), - ).render(); + return [ + coreExtensionData.reactElement(compatWrapper()), + ]; + }, + }), + ).reactElement(), + ); expect(screen.getByTestId('ctx').textContent).toMatchInlineSnapshot(` - "plugins: + "plugins: test, app components: NotFoundErrorPage, BootErrorPage, Progress, Router, ErrorBoundaryFallback icons: brokenImage, catalog, scaffolder, techdocs, search, chat, dashboard, docs, email, github, group, help, kind:api, kind:component, kind:domain, kind:group, kind:location, kind:system, kind:user, kind:resource, kind:template, user, warning, star, unstarred" `); diff --git a/packages/core-compat-api/src/convertLegacyApp.test.tsx b/packages/core-compat-api/src/convertLegacyApp.test.tsx index b76a6c2d71..224ab46221 100644 --- a/packages/core-compat-api/src/convertLegacyApp.test.tsx +++ b/packages/core-compat-api/src/convertLegacyApp.test.tsx @@ -65,7 +65,7 @@ describe('convertLegacyApp', () => { defaultConfig: {}, }, { - id: 'api:plugin.scoringdata.service', + id: 'api:score-card/plugin.scoringdata.service', attachTo: { id: 'root', input: 'apis' }, disabled: false, }, @@ -81,7 +81,7 @@ describe('convertLegacyApp', () => { defaultConfig: {}, }, { - id: 'api:plugin.stackstorm.service', + id: 'api:stackstorm/plugin.stackstorm.service', attachTo: { id: 'root', input: 'apis' }, disabled: false, }, @@ -103,7 +103,7 @@ describe('convertLegacyApp', () => { defaultConfig: {}, }, { - id: 'api:plugin.puppetdb.service', + id: 'api:puppetDb/plugin.puppetdb.service', attachTo: { id: 'root', input: 'apis' }, disabled: false, }, diff --git a/packages/core-compat-api/src/convertLegacyApp.ts b/packages/core-compat-api/src/convertLegacyApp.ts index ffeab3bdc6..3f35c78408 100644 --- a/packages/core-compat-api/src/convertLegacyApp.ts +++ b/packages/core-compat-api/src/convertLegacyApp.ts @@ -22,11 +22,13 @@ import React, { isValidElement, } from 'react'; import { - FrontendFeature, + FrontendModule, + FrontendPlugin, coreExtensionData, createExtension, + ExtensionOverrides, createExtensionInput, - createExtensionOverrides, + createFrontendModule, } from '@backstage/frontend-plugin-api'; import { getComponentData } from '@backstage/core-plugin-api'; import { collectLegacyRoutes } from './collectLegacyRoutes'; @@ -60,7 +62,7 @@ function selectChildren( /** @public */ export function convertLegacyApp( rootElement: React.JSX.Element, -): FrontendFeature[] { +): (FrontendPlugin | FrontendModule | ExtensionOverrides)[] { if (getComponentData(rootElement, 'core.type') === 'FlatRoutes') { return collectLegacyRoutes(rootElement); } @@ -103,7 +105,6 @@ export function convertLegacyApp( const [routesEl] = routesEls; const CoreLayoutOverride = createExtension({ - namespace: 'app', name: 'layout', attachTo: { id: 'app', input: 'root' }, inputs: { @@ -126,7 +127,6 @@ export function convertLegacyApp( }, }); const CoreNavOverride = createExtension({ - namespace: 'app', name: 'nav', attachTo: { id: 'app/layout', input: 'nav' }, output: [], @@ -138,7 +138,8 @@ export function convertLegacyApp( return [ ...collectedRoutes, - createExtensionOverrides({ + createFrontendModule({ + pluginId: 'app', extensions: [CoreLayoutOverride, CoreNavOverride], }), ]; diff --git a/packages/core-compat-api/src/convertLegacyPageExtension.test.tsx b/packages/core-compat-api/src/convertLegacyPageExtension.test.tsx index 482474d580..c1630b31b5 100644 --- a/packages/core-compat-api/src/convertLegacyPageExtension.test.tsx +++ b/packages/core-compat-api/src/convertLegacyPageExtension.test.tsx @@ -48,12 +48,11 @@ describe('convertLegacyPageExtension', () => { ); const converted = convertLegacyPageExtension(LegacyExtension); - expect(converted.kind).toBe('page'); - expect(converted.namespace).toBe(undefined); - expect(converted.name).toBe('example'); const tester = createExtensionTester(converted); + expect(tester.query(converted).node.spec.id).toBe('page:example'); + await renderInTestApp(tester.reactElement(), { mountedRoutes: { '/': convertLegacyRouteRef(routeRef), @@ -79,12 +78,11 @@ describe('convertLegacyPageExtension', () => { name: 'other', defaultPath: '/other', }); - expect(converted.kind).toBe('page'); - expect(converted.namespace).toBe(undefined); - expect(converted.name).toBe('other'); const tester = createExtensionTester(converted); + expect(tester.query(converted).node.spec.id).toBe('page:other'); + await renderInTestApp(tester.reactElement(), { mountedRoutes: { '/': convertLegacyRouteRef(routeRef), diff --git a/packages/core-compat-api/src/convertLegacyPageExtension.tsx b/packages/core-compat-api/src/convertLegacyPageExtension.tsx index 7ef4e0faff..3931a730c8 100644 --- a/packages/core-compat-api/src/convertLegacyPageExtension.tsx +++ b/packages/core-compat-api/src/convertLegacyPageExtension.tsx @@ -35,7 +35,7 @@ export function convertLegacyPageExtension( name?: string; defaultPath?: string; }, -): ExtensionDefinition { +): ExtensionDefinition { const element = ; const extName = getComponentData(element, 'core.extensionName'); diff --git a/packages/core-compat-api/src/convertLegacyPlugin.test.tsx b/packages/core-compat-api/src/convertLegacyPlugin.test.tsx index 657ee91725..01266a35b7 100644 --- a/packages/core-compat-api/src/convertLegacyPlugin.test.tsx +++ b/packages/core-compat-api/src/convertLegacyPlugin.test.tsx @@ -24,7 +24,7 @@ import { import { convertLegacyPlugin } from './convertLegacyPlugin'; import { PageBlueprint } from '@backstage/frontend-plugin-api'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { toInternalBackstagePlugin } from '../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +import { toInternalFrontendPlugin } from '../../frontend-plugin-api/src/wiring/createFrontendPlugin'; describe('convertLegacyPlugin', () => { it('should convert a plain legacy plugin to a new plugin', () => { @@ -34,7 +34,7 @@ describe('convertLegacyPlugin', () => { }), ).toMatchInlineSnapshot(` { - "$$type": "@backstage/BackstagePlugin", + "$$type": "@backstage/FrontendPlugin", "extensions": [], "externalRoutes": {}, "featureFlags": [], @@ -73,7 +73,7 @@ describe('convertLegacyPlugin', () => { }, ); - const internalConverted = toInternalBackstagePlugin(converted); + const internalConverted = toInternalFrontendPlugin(converted); expect(internalConverted.id).toBe('test'); expect(internalConverted.routes).toEqual({ @@ -84,7 +84,7 @@ describe('convertLegacyPlugin', () => { }); expect(internalConverted.featureFlags).toEqual([{ name: 'test-flag' }]); expect(internalConverted.extensions.map(e => e.id)).toEqual([ - 'api:plugin.test.client', + 'api:test/plugin.test.client', 'page:test', ]); }); diff --git a/packages/core-compat-api/src/convertLegacyPlugin.ts b/packages/core-compat-api/src/convertLegacyPlugin.ts index 5856108f29..5fd5e585e6 100644 --- a/packages/core-compat-api/src/convertLegacyPlugin.ts +++ b/packages/core-compat-api/src/convertLegacyPlugin.ts @@ -18,7 +18,7 @@ import { BackstagePlugin as LegacyBackstagePlugin } from '@backstage/core-plugin import { ApiBlueprint, ExtensionDefinition, - BackstagePlugin as NewBackstagePlugin, + FrontendPlugin as NewBackstagePlugin, createFrontendPlugin, } from '@backstage/frontend-plugin-api'; import { convertLegacyRouteRefs } from './convertLegacyRouteRef'; @@ -26,10 +26,10 @@ import { convertLegacyRouteRefs } from './convertLegacyRouteRef'; /** @public */ export function convertLegacyPlugin( legacyPlugin: LegacyBackstagePlugin, - options: { extensions: ExtensionDefinition[] }, + options: { extensions: ExtensionDefinition[] }, ): NewBackstagePlugin { const apiExtensions = Array.from(legacyPlugin.getApis()).map(factory => - ApiBlueprint.make({ namespace: factory.api.id, params: { factory } }), + ApiBlueprint.make({ name: factory.api.id, params: { factory } }), ); return createFrontendPlugin({ id: legacyPlugin.getId(), diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index f50b830702..72fe6e6692 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/core-components +## 0.14.11-next.0 + +### Patch Changes + +- 06b8206: Added `titleComponent` prop to `SignInPage` component to allow further customization of the title using `ReactNode` +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/version-bridge@1.0.8 + ## 0.14.10 ### Patch Changes diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index e2c1e47f78..ebcc053648 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -19,6 +19,7 @@ import { default as CSS_2 } from 'csstype'; import { CSSProperties } from 'react'; import { ElementType } from 'react'; import { ErrorInfo } from 'react'; +import IconButton from '@material-ui/core/IconButton'; import { IconComponent } from '@backstage/core-plugin-api'; import { Icons } from '@material-table/core'; import { IdentityApi } from '@backstage/core-plugin-api'; @@ -401,6 +402,24 @@ export type ErrorPanelProps = { title?: string; }; +// @public +export function FavoriteToggle( + props: ComponentProps & { + id: string; + title: string; + isFavorite: boolean; + onToggle: (value: boolean) => void; + }, +): React_2.JSX.Element; + +// @public +export function FavoriteToggleIcon(props: { + isFavorite: boolean; +}): React_2.JSX.Element; + +// @public (undocumented) +export type FavoriteToggleIconClassKey = 'icon' | 'iconBorder'; + // @public (undocumented) export type FeatureCalloutCircleClassKey = | '@keyframes pulsateSlightly' diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 154331d70d..ba0634bfe9 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.14.10", + "version": "0.14.11-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/core-components/src/components/CodeSnippet/CodeSnippet.stories.tsx b/packages/core-components/src/components/CodeSnippet/CodeSnippet.stories.tsx index a266c8c6cb..c4ed5ae072 100644 --- a/packages/core-components/src/components/CodeSnippet/CodeSnippet.stories.tsx +++ b/packages/core-components/src/components/CodeSnippet/CodeSnippet.stories.tsx @@ -52,7 +52,7 @@ greet(world) export const Default = () => ( - + ); diff --git a/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.stories.tsx b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.stories.tsx new file mode 100644 index 0000000000..cfe44b8728 --- /dev/null +++ b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.stories.tsx @@ -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 React from 'react'; +import { FavoriteToggle } from './FavoriteToggle'; +import { + UnifiedThemeProvider, + createBaseThemeOptions, + createUnifiedTheme, + palettes, +} from '@backstage/theme'; + +export default { + title: 'Core/FavoriteToggle', + component: FavoriteToggle, +}; + +export const Default = () => { + const [isFavorite, setFavorite] = React.useState(false); + return ( + + ); +}; + +const theme = createUnifiedTheme({ + ...createBaseThemeOptions({ + palette: palettes.dark, + }), + components: { + BackstageFavoriteToggleIcon: { + styleOverrides: { + icon: () => ({ color: 'aqua' }), + iconBorder: () => ({ color: 'white' }), + }, + }, + }, +}); + +export const WithThemeOverride = () => { + const [isFavorite, setFavorite] = React.useState(false); + return ( + + + + ); +}; diff --git a/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.test.tsx b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.test.tsx new file mode 100644 index 0000000000..c5ca4c33f2 --- /dev/null +++ b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.test.tsx @@ -0,0 +1,55 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { render } from '@testing-library/react'; +import { FavoriteToggle } from './FavoriteToggle'; +import React from 'react'; +import userEvent from '@testing-library/user-event'; + +describe('', () => { + const onToggle = jest.fn(); + + const props = { + title: 'Favorite this thing', + id: 'some-thing-favorite', + onToggle, + isFavorite: true, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders with valid props', async () => { + const { getByRole } = render(); + + expect(getByRole('button', { name: props.title })).toBeInTheDocument(); + }); + + it('should return inverted value on toggle', async () => { + const { getByRole } = render(); + + await userEvent.click(getByRole('button', { name: props.title })); + expect(onToggle).toHaveBeenCalledWith(!props.isFavorite); + }); + + it('should show accessible tooltip', async () => { + const { findByRole, getByRole } = render(); + + await userEvent.hover(getByRole('button', { name: props.title })); + + expect(await findByRole('tooltip')).toHaveTextContent(props.title); + }); +}); diff --git a/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.tsx b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.tsx new file mode 100644 index 0000000000..65124ab05c --- /dev/null +++ b/packages/core-components/src/components/FavoriteToggle/FavoriteToggle.tsx @@ -0,0 +1,95 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React, { ComponentProps } from 'react'; +import IconButton from '@material-ui/core/IconButton'; +import Tooltip from '@material-ui/core/Tooltip'; +import { Theme, makeStyles } from '@material-ui/core/styles'; +import Star from '@material-ui/icons/Star'; +import StarBorder from '@material-ui/icons/StarBorder'; + +const useStyles = makeStyles( + theme => ({ + icon: { + color: '#f3ba37', + cursor: 'pointer', + }, + iconBorder: { + color: theme.palette.text.primary, + cursor: 'pointer', + }, + }), + { name: 'BackstageFavoriteToggleIcon' }, +); + +/** + * @public + */ +export type FavoriteToggleIconClassKey = 'icon' | 'iconBorder'; + +/** + * Icon used in FavoriteToggle component. + * + * Can be used independently, useful when used as {@link @material-table/core#MaterialTableProps.actions} in {@link @material-table/core#MaterialTable} + * + * @public + */ +export function FavoriteToggleIcon(props: { isFavorite: boolean }) { + const { isFavorite } = props; + const classes = useStyles(); + + return isFavorite ? ( + + ) : ( + + ); +} + +/** + * Toggle encapsulating logic for marking something as favorite, + * primarily used in various instances of entity lists and cards but can be used elsewhere. + * + * This component can only be used in as a controlled toggle and does not keep internal state. + * + * @public + */ +export function FavoriteToggle( + props: ComponentProps & { + id: string; + title: string; + isFavorite: boolean; + onToggle: (value: boolean) => void; + }, +) { + const { + id, + title, + isFavorite: value, + onToggle: onChange, + ...iconButtonProps + } = props; + return ( + + onChange(!value)} + {...iconButtonProps} + > + + + + ); +} diff --git a/packages/app/src/plugins.ts b/packages/core-components/src/components/FavoriteToggle/index.ts similarity index 64% rename from packages/app/src/plugins.ts rename to packages/core-components/src/components/FavoriteToggle/index.ts index 9280536997..460b162bdf 100644 --- a/packages/app/src/plugins.ts +++ b/packages/core-components/src/components/FavoriteToggle/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Backstage Authors + * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,5 @@ * limitations under the License. */ -// TODO(Rugvip): This plugin is currently not part of the app element tree, -// ideally we have an API for the context menu that permits that. -export { homePlugin } from '@backstage/plugin-home'; -export { signalsPlugin } from '@backstage/plugin-signals'; +export { FavoriteToggle, FavoriteToggleIcon } from './FavoriteToggle'; +export type { FavoriteToggleIconClassKey } from './FavoriteToggle'; diff --git a/packages/core-components/src/components/index.ts b/packages/core-components/src/components/index.ts index a58208fabb..828df3ec03 100644 --- a/packages/core-components/src/components/index.ts +++ b/packages/core-components/src/components/index.ts @@ -25,6 +25,7 @@ export * from './DependencyGraph'; export * from './DismissableBanner'; export * from './EmptyState'; export * from './ErrorPanel'; +export * from './FavoriteToggle'; export * from './ResponseErrorPanel'; export * from './FeatureDiscovery'; export * from './HeaderIconLinkRow'; @@ -47,3 +48,4 @@ export * from './TabbedLayout'; export * from './Table'; export * from './TrendLine'; export * from './WarningPanel'; +export * from './FavoriteToggle'; diff --git a/packages/core-components/src/layout/SignInPage/SignInPage.tsx b/packages/core-components/src/layout/SignInPage/SignInPage.tsx index 95d96b701a..fb8f804d5e 100644 --- a/packages/core-components/src/layout/SignInPage/SignInPage.tsx +++ b/packages/core-components/src/layout/SignInPage/SignInPage.tsx @@ -24,7 +24,7 @@ import { UserIdentity } from './UserIdentity'; import Button from '@material-ui/core/Button'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; -import React, { useState } from 'react'; +import React, { ReactNode, useState } from 'react'; import { useMountEffect } from '@react-hookz/web'; import { Progress } from '../../components/Progress'; import { Content } from '../Content/Content'; @@ -41,6 +41,7 @@ import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; type MultiSignInPageProps = SignInPageProps & { providers: IdentityProviders; title?: string; + titleComponent?: ReactNode; align?: 'center' | 'left'; }; @@ -55,6 +56,7 @@ export const MultiSignInPage = ({ onSignInSuccess, providers = [], title, + titleComponent, align = 'left', }: MultiSignInPageProps) => { const configApi = useApi(configApiRef); @@ -74,7 +76,13 @@ export const MultiSignInPage = ({
- {title && } + {(title || titleComponent) && ( + + )} ({ packageVersions: { root: '1.2.3', '@backstage/cli': '1.0.0', - '@backstage/backend-common': '1.0.0', '@backstage/backend-defaults': '1.0.0', '@backstage/backend-tasks': '1.0.0', '@backstage/catalog-model': '1.0.0', diff --git a/packages/create-app/src/lib/versions.ts b/packages/create-app/src/lib/versions.ts index 194ffa21d9..84fbc25450 100644 --- a/packages/create-app/src/lib/versions.ts +++ b/packages/create-app/src/lib/versions.ts @@ -32,9 +32,7 @@ leaving any imports in place. import { version as root } from '../../../../package.json'; import { version as appDefaults } from '../../../app-defaults/package.json'; -import { version as backendCommon } from '../../../backend-common/package.json'; import { version as backendDefaults } from '../../../backend-defaults/package.json'; -import { version as backendTasks } from '../../../backend-tasks/package.json'; import { version as catalogClient } from '../../../catalog-client/package.json'; import { version as catalogModel } from '../../../catalog-model/package.json'; import { version as cli } from '../../../cli/package.json'; @@ -89,9 +87,7 @@ import { version as pluginUserSettings } from '../../../../plugins/user-settings export const packageVersions = { root, '@backstage/app-defaults': appDefaults, - '@backstage/backend-common': backendCommon, '@backstage/backend-defaults': backendDefaults, - '@backstage/backend-tasks': backendTasks, '@backstage/catalog-client': catalogClient, '@backstage/catalog-model': catalogModel, '@backstage/cli': cli, diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index 757d849fd7..c7625ba5cc 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -16,9 +16,7 @@ "build-image": "docker build ../.. -f Dockerfile --tag backstage" }, "dependencies": { - "@backstage/backend-common": "^{{version '@backstage/backend-common'}}", "@backstage/backend-defaults": "^{{version '@backstage/backend-defaults'}}", - "@backstage/backend-tasks": "^{{version '@backstage/backend-tasks'}}", "@backstage/config": "^{{version '@backstage/config'}}", "@backstage/plugin-app-backend": "^{{version '@backstage/plugin-app-backend'}}", "@backstage/plugin-auth-backend": "^{{version '@backstage/plugin-auth-backend'}}", diff --git a/packages/create-app/templates/default-app/tsconfig.json b/packages/create-app/templates/default-app/tsconfig.json index ba3f90177d..2aa745d3a9 100644 --- a/packages/create-app/templates/default-app/tsconfig.json +++ b/packages/create-app/templates/default-app/tsconfig.json @@ -2,7 +2,9 @@ "extends": "@backstage/cli/config/tsconfig.json", "include": [ "packages/*/src", + "packages/*/config.d.ts", "plugins/*/src", + "plugins/*/config.d.ts", "plugins/*/dev", "plugins/*/migrations" ], diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 6d40e8fe18..e71ef37738 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/dev-utils +## 1.0.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/app-defaults@1.5.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + +## 1.0.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/app-defaults@1.5.10 + - @backstage/catalog-model@1.6.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + ## 1.0.37 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 447cc13cdc..71a4de45ca 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/dev-utils", - "version": "1.0.37", + "version": "1.0.38-next.1", "description": "Utilities for developing Backstage plugins.", "backstage": { "role": "web-library" diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index 13f01f7458..f553c6e450 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,23 @@ # e2e-test +## 0.2.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.19-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + +## 0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.5.19-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/errors@1.2.4 + ## 0.2.19 ### Patch Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 2e2ca6e331..db0b649123 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -1,7 +1,7 @@ { "name": "e2e-test", "description": "E2E test for verifying Backstage packages", - "version": "0.2.19", + "version": "0.2.20-next.1", "private": true, "backstage": { "role": "cli" diff --git a/packages/frontend-app-api/CHANGELOG.md b/packages/frontend-app-api/CHANGELOG.md index 961d099fa1..9596e51ee3 100644 --- a/packages/frontend-app-api/CHANGELOG.md +++ b/packages/frontend-app-api/CHANGELOG.md @@ -1,5 +1,69 @@ # @backstage/frontend-app-api +## 0.9.0-next.1 + +### Minor Changes + +- 7c80650: **BREAKING**: The `createSpecializedApp` function now creates a bare-bones app without any of the default app structure or APIs. To re-introduce this functionality if you need to use `createSpecializedApp` you can install the `app` plugin from `@backstage/plugin-app`. + + In addition, the `createApp` and `CreateAppFeatureLoader` exports are now deprecated as they are being moved to `@backstage/frontend-defaults`, which should be used instead. + +### Patch Changes + +- c816e2d: Added support for new `FrontendPlugin` and `FrontendModule` types. +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead +- Updated dependencies + - @backstage/frontend-defaults@0.1.0-next.0 + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 0.9.0-next.0 + +### Minor Changes + +- 62cce6c: Removed deprecated `icons` property passing to `createApp` and `createSpecializedApp`. Use `IconBundleBlueprint.make` to create extensions instead and include them in the app. + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. +- f3a2b91: Moved several implementations of built-in APIs from being hardcoded in the app to instead be provided as API extensions. This moves all API-related inputs from the `app` extension to the respective API extensions. For example, extensions created with `ThemeBlueprint` are now attached to the `themes` input of `api:app-theme` rather than the `app` extension. +- 5446061: Internal refactor following removal of v1 extension support. The app implementation itself still supports v1 extensions at runtime. +- 98850de: Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. + + ```ts + export const AppThemeApi = ApiBlueprint.makeWithOverrides({ + name: 'app-theme', + inputs: { + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead + replaces: [{ id: 'app', input: 'themes' }], + }), + }, + factory: () { + ... + } + }); + ``` + +- 4a66456: Added the `root` extension the replace the `app` extension as the root of the app. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/plugin-app@0.1.0-next.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 0.8.0 ### Minor Changes diff --git a/packages/frontend-app-api/api-report.md b/packages/frontend-app-api/api-report.md index c837ff09b7..e102d6bf20 100644 --- a/packages/frontend-app-api/api-report.md +++ b/packages/frontend-app-api/api-report.md @@ -4,32 +4,20 @@ ```ts import { ConfigApi } from '@backstage/core-plugin-api'; +import { createApp as createApp_2 } from '@backstage/frontend-defaults'; +import { CreateAppFeatureLoader as CreateAppFeatureLoader_2 } from '@backstage/frontend-defaults'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; -import { FrontendFeature } from '@backstage/frontend-plugin-api'; +import { FrontendModule } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { JSX as JSX_2 } from 'react'; -import { ReactNode } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { SubRouteRef } from '@backstage/frontend-plugin-api'; -// @public (undocumented) -export function createApp(options?: { - features?: (FrontendFeature | CreateAppFeatureLoader)[]; - configLoader?: () => Promise<{ - config: ConfigApi; - }>; - bindRoutes?(context: { bind: CreateAppRouteBinder }): void; - loadingComponent?: ReactNode; -}): { - createRoot(): JSX_2.Element; -}; +// @public @deprecated (undocumented) +export const createApp: typeof createApp_2; -// @public -export interface CreateAppFeatureLoader { - getLoaderName(): string; - load(options: { config: ConfigApi }): Promise<{ - features: FrontendFeature[]; - }>; -} +// @public @deprecated (undocumented) +export type CreateAppFeatureLoader = CreateAppFeatureLoader_2; // @public export type CreateAppRouteBinder = < @@ -52,4 +40,15 @@ export function createSpecializedApp(options?: { }): { createRoot(): JSX_2.Element; }; + +// @public (undocumented) +export type FrontendFeature = + | FrontendPlugin + | FrontendModule + | { + $$type: '@backstage/ExtensionOverrides'; + } + | { + $$type: '@backstage/BackstagePlugin'; + }; ``` diff --git a/packages/frontend-app-api/package.json b/packages/frontend-app-api/package.json index 3f13b4ad93..140266eae6 100644 --- a/packages/frontend-app-api/package.json +++ b/packages/frontend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/frontend-app-api", - "version": "0.8.0", + "version": "0.9.0-next.1", "backstage": { "role": "web-library" }, @@ -34,20 +34,18 @@ "dependencies": { "@backstage/config": "workspace:^", "@backstage/core-app-api": "workspace:^", - "@backstage/core-components": "workspace:^", "@backstage/core-plugin-api": "workspace:^", "@backstage/errors": "workspace:^", + "@backstage/frontend-defaults": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", - "@backstage/theme": "workspace:^", "@backstage/types": "workspace:^", "@backstage/version-bridge": "workspace:^", - "@material-ui/core": "^4.12.4", - "@material-ui/icons": "^4.11.3", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "lodash": "^4.17.21" }, "devDependencies": { "@backstage/cli": "workspace:^", + "@backstage/plugin-app": "workspace:^", "@backstage/test-utils": "workspace:^", "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^15.0.0" diff --git a/packages/frontend-app-api/src/extensions/Root.ts b/packages/frontend-app-api/src/extensions/Root.ts index e33f794cd6..66c4db3140 100644 --- a/packages/frontend-app-api/src/extensions/Root.ts +++ b/packages/frontend-app-api/src/extensions/Root.ts @@ -22,14 +22,15 @@ import { } from '@backstage/frontend-plugin-api'; export const Root = createExtension({ - namespace: 'root', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { app: createExtensionInput([coreExtensionData.reactElement], { singleton: true, }), - apis: createExtensionInput([ApiBlueprint.dataRefs.factory]), + apis: createExtensionInput([ApiBlueprint.dataRefs.factory], { + replaces: [{ id: 'app', input: 'apis' }], + }), }, - output: [], - factory: () => [], + output: [coreExtensionData.reactElement], + factory: ({ inputs }) => inputs.app, }); diff --git a/packages/frontend-app-api/src/routing/RouteTracker.test.tsx b/packages/frontend-app-api/src/routing/RouteTracker.test.tsx index 935449b697..aeec03992f 100644 --- a/packages/frontend-app-api/src/routing/RouteTracker.test.tsx +++ b/packages/frontend-app-api/src/routing/RouteTracker.test.tsx @@ -46,7 +46,10 @@ describe('RouteTracker', () => { caseSensitive: false, children: [MATCH_ALL_ROUTE], appNode: { - spec: { extension: { id: 'home.page.index' }, source: { id: 'home' } }, + spec: { + extension: { id: 'home.page.index' }, + source: { id: 'home' }, + }, } as AppNode, }, { diff --git a/packages/frontend-app-api/src/routing/collectRouteIds.ts b/packages/frontend-app-api/src/routing/collectRouteIds.ts index d45871ae89..d89834c02e 100644 --- a/packages/frontend-app-api/src/routing/collectRouteIds.ts +++ b/packages/frontend-app-api/src/routing/collectRouteIds.ts @@ -18,7 +18,6 @@ import { RouteRef, SubRouteRef, ExternalRouteRef, - FrontendFeature, } from '@backstage/frontend-plugin-api'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { @@ -29,6 +28,9 @@ import { import { toInternalExternalRouteRef } from '../../../frontend-plugin-api/src/routing/ExternalRouteRef'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalSubRouteRef } from '../../../frontend-plugin-api/src/routing/SubRouteRef'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { isInternalFrontendPlugin } from '../../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +import { FrontendFeature } from '../wiring'; /** @internal */ export interface RouteRefsById { @@ -42,7 +44,7 @@ export function collectRouteIds(features: FrontendFeature[]): RouteRefsById { const externalRoutesById = new Map(); for (const feature of features) { - if (feature.$$type !== '@backstage/BackstagePlugin') { + if (!isInternalFrontendPlugin(feature)) { continue; } diff --git a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts index 8dc41ef155..7ffe64d6d7 100644 --- a/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts +++ b/packages/frontend-app-api/src/routing/extractRouteInfoFromAppNode.test.ts @@ -29,12 +29,15 @@ import { createRouteRef, } from '@backstage/frontend-plugin-api'; import { MockConfigApi, TestApiRegistry } from '@backstage/test-utils'; +import appPlugin from '@backstage/plugin-app'; -import { builtinExtensions } from '../wiring/createApp'; import { readAppExtensionsConfig } from '../tree/readAppExtensionsConfig'; import { resolveAppNodeSpecs } from '../tree/resolveAppNodeSpecs'; import { resolveAppTree } from '../tree/resolveAppTree'; import { instantiateAppNodeTree } from '../tree/instantiateAppNodeTree'; +import { Root } from '../extensions/Root'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; const ref1 = createRouteRef(); const ref2 = createRouteRef(); @@ -76,19 +79,21 @@ function createTestExtension(options: { }); } -function routeInfoFromExtensions(extensions: ExtensionDefinition[]) { +function routeInfoFromExtensions(extensions: ExtensionDefinition[]) { const plugin = createFrontendPlugin({ id: 'test', extensions, }); const tree = resolveAppTree( - 'app', + 'root', resolveAppNodeSpecs({ - features: [plugin], - builtinExtensions, + features: [appPlugin, plugin], + builtinExtensions: [ + resolveExtensionDefinition(Root, { namespace: 'root' }), + ], parameters: readAppExtensionsConfig(new MockConfigApi({})), - forbidden: new Set(['app']), + forbidden: new Set(['root']), }), ); diff --git a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts index 06d412b30e..f24a9e17f3 100644 --- a/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts +++ b/packages/frontend-app-api/src/tree/instantiateAppNodeTree.test.ts @@ -667,7 +667,6 @@ describe('instantiateAppNodeTree', () => { describe('v2', () => { const simpleExtension = resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: [testDataRef, otherDataRef.optional()], @@ -684,6 +683,7 @@ describe('instantiateAppNodeTree', () => { ]; }, }), + { namespace: 'app' }, ); function mirrorInputs(ctx: { @@ -750,7 +750,6 @@ describe('instantiateAppNodeTree', () => { makeSpec( resolveExtensionDefinition( createExtension({ - namespace: 'root-node', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { test: createExtensionInput([testDataRef]), @@ -758,6 +757,7 @@ describe('instantiateAppNodeTree', () => { output: [inputMirrorDataRef], factory: mirrorInputs, }), + { namespace: 'root-node' }, ), ), makeSpec(simpleExtension, { @@ -790,7 +790,6 @@ describe('instantiateAppNodeTree', () => { ...makeSpec( resolveExtensionDefinition( createExtension({ - namespace: 'root-node', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { test: createExtensionInput([testDataRef]), @@ -798,6 +797,7 @@ describe('instantiateAppNodeTree', () => { output: [inputMirrorDataRef], factory: mirrorInputs, }), + { namespace: 'root-node' }, ), ), }, @@ -873,7 +873,6 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -897,6 +896,7 @@ describe('instantiateAppNodeTree', () => { output: [inputMirrorDataRef], factory: mirrorInputs, }), + { namespace: 'app' }, ), ), }); @@ -946,7 +946,6 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: [testDataRef], @@ -956,6 +955,7 @@ describe('instantiateAppNodeTree', () => { throw error; }, }), + { namespace: 'app' }, ), ), attachments: new Map(), @@ -972,7 +972,6 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: [testDataRef, testDataRef], @@ -980,6 +979,7 @@ describe('instantiateAppNodeTree', () => { return [testDataRef('test'), testDataRef('test2')]; }, }), + { namespace: 'app' }, ), ), attachments: new Map(), @@ -996,7 +996,6 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: [testDataRef], @@ -1004,6 +1003,7 @@ describe('instantiateAppNodeTree', () => { return [] as any; }, }), + { namespace: 'app' }, ), ), attachments: new Map(), @@ -1021,7 +1021,6 @@ describe('instantiateAppNodeTree', () => { resolveExtensionDefinition( // @ts-expect-error createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: [], // Output not declared @@ -1029,6 +1028,7 @@ describe('instantiateAppNodeTree', () => { return [testDataRef('test')] as any; }, }), + { namespace: 'app' }, ), ), attachments: new Map(), @@ -1045,7 +1045,6 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -1056,6 +1055,7 @@ describe('instantiateAppNodeTree', () => { output: [], factory: () => [], }), + { namespace: 'app' }, ), ), attachments: new Map(), @@ -1090,7 +1090,6 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'parent', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -1099,6 +1098,7 @@ describe('instantiateAppNodeTree', () => { output: [], factory: () => [], }), + { namespace: 'app' }, ), ), }), @@ -1129,12 +1129,12 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'parent', attachTo: { id: 'ignored', input: 'ignored' }, output: [], factory: () => [], }), + { namespace: 'app' }, ), ), }), @@ -1162,7 +1162,6 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -1173,6 +1172,7 @@ describe('instantiateAppNodeTree', () => { output: [], factory: () => [], }), + { namespace: 'app' }, ), ), }), @@ -1197,7 +1197,6 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -1209,6 +1208,7 @@ describe('instantiateAppNodeTree', () => { output: [], factory: () => [], }), + { namespace: 'app' }, ), ), }), @@ -1227,7 +1227,6 @@ describe('instantiateAppNodeTree', () => { node: makeNode( resolveExtensionDefinition( createExtension({ - namespace: 'app', name: 'test', attachTo: { id: 'ignored', input: 'ignored' }, inputs: { @@ -1238,6 +1237,7 @@ describe('instantiateAppNodeTree', () => { output: [], factory: () => [], }), + { namespace: 'app' }, ), ), }), diff --git a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts index a732b327b6..e4500df6c0 100644 --- a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts +++ b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.test.ts @@ -16,6 +16,7 @@ import { createExtensionOverrides, + createFrontendModule, createFrontendPlugin, Extension, ExtensionDefinition, @@ -38,18 +39,19 @@ function makeExt( } function makeExtDef( - name: string, + name: string | undefined = undefined, status: 'disabled' | 'enabled' = 'enabled', attachId: string = 'root', ) { return { $$type: '@backstage/ExtensionDefinition', + T: undefined as any, version: 'v1', name, attachTo: { id: attachId, input: 'default' }, disabled: status === 'disabled', - override: () => ({} as ExtensionDefinition), - } as ExtensionDefinition; + override: () => ({} as ExtensionDefinition), + } as ExtensionDefinition; } describe('resolveAppNodeSpecs', () => { @@ -323,6 +325,56 @@ describe('resolveAppNodeSpecs', () => { ]); }); + it('should apply module overrides', () => { + const plugin = createFrontendPlugin({ + id: 'test', + extensions: [makeExtDef('a'), makeExtDef('b')], + }); + const aOverride = makeExt('test/a', 'enabled', 'other'); + const bOverride = makeExt('test/b', 'disabled', 'other'); + const cOverride = makeExt('test/c'); + + expect( + resolveAppNodeSpecs({ + features: [ + plugin, + createFrontendModule({ + pluginId: 'test', + extensions: [ + makeExtDef('a', 'enabled', 'other'), + makeExtDef('b', 'disabled', 'other'), + makeExtDef('c'), + ], + }), + ], + builtinExtensions: [], + parameters: [], + }), + ).toEqual([ + { + id: 'test/a', + extension: expect.objectContaining(aOverride), + attachTo: { id: 'other', input: 'default' }, + source: plugin, + disabled: false, + }, + { + id: 'test/b', + extension: expect.objectContaining(bOverride), + attachTo: { id: 'other', input: 'default' }, + source: plugin, + disabled: true, + }, + { + id: 'test/c', + extension: expect.objectContaining(cOverride), + attachTo: { id: 'root', input: 'default' }, + source: plugin, + disabled: false, + }, + ]); + }); + it('should use order from configuration when rather than overrides', () => { const result = resolveAppNodeSpecs({ features: [ @@ -356,6 +408,40 @@ describe('resolveAppNodeSpecs', () => { ]); }); + it('should use order from configuration when rather than modules', () => { + const result = resolveAppNodeSpecs({ + features: [ + createFrontendPlugin({ + id: 'test', + extensions: [ + makeExtDef('a', 'disabled'), + makeExtDef('b', 'disabled'), + makeExtDef('c', 'disabled'), + ], + }), + createFrontendModule({ + pluginId: 'test', + extensions: [ + makeExtDef('c', 'disabled'), + makeExtDef('b', 'disabled'), + makeExtDef('a', 'disabled'), + ], + }), + ], + builtinExtensions: [], + parameters: ['test/b', 'test/c', 'test/a'].map(id => ({ + id, + disabled: false, + })), + }); + + expect(result.map(r => r.extension.id)).toEqual([ + 'test/b', + 'test/c', + 'test/a', + ]); + }); + it('throws an error when a forbidden extension is overridden by a plugin', () => { expect(() => resolveAppNodeSpecs({ @@ -389,6 +475,28 @@ describe('resolveAppNodeSpecs', () => { ); }); + it('throws an error when a forbidden extension is overridden by module', () => { + expect(() => + resolveAppNodeSpecs({ + features: [ + createFrontendPlugin({ + id: 'forbidden', + extensions: [], + }), + createFrontendModule({ + pluginId: 'forbidden', + extensions: [makeExtDef()], + }), + ], + builtinExtensions: [], + parameters: [], + forbidden: new Set(['forbidden']), + }), + ).toThrow( + "It is forbidden to override the following extension(s): 'forbidden', which is done by a module for the following plugin(s): 'forbidden'", + ); + }); + it('throws an error when a forbidden extension is parametrized', () => { expect(() => resolveAppNodeSpecs({ diff --git a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts index b92485c5d6..bc3da52cd6 100644 --- a/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts +++ b/packages/frontend-app-api/src/tree/resolveAppNodeSpecs.ts @@ -14,20 +14,24 @@ * limitations under the License. */ -import { - BackstagePlugin, - Extension, - ExtensionOverrides, - FrontendFeature, -} from '@backstage/frontend-plugin-api'; +import { Extension, ExtensionOverrides } from '@backstage/frontend-plugin-api'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalExtensionOverrides } from '../../../frontend-plugin-api/src/wiring/createExtensionOverrides'; import { ExtensionParameters } from './readAppExtensionsConfig'; import { AppNodeSpec } from '@backstage/frontend-plugin-api'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { toInternalBackstagePlugin } from '../../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +import { + isInternalFrontendPlugin, + toInternalFrontendPlugin, +} from '../../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { + isInternalFrontendModule, + toInternalFrontendModule, +} from '../../../frontend-plugin-api/src/wiring/createFrontendModule'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalExtension } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; +import { FrontendFeature } from '../wiring'; /** @internal */ export function resolveAppNodeSpecs(options: { @@ -43,20 +47,30 @@ export function resolveAppNodeSpecs(options: { features = [], } = options; - const plugins = features.filter( - (f): f is BackstagePlugin => f.$$type === '@backstage/BackstagePlugin', - ); + const plugins = features.filter(isInternalFrontendPlugin); const overrides = features.filter( (f): f is ExtensionOverrides => f.$$type === '@backstage/ExtensionOverrides', ); + const modules = features.filter(isInternalFrontendModule); const pluginExtensions = plugins.flatMap(source => { - return toInternalBackstagePlugin(source).extensions.map(extension => ({ + return toInternalFrontendPlugin(source).extensions.map(extension => ({ ...extension, source, })); }); + const moduleExtensions = modules.flatMap(mod => + toInternalFrontendModule(mod).extensions.flatMap(extension => { + // Modules for plugins that are not installed are ignored + const source = plugins.find(p => p.id === mod.pluginId); + if (!source) { + return []; + } + + return [{ ...extension, source }]; + }), + ); const overrideExtensions = overrides.flatMap( override => toInternalExtensionOverrides(override).extensions, ); @@ -72,13 +86,23 @@ export function resolveAppNodeSpecs(options: { `It is forbidden to override the following extension(s): ${forbiddenStr}, which is done by the following plugin(s): ${pluginsStr}`, ); } - + if (moduleExtensions.some(({ id }) => forbidden.has(id))) { + const pluginsStr = moduleExtensions + .filter(({ id }) => forbidden.has(id)) + .map(({ source }) => `'${source.id}'`) + .join(', '); + const forbiddenStr = [...forbidden].map(id => `'${id}'`).join(', '); + throw new Error( + `It is forbidden to override the following extension(s): ${forbiddenStr}, which is done by a module for the following plugin(s): ${pluginsStr}`, + ); + } if (overrideExtensions.some(({ id }) => forbidden.has(id))) { const forbiddenStr = [...forbidden].map(id => `'${id}'`).join(', '); throw new Error( `It is forbidden to override the following extension(s): ${forbiddenStr}, which is done by one or more extension overrides`, ); } + const overrideExtensionIds = overrideExtensions.map(({ id }) => id); if (overrideExtensionIds.length !== new Set(overrideExtensionIds).size) { const counts = new Map(); @@ -149,6 +173,33 @@ export function resolveAppNodeSpecs(options: { } } + // Install all module overrides + for (const extension of moduleExtensions) { + const internalExtension = toInternalExtension(extension); + + // Check if our override is overriding an extension that already exists + const index = configuredExtensions.findIndex( + e => e.extension.id === extension.id, + ); + if (index !== -1) { + // Only implementation, attachment point and default disabled status are overridden, the source is kept + configuredExtensions[index].extension = internalExtension; + configuredExtensions[index].params.attachTo = internalExtension.attachTo; + configuredExtensions[index].params.disabled = internalExtension.disabled; + } else { + // Add the extension as a new one when not overriding an existing one + configuredExtensions.push({ + extension: internalExtension, + params: { + source: extension.source, + attachTo: internalExtension.attachTo, + disabled: internalExtension.disabled, + config: undefined, + }, + }); + } + } + const duplicatedExtensionIds = new Set(); const duplicatedExtensionData = configuredExtensions.reduce< Record> diff --git a/packages/frontend-app-api/src/tree/resolveAppTree.test.ts b/packages/frontend-app-api/src/tree/resolveAppTree.test.ts index 740f05d5f7..0517e943aa 100644 --- a/packages/frontend-app-api/src/tree/resolveAppTree.test.ts +++ b/packages/frontend-app-api/src/tree/resolveAppTree.test.ts @@ -14,7 +14,12 @@ * limitations under the License. */ -import { createExtension, Extension } from '@backstage/frontend-plugin-api'; +import { + coreExtensionData, + createExtension, + createExtensionInput, + Extension, +} from '@backstage/frontend-plugin-api'; import { resolveAppTree } from './resolveAppTree'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; @@ -165,4 +170,146 @@ describe('buildAppTree', () => { ]), ).toThrow("Unexpected duplicate extension id 'a'"); }); + + describe('redirects', () => { + it('should throw an error when theres a duplicate redirect target', () => { + const e1 = resolveExtensionDefinition( + createExtension({ + name: 'test', + attachTo: { id: 'nonexistent', input: 'nonexistent' }, + inputs: { + test: createExtensionInput([coreExtensionData.reactElement], { + replaces: [{ id: 'a', input: 'test' }], + }), + }, + output: [], + factory: () => [], + }), + ) as Extension; + + const e2 = resolveExtensionDefinition( + createExtension({ + name: 'test-2', + attachTo: { id: 'nonexistent', input: 'nonexistent' }, + inputs: { + test: createExtensionInput([coreExtensionData.reactElement], { + replaces: [{ id: 'a', input: 'test' }], + }), + }, + output: [], + factory: () => [], + }), + ) as Extension; + + expect(() => + resolveAppTree('a', [ + { ...baseSpec, id: 'a', extension: e1 }, + { ...baseSpec, id: 'b', extension: e2 }, + ]), + ).toThrow("Duplicate redirect target for input 'test' in extension 'b'"); + }); + + it('should set the correct attachment point for a redirect', () => { + const e1 = resolveExtensionDefinition( + createExtension({ + name: 'test', + attachTo: { id: 'nonexistent', input: 'nonexistent' }, + inputs: { + test: createExtensionInput([coreExtensionData.reactElement], { + replaces: [{ id: 'replace', input: 'me' }], + }), + }, + output: [], + factory: () => [], + }), + ) as Extension; + + const e2 = resolveExtensionDefinition( + createExtension({ + name: 'test-2', + attachTo: { id: 'replace', input: 'me' }, + output: [], + factory: () => [], + }), + ) as Extension; + + const tree = resolveAppTree('a', [ + { attachTo: e1.attachTo, id: 'a', extension: e1, disabled: false }, + { attachTo: e2.attachTo, id: 'b', extension: e2, disabled: false }, + ]); + + expect(tree.root).toMatchInlineSnapshot(` + { + "attachments": { + "test": [ + { + "attachments": undefined, + "id": "b", + "output": undefined, + }, + ], + }, + "id": "a", + "output": undefined, + } + `); + + expect(tree.orphans).toMatchInlineSnapshot(`[]`); + + expect(String(tree.root)).toMatchInlineSnapshot(` + " + test [ + + ] + " + `); + }); + + it('should not allow redirects for attachment points that already exist', () => { + const e1 = resolveExtensionDefinition( + createExtension({ + name: 'test', + attachTo: { id: 'a', input: 'a' }, + inputs: { + test: createExtensionInput([coreExtensionData.reactElement], { + replaces: [{ id: 'test-2', input: 'test' }], + }), + }, + output: [], + factory: () => [], + }), + ) as Extension; + + const e2 = resolveExtensionDefinition( + createExtension({ + name: 'test-2', + attachTo: { id: 'b', input: 'b' }, + inputs: { + test: createExtensionInput([coreExtensionData.reactElement]), + }, + output: [], + factory: () => [], + }), + ) as Extension; + + const e3 = resolveExtensionDefinition( + createExtension({ + name: 'test-3', + attachTo: { id: 'test-2', input: 'test' }, + output: [], + factory: () => [], + }), + ) as Extension; + + const tree = resolveAppTree('test-2', [ + { attachTo: e1.attachTo, id: e1.id, extension: e1, disabled: false }, + { attachTo: e2.attachTo, id: e2.id, extension: e2, disabled: false }, + { attachTo: e3.attachTo, id: e3.id, extension: e3, disabled: false }, + ]); + + expect(tree.nodes.get('test-3')?.edges.attachedTo?.node).toBe( + tree.nodes.get('test-2'), + ); + }); + }); }); diff --git a/packages/frontend-app-api/src/tree/resolveAppTree.ts b/packages/frontend-app-api/src/tree/resolveAppTree.ts index 24948373bf..dc9985da30 100644 --- a/packages/frontend-app-api/src/tree/resolveAppTree.ts +++ b/packages/frontend-app-api/src/tree/resolveAppTree.ts @@ -21,6 +21,9 @@ import { AppNodeSpec, } from '@backstage/frontend-plugin-api'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { toInternalExtension } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; + function indent(str: string) { return str.replace(/^/gm, ' '); } @@ -38,9 +41,7 @@ class SerializableAppNode implements AppNode { this.spec = spec; } - setParent(parent: SerializableAppNode) { - const input = this.spec.attachTo.input; - + setParent(parent: SerializableAppNode, input: string) { this.edges.attachedTo = { node: parent, input }; const parentInputEdges = parent.edges.attachments.get(input); @@ -87,6 +88,24 @@ class SerializableAppNode implements AppNode { } } +function makeRedirectKey(attachTo: { id: string; input: string }) { + return `${attachTo.id}%${attachTo.input}`; +} + +const isValidAttachmentPoint = ( + attachTo: { id: string; input: string }, + nodes: Map, +) => { + if (!nodes.has(attachTo.id)) { + return false; + } + + return ( + attachTo.input in + toInternalExtension(nodes.get(attachTo.id)!.spec.extension).inputs + ); +}; + /** * Build the app tree by iterating through all node specs and constructing the app * tree with all attachments in the same order as they appear in the input specs array. @@ -98,17 +117,7 @@ export function resolveAppTree( ): AppTree { const nodes = new Map(); - // A node with the provided rootNodeId must be found in the tree, and it must not be attached to anything - let rootNode: AppNode | undefined = undefined; - - // While iterating through the inputs specs we keep track of all nodes that were created - // before their parent, and attach them later when the parent is created. - // As we find the parents and attach the children, we remove them from this map. This means - // that after iterating through all input specs, this will be a map for each root node. - const orphansByParent = new Map< - string /* parentId */, - SerializableAppNode[] - >(); + const redirectTargetsByKey = new Map(); for (const spec of specs) { // The main check with a more helpful error message happens in resolveAppNodeSpecs @@ -119,28 +128,46 @@ export function resolveAppTree( const node = new SerializableAppNode(spec); nodes.set(spec.id, node); + const internal = toInternalExtension(spec.extension); + for (const [inputName, input] of Object.entries(internal.inputs)) { + if (input.replaces) { + for (const replace of input.replaces) { + const key = makeRedirectKey(replace); + if (redirectTargetsByKey.has(key)) { + throw new Error( + `Duplicate redirect target for input '${inputName}' in extension '${spec.id}'`, + ); + } + redirectTargetsByKey.set(key, { id: spec.id, input: inputName }); + } + } + } + } + + const orphans = new Array(); + + // A node with the provided rootNodeId must be found in the tree, and it must not be attached to anything + let rootNode: AppNode | undefined = undefined; + + for (const node of nodes.values()) { + const spec = node.spec; + // TODO: For now we simply ignore the attachTo spec of the root node, but it'd be cleaner if we could avoid defining it if (spec.id === rootNodeId) { rootNode = node; } else { - const parent = nodes.get(spec.attachTo.id); - if (parent) { - node.setParent(parent); - } else { - const orphanNodesForParent = orphansByParent.get(spec.attachTo.id); - if (orphanNodesForParent) { - orphanNodesForParent.push(node); - } else { - orphansByParent.set(spec.attachTo.id, [node]); - } - } - } + let attachTo = node.spec.attachTo; - const orphanedChildren = orphansByParent.get(spec.id); - if (orphanedChildren) { - orphansByParent.delete(spec.id); - for (const orphan of orphanedChildren) { - orphan.setParent(node); + if (!isValidAttachmentPoint(attachTo, nodes)) { + attachTo = + redirectTargetsByKey.get(makeRedirectKey(attachTo)) ?? attachTo; + } + + const parent = nodes.get(attachTo.id); + if (parent) { + node.setParent(parent, attachTo.input); + } else { + orphans.push(node); } } } @@ -152,6 +179,6 @@ export function resolveAppTree( return { root: rootNode, nodes, - orphans: Array.from(orphansByParent.values()).flat(), + orphans, }; } diff --git a/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx b/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx new file mode 100644 index 0000000000..e98014f273 --- /dev/null +++ b/packages/frontend-app-api/src/wiring/createSpecializedApp.test.tsx @@ -0,0 +1,283 @@ +/* + * 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 { + AppTreeApi, + appTreeApiRef, + coreExtensionData, + createExtension, + createFrontendPlugin, + ApiBlueprint, + createRouteRef, + createExternalRouteRef, + createExtensionInput, + useRouteRef, +} from '@backstage/frontend-plugin-api'; +import { screen, render } from '@testing-library/react'; +import { createSpecializedApp } from './createSpecializedApp'; +import { MockConfigApi } from '@backstage/test-utils'; +import React from 'react'; +import { + configApiRef, + createApiFactory, + featureFlagsApiRef, +} from '@backstage/core-plugin-api'; +import { MemoryRouter } from 'react-router-dom'; +import { ApiProvider } from '@backstage/core-app-api'; + +describe('createSpecializedApp', () => { + it('should render the root app', () => { + const app = createSpecializedApp({ + features: [ + createFrontendPlugin({ + id: 'test', + extensions: [ + createExtension({ + attachTo: { id: 'root', input: 'app' }, + output: [coreExtensionData.reactElement], + factory: () => [coreExtensionData.reactElement(
Test
)], + }), + ], + }), + ], + }); + + render(app.createRoot()); + + expect(screen.getByText('Test')).toBeInTheDocument(); + }); + + it('should deduplicate features keeping the last received one', () => { + const app = createSpecializedApp({ + features: [ + createFrontendPlugin({ + id: 'test', + extensions: [ + createExtension({ + attachTo: { id: 'root', input: 'app' }, + output: [coreExtensionData.reactElement], + factory: () => [ + coreExtensionData.reactElement(
Test 1
), + ], + }), + ], + }), + createFrontendPlugin({ + id: 'test', + extensions: [ + createExtension({ + attachTo: { id: 'root', input: 'app' }, + output: [coreExtensionData.reactElement], + factory: () => [ + coreExtensionData.reactElement(
Test 2
), + ], + }), + ], + }), + ], + }); + + render(app.createRoot()); + + expect(screen.getByText('Test 2')).toBeInTheDocument(); + }); + + it('should forward config', () => { + const app = createSpecializedApp({ + config: new MockConfigApi({ test: 'foo' }), + features: [ + createFrontendPlugin({ + id: 'test', + extensions: [ + createExtension({ + attachTo: { id: 'root', input: 'app' }, + output: [coreExtensionData.reactElement], + factory: ({ apis }) => [ + coreExtensionData.reactElement( +
Test {apis.get(configApiRef)!.getString('test')}
, + ), + ], + }), + ], + }), + ], + }); + + render(app.createRoot()); + + expect(screen.getByText('Test foo')).toBeInTheDocument(); + }); + + it('should support APIs and feature flags', async () => { + const flags = new Array<{ name: string; pluginId: string }>(); + const app = createSpecializedApp({ + features: [ + createFrontendPlugin({ + id: 'test', + featureFlags: [{ name: 'a' }, { name: 'b' }], + extensions: [ + createExtension({ + attachTo: { id: 'root', input: 'app' }, + output: [coreExtensionData.reactElement], + factory: ({ apis }) => [ + coreExtensionData.reactElement( +
+ flags: + {apis + .get(featureFlagsApiRef)! + .getRegisteredFlags() + .map(f => `${f.pluginId}=${f.name}`) + .join(',')} +
, + ), + ], + }), + ApiBlueprint.make({ + params: { + factory: createApiFactory(featureFlagsApiRef, { + registerFlag(flag) { + flags.push(flag); + }, + getRegisteredFlags() { + return flags; + }, + } as typeof featureFlagsApiRef.T), + }, + }), + ], + }), + ], + }); + + render(app.createRoot()); + + expect(screen.getByText('flags:test=a,test=b')).toBeInTheDocument(); + }); + + it('should make the app structure available through the AppTreeApi', async () => { + let appTreeApi: AppTreeApi | undefined = undefined; + + createSpecializedApp({ + features: [ + createFrontendPlugin({ + id: 'test', + extensions: [ + createExtension({ + attachTo: { id: 'root', input: 'app' }, + output: [coreExtensionData.reactElement], + factory: ({ apis }) => { + appTreeApi = apis.get(appTreeApiRef); + return [coreExtensionData.reactElement(
)]; + }, + }), + ], + }), + ], + }); + + expect(String(appTreeApi!.getTree().tree.root)).toMatchInlineSnapshot(` + " + app [ + + ] + " + `); + }); + + it('should support route bindings', async () => { + const routeRef = createRouteRef(); + const extRouteRef = createExternalRouteRef(); + + const pluginA = createFrontendPlugin({ + id: 'a', + externalRoutes: { + ext: extRouteRef, + }, + extensions: [ + createExtension({ + name: 'parent', + attachTo: { id: 'root', input: 'app' }, + inputs: { + children: createExtensionInput([coreExtensionData.reactElement]), + }, + output: [coreExtensionData.reactElement], + factory: ({ apis, inputs }) => { + return [ + coreExtensionData.reactElement( + + + {inputs.children.map(i => ( + + {i.get(coreExtensionData.reactElement)} + + ))} + + , + ), + ]; + }, + }), + createExtension({ + name: 'child', + attachTo: { id: 'a/parent', input: 'children' }, + output: [coreExtensionData.reactElement], + factory: () => { + const Component = () => { + const link = useRouteRef(extRouteRef); + return
link: {link?.() ?? 'none'}
; + }; + return [coreExtensionData.reactElement()]; + }, + }), + ], + }); + const pluginB = createFrontendPlugin({ + id: 'b', + routes: { + root: routeRef, + }, + extensions: [ + createExtension({ + name: 'child', + attachTo: { id: 'a/parent', input: 'children' }, + output: [ + coreExtensionData.reactElement, + coreExtensionData.routePath, + coreExtensionData.routeRef, + ], + factory: () => { + return [ + coreExtensionData.reactElement(
), + coreExtensionData.routePath('/test'), + coreExtensionData.routeRef(routeRef), + ]; + }, + }), + ], + }); + + render( + createSpecializedApp({ + features: [pluginA, pluginB], + bindRoutes({ bind }) { + bind(pluginA.externalRoutes, { ext: pluginB.routes.root }); + }, + }).createRoot(), + ); + + expect(screen.getByText('link: /test')).toBeInTheDocument(); + }); +}); diff --git a/packages/frontend-app-api/src/wiring/createApp.tsx b/packages/frontend-app-api/src/wiring/createSpecializedApp.tsx similarity index 54% rename from packages/frontend-app-api/src/wiring/createApp.tsx rename to packages/frontend-app-api/src/wiring/createSpecializedApp.tsx index b31ce85f1a..612befc597 100644 --- a/packages/frontend-app-api/src/wiring/createApp.tsx +++ b/packages/frontend-app-api/src/wiring/createSpecializedApp.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { JSX, ReactNode } from 'react'; +import React, { JSX } from 'react'; import { ConfigReader } from '@backstage/config'; import { ApiBlueprint, @@ -22,7 +22,6 @@ import { AppTreeApi, appTreeApiRef, coreExtensionData, - FrontendFeature, RouteRef, ExternalRouteRef, SubRouteRef, @@ -33,10 +32,6 @@ import { createApiFactory, routeResolutionApiRef, } from '@backstage/frontend-plugin-api'; -import { App } from '../extensions/App'; -import { AppRoutes } from '../extensions/AppRoutes'; -import { AppLayout } from '../extensions/AppLayout'; -import { AppNav } from '../extensions/AppNav'; import { AnyApiFactory, ApiHolder, @@ -44,62 +39,37 @@ import { configApiRef, featureFlagsApiRef, identityApiRef, - errorApiRef, - discoveryApiRef, - fetchApiRef, } from '@backstage/core-plugin-api'; -import { getAvailableFeatures } from './discovery'; -import { - ApiFactoryRegistry, - ApiProvider, - ApiResolver, -} from '@backstage/core-app-api'; +import { ApiFactoryRegistry, ApiResolver } from '@backstage/core-app-api'; // TODO: Get rid of all of these -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { isProtectedApp } from '../../../core-app-api/src/app/isProtectedApp'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { AppThemeProvider } from '../../../core-app-api/src/app/AppThemeProvider'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { AppIdentityProxy } from '../../../core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { defaultConfigLoaderSync } from '../../../core-app-api/src/app/defaultConfigLoader'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { overrideBaseUrlConfigs } from '../../../core-app-api/src/app/overrideBaseUrlConfigs'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { apis as defaultApis } from '../../../app-defaults/src/defaults'; import { - oauthRequestDialogAppRootElement, - alertDisplayAppRootElement, -} from '../extensions/elements'; + createApp as _createApp, + CreateAppFeatureLoader as _CreateAppFeatureLoader, +} from '@backstage/frontend-defaults'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { resolveExtensionDefinition } from '../../../frontend-plugin-api/src/wiring/resolveExtensionDefinition'; + import { extractRouteInfoFromAppNode } from '../routing/extractRouteInfoFromAppNode'; import { CreateAppRouteBinder } from '../routing'; import { RouteResolver } from '../routing/RouteResolver'; import { resolveRouteBindings } from '../routing/resolveRouteBindings'; import { collectRouteIds } from '../routing/collectRouteIds'; -import { - DefaultProgressComponent, - DefaultErrorBoundaryComponent, - DefaultNotFoundErrorPageComponent, -} from '../extensions/components'; -import { InternalAppContext } from './InternalAppContext'; -import { AppRoot } from '../extensions/AppRoot'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { toInternalBackstagePlugin } from '../../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +import { + toInternalFrontendPlugin, + isInternalFrontendPlugin, +} from '../../../frontend-plugin-api/src/wiring/createFrontendPlugin'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { + toInternalFrontendModule, + isInternalFrontendModule, +} from '../../../frontend-plugin-api/src/wiring/createFrontendModule'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { toInternalExtensionOverrides } from '../../../frontend-plugin-api/src/wiring/createExtensionOverrides'; -import { stringifyError } from '@backstage/errors'; import { getBasePath } from '../routing/getBasePath'; -import { AppThemeApi, DarkTheme, LightTheme } from '../extensions/AppThemeApi'; -import { IconsApi } from '../extensions/IconsApi'; -import { TranslationsApi } from '../extensions/TranslationsApi'; -import { ComponentsApi } from '../extensions/ComponentsApi'; -import { AppLanguageApi } from '../extensions/AppLanguageApi'; -import { FeatureFlagsApi } from '../extensions/FeatureFlagsApi'; import { Root } from '../extensions/Root'; import { resolveAppTree } from '../tree/resolveAppTree'; import { resolveAppNodeSpecs } from '../tree/resolveAppNodeSpecs'; @@ -107,33 +77,10 @@ import { readAppExtensionsConfig } from '../tree/readAppExtensionsConfig'; import { instantiateAppNodeTree } from '../tree/instantiateAppNodeTree'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports import { ApiRegistry } from '../../../core-app-api/src/apis/system/ApiRegistry'; - -const DefaultApis = defaultApis.map(factory => - ApiBlueprint.make({ namespace: factory.api.id, params: { factory } }), -); - -export const builtinExtensions = [ - Root, - App, - AppRoot, - AppRoutes, - AppNav, - AppLayout, - DefaultProgressComponent, - DefaultErrorBoundaryComponent, - DefaultNotFoundErrorPageComponent, - LightTheme, - DarkTheme, - oauthRequestDialogAppRootElement, - alertDisplayAppRootElement, - AppThemeApi, - AppLanguageApi, - IconsApi, - TranslationsApi, - ComponentsApi, - FeatureFlagsApi, - ...DefaultApis, -].map(def => resolveExtensionDefinition(def)); +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { AppIdentityProxy } from '../../../core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy'; +import { BackstageRouteObject } from '../routing/types'; +import { FrontendFeature } from './types'; function deduplicateFeatures( allFeatures: FrontendFeature[], @@ -146,7 +93,7 @@ function deduplicateFeatures( return features .reverse() .filter(feature => { - if (feature.$$type !== '@backstage/BackstagePlugin') { + if (!isInternalFrontendPlugin(feature)) { return true; } if (seenIds.has(feature.id)) { @@ -158,93 +105,6 @@ function deduplicateFeatures( .reverse(); } -/** - * A source of dynamically loaded frontend features. - * - * @public - */ -export interface CreateAppFeatureLoader { - /** - * Returns name of this loader. suitable for showing to users. - */ - getLoaderName(): string; - - /** - * Loads a number of features dynamically. - */ - load(options: { config: ConfigApi }): Promise<{ - features: FrontendFeature[]; - }>; -} - -/** @public */ -export function createApp(options?: { - features?: (FrontendFeature | CreateAppFeatureLoader)[]; - configLoader?: () => Promise<{ config: ConfigApi }>; - bindRoutes?(context: { bind: CreateAppRouteBinder }): void; - /** - * The component to render while loading the app (waiting for config, features, etc) - * - * Is the text "Loading..." by default. - * If set to "null" then no loading fallback component is rendered. * - */ - loadingComponent?: ReactNode; -}): { - createRoot(): JSX.Element; -} { - let suspenseFallback = options?.loadingComponent; - if (suspenseFallback === undefined) { - suspenseFallback = 'Loading...'; - } - - async function appLoader() { - const config = - (await options?.configLoader?.().then(c => c.config)) ?? - ConfigReader.fromConfigs( - overrideBaseUrlConfigs(defaultConfigLoaderSync()), - ); - - const discoveredFeatures = getAvailableFeatures(config); - - const providedFeatures: FrontendFeature[] = []; - for (const entry of options?.features ?? []) { - if ('load' in entry) { - try { - const result = await entry.load({ config }); - providedFeatures.push(...result.features); - } catch (e) { - throw new Error( - `Failed to read frontend features from loader '${entry.getLoaderName()}', ${stringifyError( - e, - )}`, - ); - } - } else { - providedFeatures.push(entry); - } - } - - const app = createSpecializedApp({ - config, - features: [...discoveredFeatures, ...providedFeatures], - bindRoutes: options?.bindRoutes, - }).createRoot(); - - return { default: () => app }; - } - - return { - createRoot() { - const LazyApp = React.lazy(appLoader); - return ( - - - - ); - }, - }; -} - // Helps delay callers from reaching out to the API before the app tree has been materialized class AppTreeApiProxy implements AppTreeApi { #safeToUse: boolean = false; @@ -268,6 +128,7 @@ class AppTreeApiProxy implements AppTreeApi { // Helps delay callers from reaching out to the API before the app tree has been materialized class RouteResolutionApiProxy implements RouteResolutionApi { #delegate: RouteResolutionApi | undefined; + #routeObjects: BackstageRouteObject[] | undefined; constructor( private readonly tree: AppTree, @@ -304,14 +165,32 @@ class RouteResolutionApiProxy implements RouteResolutionApi { this.routeBindings, this.basePath, ); + this.#routeObjects = routeInfo.routeObjects; return routeInfo; } + + getRouteObjects() { + return this.#routeObjects; + } } /** - * Synchronous version of {@link createApp}, expecting all features and - * config to have been loaded already. + * @public + * @deprecated Import from `@backstage/frontend-defaults` instead. + */ +export const createApp = _createApp; + +/** + * @public + * @deprecated Import from `@backstage/frontend-defaults` instead. + */ +export type CreateAppFeatureLoader = _CreateAppFeatureLoader; + +/** + * Creates an empty app without any default features. This is a low-level API is + * intended for use in tests or specialized setups. Typically wou want to use + * `createApp` from `@backstage/frontend-defaults` instead. * * @public */ @@ -320,25 +199,22 @@ export function createSpecializedApp(options?: { config?: ConfigApi; bindRoutes?(context: { bind: CreateAppRouteBinder }): void; }): { createRoot(): JSX.Element } { - const { - features: duplicatedFeatures = [], - config = new ConfigReader({}, 'empty-config'), - } = options ?? {}; - - const features = deduplicateFeatures(duplicatedFeatures); + const config = options?.config ?? new ConfigReader({}, 'empty-config'); + const features = deduplicateFeatures(options?.features ?? []); const tree = resolveAppTree( 'root', resolveAppNodeSpecs({ features, - builtinExtensions, + builtinExtensions: [ + resolveExtensionDefinition(Root, { namespace: 'root' }), + ], parameters: readAppExtensionsConfig(config), forbidden: new Set(['root']), }), ); const factories = createApiFactories({ tree }); - const appTreeApi = new AppTreeApiProxy(tree); const routeResolutionApi = new RouteResolutionApiProxy( tree, @@ -361,40 +237,25 @@ export function createSpecializedApp(options?: { ], }); - for (const appNode of tree.root.edges.attachments.get('app') ?? []) { - instantiateAppNodeTree(appNode, apiHolder); - } - - const routeInfo = routeResolutionApi.initialize(); - appTreeApi.initialize(); - - if (isProtectedApp()) { - const discoveryApi = apiHolder.get(discoveryApiRef); - const errorApi = apiHolder.get(errorApiRef); - const fetchApi = apiHolder.get(fetchApiRef); - if (!discoveryApi || !errorApi || !fetchApi) { - throw new Error( - 'App is running in protected mode but missing required APIs', - ); - } - appIdentityProxy.enableCookieAuth({ - discoveryApi, - errorApi, - fetchApi, - }); - } - const featureFlagApi = apiHolder.get(featureFlagsApiRef); if (featureFlagApi) { for (const feature of features) { - if (feature.$$type === '@backstage/BackstagePlugin') { - toInternalBackstagePlugin(feature).featureFlags.forEach(flag => + if (isInternalFrontendPlugin(feature)) { + toInternalFrontendPlugin(feature).featureFlags.forEach(flag => featureFlagApi.registerFlag({ name: flag.name, pluginId: feature.id, }), ); } + if (isInternalFrontendModule(feature)) { + toInternalFrontendModule(feature).featureFlags.forEach(flag => + featureFlagApi.registerFlag({ + name: flag.name, + pluginId: feature.pluginId, + }), + ); + } if (feature.$$type === '@backstage/ExtensionOverrides') { toInternalExtensionOverrides(feature).featureFlags.forEach(flag => featureFlagApi.registerFlag({ name: flag.name, pluginId: '' }), @@ -403,21 +264,15 @@ export function createSpecializedApp(options?: { } } - const rootEl = tree.root.edges.attachments - .get('app')![0] - .instance!.getData(coreExtensionData.reactElement); + // Now instantiate the entire tree, which will skip anything that's already been instantiated + instantiateAppNodeTree(tree.root, apiHolder); - const AppComponent = () => ( - - - - {rootEl} - - - - ); + routeResolutionApi.initialize(); + appTreeApi.initialize(); + + const rootEl = tree.root.instance!.getData(coreExtensionData.reactElement); + + const AppComponent = () => rootEl; return { createRoot() { diff --git a/packages/frontend-app-api/src/wiring/index.ts b/packages/frontend-app-api/src/wiring/index.ts index d1498514c8..d76055f63b 100644 --- a/packages/frontend-app-api/src/wiring/index.ts +++ b/packages/frontend-app-api/src/wiring/index.ts @@ -18,4 +18,5 @@ export { createApp, createSpecializedApp, type CreateAppFeatureLoader, -} from './createApp'; +} from './createSpecializedApp'; +export * from './types'; diff --git a/packages/frontend-app-api/src/wiring/types.ts b/packages/frontend-app-api/src/wiring/types.ts new file mode 100644 index 0000000000..fb887534e3 --- /dev/null +++ b/packages/frontend-app-api/src/wiring/types.ts @@ -0,0 +1,24 @@ +/* + * 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 { FrontendModule, FrontendPlugin } from '@backstage/frontend-plugin-api'; + +/** @public */ +export type FrontendFeature = + | FrontendPlugin + | FrontendModule + // TODO(blam): This is just forwards backwards compatibility, remove after v1.31.0 + | { $$type: '@backstage/ExtensionOverrides' } + | { $$type: '@backstage/BackstagePlugin' }; diff --git a/packages/backend-tasks/.eslintrc.js b/packages/frontend-defaults/.eslintrc.js similarity index 100% rename from packages/backend-tasks/.eslintrc.js rename to packages/frontend-defaults/.eslintrc.js diff --git a/packages/frontend-defaults/CHANGELOG.md b/packages/frontend-defaults/CHANGELOG.md new file mode 100644 index 0000000000..79ea0d79eb --- /dev/null +++ b/packages/frontend-defaults/CHANGELOG.md @@ -0,0 +1,18 @@ +# @backstage/frontend-defaults + +## 0.1.0-next.0 + +### Minor Changes + +- 7c80650: Initial release of this package, which provides a default app setup through the `createApp` function. This replaces the existing `createApp` method from `@backstage/frontend-app-api`. + +### Patch Changes + +- 7d19cd5: Added a new `CreateAppOptions` type for the `createApp` options. +- 7d19cd5: Added `createPublicSignInApp`, used to creating apps for the public entry point. +- Updated dependencies + - @backstage/frontend-app-api@0.9.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/plugin-app@0.1.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 diff --git a/packages/frontend-defaults/README.md b/packages/frontend-defaults/README.md new file mode 100644 index 0000000000..2cca17ee85 --- /dev/null +++ b/packages/frontend-defaults/README.md @@ -0,0 +1,9 @@ +# @backstage/frontend-defaults + +**The [new frontend system](https://backstage.io/docs/frontend-system/) that this package is part of is in alpha, and we do not yet recommend using it for production deployments** + +This package provides the high-level APIs used to create Backstage frontend applications with the default setup. For more information, see the [documentation on how to build Backstage frontend applications](https://backstage.io/docs/frontend-system/building-apps/index). + +## Documentation + +- [Backstage Documentation](https://backstage.io/docs) diff --git a/packages/frontend-defaults/api-report.md b/packages/frontend-defaults/api-report.md new file mode 100644 index 0000000000..b99232b784 --- /dev/null +++ b/packages/frontend-defaults/api-report.md @@ -0,0 +1,43 @@ +## API Report File for "@backstage/frontend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ConfigApi } from '@backstage/frontend-plugin-api'; +import { CreateAppRouteBinder } from '@backstage/frontend-app-api'; +import { FrontendFeature } from '@backstage/frontend-app-api'; +import { JSX as JSX_2 } from 'react'; +import { default as React_2 } from 'react'; +import { ReactNode } from 'react'; + +// @public +export function createApp(options?: CreateAppOptions): { + createRoot(): JSX_2.Element; +}; + +// @public +export interface CreateAppFeatureLoader { + getLoaderName(): string; + load(options: { config: ConfigApi }): Promise<{ + features: FrontendFeature[]; + }>; +} + +// @public +export interface CreateAppOptions { + // (undocumented) + bindRoutes?(context: { bind: CreateAppRouteBinder }): void; + // (undocumented) + configLoader?: () => Promise<{ + config: ConfigApi; + }>; + // (undocumented) + features?: (FrontendFeature | CreateAppFeatureLoader)[]; + loadingComponent?: ReactNode; +} + +// @public +export function createPublicSignInApp(options?: CreateAppOptions): { + createRoot(): React_2.JSX.Element; +}; +``` diff --git a/packages/frontend-defaults/catalog-info.yaml b/packages/frontend-defaults/catalog-info.yaml new file mode 100644 index 0000000000..cd0ac9b79a --- /dev/null +++ b/packages/frontend-defaults/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-frontend-defaults + title: '@backstage/frontend-defaults' +spec: + lifecycle: experimental + type: backstage-web-library + owner: maintainers diff --git a/packages/frontend-defaults/package.json b/packages/frontend-defaults/package.json new file mode 100644 index 0000000000..7f00371525 --- /dev/null +++ b/packages/frontend-defaults/package.json @@ -0,0 +1,52 @@ +{ + "name": "@backstage/frontend-defaults", + "version": "0.1.0-next.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/frontend-defaults" + }, + "backstage": { + "role": "web-library" + }, + "sideEffects": false, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^15.0.0" + }, + "files": [ + "dist" + ], + "dependencies": { + "@backstage/config": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/frontend-app-api": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", + "@backstage/plugin-app": "workspace:^", + "@react-hookz/web": "^24.0.0", + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + } +} diff --git a/packages/frontend-app-api/src/wiring/createApp.test.tsx b/packages/frontend-defaults/src/createApp.test.tsx similarity index 68% rename from packages/frontend-app-api/src/wiring/createApp.test.tsx rename to packages/frontend-defaults/src/createApp.test.tsx index e29a3afe94..2890700653 100644 --- a/packages/frontend-app-api/src/wiring/createApp.test.tsx +++ b/packages/frontend-defaults/src/createApp.test.tsx @@ -19,16 +19,17 @@ import { appTreeApiRef, coreExtensionData, createExtension, - createExtensionOverrides, PageBlueprint, createFrontendPlugin, ThemeBlueprint, + createFrontendModule, } from '@backstage/frontend-plugin-api'; import { screen, waitFor } from '@testing-library/react'; import { CreateAppFeatureLoader, createApp } from './createApp'; import { MockConfigApi, renderWithEffects } from '@backstage/test-utils'; import React from 'react'; import { featureFlagsApiRef, useApi } from '@backstage/core-plugin-api'; +import appPlugin from '@backstage/plugin-app'; describe('createApp', () => { it('should allow themes to be installed', async () => { @@ -136,7 +137,7 @@ describe('createApp', () => { configLoader: async () => ({ config: new MockConfigApi({ key: 'config-value' }), }), - features: [loader], + features: [appPlugin, loader], }); await renderWithEffects(app.createRoot()); @@ -174,6 +175,13 @@ describe('createApp', () => { const app = createApp({ configLoader: async () => ({ config: new MockConfigApi({}) }), features: [ + appPlugin.withOverrides({ + extensions: [ + appPlugin + .getExtension('app/root') + .override({ disabled: true, factory: orig => orig() }), + ], + }), createFrontendPlugin({ id: 'test', featureFlags: [{ name: 'test-1' }], @@ -200,18 +208,10 @@ describe('createApp', () => { }), ], }), - createExtensionOverrides({ + createFrontendPlugin({ + id: 'other', featureFlags: [{ name: 'test-2' }], - extensions: [ - createExtension({ - namespace: 'app', - name: 'root', - attachTo: { id: 'app', input: 'root' }, - disabled: true, - output: [], - factory: () => [], - }), - ], + extensions: [], }), ], }); @@ -219,7 +219,7 @@ describe('createApp', () => { await renderWithEffects(app.createRoot()); await expect( - screen.findByText("Flags: test-1 from 'test', test-2 from ''"), + screen.findByText("Flags: test-1 from 'test', test-2 from 'other'"), ).resolves.toBeInTheDocument(); }); @@ -255,13 +255,53 @@ describe('createApp', () => { const { tree } = appTreeApi!.getTree(); expect(String(tree.root)).toMatchInlineSnapshot(` - " + " + apis [ + + + + + + + + + + + + + + + + + + + + + themes [ + + + ] + + + components [ + + + + ] + + + + + ] app [ root [ children [ + nav [ + + ] content [ routes [ @@ -269,9 +309,6 @@ describe('createApp', () => { ] ] - nav [ - - ] ] elements [ @@ -282,43 +319,6 @@ describe('createApp', () => { ] ] - apis [ - - themes [ - - - ] - - - - - - components [ - - - - ] - - - - - - - - - - - - - - - - - - - - - ] " `); }); @@ -354,4 +354,80 @@ describe('createApp', () => { expect(screen.queryByText('Custom loading message')).toBeNull(); }); + + it('should allow overriding the app plugin', async () => { + const app = createApp({ + configLoader: () => new Promise(() => {}), + features: [ + appPlugin.withOverrides({ + extensions: [ + appPlugin.getExtension('app/root').override({ + factory: () => [ + coreExtensionData.reactElement( +
Custom app root element
, + ), + ], + }), + ], + }), + ], + }); + + await renderWithEffects(app.createRoot()); + + expect(screen.queryByText('Custom app root element')).toBeNull(); + }); + + describe('modules', () => { + it('should be able to override extensions with a plugin extension override', async () => { + const mod = createFrontendModule({ + pluginId: 'app', + extensions: [ + appPlugin.getExtension('app/root').override({ + factory: () => [ + coreExtensionData.reactElement( +
Custom app root element
, + ), + ], + }), + ], + }); + + const app = createApp({ + configLoader: () => new Promise(() => {}), + features: [mod], + }); + + await renderWithEffects(app.createRoot()); + + expect(screen.queryByText('Custom app root element')).toBeNull(); + }); + + it('should be able to override extensions with a standalone extension override', async () => { + const mod = createFrontendModule({ + pluginId: 'app', + extensions: [ + createExtension({ + name: 'root', + attachTo: { id: 'app', input: 'root' }, + output: [coreExtensionData.reactElement], + factory: () => [ + coreExtensionData.reactElement( +
Custom app root element
, + ), + ], + }), + ], + }); + + const app = createApp({ + configLoader: () => new Promise(() => {}), + features: [mod], + }); + + await renderWithEffects(app.createRoot()); + + expect(screen.queryByText('Custom app root element')).toBeNull(); + }); + }); }); diff --git a/packages/frontend-defaults/src/createApp.tsx b/packages/frontend-defaults/src/createApp.tsx new file mode 100644 index 0000000000..79c9eb4a16 --- /dev/null +++ b/packages/frontend-defaults/src/createApp.tsx @@ -0,0 +1,129 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { JSX, ReactNode } from 'react'; +import { ConfigApi } from '@backstage/frontend-plugin-api'; +import { stringifyError } from '@backstage/errors'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { defaultConfigLoaderSync } from '../../core-app-api/src/app/defaultConfigLoader'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { overrideBaseUrlConfigs } from '../../core-app-api/src/app/overrideBaseUrlConfigs'; +import { getAvailableFeatures } from './discovery'; +import { ConfigReader } from '@backstage/config'; +import appPlugin from '@backstage/plugin-app'; +import { + CreateAppRouteBinder, + FrontendFeature, + createSpecializedApp, +} from '@backstage/frontend-app-api'; + +/** + * A source of dynamically loaded frontend features. + * + * @public + */ +export interface CreateAppFeatureLoader { + /** + * Returns name of this loader. suitable for showing to users. + */ + getLoaderName(): string; + + /** + * Loads a number of features dynamically. + */ + load(options: { config: ConfigApi }): Promise<{ + features: FrontendFeature[]; + }>; +} + +/** + * Options for {@link createApp}. + * + * @public + */ +export interface CreateAppOptions { + features?: (FrontendFeature | CreateAppFeatureLoader)[]; + configLoader?: () => Promise<{ config: ConfigApi }>; + bindRoutes?(context: { bind: CreateAppRouteBinder }): void; + /** + * The component to render while loading the app (waiting for config, features, etc) + * + * Is the text "Loading..." by default. + * If set to "null" then no loading fallback component is rendered. * + */ + loadingComponent?: ReactNode; +} + +/** + * Creates a new Backstage frontend app instance. See https://backstage.io/docs/frontend-system/building-apps/index + * + * @public + */ +export function createApp(options?: CreateAppOptions): { + createRoot(): JSX.Element; +} { + let suspenseFallback = options?.loadingComponent; + if (suspenseFallback === undefined) { + suspenseFallback = 'Loading...'; + } + + async function appLoader() { + const config = + (await options?.configLoader?.().then(c => c.config)) ?? + ConfigReader.fromConfigs( + overrideBaseUrlConfigs(defaultConfigLoaderSync()), + ); + + const discoveredFeatures = getAvailableFeatures(config); + + const providedFeatures: FrontendFeature[] = []; + for (const entry of options?.features ?? []) { + if ('load' in entry) { + try { + const result = await entry.load({ config }); + providedFeatures.push(...result.features); + } catch (e) { + throw new Error( + `Failed to read frontend features from loader '${entry.getLoaderName()}', ${stringifyError( + e, + )}`, + ); + } + } else { + providedFeatures.push(entry); + } + } + + const app = createSpecializedApp({ + config, + features: [appPlugin, ...discoveredFeatures, ...providedFeatures], + bindRoutes: options?.bindRoutes, + }).createRoot(); + + return { default: () => app }; + } + + return { + createRoot() { + const LazyApp = React.lazy(appLoader); + return ( + + + + ); + }, + }; +} diff --git a/packages/frontend-defaults/src/createPublicSignInApp.test.tsx b/packages/frontend-defaults/src/createPublicSignInApp.test.tsx new file mode 100644 index 0000000000..ac1adf9b0f --- /dev/null +++ b/packages/frontend-defaults/src/createPublicSignInApp.test.tsx @@ -0,0 +1,119 @@ +/* + * 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 { + IdentityApi, + SignInPageBlueprint, + createFrontendModule, +} from '@backstage/frontend-plugin-api'; +import { render, screen, waitFor } from '@testing-library/react'; +import React, { useEffect } from 'react'; +import { createPublicSignInApp } from './createPublicSignInApp'; +import { MockConfigApi } from '@backstage/test-utils'; + +describe('createPublicSignInApp', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('should render a sign-in page', async () => { + const app = createPublicSignInApp({ + configLoader: async () => ({ config: new MockConfigApi({}) }), + features: [ + createFrontendModule({ + pluginId: 'app', + extensions: [ + SignInPageBlueprint.make({ + params: { + loader: async () => () =>
Sign in page
, + }, + }), + ], + }), + ], + }); + + render(app.createRoot()); + + await expect( + screen.findByText('Sign in page'), + ).resolves.toBeInTheDocument(); + }); + + it('should render the form redirect on sign-in', async () => { + const submitSpy = jest + .spyOn(HTMLFormElement.prototype, 'submit') + .mockReturnValue(); + + const app = createPublicSignInApp({ + configLoader: async () => ({ config: new MockConfigApi({}) }), + features: [ + createFrontendModule({ + pluginId: 'app', + extensions: [ + SignInPageBlueprint.make({ + params: { + loader: + async () => + ({ onSignInSuccess }) => { + useEffect(() => { + onSignInSuccess({ + getCredentials: async () => ({ token: 'mock-token' }), + } as IdentityApi); + }, [onSignInSuccess]); + return
; + }, + }, + }), + ], + }), + ], + }); + + const { baseElement } = render(app.createRoot()); + + await waitFor(() => { + expect(submitSpy).toHaveBeenCalled(); + }); + + expect(baseElement).toMatchInlineSnapshot(` + +
+
+ + + + +
+ + `); + }); +}); diff --git a/packages/frontend-defaults/src/createPublicSignInApp.tsx b/packages/frontend-defaults/src/createPublicSignInApp.tsx new file mode 100644 index 0000000000..a8fd456c73 --- /dev/null +++ b/packages/frontend-defaults/src/createPublicSignInApp.tsx @@ -0,0 +1,108 @@ +/* + * 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 { + coreExtensionData, + createFrontendModule, + identityApiRef, + useApi, +} from '@backstage/frontend-plugin-api'; +import React from 'react'; +import { useAsync, useMountEffect } from '@react-hookz/web'; +import { CreateAppOptions, createApp } from './createApp'; +import appPlugin from '@backstage/plugin-app'; + +// This is a copy of the CookieAuthRedirect component from the auth-react +// plugin, to avoid a dependency on that package. Long-term we want this to be +// the only implementation and remove the one in auth-react once the old frontend system is gone. + +// TODO(Rugvip): Should this be part of the app plugin instead? since it owns the backend part of it. + +/** @internal */ +export function InternalCookieAuthRedirect() { + const identityApi = useApi(identityApiRef); + + const [state, actions] = useAsync(async () => { + const { token } = await identityApi.getCredentials(); + if (!token) { + throw new Error('Expected Backstage token in sign-in response'); + } + return token; + }); + + useMountEffect(actions.execute); + + if (state.status === 'error' && state.error) { + return <>An error occurred: {state.error.message}; + } + + if (state.status === 'success' && state.result) { + return ( +
form?.submit()} + action={window.location.href} + method="POST" + style={{ visibility: 'hidden' }} + > + + + + + ); + } + + 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 + */ +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(), + ], + }), + ], + }), + ], + }); +} diff --git a/packages/frontend-app-api/src/wiring/discovery.test.ts b/packages/frontend-defaults/src/discovery.test.ts similarity index 100% rename from packages/frontend-app-api/src/wiring/discovery.test.ts rename to packages/frontend-defaults/src/discovery.test.ts diff --git a/packages/frontend-app-api/src/wiring/discovery.ts b/packages/frontend-defaults/src/discovery.ts similarity index 89% rename from packages/frontend-app-api/src/wiring/discovery.ts rename to packages/frontend-defaults/src/discovery.ts index 4e50290350..e04960dc48 100644 --- a/packages/frontend-app-api/src/wiring/discovery.ts +++ b/packages/frontend-defaults/src/discovery.ts @@ -15,7 +15,7 @@ */ import { Config, ConfigReader } from '@backstage/config'; -import { FrontendFeature } from '@backstage/frontend-plugin-api'; +import { FrontendFeature } from '@backstage/frontend-app-api'; interface DiscoveryGlobal { modules: Array<{ name: string; export?: string; default: unknown }>; @@ -53,7 +53,7 @@ function readPackageDetectionConfig(config: Config) { } /** - * @public + * @internal */ export function getAvailableFeatures(config: Config): FrontendFeature[] { const discovered = ( @@ -84,6 +84,10 @@ export function getAvailableFeatures(config: Config): FrontendFeature[] { function isBackstageFeature(obj: unknown): obj is FrontendFeature { if (obj !== null && typeof obj === 'object' && '$$type' in obj) { return ( + obj.$$type === '@backstage/FrontendPlugin' || + obj.$$type === '@backstage/FrontendModule' || + // TODO: Remove this once the old plugin type and extension overrides + // are no longer supported obj.$$type === '@backstage/BackstagePlugin' || obj.$$type === '@backstage/ExtensionOverrides' ); diff --git a/packages/backend-tasks/src/deprecated.ts b/packages/frontend-defaults/src/index.ts similarity index 66% rename from packages/backend-tasks/src/deprecated.ts rename to packages/frontend-defaults/src/index.ts index 629e5f6d4d..7ee60a2116 100644 --- a/packages/backend-tasks/src/deprecated.ts +++ b/packages/frontend-defaults/src/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Backstage Authors + * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,15 @@ * limitations under the License. */ -import { HumanDuration as TypesHumanDuration } from '@backstage/types'; - /** - * Human friendly durations object. + * APIs for creating Backstage apps with a default setup. * - * @public - * @deprecated Import from `@backstage/types` instead + * @packageDocumentation */ -export type HumanDuration = TypesHumanDuration; -export * from './tasks'; +export { + createApp, + type CreateAppOptions, + type CreateAppFeatureLoader, +} from './createApp'; +export { createPublicSignInApp } from './createPublicSignInApp'; diff --git a/packages/frontend-defaults/src/setupTests.ts b/packages/frontend-defaults/src/setupTests.ts new file mode 100644 index 0000000000..91af6695ac --- /dev/null +++ b/packages/frontend-defaults/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '@testing-library/jest-dom'; diff --git a/packages/frontend-plugin-api/CHANGELOG.md b/packages/frontend-plugin-api/CHANGELOG.md index cce56f0855..e16c08ac7a 100644 --- a/packages/frontend-plugin-api/CHANGELOG.md +++ b/packages/frontend-plugin-api/CHANGELOG.md @@ -1,5 +1,111 @@ # @backstage/frontend-plugin-api +## 0.8.0-next.1 + +### Patch Changes + +- c816e2d: Added `createFrontendModule` as a replacement for `createExtensionOverrides`, which is now deprecated. + + Deprecated the `BackstagePlugin` and `FrontendFeature` type in favor of `FrontendPlugin` and `FrontendFeature` from `@backstage/frontend-app-api` respectively. + +- 52f9c5a: Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. + + You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. + + ```ts + // Before + createExtensionOverrides({ + extensions: [ + createExtension({ + name: 'my-extension', + namespace: 'my-namespace', + kind: 'test', + ... + }) + ], + }); + + // After + createFrontendModule({ + pluginId: 'my-namespace', + extensions: [ + createExtension({ + name: 'my-extension', + kind: 'test', + ... + }) + ], + }); + ``` + +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + +## 0.8.0-next.0 + +### Minor Changes + +- 5446061: **BREAKING**: Removed support for "v1" extensions. This means that it is no longer possible to declare inputs and outputs as objects when using `createExtension`. In addition, all extension creators except for `createComponentExtension` have been removed, use the equivalent blueprint instead. See the [1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations/#130) for more information on this change. +- fec8b57: **BREAKING**: Updated the type parameters for `ExtensionDefinition` and `ExtensionBlueprint` to only have a single object parameter. The base type parameter is exported as `ExtensionDefinitionParameters` and `ExtensionBlueprintParameters` respectively. This is shipped as an immediate breaking change as we expect usage of these types to be rare, and it does not affect the runtime behavior of the API. + + This is a breaking change as it changes the type parameters. Existing usage can generally be updated as follows: + + - `ExtensionDefinition` -> `ExtensionDefinition` + - `ExtensionDefinition` -> `ExtensionDefinition` + - `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig }>` + - `ExtensionDefinition` -> `ExtensionDefinition<{ config: TConfig, configInput: TConfigInput }>` + + If you need to infer the parameter you can use `ExtensionDefinitionParameters`, for example: + + ```ts + import { + ExtensionDefinition, + ExtensionDefinitionParameters, + } from '@backstage/frontend-plugin-api'; + + function myUtility( + ext: ExtensionDefinition, + ): T['config'] { + // ... + } + ``` + + The same patterns apply to `ExtensionBlueprint`. + + This change is made to improve the readability of API references and ability to evolve the type parameters in the future. + +### Patch Changes + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. +- f3a2b91: Moved several implementations of built-in APIs from being hardcoded in the app to instead be provided as API extensions. This moves all API-related inputs from the `app` extension to the respective API extensions. For example, extensions created with `ThemeBlueprint` are now attached to the `themes` input of `api:app-theme` rather than the `app` extension. +- 98850de: Added support for defining `replaces` in `createExtensionInput` which will allow extensions to redirect missing `attachTo` points to an input of the created extension. + + ```ts + export const AppThemeApi = ApiBlueprint.makeWithOverrides({ + name: 'app-theme', + inputs: { + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + // attachTo: { id: 'app', input: 'themes'} will be redirected to this input instead + replaces: [{ id: 'app', input: 'themes' }], + }), + }, + factory: () { + ... + } + }); + ``` + +- 4a66456: A new `apis` parameter has been added to `factory` for extensions. This is a way to access utility APIs without being coupled to the React context. +- Updated dependencies + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + ## 0.7.0 ### Minor Changes diff --git a/packages/frontend-plugin-api/api-report.md b/packages/frontend-plugin-api/api-report.md index c32d5b4edb..75d91d28f0 100644 --- a/packages/frontend-plugin-api/api-report.md +++ b/packages/frontend-plugin-api/api-report.md @@ -172,27 +172,25 @@ export type AnyRoutes = { }; // @public -export const ApiBlueprint: ExtensionBlueprint< - { - kind: 'api'; - namespace: undefined; - name: undefined; - }, - { +export const ApiBlueprint: ExtensionBlueprint<{ + kind: 'api'; + namespace: undefined; + name: undefined; + params: { factory: AnyApiFactory; - }, - ConfigurableExtensionDataRef, - {}, - {}, - {}, - { + }; + output: ConfigurableExtensionDataRef; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { factory: ConfigurableExtensionDataRef< AnyApiFactory, 'core.api.factory', {} >; - } ->; + }; +}>; export { ApiFactory }; @@ -246,43 +244,39 @@ export interface AppNodeSpec { } // @public -export const AppRootElementBlueprint: ExtensionBlueprint< - { - kind: 'app-root-element'; - namespace: undefined; - name: undefined; - }, - { +export const AppRootElementBlueprint: ExtensionBlueprint<{ + kind: 'app-root-element'; + namespace: undefined; + name: undefined; + params: { element: JSX.Element | (() => JSX.Element); - }, - ConfigurableExtensionDataRef, - {}, - {}, - {}, - never ->; + }; + output: ConfigurableExtensionDataRef; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: never; +}>; // @public -export const AppRootWrapperBlueprint: ExtensionBlueprint< - { - kind: 'app-root-wrapper'; - namespace: undefined; - name: undefined; - }, - { +export const AppRootWrapperBlueprint: ExtensionBlueprint<{ + kind: 'app-root-wrapper'; + namespace: undefined; + name: undefined; + params: { Component: ComponentType>; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< React_2.ComponentType<{ children?: React_2.ReactNode; }>, 'app.root.wrapper', {} - >, - {}, - {}, - {}, - { + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { component: ConfigurableExtensionDataRef< React_2.ComponentType<{ children?: React_2.ReactNode; @@ -290,8 +284,8 @@ export const AppRootWrapperBlueprint: ExtensionBlueprint< 'app.root.wrapper', {} >; - } ->; + }; +}>; export { AppTheme }; @@ -326,29 +320,14 @@ export { BackstageIdentityApi }; export { BackstageIdentityResponse }; -// @public (undocumented) -export interface BackstagePlugin< +// @public @deprecated (undocumented) +export type BackstagePlugin< TRoutes extends AnyRoutes = AnyRoutes, TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, TExtensionMap extends { - [id in string]: ExtensionDefinition; + [id in string]: ExtensionDefinition; } = {}, -> { - // (undocumented) - readonly $$type: '@backstage/BackstagePlugin'; - // (undocumented) - readonly externalRoutes: TExternalRoutes; - // (undocumented) - getExtension(id: TId): TExtensionMap[TId]; - // (undocumented) - readonly id: string; - // (undocumented) - readonly routes: TRoutes; - // (undocumented) - withOverrides(options: { - extensions: Array>; - }): BackstagePlugin; -} +> = FrontendPlugin; export { BackstageUserIdentity }; @@ -454,22 +433,18 @@ export function createComponentExtension(options: { | { sync: () => ComponentType; }; -}): ExtensionDefinition< - { - [x: string]: any; - }, - { - [x: string]: any; - }, - ConfigurableExtensionDataRef< +}): ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { ref: ComponentRef; impl: ComponentType; }, 'core.component.component', {} - >, - { + >; + inputs: { [x: string]: ExtensionInput< AnyExtensionDataRef, { @@ -477,13 +452,11 @@ export function createComponentExtension(options: { singleton: boolean; } >; - }, - { - kind: 'component'; - namespace: string; - name: string; - } ->; + }; + kind: 'component'; + namespace: undefined; + name: string; +}>; // @public (undocumented) export namespace createComponentExtension { @@ -504,6 +477,55 @@ export function createComponentRef(options: { }): ComponentRef; // @public (undocumented) +export function createExtension< + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }, + TConfigSchema extends { + [key: string]: (zImpl: typeof z) => z.ZodType; + }, + UFactoryOutput extends ExtensionDataValue, + const TKind extends string | undefined = undefined, + const TNamespace extends string | undefined = undefined, + const TName extends string | undefined = undefined, +>( + options: CreateExtensionOptions< + TKind, + undefined, + TName, + UOutput, + TInputs, + TConfigSchema, + UFactoryOutput + >, +): ExtensionDefinition<{ + config: string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer>; + }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + output: UOutput; + inputs: TInputs; + kind: string | undefined extends TKind ? undefined : TKind; + namespace: string | undefined extends TNamespace ? undefined : TNamespace; + name: string | undefined extends TName ? undefined : TName; +}>; + +// @public @deprecated (undocumented) export function createExtension< UOutput extends AnyExtensionDataRef, TInputs extends { @@ -532,27 +554,86 @@ export function createExtension< TConfigSchema, UFactoryOutput >, -): ExtensionDefinition< - { - [key in keyof TConfigSchema]: z.infer>; - }, - z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >, - UOutput, - TInputs, - { - kind: string | undefined extends TKind ? undefined : TKind; - namespace: string | undefined extends TNamespace ? undefined : TNamespace; - name: string | undefined extends TName ? undefined : TName; - } ->; +): ExtensionDefinition<{ + config: string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer>; + }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + output: UOutput; + inputs: TInputs; + kind: string | undefined extends TKind ? undefined : TKind; + namespace: string | undefined extends TNamespace ? undefined : TNamespace; + name: string | undefined extends TName ? undefined : TName; +}>; // @public export function createExtensionBlueprint< - TParams, + TParams extends object, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }, + TConfigSchema extends { + [key in string]: (zImpl: typeof z) => z.ZodType; + }, + UFactoryOutput extends ExtensionDataValue, + TKind extends string, + TNamespace extends undefined = undefined, + TName extends string | undefined = undefined, + TDataRefs extends { + [name in string]: AnyExtensionDataRef; + } = never, +>( + options: CreateExtensionBlueprintOptions< + TKind, + undefined, + TName, + TParams, + UOutput, + TInputs, + TConfigSchema, + UFactoryOutput, + TDataRefs + >, +): ExtensionBlueprint<{ + kind: TKind; + namespace: undefined; + name: TName; + params: TParams; + output: UOutput; + inputs: string extends keyof TInputs ? {} : TInputs; + config: string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer>; + }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + dataRefs: TDataRefs; +}>; + +// @public @deprecated (undocumented) +export function createExtensionBlueprint< + TParams extends object, UOutput extends AnyExtensionDataRef, TInputs extends { [inputName in string]: ExtensionInput< @@ -585,29 +666,27 @@ export function createExtensionBlueprint< UFactoryOutput, TDataRefs >, -): ExtensionBlueprint< - { - kind: TKind; - namespace: TNamespace; - name: TName; - }, - TParams, - UOutput, - string extends keyof TInputs ? {} : TInputs, - string extends keyof TConfigSchema +): ExtensionBlueprint<{ + kind: TKind; + namespace: TNamespace; + name: TName; + params: TParams; + output: UOutput; + inputs: string extends keyof TInputs ? {} : TInputs; + config: string extends keyof TConfigSchema ? {} : { [key in keyof TConfigSchema]: z.infer>; - }, - string extends keyof TConfigSchema + }; + configInput: string extends keyof TConfigSchema ? {} : z.input< z.ZodObject<{ [key in keyof TConfigSchema]: ReturnType; }> - >, - TDataRefs ->; + >; + dataRefs: TDataRefs; +}>; // @public (undocumented) export type CreateExtensionBlueprintOptions< @@ -687,7 +766,12 @@ export function createExtensionInput< }, >( extensionData: Array, - config?: TConfig, + config?: TConfig & { + replaces?: Array<{ + id: string; + input: string; + }>; + }, ): ExtensionInput< UExtensionData, { @@ -739,7 +823,7 @@ export type CreateExtensionOptions< }): Iterable; } & VerifyExtensionFactoryOutput; -// @public (undocumented) +// @public @deprecated (undocumented) export function createExtensionOverrides( options: ExtensionOverridesOptions, ): ExtensionOverrides; @@ -767,15 +851,34 @@ export function createExternalRouteRef< } >; +// @public (undocumented) +export function createFrontendModule< + TId extends string, + TExtensions extends readonly ExtensionDefinition[] = [], +>(options: CreateFrontendModuleOptions): FrontendModule; + +// @public (undocumented) +export interface CreateFrontendModuleOptions< + TPluginId extends string, + TExtensions extends readonly ExtensionDefinition[], +> { + // (undocumented) + extensions?: TExtensions; + // (undocumented) + featureFlags?: FeatureFlagConfig[]; + // (undocumented) + pluginId: TPluginId; +} + // @public (undocumented) export function createFrontendPlugin< TId extends string, TRoutes extends AnyRoutes = {}, TExternalRoutes extends AnyExternalRoutes = {}, - TExtensions extends readonly ExtensionDefinition[] = [], + TExtensions extends readonly ExtensionDefinition[] = [], >( options: PluginOptions, -): BackstagePlugin< +): FrontendPlugin< TRoutes, TExternalRoutes, { @@ -855,35 +958,33 @@ export interface Extension { // @public (undocumented) export interface ExtensionBlueprint< - TIdParts extends { - kind: string; - namespace?: string; - name?: string; - }, - TParams, - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; - }, - TConfig extends { - [key in string]: unknown; - }, - TConfigInput extends { - [key in string]: unknown; - }, - TDataRefs extends { - [name in string]: AnyExtensionDataRef; - }, + T extends ExtensionBlueprintParameters = ExtensionBlueprintParameters, > { // (undocumented) - dataRefs: TDataRefs; + dataRefs: T['dataRefs']; // (undocumented) + make< + TNewNamespace extends string | undefined, + TNewName extends string | undefined, + >(args: { + namespace?: undefined; + name?: TNewName; + attachTo?: { + id: string; + input: string; + }; + disabled?: boolean; + params: T['params']; + }): ExtensionDefinition<{ + kind: T['kind']; + namespace: undefined; + name: string | undefined extends TNewName ? T['name'] : TNewName; + config: T['config']; + configInput: T['configInput']; + output: T['output']; + inputs: T['inputs']; + }>; + // @deprecated (undocumented) make< TNewNamespace extends string | undefined, TNewName extends string | undefined, @@ -895,20 +996,18 @@ export interface ExtensionBlueprint< input: string; }; disabled?: boolean; - params: TParams; - }): ExtensionDefinition< - TConfig, - TConfigInput, - UOutput, - TInputs, - { - kind: TIdParts['kind']; - namespace: string | undefined extends TNewNamespace - ? TIdParts['namespace'] - : TNewNamespace; - name: string | undefined extends TNewName ? TIdParts['name'] : TNewName; - } - >; + params: T['params']; + }): ExtensionDefinition<{ + kind: T['kind']; + namespace: string | undefined extends TNewNamespace + ? T['namespace'] + : TNewNamespace; + name: string | undefined extends TNewName ? T['name'] : TNewName; + config: T['config']; + configInput: T['configInput']; + output: T['output']; + inputs: T['inputs']; + }>; makeWithOverrides< TNewNamespace extends string | undefined, TNewName extends string | undefined, @@ -927,7 +1026,7 @@ export interface ExtensionBlueprint< >; }, >(args: { - namespace?: TNewNamespace; + namespace?: undefined; name?: TNewName; attachTo?: { id: string; @@ -935,65 +1034,184 @@ export interface ExtensionBlueprint< }; disabled?: boolean; inputs?: TExtraInputs & { - [KName in keyof TInputs]?: `Error: Input '${KName & + [KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`; }; output?: Array; config?: { schema: TExtensionConfigSchema & { - [KName in keyof TConfig]?: `Error: Config key '${KName & + [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`; }; }; factory( originalFactory: ( - params: TParams, + params: T['params'], context?: { - config?: TConfig; - inputs?: ResolveInputValueOverrides; + config?: T['config']; + inputs?: ResolveInputValueOverrides>; }, - ) => ExtensionDataContainer, + ) => ExtensionDataContainer>, context: { node: AppNode; apis: ApiHolder; - config: TConfig & { + config: T['config'] & { [key in keyof TExtensionConfigSchema]: z.infer< ReturnType >; }; - inputs: Expand>; + inputs: Expand>; }, ): Iterable & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, + AnyExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, UFactoryOutput >; - }): ExtensionDefinition< - { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType + }): ExtensionDefinition<{ + config: (string extends keyof TExtensionConfigSchema + ? {} + : { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }) & + T['config']; + configInput: (string extends keyof TExtensionConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + }> + >) & + T['configInput']; + output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + inputs: T['inputs'] & TExtraInputs; + kind: T['kind']; + namespace: undefined; + name: string | undefined extends TNewName ? T['name'] : TNewName; + }>; + // @deprecated (undocumented) + makeWithOverrides< + TNewNamespace extends string | undefined, + TNewName 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; + } >; - } & TConfig, - z.input< - z.ZodObject<{ - [key in keyof TExtensionConfigSchema]: ReturnType< - TExtensionConfigSchema[key] - >; - }> - > & - TConfigInput, - AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, - TInputs & TExtraInputs, - { - kind: TIdParts['kind']; - namespace: string | undefined extends TNewNamespace - ? TIdParts['namespace'] - : TNewNamespace; - name: string | undefined extends TNewName ? TIdParts['name'] : TNewName; - } - >; + }, + >(args: { + namespace: TNewNamespace; + name?: TNewName; + attachTo?: { + id: string; + input: string; + }; + disabled?: boolean; + inputs?: TExtraInputs & { + [KName in keyof T['inputs']]?: `Error: Input '${KName & + string}' is already defined in parent definition`; + }; + output?: Array; + config?: { + schema: TExtensionConfigSchema & { + [KName in keyof T['config']]?: `Error: Config key '${KName & + string}' is already defined in parent schema`; + }; + }; + factory( + originalFactory: ( + params: T['params'], + context?: { + config?: T['config']; + inputs?: ResolveInputValueOverrides>; + }, + ) => ExtensionDataContainer>, + context: { + node: AppNode; + apis: ApiHolder; + config: T['config'] & { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }; + inputs: Expand>; + }, + ): Iterable & + VerifyExtensionFactoryOutput< + AnyExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, + UFactoryOutput + >; + }): ExtensionDefinition<{ + config: (string extends keyof TExtensionConfigSchema + ? {} + : { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }) & + T['config']; + configInput: (string extends keyof TExtensionConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + }> + >) & + T['configInput']; + output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + inputs: T['inputs'] & TExtraInputs; + kind: T['kind']; + namespace: string | undefined extends TNewNamespace + ? T['namespace'] + : TNewNamespace; + name: string | undefined extends TNewName ? T['name'] : TNewName; + }>; } +// @public (undocumented) +export type ExtensionBlueprintParameters = { + kind: string; + namespace?: string; + name?: string; + params?: object; + 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; + }; +}; + // @public (undocumented) export function ExtensionBoundary( props: ExtensionBoundaryProps, @@ -1067,47 +1285,11 @@ export type ExtensionDataValue = { }; // @public (undocumented) -export interface ExtensionDefinition< - TConfig, - TConfigInput = TConfig, - UOutput extends AnyExtensionDataRef = AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { - optional: boolean; - singleton: boolean; - } - >; - } = {}, - TIdParts extends { - kind?: string; - namespace?: string; - name?: string; - } = { - kind?: string; - namespace?: string; - name?: string; - }, -> { - // (undocumented) +export type ExtensionDefinition< + T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters, +> = { $$type: '@backstage/ExtensionDefinition'; - // (undocumented) - readonly attachTo: { - id: string; - input: string; - }; - // (undocumented) - readonly configSchema?: PortableSchema; - // (undocumented) - readonly disabled: boolean; - // (undocumented) - readonly kind?: TIdParts['kind']; - // (undocumented) - readonly name?: TIdParts['name']; - // (undocumented) - readonly namespace?: TIdParts['namespace']; - // (undocumented) + readonly T: T; override< TExtensionConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType; @@ -1131,59 +1313,86 @@ export interface ExtensionDefinition< }; disabled?: boolean; inputs?: TExtraInputs & { - [KName in keyof TInputs]?: `Error: Input '${KName & + [KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`; }; output?: Array; config?: { schema: TExtensionConfigSchema & { - [KName in keyof TConfig]?: `Error: Config key '${KName & + [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`; }; }; factory( originalFactory: (context?: { - config?: TConfig; - inputs?: ResolveInputValueOverrides; - }) => ExtensionDataContainer, + config?: T['config']; + inputs?: ResolveInputValueOverrides>; + }) => ExtensionDataContainer>, context: { node: AppNode; apis: ApiHolder; - config: TConfig & { + config: T['config'] & { [key in keyof TExtensionConfigSchema]: z.infer< ReturnType >; }; - inputs: Expand>; + inputs: Expand>; }, ): Iterable; } & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, + AnyExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, UFactoryOutput >, - ): ExtensionDefinition< - { + ): ExtensionDefinition<{ + kind: T['kind']; + namespace: T['namespace']; + name: T['name']; + output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + inputs: T['inputs'] & TExtraInputs; + config: T['config'] & { [key in keyof TExtensionConfigSchema]: z.infer< ReturnType >; - } & TConfig, - z.input< - z.ZodObject<{ - [key in keyof TExtensionConfigSchema]: ReturnType< - TExtensionConfigSchema[key] - >; - }> - > & - TConfigInput, - AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, - TInputs & TExtraInputs, - TIdParts - >; -} + }; + configInput: T['configInput'] & + z.input< + z.ZodObject<{ + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + }> + >; + }>; +}; + +// @public (undocumented) +export type ExtensionDefinitionParameters = { + kind?: string; + namespace?: string; + name?: string; + configInput?: { + [K in string]: any; + }; + config?: { + [K in string]: any; + }; + output?: AnyExtensionDataRef; + inputs?: { + [KName in string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }; +}; // @public (undocumented) export interface ExtensionInput< - TExtensionData extends ExtensionDataRef< + UExtensionData extends ExtensionDataRef< unknown, string, { @@ -1200,7 +1409,12 @@ export interface ExtensionInput< // (undocumented) config: TConfig; // (undocumented) - extensionData: Array; + extensionData: Array; + // (undocumented) + replaces?: Array<{ + id: string; + input: string; + }>; } // @public (undocumented) @@ -1209,10 +1423,10 @@ export interface ExtensionOverrides { readonly $$type: '@backstage/ExtensionOverrides'; } -// @public (undocumented) +// @public @deprecated (undocumented) export interface ExtensionOverridesOptions { // (undocumented) - extensions: ExtensionDefinition[]; + extensions: ExtensionDefinition[]; // (undocumented) featureFlags?: FeatureFlagConfig[]; } @@ -1246,8 +1460,40 @@ export { FetchApi }; export { fetchApiRef }; +// @public @deprecated (undocumented) +export type FrontendFeature = FrontendPlugin | ExtensionOverrides; + // @public (undocumented) -export type FrontendFeature = BackstagePlugin | ExtensionOverrides; +export interface FrontendModule { + // (undocumented) + readonly $$type: '@backstage/FrontendModule'; + // (undocumented) + readonly pluginId: string; +} + +// @public (undocumented) +export interface FrontendPlugin< + TRoutes extends AnyRoutes = AnyRoutes, + TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, + TExtensionMap extends { + [id in string]: ExtensionDefinition; + } = {}, +> { + // (undocumented) + readonly $$type: '@backstage/FrontendPlugin'; + // (undocumented) + readonly externalRoutes: TExternalRoutes; + // (undocumented) + getExtension(id: TId): TExtensionMap[TId]; + // (undocumented) + readonly id: string; + // (undocumented) + readonly routes: TRoutes; + // (undocumented) + withOverrides(options: { + extensions: Array; + }): FrontendPlugin; +} export { githubAuthApiRef }; @@ -1256,34 +1502,32 @@ export { gitlabAuthApiRef }; export { googleAuthApiRef }; // @public (undocumented) -export const IconBundleBlueprint: ExtensionBlueprint< - { - kind: 'icon-bundle'; - namespace: 'app'; - name: undefined; - }, - { +export const IconBundleBlueprint: ExtensionBlueprint<{ + kind: 'icon-bundle'; + namespace: undefined; + name: undefined; + params: { icons: { [x: string]: IconComponent; }; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< { [x: string]: IconComponent; }, 'core.icons', {} - >, - {}, - { + >; + inputs: {}; + config: { icons: string; test: string; - }, - { + }; + configInput: { test: string; icons?: string | undefined; - }, - { + }; + dataRefs: { icons: ConfigurableExtensionDataRef< { [x: string]: IconComponent; @@ -1291,8 +1535,8 @@ export const IconBundleBlueprint: ExtensionBlueprint< 'core.icons', {} >; - } ->; + }; +}>; // @public export type IconComponent = ComponentType< @@ -1322,18 +1566,16 @@ export { identityApiRef }; export { microsoftAuthApiRef }; // @public -export const NavItemBlueprint: ExtensionBlueprint< - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - }, - { +export const NavItemBlueprint: ExtensionBlueprint<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + params: { title: string; icon: IconComponent_2; routeRef: RouteRef; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent_2; @@ -1341,11 +1583,11 @@ export const NavItemBlueprint: ExtensionBlueprint< }, 'core.nav-item.target', {} - >, - {}, - {}, - {}, - { + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { target: ConfigurableExtensionDataRef< { title: string; @@ -1355,32 +1597,30 @@ export const NavItemBlueprint: ExtensionBlueprint< 'core.nav-item.target', {} >; - } ->; + }; +}>; // @public -export const NavLogoBlueprint: ExtensionBlueprint< - { - kind: 'nav-logo'; - namespace: undefined; - name: undefined; - }, - { +export const NavLogoBlueprint: ExtensionBlueprint<{ + kind: 'nav-logo'; + namespace: undefined; + name: undefined; + params: { logoIcon: JSX.Element; logoFull: JSX.Element; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< { logoIcon?: JSX.Element | undefined; logoFull?: JSX.Element | undefined; }, 'core.nav-logo.logo-elements', {} - >, - {}, - {}, - {}, - { + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { logoElements: ConfigurableExtensionDataRef< { logoIcon?: JSX.Element | undefined; @@ -1389,8 +1629,8 @@ export const NavLogoBlueprint: ExtensionBlueprint< 'core.nav-logo.logo-elements', {} >; - } ->; + }; +}>; export { OAuthApi }; @@ -1411,35 +1651,34 @@ export { oneloginAuthApiRef }; export { OpenIdConnectApi }; // @public -export const PageBlueprint: ExtensionBlueprint< - { - kind: 'page'; - namespace: undefined; - name: undefined; - }, - { +export const PageBlueprint: ExtensionBlueprint<{ + kind: 'page'; + namespace: undefined; + name: undefined; + params: { defaultPath: string; loader: () => Promise; routeRef?: RouteRef | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - {}, - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: {}; + config: { path: string | undefined; - }, - { + }; + configInput: { path?: string | undefined; - }, - never ->; + }; + dataRefs: never; +}>; export { PendingOAuthRequest }; @@ -1448,7 +1687,7 @@ export interface PluginOptions< TId extends string, TRoutes extends AnyRoutes, TExternalRoutes extends AnyExternalRoutes, - TExtensions extends readonly ExtensionDefinition[], + TExtensions extends readonly ExtensionDefinition[], > { // (undocumented) extensions?: TExtensions; @@ -1569,26 +1808,24 @@ export type RouteFunc = ( ) => string; // @public (undocumented) -export const RouterBlueprint: ExtensionBlueprint< - { - kind: 'app-router-component'; - namespace: undefined; - name: undefined; - }, - { +export const RouterBlueprint: ExtensionBlueprint<{ + kind: 'app-router-component'; + namespace: undefined; + name: undefined; + params: { Component: ComponentType>; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< ComponentType<{ children?: ReactNode; }>, 'app.router.wrapper', {} - >, - {}, - {}, - {}, - { + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { component: ConfigurableExtensionDataRef< ComponentType<{ children?: ReactNode; @@ -1596,8 +1833,8 @@ export const RouterBlueprint: ExtensionBlueprint< 'app.router.wrapper', {} >; - } ->; + }; +}>; // @public export interface RouteRef< @@ -1634,31 +1871,29 @@ export { SessionApi }; export { SessionState }; // @public -export const SignInPageBlueprint: ExtensionBlueprint< - { - kind: 'sign-in-page'; - namespace: undefined; - name: undefined; - }, - { +export const SignInPageBlueprint: ExtensionBlueprint<{ + kind: 'sign-in-page'; + namespace: undefined; + name: undefined; + params: { loader: () => Promise>; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< React_2.ComponentType, 'core.sign-in-page.component', {} - >, - {}, - {}, - {}, - { + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { component: ConfigurableExtensionDataRef< React_2.ComponentType, 'core.sign-in-page.component', {} >; - } ->; + }; +}>; export { StorageApi }; @@ -1679,35 +1914,31 @@ export interface SubRouteRef< } // @public -export const ThemeBlueprint: ExtensionBlueprint< - { - kind: 'theme'; - namespace: 'app'; - name: undefined; - }, - { +export const ThemeBlueprint: ExtensionBlueprint<{ + kind: 'theme'; + namespace: undefined; + name: undefined; + params: { theme: AppTheme; - }, - ConfigurableExtensionDataRef, - {}, - {}, - {}, - { + }; + output: ConfigurableExtensionDataRef; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { theme: ConfigurableExtensionDataRef; - } ->; + }; +}>; // @public -export const TranslationBlueprint: ExtensionBlueprint< - { - kind: 'translation'; - namespace: undefined; - name: undefined; - }, - { +export const TranslationBlueprint: ExtensionBlueprint<{ + kind: 'translation'; + namespace: undefined; + name: undefined; + params: { resource: TranslationResource | TranslationMessages; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< | TranslationResource | TranslationMessages< string, @@ -1718,11 +1949,11 @@ export const TranslationBlueprint: ExtensionBlueprint< >, 'core.translation.translation', {} - >, - {}, - {}, - {}, - { + >; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: { translation: ConfigurableExtensionDataRef< | TranslationResource | TranslationMessages< @@ -1735,8 +1966,8 @@ export const TranslationBlueprint: ExtensionBlueprint< 'core.translation.translation', {} >; - } ->; + }; +}>; export { TranslationMessages }; diff --git a/packages/frontend-plugin-api/package.json b/packages/frontend-plugin-api/package.json index c76bae094e..55168aed65 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.7.0", + "version": "0.8.0-next.1", "backstage": { "role": "web-library" }, diff --git a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts index f937b556ed..519b7a4d1a 100644 --- a/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/ApiBlueprint.test.ts @@ -31,12 +31,13 @@ describe('ApiBlueprint', () => { params: { factory, }, - namespace: 'test', + name: 'test', }); expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "root", "input": "apis", @@ -46,8 +47,8 @@ describe('ApiBlueprint', () => { "factory": [Function], "inputs": {}, "kind": "api", - "name": undefined, - "namespace": "test", + "name": "test", + "namespace": undefined, "output": [ [Function], ], @@ -71,7 +72,7 @@ describe('ApiBlueprint', () => { inputs: { test: createExtensionInput([ApiBlueprint.dataRefs.factory]), }, - namespace: api.id, + name: api.id, factory(originalFactory, { config: _config, inputs: _inputs }) { return originalFactory({ factory: createApiFactory({ @@ -86,6 +87,7 @@ describe('ApiBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "root", "input": "apis", @@ -116,11 +118,12 @@ describe('ApiBlueprint', () => { "extensionData": [ [Function], ], + "replaces": undefined, }, }, "kind": "api", - "name": undefined, - "namespace": "test", + "name": "test", + "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.test.tsx index e76bed8155..0f4d0b2092 100644 --- a/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/AppRootElementBlueprint.test.tsx @@ -27,6 +27,7 @@ describe('AppRootElementBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "app/root", "input": "elements", diff --git a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx index 5cbb96fbbf..f9214121ce 100644 --- a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx @@ -16,14 +16,13 @@ import React from 'react'; import { AppRootWrapperBlueprint } from './AppRootWrapperBlueprint'; -import { createExtensionTester } from '@backstage/frontend-test-utils'; -import { PageBlueprint } from './PageBlueprint'; -import { waitFor } from '@testing-library/react'; +import { screen, waitFor } from '@testing-library/react'; import { coreExtensionData, createExtension, createExtensionInput, } from '../wiring'; +import { renderInTestApp } from '@backstage/frontend-test-utils'; describe('AppRootWrapperBlueprint', () => { it('should return an extension with sensible defaults', () => { @@ -36,6 +35,7 @@ describe('AppRootWrapperBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "app/root", "input": "wrappers", @@ -59,29 +59,19 @@ describe('AppRootWrapperBlueprint', () => { it('should render the simple component wrapper', async () => { const extension = AppRootWrapperBlueprint.make({ + name: 'test', params: { Component: () =>
Hello
, }, }); - const { getByText } = createExtensionTester( - PageBlueprint.make({ - params: { - defaultPath: '/', - loader: async () =>
, - }, - }), - ) - .add(extension) - .render(); + renderInTestApp(
, { extensions: [extension] }); - await waitFor(() => expect(getByText('Hello')).toBeInTheDocument()); + await waitFor(() => expect(screen.getByText('Hello')).toBeInTheDocument()); }); it('should render the complex component wrapper', async () => { const extension = AppRootWrapperBlueprint.makeWithOverrides({ - namespace: 'ns', - name: 'test', config: { schema: { name: z => z.string(), @@ -104,28 +94,30 @@ describe('AppRootWrapperBlueprint', () => { }, }); - const { getByText, getByTestId } = createExtensionTester( - PageBlueprint.make({ - params: { - defaultPath: '/', - loader: async () =>
Hi
, - }, - }), - ) - .add(extension, { config: { name: 'Robin' } }) - .add( + renderInTestApp(
, { + extensions: [ + extension, createExtension({ - attachTo: { id: 'app-root-wrapper:ns/test', input: 'children' }, + name: 'test-child', + attachTo: { id: 'app-root-wrapper:test', input: 'children' }, output: [coreExtensionData.reactElement], factory: () => [coreExtensionData.reactElement(
Its Me
)], }), - ) - .render(); + ], + config: { + app: { + extensions: [ + { + 'app-root-wrapper:test': { config: { name: 'Robin' } }, + }, + ], + }, + }, + }); await waitFor(() => { - expect(getByText('Hi')).toBeInTheDocument(); - expect(getByTestId('Robin-1')).toBeInTheDocument(); - expect(getByText('Its Me')).toBeInTheDocument(); + expect(screen.getByTestId('Robin-1')).toBeInTheDocument(); + expect(screen.getByText('Its Me')).toBeInTheDocument(); }); }); }); diff --git a/packages/frontend-plugin-api/src/blueprints/IconBundleBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/IconBundleBlueprint.ts index de2df761ff..51b3b6d633 100644 --- a/packages/frontend-plugin-api/src/blueprints/IconBundleBlueprint.ts +++ b/packages/frontend-plugin-api/src/blueprints/IconBundleBlueprint.ts @@ -24,8 +24,7 @@ const iconsDataRef = createExtensionDataRef<{ /** @public */ export const IconBundleBlueprint = createExtensionBlueprint({ kind: 'icon-bundle', - namespace: 'app', - attachTo: { id: 'api:icons', input: 'icons' }, + attachTo: { id: 'api:app/icons', input: 'icons' }, output: [iconsDataRef], config: { schema: { diff --git a/packages/frontend-plugin-api/src/blueprints/NavItemBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/NavItemBlueprint.test.tsx index daa21f88bb..ddde2ff47d 100644 --- a/packages/frontend-plugin-api/src/blueprints/NavItemBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/NavItemBlueprint.test.tsx @@ -33,6 +33,7 @@ describe('NavItemBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "app/nav", "input": "items", diff --git a/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx index 621dca72ba..a08dda1201 100644 --- a/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/NavLogoBlueprint.test.tsx @@ -30,6 +30,7 @@ describe('NavLogoBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "app/nav", "input": "logos", diff --git a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx index dedc5454bd..c586ed8c04 100644 --- a/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/PageBlueprint.test.tsx @@ -43,6 +43,7 @@ describe('PageBlueprint', () => { expect(myPage).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "app/routes", "input": "routes", @@ -103,7 +104,7 @@ describe('PageBlueprint', () => { expect(tester.get(coreExtensionData.routeRef)).toBe(mockRouteRef); - const { getByTestId } = tester.render(); + const { getByTestId } = renderInTestApp(tester.reactElement()); await waitFor(() => expect(getByTestId('test')).toBeInTheDocument()); }); diff --git a/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx index fe40aaa8d7..ab6bb1eb1f 100644 --- a/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx @@ -17,15 +17,12 @@ import React from 'react'; import { RouterBlueprint } from './RouterBlueprint'; import { MemoryRouter } from 'react-router-dom'; import { render, waitFor } from '@testing-library/react'; -import { createSpecializedApp } from '@backstage/frontend-app-api'; import { coreExtensionData, createExtension, createExtensionInput, - createExtensionOverrides, } from '../wiring'; -import { MockConfigApi } from '@backstage/test-utils'; -import { PageBlueprint } from './PageBlueprint'; +import { createExtensionTester } from '@backstage/frontend-test-utils'; describe('RouterBlueprint', () => { it('should return an extension when calling make with sensible defaults', () => { @@ -38,6 +35,7 @@ describe('RouterBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "app/root", "input": "router", @@ -61,7 +59,6 @@ describe('RouterBlueprint', () => { it('should work with simple options', async () => { const extension = RouterBlueprint.make({ - namespace: 'test', params: { Component: ({ children }) => ( @@ -71,24 +68,14 @@ describe('RouterBlueprint', () => { }, }); - const app = createSpecializedApp({ - features: [ - createExtensionOverrides({ - extensions: [ - extension, - PageBlueprint.make({ - namespace: 'test', - params: { - defaultPath: '/', - loader: async () =>
, - }, - }), - ], - }), - ], - }); + const tester = createExtensionTester(extension); + const Component = tester.get(RouterBlueprint.dataRefs.component); - const { getByTestId } = render(app.createRoot()); + const { getByTestId } = render( + +
+ , + ); await waitFor(() => { expect(getByTestId('test-contents')).toBeInTheDocument(); @@ -98,7 +85,6 @@ describe('RouterBlueprint', () => { it('should work with complex options and props', async () => { const extension = RouterBlueprint.makeWithOverrides({ - namespace: 'test', name: 'test', config: { schema: { @@ -123,44 +109,27 @@ describe('RouterBlueprint', () => { }, }); - const app = createSpecializedApp({ - features: [ - createExtensionOverrides({ - extensions: [ - extension, - createExtension({ - namespace: 'test', - attachTo: { - id: 'app-router-component:test/test', - input: 'children', - }, - output: [coreExtensionData.reactElement], - *factory() { - yield coreExtensionData.reactElement(
); - }, - }), - PageBlueprint.make({ - namespace: 'test', - params: { - defaultPath: '/', - loader: async () =>
, - }, - }), - ], - }), - ], - config: new MockConfigApi({ - app: { - extensions: [ - { - 'app-router-component:test/test': { config: { name: 'Robin' } }, - }, - ], + const tester = createExtensionTester(extension, { + config: { name: 'Robin' }, + }).add( + createExtension({ + attachTo: { + id: 'app-router-component:test', + input: 'children', + }, + output: [coreExtensionData.reactElement], + *factory() { + yield coreExtensionData.reactElement(
); }, }), - }); + ); + const Component = tester.get(RouterBlueprint.dataRefs.component); - const { getByTestId } = render(app.createRoot()); + const { getByTestId } = render( + +
+ , + ); await waitFor(() => { expect(getByTestId('test-contents')).toBeInTheDocument(); diff --git a/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.test.tsx index e6389da574..a85b5e6f39 100644 --- a/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/SignInPageBlueprint.test.tsx @@ -31,6 +31,7 @@ describe('SignInPageBlueprint', () => { ).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "app/root", "input": "signInPage", @@ -56,7 +57,6 @@ describe('SignInPageBlueprint', () => { const MockSignInPage = () =>
; const extension = SignInPageBlueprint.make({ - name: 'test', params: { loader: async () => () => }, }); diff --git a/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.test.ts index 75d342fdcb..89c2229fab 100644 --- a/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.test.ts @@ -31,8 +31,9 @@ describe('ThemeBlueprint', () => { .toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { - "id": "api:app-theme", + "id": "api:app/app-theme", "input": "themes", }, "configSchema": undefined, @@ -41,7 +42,7 @@ describe('ThemeBlueprint', () => { "inputs": {}, "kind": "theme", "name": "light", - "namespace": "app", + "namespace": undefined, "output": [ [Function], ], diff --git a/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.ts index c06078b122..323078bc4e 100644 --- a/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.ts +++ b/packages/frontend-plugin-api/src/blueprints/ThemeBlueprint.ts @@ -28,8 +28,7 @@ const themeDataRef = createExtensionDataRef().with({ */ export const ThemeBlueprint = createExtensionBlueprint({ kind: 'theme', - namespace: 'app', - attachTo: { id: 'api:app-theme', input: 'themes' }, + attachTo: { id: 'api:app/app-theme', input: 'themes' }, output: [themeDataRef], dataRefs: { theme: themeDataRef, diff --git a/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.test.ts b/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.test.ts index 65ef4f7ee0..6bccd68c53 100644 --- a/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.test.ts +++ b/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.test.ts @@ -46,8 +46,9 @@ describe('TranslationBlueprint', () => { ).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { - "id": "api:translations", + "id": "api:app/translations", "input": "translations", }, "configSchema": undefined, diff --git a/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.ts b/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.ts index ea7aa64713..dd4a9ddc09 100644 --- a/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.ts +++ b/packages/frontend-plugin-api/src/blueprints/TranslationBlueprint.ts @@ -28,7 +28,7 @@ const translationDataRef = createExtensionDataRef< */ export const TranslationBlueprint = createExtensionBlueprint({ kind: 'translation', - attachTo: { id: 'api:translations', input: 'translations' }, + attachTo: { id: 'api:app/translations', input: 'translations' }, output: [translationDataRef], dataRefs: { translation: translationDataRef, diff --git a/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx b/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx index 403d591db1..3e260f0c9b 100644 --- a/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx +++ b/packages/frontend-plugin-api/src/components/ExtensionBoundary.test.tsx @@ -23,14 +23,12 @@ import { } from '@backstage/test-utils'; import { ExtensionBoundary } from './ExtensionBoundary'; import { coreExtensionData, createExtension } from '../wiring'; -import { - analyticsApiRef, - createApiFactory, - useAnalytics, -} from '@backstage/core-plugin-api'; +import { analyticsApiRef, useAnalytics } from '@backstage/core-plugin-api'; import { createRouteRef } from '../routing'; -import { createExtensionTester } from '@backstage/frontend-test-utils'; -import { ApiBlueprint } from '../blueprints'; +import { + createExtensionTester, + renderInTestApp, +} from '@backstage/frontend-test-utils'; const wrapInBoundaryExtension = (element?: JSX.Element) => { const routeRef = createRouteRef(); @@ -60,7 +58,11 @@ describe('ExtensionBoundary', () => { const TextComponent = () => { return

{text}

; }; - createExtensionTester(wrapInBoundaryExtension()).render(); + renderInTestApp( + createExtensionTester( + wrapInBoundaryExtension(), + ).reactElement(), + ); await waitFor(() => expect(screen.getByText(text)).toBeInTheDocument()); }); @@ -70,9 +72,11 @@ describe('ExtensionBoundary', () => { throw new Error(errorMsg); }; const { error } = await withLogCollector(['error'], async () => { - createExtensionTester( - wrapInBoundaryExtension(), - ).render(); + renderInTestApp( + createExtensionTester( + wrapInBoundaryExtension(), + ).reactElement(), + ); await waitFor(() => expect(screen.getByText(errorMsg)).toBeInTheDocument(), ); @@ -99,13 +103,13 @@ describe('ExtensionBoundary', () => { return null; }; - createExtensionTester( - wrapInBoundaryExtension( - - - , - ), - ).render(); + renderInTestApp( + + {createExtensionTester( + wrapInBoundaryExtension(), + ).reactElement()} + , + ); await waitFor(() => { const event = analyticsApiMock @@ -122,8 +126,9 @@ describe('ExtensionBoundary', () => { }); }); - // TODO(Rugvip): It's annoying to test the inverse of this currently, because the extension tester overrides the subject to always output a path - it('should emit analytics events if routable', async () => { + // TODO(Rugvip): Need a way to be able to override APIs in the app to be able to test this properly + // eslint-disable-next-line jest/no-disabled-tests + it.skip('should emit analytics events if routable', async () => { const Emitter = () => { const analytics = useAnalytics(); useEffect(() => { @@ -134,16 +139,12 @@ describe('ExtensionBoundary', () => { const analyticsApiMock = new MockAnalyticsApi(); await act(async () => { - createExtensionTester(wrapInBoundaryExtension()) - .add( - ApiBlueprint.make({ - namespace: analyticsApiRef.id, - params: { - factory: createApiFactory(analyticsApiRef, analyticsApiMock), - }, - }), - ) - .render(); + renderInTestApp( + createExtensionTester( + wrapInBoundaryExtension(), + ).reactElement(), + // { apis: [[analyticsApiRef, analyticsApiMock]] }, + ); }); expect(analyticsApiMock.getEvents()).toEqual([ diff --git a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx index 35d003e99b..f561a73dc6 100644 --- a/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx +++ b/packages/frontend-plugin-api/src/extensions/createComponentExtension.tsx @@ -33,9 +33,8 @@ export function createComponentExtension(options: { }) { return createExtension({ kind: 'component', - namespace: options.ref.id, - name: options.name, - attachTo: { id: 'api:components', input: 'components' }, + name: options.name ?? options.ref.id, + attachTo: { id: 'api:app/components', input: 'components' }, disabled: options.disabled, output: [createComponentExtension.componentDataRef], factory() { diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts index 5853f28004..5e8aa1c57a 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.test.ts @@ -18,6 +18,7 @@ import { createExtensionTester } from '@backstage/frontend-test-utils'; import { createExtension } from './createExtension'; import { createExtensionDataRef } from './createExtensionDataRef'; import { createExtensionInput } from './createExtensionInput'; +import { PortableSchema } from '../schema'; const stringDataRef = createExtensionDataRef().with({ id: 'string' }); const numberDataRef = createExtensionDataRef().with({ id: 'number' }); @@ -30,7 +31,6 @@ function unused(..._any: any[]) {} describe('createExtension', () => { it('should create an extension with a simple output', () => { const baseConfig = { - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef], }; @@ -40,7 +40,7 @@ describe('createExtension', () => { return [stringDataRef('bar')]; }, }); - expect(extension).toMatchObject({ version: 'v2', namespace: 'test' }); + expect(extension).toMatchObject({ version: 'v2' }); // Member arrow function declaration createExtension({ @@ -160,7 +160,6 @@ describe('createExtension', () => { it('should create an extension with a some optional output', () => { const baseConfig = { - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef.optional()], }; @@ -168,7 +167,7 @@ describe('createExtension', () => { ...baseConfig, factory: () => [stringDataRef('bar')], }); - expect(extension).toMatchObject({ version: 'v2', namespace: 'test' }); + expect(extension).toMatchObject({ version: 'v2' }); createExtension({ ...baseConfig, @@ -205,7 +204,6 @@ describe('createExtension', () => { it('should create an extension with input', () => { const extension = createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, inputs: { mixed: createExtensionInput([stringDataRef, numberDataRef.optional()]), @@ -249,15 +247,14 @@ describe('createExtension', () => { return [stringDataRef('bar')]; }, }); - expect(extension).toMatchObject({ version: 'v2', namespace: 'test' }); + expect(extension).toMatchObject({ version: 'v2' }); expect(String(extension)).toBe( - 'ExtensionDefinition{namespace=test,attachTo=root@default}', + 'ExtensionDefinition{attachTo=root@default}', ); }); it('should create an extension with config', () => { const extension = createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, config: { schema: { @@ -283,13 +280,18 @@ describe('createExtension', () => { return [stringDataRef('bar')]; }, }); - expect(extension).toMatchObject({ version: 'v2', namespace: 'test' }); + expect(extension).toMatchObject({ version: 'v2' }); expect(String(extension)).toBe( - 'ExtensionDefinition{namespace=test,attachTo=root@default}', + 'ExtensionDefinition{attachTo=root@default}', ); expect( - extension.configSchema?.parse({ + ( + (extension as any).configSchema as PortableSchema< + (typeof extension.T)['config'], + (typeof extension.T)['configInput'] + > + )?.parse({ foo: 'x', bar: 'y', baz: 'z', @@ -302,7 +304,12 @@ describe('createExtension', () => { baz: 'z', }); expect( - extension.configSchema?.parse({ + ( + (extension as any).configSchema as PortableSchema< + (typeof extension.T)['config'], + (typeof extension.T)['configInput'] + > + )?.parse({ foo: 'x', }), ).toEqual({ @@ -319,7 +326,6 @@ describe('createExtension', () => { expect( // @ts-expect-error createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef], factory() { @@ -331,7 +337,6 @@ describe('createExtension', () => { expect( // @ts-expect-error createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef], factory() { @@ -343,7 +348,6 @@ describe('createExtension', () => { // Duplicate output, we won't attempt to handle this a compile time and instead error out at runtime expect( createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef], factory() { @@ -355,7 +359,6 @@ describe('createExtension', () => { expect( // @ts-expect-error createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef], factory() { @@ -366,7 +369,6 @@ describe('createExtension', () => { expect( createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef], factory() { @@ -377,7 +379,6 @@ describe('createExtension', () => { expect( createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef.optional()], factory() { @@ -388,7 +389,6 @@ describe('createExtension', () => { expect( createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef.optional()], factory() { @@ -402,7 +402,6 @@ describe('createExtension', () => { expect( // @ts-expect-error createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef], *factory() { @@ -414,7 +413,6 @@ describe('createExtension', () => { expect( // @ts-expect-error createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef], *factory() { @@ -426,7 +424,6 @@ describe('createExtension', () => { // Duplicate output, we won't attempt to handle this a compile time and instead error out at runtime expect( createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef], *factory() { @@ -439,7 +436,6 @@ describe('createExtension', () => { expect( // @ts-expect-error createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef], *factory() { @@ -451,7 +447,6 @@ describe('createExtension', () => { expect( createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef], *factory() { @@ -463,7 +458,6 @@ describe('createExtension', () => { expect( createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef.optional()], *factory() { @@ -475,7 +469,6 @@ describe('createExtension', () => { expect( createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef.optional()], *factory() { @@ -488,7 +481,6 @@ describe('createExtension', () => { it('should support new form of inputs', () => { expect( createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'default' }, inputs: { header: createExtensionInput([stringDataRef.optional()], { @@ -523,7 +515,6 @@ describe('createExtension', () => { describe('overrides', () => { it('should allow overriding of config and merging', () => { const testExtension = createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'blob' }, output: [stringDataRef], config: { @@ -552,7 +543,6 @@ describe('createExtension', () => { it('should allow overriding of outputs', () => { const testExtension = createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'blob' }, output: [stringDataRef], inputs: { @@ -592,7 +582,6 @@ describe('createExtension', () => { it('should allow overriding the factory function and calling the original factory', () => { const testExtension = createExtension({ - namespace: 'test', attachTo: { id: 'root', input: 'blob' }, output: [stringDataRef], config: { @@ -624,7 +613,6 @@ describe('createExtension', () => { it('should allow overriding the returned values from the parent factory', () => { const testExtension = createExtension({ kind: 'thing', - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef, numberDataRef], config: { @@ -655,7 +643,6 @@ describe('createExtension', () => { it('should work functionally with overrides', () => { const testExtension = createExtension({ kind: 'thing', - namespace: 'test', attachTo: { id: 'root', input: 'default' }, output: [stringDataRef], config: { diff --git a/packages/frontend-plugin-api/src/wiring/createExtension.ts b/packages/frontend-plugin-api/src/wiring/createExtension.ts index 9d1568dc2f..8c79758395 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtension.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtension.ts @@ -142,33 +142,27 @@ export type CreateExtensionOptions< } & VerifyExtensionFactoryOutput; /** @public */ -export interface ExtensionDefinition< - TConfig, - TConfigInput = TConfig, - UOutput extends AnyExtensionDataRef = AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< +export type ExtensionDefinitionParameters = { + kind?: string; + namespace?: string; + name?: string; + configInput?: { [K in string]: any }; + config?: { [K in string]: any }; + output?: AnyExtensionDataRef; + inputs?: { + [KName in string]: ExtensionInput< AnyExtensionDataRef, { optional: boolean; singleton: boolean } >; - } = {}, - TIdParts extends { - kind?: string; - namespace?: string; - name?: string; - } = { - kind?: string; - namespace?: string; - name?: string; - }, -> { + }; +}; + +/** @public */ +export type ExtensionDefinition< + T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters, +> = { $$type: '@backstage/ExtensionDefinition'; - readonly kind?: TIdParts['kind']; - readonly namespace?: TIdParts['namespace']; - readonly name?: TIdParts['name']; - readonly attachTo: { id: string; input: string }; - readonly disabled: boolean; - readonly configSchema?: PortableSchema; + readonly T: T; override< TExtensionConfigSchema extends { @@ -187,78 +181,71 @@ export interface ExtensionDefinition< attachTo?: { id: string; input: string }; disabled?: boolean; inputs?: TExtraInputs & { - [KName in keyof TInputs]?: `Error: Input '${KName & + [KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`; }; output?: Array; config?: { schema: TExtensionConfigSchema & { - [KName in keyof TConfig]?: `Error: Config key '${KName & + [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`; }; }; factory( originalFactory: (context?: { - config?: TConfig; - inputs?: ResolveInputValueOverrides; - }) => ExtensionDataContainer, + config?: T['config']; + inputs?: ResolveInputValueOverrides>; + }) => ExtensionDataContainer>, context: { node: AppNode; apis: ApiHolder; - config: TConfig & { + config: T['config'] & { [key in keyof TExtensionConfigSchema]: z.infer< ReturnType >; }; - inputs: Expand>; + inputs: Expand>; }, ): Iterable; } & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, + AnyExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, UFactoryOutput >, - ): ExtensionDefinition< - { + ): ExtensionDefinition<{ + kind: T['kind']; + namespace: T['namespace']; + name: T['name']; + output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + inputs: T['inputs'] & TExtraInputs; + config: T['config'] & { [key in keyof TExtensionConfigSchema]: z.infer< ReturnType >; - } & TConfig, - z.input< - z.ZodObject<{ - [key in keyof TExtensionConfigSchema]: ReturnType< - TExtensionConfigSchema[key] - >; - }> - > & - TConfigInput, - AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, - TInputs & TExtraInputs, - TIdParts - >; -} + }; + configInput: T['configInput'] & + z.input< + z.ZodObject<{ + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + }> + >; + }>; +}; /** @internal */ export type InternalExtensionDefinition< - TConfig, - TConfigInput = TConfig, - UOutput extends AnyExtensionDataRef = AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - } = {}, - TIdParts extends { - kind?: string; - namespace?: string; - name?: string; - } = { - kind?: string; - namespace?: string; - name?: string; - }, -> = ExtensionDefinition & - ( + T extends ExtensionDefinitionParameters = ExtensionDefinitionParameters, +> = ExtensionDefinition & { + readonly kind?: string; + readonly namespace?: string; + readonly name?: string; + readonly attachTo: { id: string; input: string }; + readonly disabled: boolean; + readonly configSchema?: PortableSchema; +} & ( | { readonly version: 'v1'; readonly inputs: { @@ -276,7 +263,7 @@ export type InternalExtensionDefinition< factory(context: { node: AppNode; apis: ApiHolder; - config: TConfig; + config: object; inputs: { [inputName in string]: unknown; }; @@ -296,7 +283,7 @@ export type InternalExtensionDefinition< factory(context: { node: AppNode; apis: ApiHolder; - config: TConfig; + config: object; inputs: ResolvedExtensionInputs<{ [inputName in string]: ExtensionInput< AnyExtensionDataRef, @@ -308,13 +295,10 @@ export type InternalExtensionDefinition< ); /** @internal */ -export function toInternalExtensionDefinition( - overrides: ExtensionDefinition, -): InternalExtensionDefinition { - const internal = overrides as InternalExtensionDefinition< - TConfig, - TConfigInput - >; +export function toInternalExtensionDefinition< + T extends ExtensionDefinitionParameters, +>(overrides: ExtensionDefinition): InternalExtensionDefinition { + const internal = overrides as InternalExtensionDefinition; if (internal.$$type !== '@backstage/ExtensionDefinition') { throw new Error( `Invalid extension definition instance, bad type '${internal.$$type}'`, @@ -330,6 +314,52 @@ export function toInternalExtensionDefinition( } /** @public */ +export function createExtension< + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, + UFactoryOutput extends ExtensionDataValue, + const TKind extends string | undefined = undefined, + const TNamespace extends string | undefined = undefined, + const TName extends string | undefined = undefined, +>( + options: CreateExtensionOptions< + TKind, + undefined, + TName, + UOutput, + TInputs, + TConfigSchema, + UFactoryOutput + >, +): ExtensionDefinition<{ + config: string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer>; + }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + output: UOutput; + inputs: TInputs; + kind: string | undefined extends TKind ? undefined : TKind; + namespace: string | undefined extends TNamespace ? undefined : TNamespace; + name: string | undefined extends TName ? undefined : TName; +}>; +/** + * @public + * @deprecated namespace is no longer required, you can safely remove this option and it will default to the `pluginId`. It will be removed in a future release. + */ export function createExtension< UOutput extends AnyExtensionDataRef, TInputs extends { @@ -353,23 +383,87 @@ export function createExtension< TConfigSchema, UFactoryOutput >, -): ExtensionDefinition< - { - [key in keyof TConfigSchema]: z.infer>; +): ExtensionDefinition<{ + config: string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer>; + }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + output: UOutput; + inputs: TInputs; + kind: string | undefined extends TKind ? undefined : TKind; + namespace: string | undefined extends TNamespace ? undefined : TNamespace; + name: string | undefined extends TName ? undefined : TName; +}>; +export function createExtension< + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; }, - z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> + TConfigSchema extends { [key: string]: (zImpl: typeof z) => z.ZodType }, + UFactoryOutput extends ExtensionDataValue, + const TKind extends string | undefined = undefined, + const TNamespace extends string | undefined = undefined, + const TName extends string | undefined = undefined, +>( + options: CreateExtensionOptions< + TKind, + TNamespace, + TName, + UOutput, + TInputs, + TConfigSchema, + UFactoryOutput >, - UOutput, - TInputs, - { +): ExtensionDefinition<{ + config: string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer>; + }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + output: UOutput; + inputs: TInputs; + kind: string | undefined extends TKind ? undefined : TKind; + namespace: string | undefined extends TNamespace ? undefined : TNamespace; + name: string | undefined extends TName ? undefined : TName; +}> { + type T = { + config: string extends keyof TConfigSchema + ? {} + : { + [key in keyof TConfigSchema]: z.infer>; + }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + output: UOutput; + inputs: TInputs; kind: string | undefined extends TKind ? undefined : TKind; namespace: string | undefined extends TNamespace ? undefined : TNamespace; name: string | undefined extends TName ? undefined : TName; - } -> { + }; + const schemaDeclaration = options.config?.schema; const configSchema = schemaDeclaration && @@ -384,6 +478,7 @@ export function createExtension< return { $$type: '@backstage/ExtensionDefinition', version: 'v2', + T: undefined as unknown as T, kind: options.kind, namespace: options.namespace, name: options.name, @@ -486,21 +581,5 @@ export function createExtension< }, }) as ExtensionDefinition; }, - } as InternalExtensionDefinition< - { - [key in keyof TConfigSchema]: z.infer>; - }, - z.input< - z.ZodObject<{ - [key in keyof TConfigSchema]: ReturnType; - }> - >, - UOutput, - TInputs, - { - kind: string | undefined extends TKind ? undefined : TKind; - namespace: string | undefined extends TNamespace ? undefined : TNamespace; - name: string | undefined extends TName ? undefined : TName; - } - >; + } as InternalExtensionDefinition; } diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx index f2f17079ca..fc77c63e97 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.test.tsx @@ -17,7 +17,10 @@ import React from 'react'; import { coreExtensionData } from './coreExtensionData'; import { createExtensionBlueprint } from './createExtensionBlueprint'; -import { createExtensionTester } from '@backstage/frontend-test-utils'; +import { + createExtensionTester, + renderInTestApp, +} from '@backstage/frontend-test-utils'; import { ExtensionDataValue, createExtensionDataRef, @@ -32,10 +35,7 @@ import { createExtensionDataContainer } from './createExtensionDataContainer'; function unused(..._any: any[]) {} -function factoryOutput( - ext: ExtensionDefinition, - inputs: unknown = undefined, -) { +function factoryOutput(ext: ExtensionDefinition, inputs: unknown = undefined) { const int = toInternalExtensionDefinition(ext); if (int.version !== 'v2') { throw new Error('Expected v2 extension'); @@ -80,7 +80,9 @@ describe('createExtensionBlueprint', () => { version: 'v2', }); - const { container } = createExtensionTester(extension).render(); + const { container } = renderInTestApp( + createExtensionTester(extension).reactElement(), + ); expect(container.querySelector('h1')).toHaveTextContent('Hello, world!'); }); @@ -120,7 +122,9 @@ describe('createExtensionBlueprint', () => { version: 'v2', }); - const { container } = createExtensionTester(extension).render(); + const { container } = renderInTestApp( + createExtensionTester(extension).reactElement(), + ); expect(container.querySelector('h1')).toHaveTextContent('Hello, world!'); }); @@ -145,7 +149,9 @@ describe('createExtensionBlueprint', () => { expect(extension).toBeDefined(); - const { container } = createExtensionTester(extension).render(); + const { container } = renderInTestApp( + createExtensionTester(extension).reactElement(), + ); expect(container.querySelector('h1')).toHaveTextContent('Hello, world!'); }); @@ -216,13 +222,15 @@ describe('createExtensionBlueprint', () => { expect.assertions(4); - createExtensionTester(extension, { - config: { - something: 'something new!', - text: 'Hello, world!', - defaulted: 'lolz', - }, - }).render(); + renderInTestApp( + createExtensionTester(extension, { + config: { + something: 'something new!', + text: 'Hello, world!', + defaulted: 'lolz', + }, + }).reactElement(), + ); }); it('should not allow overlapping config keys', () => { @@ -291,12 +299,14 @@ describe('createExtensionBlueprint', () => { expect.assertions(2); - createExtensionTester(extension, { - config: { - something: 'something new!', - defaulted: 'lolz', - }, - }).render(); + renderInTestApp( + createExtensionTester(extension, { + config: { + something: 'something new!', + defaulted: 'lolz', + }, + }).reactElement(), + ); }); it('should allow getting inputs properly', () => { diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts index 25eb55d21f..40d1284b15 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionBlueprint.ts @@ -81,29 +81,51 @@ export type CreateExtensionBlueprintOptions< dataRefs?: TDataRefs; } & VerifyExtensionFactoryOutput; +/** @public */ +export type ExtensionBlueprintParameters = { + kind: string; + namespace?: string; + name?: string; + params?: object; + 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 }; +}; + /** * @public */ export interface ExtensionBlueprint< - TIdParts extends { - kind: string; - namespace?: string; - name?: string; - }, - TParams, - UOutput extends AnyExtensionDataRef, - TInputs extends { - [inputName in string]: ExtensionInput< - AnyExtensionDataRef, - { optional: boolean; singleton: boolean } - >; - }, - TConfig extends { [key in string]: unknown }, - TConfigInput extends { [key in string]: unknown }, - TDataRefs extends { [name in string]: AnyExtensionDataRef }, + T extends ExtensionBlueprintParameters = ExtensionBlueprintParameters, > { - dataRefs: TDataRefs; + dataRefs: T['dataRefs']; + make< + TNewNamespace extends string | undefined, + TNewName extends string | undefined, + >(args: { + namespace?: undefined; + name?: TNewName; + attachTo?: { id: string; input: string }; + disabled?: boolean; + params: T['params']; + }): ExtensionDefinition<{ + kind: T['kind']; + namespace: undefined; + name: string | undefined extends TNewName ? T['name'] : TNewName; + config: T['config']; + configInput: T['configInput']; + output: T['output']; + inputs: T['inputs']; + }>; + /** @deprecated namespace is no longer required, you can safely remove this option and it will default to the `pluginId`. It will be removed in a future release. */ make< TNewNamespace extends string | undefined, TNewName extends string | undefined, @@ -112,20 +134,18 @@ export interface ExtensionBlueprint< name?: TNewName; attachTo?: { id: string; input: string }; disabled?: boolean; - params: TParams; - }): ExtensionDefinition< - TConfig, - TConfigInput, - UOutput, - TInputs, - { - kind: TIdParts['kind']; - namespace: string | undefined extends TNewNamespace - ? TIdParts['namespace'] - : TNewNamespace; - name: string | undefined extends TNewName ? TIdParts['name'] : TNewName; - } - >; + params: T['params']; + }): ExtensionDefinition<{ + kind: T['kind']; + namespace: string | undefined extends TNewNamespace + ? T['namespace'] + : TNewNamespace; + name: string | undefined extends TNewName ? T['name'] : TNewName; + config: T['config']; + configInput: T['configInput']; + output: T['output']; + inputs: T['inputs']; + }>; /** * Creates a new extension from the blueprint. @@ -148,68 +168,154 @@ export interface ExtensionBlueprint< >; }, >(args: { - namespace?: TNewNamespace; + namespace?: undefined; name?: TNewName; attachTo?: { id: string; input: string }; disabled?: boolean; inputs?: TExtraInputs & { - [KName in keyof TInputs]?: `Error: Input '${KName & + [KName in keyof T['inputs']]?: `Error: Input '${KName & string}' is already defined in parent definition`; }; output?: Array; config?: { schema: TExtensionConfigSchema & { - [KName in keyof TConfig]?: `Error: Config key '${KName & + [KName in keyof T['config']]?: `Error: Config key '${KName & string}' is already defined in parent schema`; }; }; factory( originalFactory: ( - params: TParams, + params: T['params'], context?: { - config?: TConfig; - inputs?: ResolveInputValueOverrides; + config?: T['config']; + inputs?: ResolveInputValueOverrides>; }, - ) => ExtensionDataContainer, + ) => ExtensionDataContainer>, context: { node: AppNode; apis: ApiHolder; - config: TConfig & { + config: T['config'] & { [key in keyof TExtensionConfigSchema]: z.infer< ReturnType >; }; - inputs: Expand>; + inputs: Expand>; }, ): Iterable & VerifyExtensionFactoryOutput< - AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, + AnyExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, UFactoryOutput >; - }): ExtensionDefinition< - { - [key in keyof TExtensionConfigSchema]: z.infer< - ReturnType + }): ExtensionDefinition<{ + config: (string extends keyof TExtensionConfigSchema + ? {} + : { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }) & + T['config']; + configInput: (string extends keyof TExtensionConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + }> + >) & + T['configInput']; + output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + inputs: T['inputs'] & TExtraInputs; + kind: T['kind']; + namespace: undefined; + name: string | undefined extends TNewName ? T['name'] : TNewName; + }>; + /** @deprecated namespace is no longer required, you can safely remove this option and it will default to the `pluginId`. It will be removed in a future release. */ + makeWithOverrides< + TNewNamespace extends string | undefined, + TNewName 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 } >; - } & TConfig, - z.input< - z.ZodObject<{ - [key in keyof TExtensionConfigSchema]: ReturnType< - TExtensionConfigSchema[key] - >; - }> - > & - TConfigInput, - AnyExtensionDataRef extends UNewOutput ? UOutput : UNewOutput, - TInputs & TExtraInputs, - { - kind: TIdParts['kind']; - namespace: string | undefined extends TNewNamespace - ? TIdParts['namespace'] - : TNewNamespace; - name: string | undefined extends TNewName ? TIdParts['name'] : TNewName; - } - >; + }, + >(args: { + namespace: TNewNamespace; + name?: TNewName; + attachTo?: { id: string; input: string }; + disabled?: boolean; + inputs?: TExtraInputs & { + [KName in keyof T['inputs']]?: `Error: Input '${KName & + string}' is already defined in parent definition`; + }; + output?: Array; + config?: { + schema: TExtensionConfigSchema & { + [KName in keyof T['config']]?: `Error: Config key '${KName & + string}' is already defined in parent schema`; + }; + }; + factory( + originalFactory: ( + params: T['params'], + context?: { + config?: T['config']; + inputs?: ResolveInputValueOverrides>; + }, + ) => ExtensionDataContainer>, + context: { + node: AppNode; + apis: ApiHolder; + config: T['config'] & { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }; + inputs: Expand>; + }, + ): Iterable & + VerifyExtensionFactoryOutput< + AnyExtensionDataRef extends UNewOutput + ? NonNullable + : UNewOutput, + UFactoryOutput + >; + }): ExtensionDefinition<{ + config: (string extends keyof TExtensionConfigSchema + ? {} + : { + [key in keyof TExtensionConfigSchema]: z.infer< + ReturnType + >; + }) & + T['config']; + configInput: (string extends keyof TExtensionConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TExtensionConfigSchema]: ReturnType< + TExtensionConfigSchema[key] + >; + }> + >) & + T['configInput']; + output: AnyExtensionDataRef extends UNewOutput ? T['output'] : UNewOutput; + inputs: T['inputs'] & TExtraInputs; + kind: T['kind']; + namespace: string | undefined extends TNewNamespace + ? T['namespace'] + : TNewNamespace; + name: string | undefined extends TNewName ? T['name'] : TNewName; + }>; } /** @@ -219,7 +325,57 @@ export interface ExtensionBlueprint< * @public */ export function createExtensionBlueprint< - TParams, + TParams extends object, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, + TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, + UFactoryOutput extends ExtensionDataValue, + TKind extends string, + TNamespace extends undefined = undefined, + TName extends string | undefined = undefined, + TDataRefs extends { [name in string]: AnyExtensionDataRef } = never, +>( + options: CreateExtensionBlueprintOptions< + TKind, + undefined, + TName, + TParams, + UOutput, + TInputs, + TConfigSchema, + UFactoryOutput, + TDataRefs + >, +): ExtensionBlueprint<{ + kind: TKind; + namespace: undefined; + name: TName; + params: TParams; + output: UOutput; + inputs: string extends keyof TInputs ? {} : TInputs; + config: string extends keyof TConfigSchema + ? {} + : { [key in keyof TConfigSchema]: z.infer> }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + dataRefs: TDataRefs; +}>; +/** + * @public + * @deprecated the namespace is no longer required, you can safely remove this option and it will default to the `pluginId`. It will be removed in a future release. + */ +export function createExtensionBlueprint< + TParams extends object, UOutput extends AnyExtensionDataRef, TInputs extends { [inputName in string]: ExtensionInput< @@ -245,27 +401,71 @@ export function createExtensionBlueprint< UFactoryOutput, TDataRefs >, -): ExtensionBlueprint< - { - kind: TKind; - namespace: TNamespace; - name: TName; - }, - TParams, - UOutput, - string extends keyof TInputs ? {} : TInputs, - string extends keyof TConfigSchema +): ExtensionBlueprint<{ + kind: TKind; + namespace: TNamespace; + name: TName; + params: TParams; + output: UOutput; + inputs: string extends keyof TInputs ? {} : TInputs; + config: string extends keyof TConfigSchema ? {} - : { [key in keyof TConfigSchema]: z.infer> }, - string extends keyof TConfigSchema + : { [key in keyof TConfigSchema]: z.infer> }; + configInput: string extends keyof TConfigSchema ? {} : z.input< z.ZodObject<{ [key in keyof TConfigSchema]: ReturnType; }> - >, - TDataRefs -> { + >; + dataRefs: TDataRefs; +}>; +export function createExtensionBlueprint< + TParams extends object, + UOutput extends AnyExtensionDataRef, + TInputs extends { + [inputName in string]: ExtensionInput< + AnyExtensionDataRef, + { optional: boolean; singleton: boolean } + >; + }, + TConfigSchema extends { [key in string]: (zImpl: typeof z) => z.ZodType }, + UFactoryOutput extends ExtensionDataValue, + TKind extends string, + TNamespace extends string | undefined = undefined, + TName extends string | undefined = undefined, + TDataRefs extends { [name in string]: AnyExtensionDataRef } = never, +>( + options: CreateExtensionBlueprintOptions< + TKind, + TNamespace, + TName, + TParams, + UOutput, + TInputs, + TConfigSchema, + UFactoryOutput, + TDataRefs + >, +): ExtensionBlueprint<{ + kind: TKind; + namespace: TNamespace; + name: TName; + params: TParams; + output: UOutput; + inputs: string extends keyof TInputs ? {} : TInputs; + config: string extends keyof TConfigSchema + ? {} + : { [key in keyof TConfigSchema]: z.infer> }; + configInput: string extends keyof TConfigSchema + ? {} + : z.input< + z.ZodObject<{ + [key in keyof TConfigSchema]: ReturnType; + }> + >; + dataRefs: TDataRefs; +}> { return { dataRefs: options.dataRefs, make(args) { @@ -282,7 +482,7 @@ export function createExtensionBlueprint< options.factory(args.params, ctx) as Iterable< ExtensionDataValue >, - }); + }) as ExtensionDefinition; }, makeWithOverrides(args) { return createExtension({ @@ -327,29 +527,27 @@ export function createExtensionBlueprint< }, ) as Iterable>; }, - }) as ExtensionDefinition; + }) as ExtensionDefinition; }, - } as ExtensionBlueprint< - { - kind: TKind; - namespace: TNamespace; - name: TName; - }, - TParams, - UOutput, - string extends keyof TInputs ? {} : TInputs, - string extends keyof TConfigSchema + } as ExtensionBlueprint<{ + kind: TKind; + namespace: TNamespace; + name: TName; + params: TParams; + output: UOutput; + inputs: string extends keyof TInputs ? {} : TInputs; + config: string extends keyof TConfigSchema ? {} : { [key in keyof TConfigSchema]: z.infer>; - }, - string extends keyof TConfigSchema + }; + configInput: string extends keyof TConfigSchema ? {} : z.input< z.ZodObject<{ [key in keyof TConfigSchema]: ReturnType; }> - >, - TDataRefs - >; + >; + dataRefs: TDataRefs; + }>; } diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts index 8d293fceb3..7209e6f647 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionInput.ts @@ -18,12 +18,13 @@ import { ExtensionDataRef } from './createExtensionDataRef'; /** @public */ export interface ExtensionInput< - TExtensionData extends ExtensionDataRef, + UExtensionData extends ExtensionDataRef, TConfig extends { singleton: boolean; optional: boolean }, > { $$type: '@backstage/ExtensionInput'; - extensionData: Array; + extensionData: Array; config: TConfig; + replaces?: Array<{ id: string; input: string }>; } /** @public */ @@ -32,7 +33,7 @@ export function createExtensionInput< TConfig extends { singleton?: boolean; optional?: boolean }, >( extensionData: Array, - config?: TConfig, + config?: TConfig & { replaces?: Array<{ id: string; input: string }> }, ): ExtensionInput< UExtensionData, { @@ -71,6 +72,7 @@ export function createExtensionInput< ? true : false, }, + replaces: config?.replaces, } as ExtensionInput< UExtensionData, { diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts index 2219f963ed..a3595fb168 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.test.ts @@ -65,6 +65,7 @@ describe('createExtensionOverrides', () => { "extensions": [ { "$$type": "@backstage/Extension", + "T": undefined, "attachTo": { "id": "app", "input": "apis", @@ -80,6 +81,7 @@ describe('createExtensionOverrides', () => { }, { "$$type": "@backstage/Extension", + "T": undefined, "attachTo": { "id": "app", "input": "apis", @@ -95,6 +97,7 @@ describe('createExtensionOverrides', () => { }, { "$$type": "@backstage/Extension", + "T": undefined, "attachTo": { "id": "app", "input": "apis", diff --git a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts index 75c43a36d2..887f9b8dab 100644 --- a/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts +++ b/packages/frontend-plugin-api/src/wiring/createExtensionOverrides.ts @@ -21,9 +21,12 @@ import { } from './resolveExtensionDefinition'; import { ExtensionOverrides, FeatureFlagConfig } from './types'; -/** @public */ +/** + * @deprecated Use {@link createFrontendModule} instead. + * @public + */ export interface ExtensionOverridesOptions { - extensions: ExtensionDefinition[]; + extensions: ExtensionDefinition[]; featureFlags?: FeatureFlagConfig[]; } @@ -34,7 +37,10 @@ export interface InternalExtensionOverrides extends ExtensionOverrides { readonly featureFlags: FeatureFlagConfig[]; } -/** @public */ +/** + * @deprecated Use {@link createFrontendModule} instead. + * @public + */ export function createExtensionOverrides( options: ExtensionOverridesOptions, ): ExtensionOverrides { diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendModule.test.ts b/packages/frontend-plugin-api/src/wiring/createFrontendModule.test.ts new file mode 100644 index 0000000000..d895f6de0f --- /dev/null +++ b/packages/frontend-plugin-api/src/wiring/createFrontendModule.test.ts @@ -0,0 +1,62 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createExtension } from './createExtension'; +import { createFrontendModule } from './createFrontendModule'; + +describe('createFrontendModule', () => { + it('should create a frontend module', () => { + expect( + createFrontendModule({ + pluginId: 'test', + extensions: [ + createExtension({ + kind: 'route', + name: 'test', + output: [], + attachTo: { id: 'ignored', input: 'ignored' }, + factory: () => [], + }), + ], + }), + ).toMatchInlineSnapshot(` + { + "$$type": "@backstage/FrontendModule", + "extensions": [ + { + "$$type": "@backstage/Extension", + "T": undefined, + "attachTo": { + "id": "ignored", + "input": "ignored", + }, + "configSchema": undefined, + "disabled": false, + "factory": [Function], + "id": "route:test/test", + "inputs": {}, + "output": [], + "toString": [Function], + "version": "v2", + }, + ], + "featureFlags": [], + "pluginId": "test", + "toString": [Function], + "version": "v1", + } + `); + }); +}); diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts b/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts new file mode 100644 index 0000000000..aacc34ccf0 --- /dev/null +++ b/packages/frontend-plugin-api/src/wiring/createFrontendModule.ts @@ -0,0 +1,127 @@ +/* + * 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 { + ExtensionDefinition, + InternalExtensionDefinition, + toInternalExtensionDefinition, +} from './createExtension'; +import { + Extension, + resolveExtensionDefinition, +} from './resolveExtensionDefinition'; +import { FeatureFlagConfig } from './types'; + +/** @public */ +export interface CreateFrontendModuleOptions< + TPluginId extends string, + TExtensions extends readonly ExtensionDefinition[], +> { + pluginId: TPluginId; + extensions?: TExtensions; + featureFlags?: FeatureFlagConfig[]; +} + +/** @public */ +export interface FrontendModule { + readonly $$type: '@backstage/FrontendModule'; + readonly pluginId: string; +} + +/** @internal */ +export interface InternalFrontendModule extends FrontendModule { + readonly version: 'v1'; + readonly extensions: Extension[]; + readonly featureFlags: FeatureFlagConfig[]; +} + +/** @public */ +export function createFrontendModule< + TId extends string, + TExtensions extends readonly ExtensionDefinition[] = [], +>(options: CreateFrontendModuleOptions): FrontendModule { + const { pluginId } = options; + + const extensions = new Array>(); + const extensionDefinitionsById = new Map< + string, + InternalExtensionDefinition + >(); + + for (const def of options.extensions ?? []) { + const internal = toInternalExtensionDefinition(def); + const ext = resolveExtensionDefinition(def, { namespace: pluginId }); + extensions.push(ext); + extensionDefinitionsById.set(ext.id, { + ...internal, + namespace: pluginId, + }); + } + + if (extensions.length !== extensionDefinitionsById.size) { + const extensionIds = extensions.map(e => e.id); + const duplicates = Array.from( + new Set( + extensionIds.filter((id, index) => extensionIds.indexOf(id) !== index), + ), + ); + // TODO(Rugvip): This could provide some more information about the kind + name of the extensions + throw new Error( + `Plugin '${pluginId}' provided duplicate extensions: ${duplicates.join( + ', ', + )}`, + ); + } + + return { + $$type: '@backstage/FrontendModule', + version: 'v1', + pluginId, + featureFlags: options.featureFlags ?? [], + extensions, + toString() { + return `Module{pluginId=${pluginId}}`; + }, + } as InternalFrontendModule; +} + +/** @internal */ +export function isInternalFrontendModule(opaque: { + $$type: string; +}): opaque is InternalFrontendModule { + if (opaque.$$type === '@backstage/FrontendModule') { + // Make sure we throw if invalid + toInternalFrontendModule(opaque as FrontendModule); + return true; + } + return false; +} + +/** @internal */ +export function toInternalFrontendModule( + plugin: FrontendModule, +): InternalFrontendModule { + const internal = plugin as InternalFrontendModule; + if (internal.$$type !== '@backstage/FrontendModule') { + throw new Error(`Invalid plugin instance, bad type '${internal.$$type}'`); + } + if (internal.version !== 'v1') { + throw new Error( + `Invalid plugin instance, bad version '${internal.version}'`, + ); + } + return internal; +} diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts index 3615ba29e5..c461d6fb20 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.test.ts @@ -17,14 +17,13 @@ import React from 'react'; import { createApp } from '@backstage/frontend-app-api'; import { screen } from '@testing-library/react'; -import { createFrontendPlugin } from './createFrontendPlugin'; +import { FrontendPlugin, createFrontendPlugin } from './createFrontendPlugin'; import { JsonObject } from '@backstage/types'; import { createExtension } from './createExtension'; import { createExtensionDataRef } from './createExtensionDataRef'; import { coreExtensionData } from './coreExtensionData'; import { MockConfigApi, renderWithEffects } from '@backstage/test-utils'; import { createExtensionInput } from './createExtensionInput'; -import { BackstagePlugin } from './types'; const nameExtensionDataRef = createExtensionDataRef().with({ id: 'name', @@ -123,11 +122,11 @@ function createTestAppRoot({ features, config = {}, }: { - features: BackstagePlugin[]; + features: FrontendPlugin[]; config: JsonObject; }) { return createApp({ - features, + features: [...features], configLoader: async () => ({ config: new MockConfigApi(config) }), }).createRoot(); } @@ -150,6 +149,7 @@ describe('createFrontendPlugin', () => { expect(plugin.getExtension('test/1')).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "test/output", "input": "names", @@ -281,6 +281,7 @@ describe('createFrontendPlugin', () => { expect(plugin.getExtension('test/1')).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "test/output", "input": "names", diff --git a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts index bab09c631e..03c843543d 100644 --- a/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts +++ b/packages/frontend-plugin-api/src/wiring/createFrontendPlugin.ts @@ -14,25 +14,49 @@ * limitations under the License. */ -import { ExtensionDefinition } from './createExtension'; +import { + ExtensionDefinition, + InternalExtensionDefinition, + toInternalExtensionDefinition, +} from './createExtension'; import { Extension, ResolveExtensionId, resolveExtensionDefinition, } from './resolveExtensionDefinition'; -import { - AnyExternalRoutes, - AnyRoutes, - BackstagePlugin, - FeatureFlagConfig, -} from './types'; +import { AnyExternalRoutes, AnyRoutes, FeatureFlagConfig } from './types'; +/** @public */ +export interface FrontendPlugin< + TRoutes extends AnyRoutes = AnyRoutes, + TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, + TExtensionMap extends { [id in string]: ExtensionDefinition } = {}, +> { + readonly $$type: '@backstage/FrontendPlugin'; + readonly id: string; + readonly routes: TRoutes; + readonly externalRoutes: TExternalRoutes; + getExtension(id: TId): TExtensionMap[TId]; + withOverrides(options: { + extensions: Array; + }): FrontendPlugin; +} + +/** + * @public + * @deprecated Use {@link FrontendPlugin} instead. + */ +export type BackstagePlugin< + TRoutes extends AnyRoutes = AnyRoutes, + TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, + TExtensionMap extends { [id in string]: ExtensionDefinition } = {}, +> = FrontendPlugin; /** @public */ export interface PluginOptions< TId extends string, TRoutes extends AnyRoutes, TExternalRoutes extends AnyExternalRoutes, - TExtensions extends readonly ExtensionDefinition[], + TExtensions extends readonly ExtensionDefinition[], > { id: TId; routes?: TRoutes; @@ -42,10 +66,10 @@ export interface PluginOptions< } /** @public */ -export interface InternalBackstagePlugin< +export interface InternalFrontendPlugin< TRoutes extends AnyRoutes = AnyRoutes, TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, -> extends BackstagePlugin { +> extends FrontendPlugin { readonly version: 'v1'; readonly extensions: Extension[]; readonly featureFlags: FeatureFlagConfig[]; @@ -56,10 +80,10 @@ export function createFrontendPlugin< TId extends string, TRoutes extends AnyRoutes = {}, TExternalRoutes extends AnyExternalRoutes = {}, - TExtensions extends readonly ExtensionDefinition[] = [], + TExtensions extends readonly ExtensionDefinition[] = [], >( options: PluginOptions, -): BackstagePlugin< +): FrontendPlugin< TRoutes, TExternalRoutes, { @@ -69,16 +93,20 @@ export function createFrontendPlugin< >]: KExtension; } > { - const extensions = new Array>(); + const extensions = new Array>(); const extensionDefinitionsById = new Map< string, - ExtensionDefinition + InternalExtensionDefinition >(); for (const def of options.extensions ?? []) { + const internal = toInternalExtensionDefinition(def); const ext = resolveExtensionDefinition(def, { namespace: options.id }); extensions.push(ext); - extensionDefinitionsById.set(ext.id, { ...def, namespace: options.id }); + extensionDefinitionsById.set(ext.id, { + ...internal, + namespace: options.id, + }); } if (extensions.length !== extensionDefinitionsById.size) { @@ -97,7 +125,7 @@ export function createFrontendPlugin< } return { - $$type: '@backstage/BackstagePlugin', + $$type: '@backstage/FrontendPlugin', version: 'v1', id: options.id, routes: options.routes ?? ({} as TRoutes), @@ -127,15 +155,33 @@ export function createFrontendPlugin< extensions: [...nonOverriddenExtensions, ...overrides.extensions], }); }, - } as InternalBackstagePlugin; + } as InternalFrontendPlugin; } /** @internal */ -export function toInternalBackstagePlugin( - plugin: BackstagePlugin, -): InternalBackstagePlugin { - const internal = plugin as InternalBackstagePlugin; - if (internal.$$type !== '@backstage/BackstagePlugin') { +export function isInternalFrontendPlugin(opaque: { + $$type: string; +}): opaque is InternalFrontendPlugin { + if ( + opaque.$$type === '@backstage/FrontendPlugin' || + opaque.$$type === '@backstage/BackstagePlugin' + ) { + // Make sure we throw if invalid + toInternalFrontendPlugin(opaque as FrontendPlugin); + return true; + } + return false; +} + +/** @internal */ +export function toInternalFrontendPlugin( + plugin: FrontendPlugin, +): InternalFrontendPlugin { + const internal = plugin as InternalFrontendPlugin; + if ( + internal.$$type !== '@backstage/FrontendPlugin' && + internal.$$type !== '@backstage/BackstagePlugin' + ) { throw new Error(`Invalid plugin instance, bad type '${internal.$$type}'`); } if (internal.version !== 'v1') { diff --git a/packages/frontend-plugin-api/src/wiring/index.ts b/packages/frontend-plugin-api/src/wiring/index.ts index 3862c0e178..f8ad362bac 100644 --- a/packages/frontend-plugin-api/src/wiring/index.ts +++ b/packages/frontend-plugin-api/src/wiring/index.ts @@ -18,6 +18,7 @@ export { coreExtensionData } from './coreExtensionData'; export { createExtension, type ExtensionDefinition, + type ExtensionDefinitionParameters, type CreateExtensionOptions, type ResolvedExtensionInput, type ResolvedExtensionInputs, @@ -38,8 +39,15 @@ export { export { createPlugin, createFrontendPlugin, + type FrontendPlugin, + type BackstagePlugin, type PluginOptions, } from './createFrontendPlugin'; +export { + createFrontendModule, + type FrontendModule, + type CreateFrontendModuleOptions, +} from './createFrontendModule'; export { createExtensionOverrides, type ExtensionOverridesOptions, @@ -48,7 +56,6 @@ export { type Extension } from './resolveExtensionDefinition'; export { type AnyRoutes, type AnyExternalRoutes, - type BackstagePlugin, type ExtensionOverrides, type FeatureFlagConfig, type FrontendFeature, @@ -56,6 +63,7 @@ export { export { type CreateExtensionBlueprintOptions, type ExtensionBlueprint, + type ExtensionBlueprintParameters, createExtensionBlueprint, } 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 3b43cd6518..09c7b9e9a9 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.test.ts @@ -23,10 +23,11 @@ import { describe('resolveExtensionDefinition', () => { const baseDef = { $$type: '@backstage/ExtensionDefinition', + T: undefined as any, version: 'v2', attachTo: { id: '', input: '' }, disabled: false, - override: () => ({} as ExtensionDefinition), + override: () => ({} as ExtensionDefinition), }; it.each([ @@ -39,7 +40,7 @@ describe('resolveExtensionDefinition', () => { const resolved = resolveExtensionDefinition({ ...baseDef, ...definition, - } as ExtensionDefinition); + } as ExtensionDefinition); expect(resolved.id).toBe(expected); expect(String(resolved)).toBe(`Extension{id=${expected}}`); }); @@ -49,12 +50,12 @@ describe('resolveExtensionDefinition', () => { resolveExtensionDefinition({ ...baseDef, kind: 'k', - } as ExtensionDefinition), + } as ExtensionDefinition), ).toThrow( 'Extension must declare an explicit namespace or name as it could not be resolved from context, kind=k namespace=undefined name=undefined', ); expect(() => - resolveExtensionDefinition(baseDef as ExtensionDefinition), + resolveExtensionDefinition(baseDef as ExtensionDefinition), ).toThrow( 'Extension must declare an explicit namespace or name as it could not be resolved from context, kind=undefined namespace=undefined name=undefined', ); @@ -64,10 +65,11 @@ describe('resolveExtensionDefinition', () => { describe('old resolveExtensionDefinition', () => { const baseDef = { $$type: '@backstage/ExtensionDefinition', + T: undefined as any, version: 'v1', attachTo: { id: '', input: '' }, disabled: false, - override: () => ({} as ExtensionDefinition), + override: () => ({} as ExtensionDefinition), }; it.each([ @@ -80,7 +82,7 @@ describe('old resolveExtensionDefinition', () => { const resolved = resolveExtensionDefinition({ ...baseDef, ...definition, - } as ExtensionDefinition); + } as ExtensionDefinition); expect(resolved.id).toBe(expected); expect(String(resolved)).toBe(`Extension{id=${expected}}`); }); @@ -90,12 +92,12 @@ describe('old resolveExtensionDefinition', () => { resolveExtensionDefinition({ ...baseDef, kind: 'k', - } as ExtensionDefinition), + } as ExtensionDefinition), ).toThrow( 'Extension must declare an explicit namespace or name as it could not be resolved from context, kind=k namespace=undefined name=undefined', ); expect(() => - resolveExtensionDefinition(baseDef as ExtensionDefinition), + resolveExtensionDefinition(baseDef as ExtensionDefinition), ).toThrow( 'Extension must declare an explicit namespace or name as it could not be resolved from context, kind=undefined namespace=undefined name=undefined', ); @@ -108,13 +110,12 @@ describe('ResolveExtensionId', () => { TKind extends string | undefined, TNamespace extends string | undefined, TName extends string | undefined, - > = ExtensionDefinition< - any, - any, - any, - any, - { kind: TKind; namespace: TNamespace; name: TName } - >; + > = ExtensionDefinition<{ + kind: TKind; + namespace: TNamespace; + name: TName; + output: any; + }>; const id1: 'k:ns' = {} as ResolveExtensionId< NamedExtension<'k', 'ns', undefined>, diff --git a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts index fe25164603..5a631819d7 100644 --- a/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts +++ b/packages/frontend-plugin-api/src/wiring/resolveExtensionDefinition.ts @@ -17,6 +17,7 @@ import { ApiHolder, AppNode } from '../apis'; import { ExtensionDefinition, + ExtensionDefinitionParameters, ResolvedExtensionInputs, toInternalExtensionDefinition, } from './createExtension'; @@ -109,19 +110,13 @@ export function toInternalExtension( /** @ignore */ export type ResolveExtensionId< - TExtension extends ExtensionDefinition, + TExtension extends ExtensionDefinition, TDefaultNamespace extends string | undefined, -> = TExtension extends ExtensionDefinition< - any, - any, - any, - any, - { - kind: infer IKind extends string | undefined; - namespace: infer INamespace extends string | undefined; - name: infer IName extends string | undefined; - } -> +> = TExtension extends ExtensionDefinition<{ + kind: infer IKind extends string | undefined; + namespace: infer INamespace extends string | undefined; + name: infer IName extends string | undefined; +}> ? [string | undefined] extends [IKind | INamespace | IName] ? never : ( @@ -140,10 +135,12 @@ export type ResolveExtensionId< : never; /** @internal */ -export function resolveExtensionDefinition( - definition: ExtensionDefinition, +export function resolveExtensionDefinition< + T extends ExtensionDefinitionParameters, +>( + definition: ExtensionDefinition, context?: { namespace?: string }, -): Extension { +): Extension { const internalDefinition = toInternalExtensionDefinition(definition); const { name, @@ -152,6 +149,7 @@ export function resolveExtensionDefinition( override: _skip2, ...rest } = internalDefinition; + const namespace = internalDefinition.namespace ?? context?.namespace; const namePart = @@ -172,5 +170,5 @@ export function resolveExtensionDefinition( toString() { return `Extension{id=${id}}`; }, - } as InternalExtension; + } as InternalExtension & Object; } diff --git a/packages/frontend-plugin-api/src/wiring/types.ts b/packages/frontend-plugin-api/src/wiring/types.ts index 4a7d972b37..b52bbf446c 100644 --- a/packages/frontend-plugin-api/src/wiring/types.ts +++ b/packages/frontend-plugin-api/src/wiring/types.ts @@ -16,6 +16,7 @@ import { ExternalRouteRef, RouteRef, SubRouteRef } from '../routing'; import { ExtensionDefinition } from './createExtension'; +import { FrontendPlugin } from './createFrontendPlugin'; /** * Feature flag configuration. @@ -35,31 +36,18 @@ export type AnyExternalRoutes = { [name in string]: ExternalRouteRef }; /** @public */ export type ExtensionMap< - TExtensionMap extends { [id in string]: ExtensionDefinition }, + TExtensionMap extends { [id in string]: ExtensionDefinition }, > = { get(id: TId): TExtensionMap[TId]; }; -/** @public */ -export interface BackstagePlugin< - TRoutes extends AnyRoutes = AnyRoutes, - TExternalRoutes extends AnyExternalRoutes = AnyExternalRoutes, - TExtensionMap extends { [id in string]: ExtensionDefinition } = {}, -> { - readonly $$type: '@backstage/BackstagePlugin'; - readonly id: string; - readonly routes: TRoutes; - readonly externalRoutes: TExternalRoutes; - getExtension(id: TId): TExtensionMap[TId]; - withOverrides(options: { - extensions: Array>; - }): BackstagePlugin; -} - /** @public */ export interface ExtensionOverrides { readonly $$type: '@backstage/ExtensionOverrides'; } -/** @public */ -export type FrontendFeature = BackstagePlugin | ExtensionOverrides; +/** + * @public + * @deprecated import from {@link @backstage/frontend-app-api#FrontendFeature} instead + */ +export type FrontendFeature = FrontendPlugin | ExtensionOverrides; diff --git a/packages/frontend-test-utils/CHANGELOG.md b/packages/frontend-test-utils/CHANGELOG.md index a35ec8203b..fdc40b60a8 100644 --- a/packages/frontend-test-utils/CHANGELOG.md +++ b/packages/frontend-test-utils/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/frontend-test-utils +## 0.2.0-next.1 + +### Patch Changes + +- 948d431: Removing deprecated `namespace` parameter in favour of `pluginId` instead +- Updated dependencies + - @backstage/frontend-app-api@0.9.0-next.1 + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/plugin-app@0.1.0-next.1 + - @backstage/config@1.2.0 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/types@1.1.1 + +## 0.2.0-next.0 + +### Minor Changes + +- 5446061: Removed support for testing "v1" extensions, where outputs are defined as an object rather than an array. +- e6e488c: **BREAKING**: The deprecated `.render()` method has been removed from the extension tester. + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 4a66456: Internal update to add support for passing an `ApiRegistry` when creating the node tree +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. +- f6d1874: Added the ability to provide additional `extensions` and `features` to `renderInTestApp` +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/frontend-app-api@0.9.0-next.0 + - @backstage/plugin-app@0.1.0-next.0 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.1.12 ### Patch Changes diff --git a/packages/frontend-test-utils/api-report.md b/packages/frontend-test-utils/api-report.md index 164c222d84..10b84b0981 100644 --- a/packages/frontend-test-utils/api-report.md +++ b/packages/frontend-test-utils/api-report.md @@ -13,6 +13,8 @@ import { AppNodeInstance } from '@backstage/frontend-plugin-api'; 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 { JsonObject } from '@backstage/types'; import { MockConfigApi } from '@backstage/test-utils'; import { MockErrorApi } from '@backstage/test-utils'; @@ -31,16 +33,12 @@ import { TestApiRegistry } from '@backstage/test-utils'; import { withLogCollector } from '@backstage/test-utils'; // @public (undocumented) -export function createExtensionTester< - TConfig, - TConfigInput, - UOutput extends AnyExtensionDataRef, ->( - subject: ExtensionDefinition, +export function createExtensionTester( + subject: ExtensionDefinition, options?: { - config?: TConfigInput; + config?: T['configInput']; }, -): ExtensionTester; +): ExtensionTester>; export { ErrorWithContext }; @@ -64,10 +62,10 @@ export class ExtensionQuery { // @public (undocumented) export class ExtensionTester { // (undocumented) - add( - extension: ExtensionDefinition, + add( + extension: ExtensionDefinition, options?: { - config?: TConfigInput; + config?: T['configInput']; }, ): ExtensionTester; // (undocumented) @@ -79,13 +77,11 @@ export class ExtensionTester { : IData : never; // (undocumented) - query( - extension: ExtensionDefinition, - ): ExtensionQuery; + query( + extension: ExtensionDefinition, + ): ExtensionQuery>; // (undocumented) reactElement(): JSX.Element; - // @deprecated (undocumented) - render(options?: { config?: JsonObject }): RenderResult; } // @public @@ -139,6 +135,8 @@ export type TestAppOptions = { [path: string]: RouteRef; }; config?: JsonObject; + extensions?: ExtensionDefinition[]; + features?: FrontendFeature[]; }; export { withLogCollector }; diff --git a/packages/frontend-test-utils/package.json b/packages/frontend-test-utils/package.json index 526e8b1713..988ce42822 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.1.12", + "version": "0.2.0-next.1", "backstage": { "role": "web-library" }, @@ -34,6 +34,7 @@ "@backstage/config": "workspace:^", "@backstage/frontend-app-api": "workspace:^", "@backstage/frontend-plugin-api": "workspace:^", + "@backstage/plugin-app": "workspace:^", "@backstage/test-utils": "workspace:^", "@backstage/types": "workspace:^" }, diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx index 9528562198..a6265ae3ac 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.test.tsx @@ -14,22 +14,13 @@ * limitations under the License. */ -import React, { useCallback } from 'react'; -import { Link } from 'react-router-dom'; -import { fireEvent, screen, waitFor } from '@testing-library/react'; +import React from 'react'; import { - ApiBlueprint, - analyticsApiRef, - configApiRef, coreExtensionData, - createApiFactory, createExtension, createExtensionDataRef, createExtensionInput, - useAnalytics, - useApi, } from '@backstage/frontend-plugin-api'; -import { MockAnalyticsApi } from '../apis'; import { createExtensionTester } from './createExtensionTester'; const stringDataRef = createExtensionDataRef().with({ @@ -37,209 +28,8 @@ const stringDataRef = createExtensionDataRef().with({ }); describe('createExtensionTester', () => { - const defaultDefinition = { - namespace: 'test', - attachTo: { id: 'ignored', input: 'ignored' }, - output: [coreExtensionData.reactElement], - factory: () => [coreExtensionData.reactElement(
test
)], - }; - - it('should render a simple extension', async () => { - const extension = createExtension(defaultDefinition); - const tester = createExtensionTester(extension); - tester.render(); - await expect(screen.findByText('test')).resolves.toBeInTheDocument(); - }); - - it('should render an extension even if disabled by default', async () => { - const extension = createExtension({ - ...defaultDefinition, - disabled: true, - }); - const tester = createExtensionTester(extension); - tester.render(); - await expect(screen.findByText('test')).resolves.toBeInTheDocument(); - }); - - it("should fail to render an extension that doesn't output a react element", async () => { - const extension = createExtension({ - ...defaultDefinition, - output: [coreExtensionData.routePath], - factory: () => [coreExtensionData.routePath('/foo')], - }); - const tester = createExtensionTester(extension); - expect(() => tester.render()).toThrowErrorMatchingInlineSnapshot( - `"Failed to instantiate extension 'app/routes', extension 'test' could not be attached because its output data ('core.routing.path') does not match what the input 'routes' requires ('core.routing.path', 'core.reactElement')"`, - ); - }); - - it('should render multiple extensions', async () => { - const indexPageExtension = createExtension({ - ...defaultDefinition, - factory: () => [ - coreExtensionData.reactElement( -
- Index page See details -
, - ), - ], - }); - const detailsPageExtension = createExtension({ - ...defaultDefinition, - name: 'details', - attachTo: { id: 'app/routes', input: 'routes' }, - output: [coreExtensionData.routePath, coreExtensionData.reactElement], - factory: () => [ - coreExtensionData.routePath('/details'), - coreExtensionData.reactElement(
Details page
), - ], - }); - - const tester = createExtensionTester(indexPageExtension); - tester.add(detailsPageExtension); - tester.render(); - - await expect(screen.findByText('Index page')).resolves.toBeInTheDocument(); - - fireEvent.click(screen.getByRole('link', { name: 'See details' })); - - await expect( - screen.findByText('Details page'), - ).resolves.toBeInTheDocument(); - }); - - it('should accepts a custom config', async () => { - const indexPageExtension = createExtension({ - ...defaultDefinition, - config: { - schema: { - title: z => z.string().optional(), - }, - }, - factory: ({ config }) => { - const Component = () => { - const configApi = useApi(configApiRef); - const appTitle = configApi.getOptionalString('app.title'); - return ( -
-

{appTitle ?? 'Backstage app'}

-

{config.title ?? 'Index page'}

- See details -
- ); - }; - - return [coreExtensionData.reactElement()]; - }, - }); - - const detailsPageExtension = createExtension({ - ...defaultDefinition, - name: 'details', - attachTo: { id: 'app/routes', input: 'routes' }, - config: { - schema: { - title: z => z.string().optional(), - }, - }, - output: [coreExtensionData.routePath, coreExtensionData.reactElement], - factory: ({ config }) => [ - coreExtensionData.routePath('/details'), - coreExtensionData.reactElement( -
{config.title ?? 'Details page'}
, - ), - ], - }); - - const tester = createExtensionTester(indexPageExtension, { - config: { title: 'Custom index' }, - }); - - tester.add(detailsPageExtension, { - config: { title: 'Custom details' }, - }); - - tester.render({ - config: { - app: { - title: 'Custom app', - }, - }, - }); - - await expect( - screen.findByRole('heading', { name: 'Custom app' }), - ).resolves.toBeInTheDocument(); - - await expect( - screen.findByRole('heading', { name: 'Custom index' }), - ).resolves.toBeInTheDocument(); - - fireEvent.click(screen.getByRole('link', { name: 'See details' })); - - await expect( - screen.findByText('Custom details'), - ).resolves.toBeInTheDocument(); - }); - - it('should capture click events in analytics', async () => { - // Mocking the analytics api implementation - const analyticsApiMock = new MockAnalyticsApi(); - - const analyticsApiOverride = ApiBlueprint.make({ - params: { - factory: createApiFactory({ - api: analyticsApiRef, - deps: {}, - factory: () => analyticsApiMock, - }), - }, - }); - - const indexPageExtension = createExtension({ - ...defaultDefinition, - factory: () => { - const Component = () => { - const analyticsApi = useAnalytics(); - const handleClick = useCallback(() => { - analyticsApi.captureEvent('click', 'See details'); - }, [analyticsApi]); - return ( -
- Index Page - -
- ); - }; - - return [coreExtensionData.reactElement()]; - }, - }); - - const tester = createExtensionTester(indexPageExtension); - - // Overriding the analytics api extension - tester.add(analyticsApiOverride); - - tester.render(); - - fireEvent.click(await screen.findByRole('button', { name: 'See details' })); - - await waitFor(() => - expect(analyticsApiMock.getEvents()).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - action: 'click', - subject: 'See details', - }), - ]), - ), - ); - }); - it('should return the correct dataRef when called', () => { const extension = createExtension({ - namespace: 'test', attachTo: { id: 'ignored', input: 'ignored' }, output: [stringDataRef], factory: () => [stringDataRef('test-text')], @@ -252,7 +42,6 @@ describe('createExtensionTester', () => { it('should throw an error if trying to access an instance not provided to the tester', () => { const extension = createExtension({ - namespace: 'test', name: 'e1', attachTo: { id: 'ignored', input: 'ignored' }, output: [stringDataRef], @@ -260,7 +49,6 @@ describe('createExtensionTester', () => { }); const extension2 = createExtension({ - namespace: 'test', name: 'e2', attachTo: { id: 'ignored', input: 'ignored' }, output: [stringDataRef], @@ -270,13 +58,12 @@ describe('createExtensionTester', () => { const tester = createExtensionTester(extension); expect(() => tester.query(extension2)).toThrow( - "Extension with ID 'test/e2' not found, please make sure it's added to the tester", + "Extension with ID 'e2' not found, please make sure it's added to the tester", ); }); it('should throw an error if trying to access an instance which is not part of the tree', () => { const extension = createExtension({ - namespace: 'test', name: 'e1', attachTo: { id: 'ignored', input: 'ignored' }, output: [stringDataRef], @@ -284,7 +71,6 @@ describe('createExtensionTester', () => { }); const extension2 = createExtension({ - namespace: 'test', name: 'e2', attachTo: { id: 'ignored', input: 'ignored' }, output: [stringDataRef], @@ -294,7 +80,7 @@ describe('createExtensionTester', () => { const tester = createExtensionTester(extension).add(extension2); expect(() => tester.query(extension2)).toThrow( - "Extension with ID 'test/e2' has not been instantiated, because it is not part of the test subject's extension tree", + "Extension with ID 'e2' has not been instantiated, because it is not part of the test subject's extension tree", ); }); @@ -308,7 +94,6 @@ describe('createExtensionTester', () => { }); const extension = createExtension({ - namespace: 'test', name: 'e1', attachTo: { id: 'ignored', input: 'ignored' }, output: [stringDataRef, internalRef.optional()], @@ -338,7 +123,6 @@ describe('createExtensionTester', () => { }); const extension = createExtension({ - namespace: 'test', name: 'e1', inputs: { ignored: createExtensionInput([stringDataRef]), @@ -349,9 +133,8 @@ describe('createExtensionTester', () => { }); const extraExtension = createExtension({ - namespace: 'test', name: 'e2', - attachTo: { id: 'test/e1', input: 'ignored' }, + attachTo: { id: 'e1', input: 'ignored' }, output: [stringDataRef, internalRef.optional()], factory: () => [stringDataRef('test-text')], }); diff --git a/packages/frontend-test-utils/src/app/createExtensionTester.tsx b/packages/frontend-test-utils/src/app/createExtensionTester.tsx index 4db5c400a1..f9c1b3cb89 100644 --- a/packages/frontend-test-utils/src/app/createExtensionTester.tsx +++ b/packages/frontend-test-utils/src/app/createExtensionTester.tsx @@ -14,10 +14,6 @@ * limitations under the License. */ -import React from 'react'; -import { MemoryRouter, Link } from 'react-router-dom'; -import { RenderResult, render } from '@testing-library/react'; -import { createSpecializedApp } from '@backstage/frontend-app-api'; import { AnyExtensionDataRef, AppNode, @@ -25,15 +21,8 @@ import { Extension, ExtensionDataRef, ExtensionDefinition, - IconComponent, - NavItemBlueprint, - RouteRef, - RouterBlueprint, + ExtensionDefinitionParameters, coreExtensionData, - createExtension, - createExtensionInput, - createExtensionOverrides, - useRouteRef, } from '@backstage/frontend-plugin-api'; import { Config, ConfigReader } from '@backstage/config'; import { JsonArray, JsonObject, JsonValue } from '@backstage/types'; @@ -51,56 +40,6 @@ import { instantiateAppNodeTree } from '../../../frontend-app-api/src/tree/insta import { readAppExtensionsConfig } from '../../../frontend-app-api/src/tree/readAppExtensionsConfig'; import { TestApiRegistry } from '@backstage/test-utils'; -const NavItem = (props: { - routeRef: RouteRef; - title: string; - icon: IconComponent; -}) => { - const { routeRef, title, icon: Icon } = props; - const link = useRouteRef(routeRef); - if (!link) { - return null; - } - return ( -
  • - - {title} - -
  • - ); -}; - -const TestAppNavExtension = createExtension({ - namespace: 'app', - name: 'nav', - attachTo: { id: 'app/layout', input: 'nav' }, - inputs: { - items: createExtensionInput([NavItemBlueprint.dataRefs.target]), - }, - output: [coreExtensionData.reactElement], - factory({ inputs }) { - return [ - coreExtensionData.reactElement( - , - ), - ]; - }, -}); - /** @public */ export class ExtensionQuery { #node: AppNode; @@ -139,12 +78,12 @@ export class ExtensionQuery { /** @public */ export class ExtensionTester { /** @internal */ - static forSubject( - subject: ExtensionDefinition, - options?: { config?: TConfigInput }, - ): ExtensionTester { + static forSubject( + subject: ExtensionDefinition, + options?: { config?: T['configInput'] }, + ): ExtensionTester> { const tester = new ExtensionTester(); - tester.add(subject, options as TConfigInput & {}); + tester.add(subject, options as T['configInput'] & {}); return tester; } @@ -153,13 +92,13 @@ export class ExtensionTester { readonly #extensions = new Array<{ id: string; extension: Extension; - definition: ExtensionDefinition; + definition: ExtensionDefinition; config?: JsonValue; }>(); - add( - extension: ExtensionDefinition, - options?: { config?: TConfigInput }, + add( + extension: ExtensionDefinition, + options?: { config?: T['configInput'] }, ): ExtensionTester { if (this.#tree) { throw new Error( @@ -167,7 +106,7 @@ export class ExtensionTester { ); } - const { name, namespace } = extension; + const { name, namespace } = toInternalExtensionDefinition(extension); const definition = { ...extension, @@ -199,12 +138,18 @@ export class ExtensionTester { return new ExtensionQuery(tree.root).get(ref); } - query( - extension: ExtensionDefinition, - ): ExtensionQuery { + query( + extension: ExtensionDefinition, + ): ExtensionQuery> { const tree = this.#resolveTree(); - const actualId = resolveExtensionDefinition(extension).id; + // Same fallback logic as in .add + const { name, namespace } = toInternalExtensionDefinition(extension); + const definition = { + ...extension, + name: !namespace && !name ? 'test' : name, + }; + const actualId = resolveExtensionDefinition(definition).id; const node = tree.nodes.get(actualId); @@ -236,70 +181,6 @@ export class ExtensionTester { return element; } - /** - * @deprecated Switch to using `renderInTestApp` directly and using `.reactElement()` or `.get(...)` to get the component you w - */ - render(options?: { config?: JsonObject }): RenderResult { - const { config = {} } = options ?? {}; - - const [subject] = this.#extensions; - if (!subject) { - throw new Error( - 'No subject found. At least one extension should be added to the tester.', - ); - } - - const subjectInternal = toInternalExtensionDefinition(subject.definition); - let subjectOverride; - // attaching to app/routes to render as index route - if (subjectInternal.version === 'v1') { - throw new Error('The extension tester does not support v1 extensions'); - } else if (subjectInternal.version === 'v2') { - subjectOverride = createExtension({ - ...subjectInternal, - attachTo: { id: 'app/routes', input: 'routes' }, - output: subjectInternal.output.find( - ref => ref.id === coreExtensionData.routePath.id, - ) - ? subjectInternal.output - : [...subjectInternal.output, coreExtensionData.routePath], - factory: params => { - const parentOutput = Array.from( - subjectInternal.factory(params as any), - ).filter(val => val.id !== coreExtensionData.routePath.id); - - return [...parentOutput, coreExtensionData.routePath('/')]; - }, - }); - (subjectOverride as any).configSchema = subjectInternal.configSchema; - } else { - throw new Error('Unsupported extension version'); - } - - const app = createSpecializedApp({ - features: [ - createExtensionOverrides({ - extensions: [ - subjectOverride, - ...this.#extensions.slice(1).map(extension => extension.definition), - TestAppNavExtension, - RouterBlueprint.make({ - namespace: 'test', - params: { - Component: ({ children }) => ( - {children} - ), - }, - }), - ], - }), - ], - config: this.#getConfig(config), - }); - - return render(app.createRoot()); - } - #resolveTree() { if (this.#tree) { return this.#tree; @@ -360,13 +241,9 @@ export class ExtensionTester { } /** @public */ -export function createExtensionTester< - TConfig, - TConfigInput, - UOutput extends AnyExtensionDataRef, ->( - subject: ExtensionDefinition, - options?: { config?: TConfigInput }, -): ExtensionTester { +export function createExtensionTester( + subject: ExtensionDefinition, + options?: { config?: T['configInput'] }, +): ExtensionTester> { return ExtensionTester.forSubject(subject, options); } diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.tsx index 8bbe2d058c..e53566a118 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.tsx @@ -16,22 +16,25 @@ import React from 'react'; import { Link, MemoryRouter } from 'react-router-dom'; -import { createSpecializedApp } from '@backstage/frontend-app-api'; +import { + createSpecializedApp, + FrontendFeature, +} from '@backstage/frontend-app-api'; import { RenderResult, render } from '@testing-library/react'; import { ConfigReader } from '@backstage/config'; import { JsonObject } from '@backstage/types'; import { createExtension, - createExtensionOverrides, ExtensionDefinition, coreExtensionData, RouteRef, useRouteRef, - createExtensionInput, IconComponent, RouterBlueprint, NavItemBlueprint, + createFrontendPlugin, } from '@backstage/frontend-plugin-api'; +import appPlugin from '@backstage/plugin-app'; /** * Options to customize the behavior of the test app. @@ -60,6 +63,16 @@ export type TestAppOptions = { * 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[]; }; const NavItem = (props: { @@ -81,38 +94,36 @@ const NavItem = (props: { ); }; -export const TestAppNavExtension = createExtension({ - namespace: 'app', - name: 'nav', - attachTo: { id: 'app/layout', input: 'nav' }, - inputs: { - items: createExtensionInput([NavItemBlueprint.dataRefs.target]), - }, - output: [coreExtensionData.reactElement], - factory({ inputs }) { - return [ - coreExtensionData.reactElement( - , + ), + ]; + }, + }), + ], }); /** @@ -123,9 +134,8 @@ export function renderInTestApp( element: JSX.Element, options?: TestAppOptions, ): RenderResult { - const extensions: Array> = [ + const extensions: Array = [ createExtension({ - namespace: 'test', attachTo: { id: 'app/routes', input: 'routes' }, output: [coreExtensionData.reactElement, coreExtensionData.routePath], factory: () => { @@ -136,12 +146,10 @@ export function renderInTestApp( }, }), RouterBlueprint.make({ - namespace: 'test', params: { Component: ({ children }) => {children}, }, }), - TestAppNavExtension, ]; if (options?.mountedRoutes) { @@ -167,12 +175,24 @@ export function renderInTestApp( } } + if (options?.extensions) { + extensions.push(...options.extensions); + } + + const features: FrontendFeature[] = [ + createFrontendPlugin({ + id: 'test', + extensions, + }), + appPluginOverride, + ]; + + if (options?.features) { + features.push(...options.features); + } + const app = createSpecializedApp({ - features: [ - createExtensionOverrides({ - extensions, - }), - ], + features, config: ConfigReader.fromConfigs([ { context: 'render-config', data: options?.config ?? {} }, ]), diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md index cf4b380ad9..e9b67bb6c1 100644 --- a/packages/integration/api-report.md +++ b/packages/integration/api-report.md @@ -766,6 +766,18 @@ export function parseGiteaUrl( path: string; }; +// @public +export function parseGitilesUrlRef( + config: GerritIntegrationConfig, + url: string, +): { + project: string; + path: string; + ref: string; + refType: 'sha' | 'branch' | 'tag' | 'head'; + basePath: string; +}; + // @public export function parseHarnessUrl( config: HarnessIntegrationConfig, diff --git a/packages/integration/src/gerrit/GerritIntegration.test.ts b/packages/integration/src/gerrit/GerritIntegration.test.ts index 1878744f68..2cfc748550 100644 --- a/packages/integration/src/gerrit/GerritIntegration.test.ts +++ b/packages/integration/src/gerrit/GerritIntegration.test.ts @@ -83,11 +83,10 @@ describe('GerritIntegration', () => { }); describe('resolves with a relative url', () => { - it('works for valid urls', () => { - const integration = new GerritIntegration({ - host: 'gerrit-review.example.com', - } as any); - + const integration = new GerritIntegration({ + host: 'gerrit-review.example.com', + } as any); + it('works for valid urls pointing to a branch', () => { expect( integration.resolveUrl({ url: './skeleton', @@ -97,15 +96,24 @@ describe('GerritIntegration', () => { 'https://gerrit-review.example.com/gerrit/plugins/repo/+/refs/heads/master/skeleton', ); }); + it('works for urls pointing to a tag', () => { + expect( + integration.resolveUrl({ + url: './skeleton.yaml', + base: 'https://gerrit-review.example.com/gerrit/plugins/repo/+/refs/tags/v.1.2.3/src/template.yaml', + }), + ).toBe( + 'https://gerrit-review.example.com/gerrit/plugins/repo/+/refs/tags/v.1.2.3/src/skeleton.yaml', + ); + }); }); describe('resolves with an absolute url', () => { - it('works for valid urls', () => { - const integration = new GerritIntegration({ - host: 'gerrit-review.example.com', - gitilesBaseUrl: 'https://gerrit-review.example.com/gitiles', - } as any); - + const integration = new GerritIntegration({ + host: 'gerrit-review.example.com', + gitilesBaseUrl: 'https://gerrit-review.example.com/gitiles', + } as any); + it('works for valid urls pointing to a branch', () => { expect( integration.resolveUrl({ url: '/catalog-info.yaml', @@ -115,6 +123,16 @@ describe('GerritIntegration', () => { 'https://gerrit-review.example.com/gitiles/repo/+/refs/heads/master/catalog-info.yaml', ); }); + it('works for urls pointing to a tag', () => { + expect( + integration.resolveUrl({ + url: '/skeleton.yaml', + base: 'https://gerrit-review.example.com/gerrit/plugins/repo/+/refs/tags/v.1.2.3/src/template.yaml', + }), + ).toBe( + 'https://gerrit-review.example.com/gerrit/plugins/repo/+/refs/tags/v.1.2.3/skeleton.yaml', + ); + }); }); it('resolve edit URL', () => { diff --git a/packages/integration/src/gerrit/GerritIntegration.ts b/packages/integration/src/gerrit/GerritIntegration.ts index 6ea426e407..7e2e757c6b 100644 --- a/packages/integration/src/gerrit/GerritIntegration.ts +++ b/packages/integration/src/gerrit/GerritIntegration.ts @@ -20,7 +20,7 @@ import { GerritIntegrationConfig, readGerritIntegrationConfigs, } from './config'; -import { parseGerritGitilesUrl, buildGerritGitilesUrl } from './core'; +import { parseGitilesUrlRef } from './core'; /** * A Gerrit based integration. @@ -60,8 +60,8 @@ export class GerritIntegration implements ScmIntegration { const { url, base, lineNumber } = options; let updated; if (url.startsWith('/')) { - const { branch, project } = parseGerritGitilesUrl(this.config, base); - return buildGerritGitilesUrl(this.config, project, branch, url); + const { basePath } = parseGitilesUrlRef(this.config, base); + return basePath + url; } if (url) { updated = new URL(url, base); diff --git a/packages/integration/src/gerrit/core.test.ts b/packages/integration/src/gerrit/core.test.ts index 35632c654e..c031612c40 100644 --- a/packages/integration/src/gerrit/core.test.ts +++ b/packages/integration/src/gerrit/core.test.ts @@ -26,6 +26,7 @@ import { getGerritCloneRepoUrl, getGerritRequestOptions, parseGerritJsonResponse, + parseGitilesUrlRef, parseGerritGitilesUrl, getGerritFileContentsApiUrl, } from './core'; @@ -148,8 +149,129 @@ describe('gerrit core', () => { ).toBeUndefined(); }); }); - - describe('parseGitilesUrl', () => { + describe('parseGitilesUrlRef', () => { + const config: GerritIntegrationConfig = { + host: 'gerrit.com', + gitilesBaseUrl: 'https://gerrit.googlesource.com', + }; + it('can parse a gitiles urls that points to specific sha.', () => { + const gitUrl = parseGitilesUrlRef( + config, + 'https://gerrit.googlesource.com/modules/cached-refdb/+/157f862803d45b9d269f0e390f88aece1ded51e8/Jenkinsfile', + ); + expect(gitUrl).toEqual({ + basePath: + 'https://gerrit.googlesource.com/modules/cached-refdb/+/157f862803d45b9d269f0e390f88aece1ded51e8', + path: 'Jenkinsfile', + project: 'modules/cached-refdb', + ref: '157f862803d45b9d269f0e390f88aece1ded51e8', + refType: 'sha', + }); + }); + it('can parse gitiles urls that points to tags.', () => { + const gitUrl = parseGitilesUrlRef( + config, + 'https://gerrit.googlesource.com/modules/events-broker/+/refs/tags/v3.5.6/src/main/java/com/gerritforge/gerrit/eventbroker/BrokerApi.java', + ); + expect(gitUrl).toEqual({ + basePath: + 'https://gerrit.googlesource.com/modules/events-broker/+/refs/tags/v3.5.6', + path: 'src/main/java/com/gerritforge/gerrit/eventbroker/BrokerApi.java', + project: 'modules/events-broker', + ref: 'v3.5.6', + refType: 'tag', + }); + }); + it('can parse gitiles urls that points to HEAD.', () => { + const gitUrl = parseGitilesUrlRef( + config, + 'https://gerrit.googlesource.com/modules/events-broker/+/HEAD/src/main/java/com/gerritforge/gerrit/eventbroker/BrokerApi.java', + ); + expect(gitUrl).toEqual({ + basePath: + 'https://gerrit.googlesource.com/modules/events-broker/+/HEAD', + path: 'src/main/java/com/gerritforge/gerrit/eventbroker/BrokerApi.java', + project: 'modules/events-broker', + ref: 'HEAD', + refType: 'head', + }); + }); + it('can parse gitiles urls that points to HEAD without path.', () => { + const gitUrl = parseGitilesUrlRef( + config, + 'https://gerrit.googlesource.com/modules/events-broker/+/HEAD', + ); + expect(gitUrl).toEqual({ + basePath: + 'https://gerrit.googlesource.com/modules/events-broker/+/HEAD', + path: '/', + project: 'modules/events-broker', + ref: 'HEAD', + refType: 'head', + }); + }); + it('can parse gitiles urls that points to branches.', () => { + const gitUrl = parseGitilesUrlRef( + config, + 'https://gerrit.googlesource.com/modules/events-broker/+/refs/heads/master/src/main/java/com/gerritforge/gerrit/eventbroker/BrokerApiModule.java', + ); + expect(gitUrl).toEqual({ + basePath: + 'https://gerrit.googlesource.com/modules/events-broker/+/refs/heads/master', + path: 'src/main/java/com/gerritforge/gerrit/eventbroker/BrokerApiModule.java', + project: 'modules/events-broker', + ref: 'master', + refType: 'branch', + }); + }); + it('can parse gitiles urls that points directly to a branch without a path.', () => { + const gitUrl = parseGitilesUrlRef( + config, + 'https://gerrit.googlesource.com/modules/events-broker/+/refs/heads/master', + ); + expect(gitUrl).toEqual({ + basePath: + 'https://gerrit.googlesource.com/modules/events-broker/+/refs/heads/master', + path: '/', + project: 'modules/events-broker', + ref: 'master', + refType: 'branch', + }); + }); + it('can parse gitiles urls that points to the repo root.', () => { + const gitUrl = parseGitilesUrlRef( + config, + 'https://gerrit.googlesource.com/modules/events-broker/+/refs/heads/master/', + ); + expect(gitUrl).toEqual({ + basePath: + 'https://gerrit.googlesource.com/modules/events-broker/+/refs/heads/master', + path: '/', + project: 'modules/events-broker', + ref: 'master', + refType: 'branch', + }); + }); + it('can parse a valid authenticated gitiles url.', () => { + const gitilesConfig: GerritIntegrationConfig = { + host: 'gerrit.com', + gitilesBaseUrl: 'https://gerrit.com/gitiles', + }; + const gitUrl = parseGitilesUrlRef( + gitilesConfig, + 'https://gerrit.com/a/gitiles/web/project/+/refs/heads/master/README.md', + ); + expect(gitUrl).toEqual({ + basePath: + 'https://gerrit.com/a/gitiles/web/project/+/refs/heads/master', + path: 'README.md', + project: 'web/project', + ref: 'master', + refType: 'branch', + }); + }); + }); + describe('parseGerritGitilesUrl', () => { it('can parse a valid gitiles urls.', () => { const config: GerritIntegrationConfig = { host: 'gerrit.com', diff --git a/packages/integration/src/gerrit/core.ts b/packages/integration/src/gerrit/core.ts index b3bdbc30e4..e50ce97bbb 100644 --- a/packages/integration/src/gerrit/core.ts +++ b/packages/integration/src/gerrit/core.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { trimStart } from 'lodash'; +import { join, takeWhile, trimEnd, trimStart } from 'lodash'; import { GerritIntegrationConfig } from './config'; const GERRIT_BODY_PREFIX = ")]}'"; @@ -81,6 +81,112 @@ export function parseGerritGitilesUrl( }; } +/** + * Parses Gitiles urls and returns the following: + * + * - The project + * - The type of ref. I.e: branch name, SHA, HEAD or tag. + * - The file path from the repo root. + * - The base path as the path that points to the repo root. + * + * Supported types of gitiles urls that point to: + * + * - Branches + * - Tags + * - A commit SHA + * - HEAD + * + * @param config - A Gerrit provider config. + * @param url - An url to a file or folder in Gitiles. + * @public + */ +export function parseGitilesUrlRef( + config: GerritIntegrationConfig, + url: string, +): { + project: string; + path: string; + ref: string; + refType: 'sha' | 'branch' | 'tag' | 'head'; + basePath: string; +} { + const baseUrlParse = new URL(config.gitilesBaseUrl!); + const urlParse = new URL(url); + // Remove the gerrit authentication prefix '/a/' from the url + // In case of the gitilesBaseUrl is https://review.gerrit.com/plugins/gitiles + // and the url provided is https://review.gerrit.com/a/plugins/gitiles/... + // remove the prefix only if the pathname start with '/a/' + const urlPath = trimStart( + urlParse.pathname + .substring(urlParse.pathname.startsWith('/a/') ? 2 : 0) + .replace(baseUrlParse.pathname, ''), + '/', + ); + + // Find the project by taking everything up to "/+/". + const parts = urlPath.split('/').filter(p => !!p); + const projectParts = takeWhile(parts, p => p !== '+'); + if (projectParts.length === 0) { + throw new Error(`Unable to parse gitiles url: ${url}`); + } + // Also remove the "+" after the project. + const rest = parts.slice(projectParts.length + 1); + const project = join(projectParts, '/'); + + // match /+/HEAD/ + if (rest.length > 0 && rest[0] === 'HEAD') { + const ref = rest.shift()!; + const path = join(rest, '/'); + return { + project, + ref, + refType: 'head' as const, + path: path || '/', + basePath: trimEnd(url.replace(path, ''), '/'), + }; + } + // match /+// + if (rest.length > 0 && rest[0].length === 40) { + const ref = rest.shift()!; + const path = join(rest, '/'); + return { + project, + ref, + refType: 'sha' as const, + path: path || '/', + basePath: trimEnd(url.replace(path, ''), '/'), + }; + } + const remainingPath = join(rest, '/'); + // Regexp for matching "refs/tags/" or "refs/heads//" + const refsRegexp = /^refs\/(?heads|tags)\/(?.*?)(\/|$)/; + const result = refsRegexp.exec(remainingPath); + if (result) { + const matchString = result[0]; + let refType; + const { refsReference, ref } = result.groups || {}; + const path = remainingPath.replace(matchString, ''); + switch (refsReference) { + case 'heads': + refType = 'branch' as const; + break; + case 'tags': + refType = 'tag' as const; + break; + default: + throw new Error(`Unable to parse gitiles url: ${url}`); + } + return { + project, + ref, + refType, + path: path || '/', + basePath: trimEnd(url.replace(path, ''), '/'), + }; + } + throw new Error(`Unable to parse gitiles : ${url}`); +} + /** * Build a Gerrit Gitiles url that targets a specific path. * diff --git a/packages/integration/src/gerrit/index.ts b/packages/integration/src/gerrit/index.ts index 6c6295f7a3..f2e5934c95 100644 --- a/packages/integration/src/gerrit/index.ts +++ b/packages/integration/src/gerrit/index.ts @@ -27,6 +27,7 @@ export { getGerritRequestOptions, parseGerritJsonResponse, parseGerritGitilesUrl, + parseGitilesUrlRef, } from './core'; export type { GerritIntegrationConfig } from './config'; diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index ffb51ea7a7..7ffae42333 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/repo-tools +## 0.9.7-next.1 + +### Patch Changes + +- 5c4aa2f: Updated dependency `@useoptic/openapi-utilities` to `^0.55.0`. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + +## 0.9.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/cli-common@0.1.14 + - @backstage/cli-node@0.2.7 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + ## 0.9.5 ### Patch Changes diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 77d0047e60..89b2f0f124 100644 --- a/packages/repo-tools/package.json +++ b/packages/repo-tools/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/repo-tools", "description": "CLI for Backstage repo tooling ", - "version": "0.9.5", + "version": "0.9.7-next.1", "publishConfig": { "access": "public" }, @@ -60,7 +60,7 @@ "@stoplight/spectral-rulesets": "^1.18.0", "@stoplight/spectral-runtime": "^1.1.2", "@stoplight/types": "^14.0.0", - "@useoptic/openapi-utilities": "^0.54.8", + "@useoptic/openapi-utilities": "^0.55.0", "chalk": "^4.0.0", "codeowners-utils": "^1.0.2", "command-exists": "^1.2.9", diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 3d0673f221..77a6e403bd 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,43 @@ # techdocs-cli-embedded-app +## 0.2.100-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.27.1-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/app-defaults@1.5.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/theme@0.5.6 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-techdocs@1.10.9-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + +## 0.2.100-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/plugin-techdocs@1.10.9-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/cli@0.27.1-next.0 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/app-defaults@1.5.10 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/theme@0.5.6 + ## 0.2.99 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index 64774310f8..83bc610762 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.99", + "version": "0.2.100-next.1", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 18b7b5150d..a7c62bd94b 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,27 @@ # @techdocs/cli +## 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 diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index b14369cfb9..64a6ebc772 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "1.8.17", + "version": "1.8.19-next.1", "publishConfig": { "access": "public" }, diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index ef2aa614e8..29d38987d7 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/test-utils +## 1.6.0-next.0 + +### Minor Changes + +- d47be30: Added the icons option to the renderInTestApp function's TestAppOptions to be forwarded to the icons option of `createApp`. + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.25 + ## 1.5.10 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 73089ddc54..16d1609c66 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/test-utils", - "version": "1.5.10", + "version": "1.6.0-next.0", "description": "Utilities to test Backstage plugins and apps.", "backstage": { "role": "web-library" diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index 211f073321..f75835f0a6 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-api-docs +## 0.11.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/core-plugin-api@1.9.3 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + +## 0.11.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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + ## 0.11.8 ### Patch Changes diff --git a/plugins/api-docs/api-report-alpha.md b/plugins/api-docs/api-report-alpha.md index c7ab4eb9e0..bb2da7bc0b 100644 --- a/plugins/api-docs/api-report-alpha.md +++ b/plugins/api-docs/api-report-alpha.md @@ -6,18 +6,18 @@ import { AnyApiFactory } from '@backstage/frontend-plugin-api'; import { AnyExtensionDataRef } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; // @public (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< { root: RouteRef; }, @@ -25,10 +25,13 @@ const _default: BackstagePlugin< registerApi: ExternalRouteRef; }, { - 'nav-item:api-docs': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef< + 'nav-item:api-docs': ExtensionDefinition<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent; @@ -36,50 +39,48 @@ const _default: BackstagePlugin< }, 'core.nav-item.target', {} - >, - {}, - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - } - >; - 'api:api-docs/config': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: 'config'; - } - >; - 'page:api-docs': ExtensionDefinition< - { + >; + inputs: {}; + }>; + 'api:api-docs/config': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'config'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'page:api-docs': ExtensionDefinition<{ + config: { initiallySelectedFilter: 'all' | 'owned' | 'starred' | undefined; } & { path: string | undefined; - }, - { + }; + configInput: { initiallySelectedFilter?: 'all' | 'owned' | 'starred' | undefined; } & { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: { [x: string]: ExtensionInput< AnyExtensionDataRef, { @@ -87,303 +88,301 @@ const _default: BackstagePlugin< singleton: boolean; } >; - }, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; - 'entity-card:api-docs/has-apis': ExtensionDefinition< - { + }; + kind: 'page'; + namespace: undefined; + name: undefined; + }>; + 'entity-card:api-docs/has-apis': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'has-apis'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'has-apis'; - } - >; - 'entity-card:api-docs/definition': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:api-docs/definition': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'definition'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'definition'; - } - >; - 'entity-card:api-docs/consumed-apis': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:api-docs/consumed-apis': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'consumed-apis'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'consumed-apis'; - } - >; - 'entity-card:api-docs/provided-apis': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:api-docs/provided-apis': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'provided-apis'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'provided-apis'; - } - >; - 'entity-card:api-docs/consuming-components': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:api-docs/consuming-components': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'consuming-components'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'consuming-components'; - } - >; - 'entity-card:api-docs/providing-components': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:api-docs/providing-components': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'providing-components'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'providing-components'; - } - >; - 'entity-content:api-docs/definition': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-content:api-docs/definition': ExtensionDefinition<{ + kind: 'entity-content'; + namespace: undefined; + name: 'definition'; + config: { path: string | undefined; title: string | undefined; filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; title?: string | undefined; path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-content'; - namespace: undefined; - name: 'definition'; - } - >; - 'entity-content:api-docs/apis': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-content-title', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-content:api-docs/apis': ExtensionDefinition<{ + kind: 'entity-content'; + namespace: undefined; + name: 'apis'; + config: { path: string | undefined; title: string | undefined; filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; title?: string | undefined; path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-content'; - namespace: undefined; - name: 'apis'; - } - >; + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-content-title', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; } >; export default _default; diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 7564b858a9..3a102a70e5 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-api-docs", - "version": "0.11.8", + "version": "0.11.9-next.1", "description": "A Backstage plugin that helps represent API entities in the frontend", "backstage": { "role": "frontend-plugin", diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index 604ef6f305..a350fb994e 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-app-backend +## 0.3.74-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-app-node@0.1.25-next.1 + +## 0.3.74-next.0 + +### Patch Changes + +- d3f79d1: Fixing dependency metadata with the new `@backstage/plugin-app` package +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-app-node@0.1.25-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.3.72 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index b7fbef8b46..4f438a7d9b 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,11 +1,12 @@ { "name": "@backstage/plugin-app-backend", - "version": "0.3.72", + "version": "0.3.74-next.1", "description": "A Backstage backend plugin that serves the Backstage frontend app", "backstage": { "role": "backend-plugin", "pluginId": "app", "pluginPackages": [ + "@backstage/plugin-app", "@backstage/plugin-app-backend", "@backstage/plugin-app-node" ] diff --git a/packages/backend-tasks/src/tasks/index.ts b/plugins/app-backend/src/lib/config/index.ts similarity index 60% rename from packages/backend-tasks/src/tasks/index.ts rename to plugins/app-backend/src/lib/config/index.ts index 6f9ac6d859..2e685578d0 100644 --- a/packages/backend-tasks/src/tasks/index.ts +++ b/plugins/app-backend/src/lib/config/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,5 @@ * limitations under the License. */ -export { readTaskScheduleDefinitionFromConfig } from './readTaskScheduleDefinitionFromConfig'; -export { TaskScheduler } from './TaskScheduler'; -export type { - PluginTaskScheduler, - TaskFunction, - TaskDescriptor, - TaskInvocationDefinition, - TaskRunner, - TaskScheduleDefinition, - TaskScheduleDefinitionConfig, -} from './types'; +export { injectConfig } from './injectConfig'; +export { readFrontendConfig } from './readFrontendConfig'; diff --git a/plugins/app-backend/src/lib/config/injectConfig.ts b/plugins/app-backend/src/lib/config/injectConfig.ts new file mode 100644 index 0000000000..9d63d219f4 --- /dev/null +++ b/plugins/app-backend/src/lib/config/injectConfig.ts @@ -0,0 +1,36 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { injectConfigIntoHtml } from './injectConfigIntoHtml'; +import { injectConfigIntoStatic } from './injectConfigIntoStatic'; +import { InjectOptions } from './types'; + +/** + * Injects configs into the app bundle, replacing any existing injected config. + * @internal + */ +export async function injectConfig( + options: InjectOptions, +): Promise { + // In order to minimize the potential impact when rolling out the new config + // injection, we use both methods for a few releases. This allows the frontend + // app to be behind the backend by a version or two, but temporarily increases + // config injection overhead. + // TODO(Rugvip): After the 1.32 release we can stop calling the static injection if the HTML one is successful + await injectConfigIntoHtml(options); + + return injectConfigIntoStatic(options); +} diff --git a/plugins/app-backend/src/lib/config/injectConfigIntoHtml.test.ts b/plugins/app-backend/src/lib/config/injectConfigIntoHtml.test.ts new file mode 100644 index 0000000000..f4f2655f1c --- /dev/null +++ b/plugins/app-backend/src/lib/config/injectConfigIntoHtml.test.ts @@ -0,0 +1,73 @@ +/* + * 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 { + createMockDirectory, + mockServices, +} from '@backstage/backend-test-utils'; +import { injectConfigIntoHtml } from './injectConfigIntoHtml'; + +describe('injectConfigIntoHtml', () => { + const mockDir = createMockDirectory(); + + const baseOptions = { + appConfigs: [], + rootDir: mockDir.path, + staticDir: 'ignored', + logger: mockServices.logger.mock(), + }; + + beforeEach(() => { + mockDir.clear(); + }); + + it('should template html', async () => { + mockDir.setContent({ + 'index.html.tmpl': "<%= config.getNumber('x') %>", + }); + await injectConfigIntoHtml({ + ...baseOptions, + appConfigs: [{ context: 'mock', data: { x: 1 } }], + }); + expect(mockDir.content()).toMatchObject({ + 'index.html': '1', + }); + }); + + it('should inject config', async () => { + mockDir.setContent({ + 'index.html.tmpl': '', + }); + await injectConfigIntoHtml({ + ...baseOptions, + appConfigs: [{ context: 'mock', data: { x: 1 } }], + }); + expect(mockDir.content()).toMatchObject({ + 'index.html': ` + +`, + }); + }); +}); diff --git a/plugins/app-backend/src/lib/config/injectConfigIntoHtml.ts b/plugins/app-backend/src/lib/config/injectConfigIntoHtml.ts new file mode 100644 index 0000000000..604b6a8711 --- /dev/null +++ b/plugins/app-backend/src/lib/config/injectConfigIntoHtml.ts @@ -0,0 +1,78 @@ +/* + * 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 fs from 'fs-extra'; +import { resolve as resolvePath } from 'path'; +import { InjectOptions } from './types'; +import compileTemplate from 'lodash/template'; +import { Config, ConfigReader } from '@backstage/config'; + +const HTML_TEMPLATE_NAME = 'index.html.tmpl'; + +/** @internal */ +export async function injectConfigIntoHtml( + options: InjectOptions, +): Promise { + const { rootDir, appConfigs } = options; + + const templatePath = resolvePath(rootDir, HTML_TEMPLATE_NAME); + + if (!(await fs.exists(templatePath))) { + return false; + } + + const templateContent = await fs.readFile( + resolvePath(rootDir, HTML_TEMPLATE_NAME), + 'utf8', + ); + + const config = ConfigReader.fromConfigs(appConfigs); + + const templateSource = compileTemplate(templateContent, { + interpolate: /<%=([\s\S]+?)%>/g, + }); + + const publicPath = resolvePublicPath(config); + const indexHtmlContent = templateSource({ + config, + publicPath, + }); + + const indexHtmlContentWithConfig = indexHtmlContent.replace( + '', + ` + +`, + ); + + await fs.writeFile( + resolvePath(rootDir, 'index.html'), + indexHtmlContentWithConfig, + 'utf8', + ); + + return true; +} + +export function resolvePublicPath(config: Config) { + const baseUrl = new URL( + config.getOptionalString('app.baseUrl') ?? '/', + 'http://localhost:7007', + ); + return baseUrl.pathname.replace(/\/+$/, ''); +} diff --git a/plugins/app-backend/src/lib/config.test.ts b/plugins/app-backend/src/lib/config/injectConfigIntoStatic.test.ts similarity index 91% rename from plugins/app-backend/src/lib/config.test.ts rename to plugins/app-backend/src/lib/config/injectConfigIntoStatic.test.ts index 34f744d5b8..cd5b4dcae2 100644 --- a/plugins/app-backend/src/lib/config.test.ts +++ b/plugins/app-backend/src/lib/config/injectConfigIntoStatic.test.ts @@ -18,13 +18,14 @@ import { createMockDirectory, mockServices, } from '@backstage/backend-test-utils'; -import { injectConfig } from './config'; +import { injectConfigIntoStatic } from './injectConfigIntoStatic'; -describe('injectConfig', () => { +describe('injectConfigIntoStatic', () => { const mockDir = createMockDirectory(); const baseOptions = { appConfigs: [], + rootDir: 'ignored', staticDir: mockDir.path, logger: mockServices.logger.mock(), }; @@ -42,7 +43,7 @@ describe('injectConfig', () => { 'main.js': '"__APP_INJECTED_RUNTIME_CONFIG__"', }); - await injectConfig(baseOptions); + await injectConfigIntoStatic(baseOptions); expect(mockDir.content()).toEqual({ 'main.js': '/*__APP_INJECTED_CONFIG_MARKER__*/"[]"/*__INJECTED_END__*/', @@ -55,7 +56,7 @@ describe('injectConfig', () => { '({a:"__APP_INJECTED_RUNTIME_CONFIG__",b:"__APP_INJECTED_RUNTIME_CONFIG__"})', }); - await injectConfig(baseOptions); + await injectConfigIntoStatic(baseOptions); expect(mockDir.content()).toEqual({ 'main.js': @@ -71,7 +72,7 @@ describe('injectConfig', () => { 'after.js': 'NO_PLACEHOLDER_HERE', }); - await injectConfig({ + await injectConfigIntoStatic({ ...baseOptions, appConfigs: [{ data: { x: 0 }, context: 'test' }], }); @@ -90,7 +91,7 @@ describe('injectConfig', () => { 'main.js': 'JSON.parse("__APP_INJECTED_RUNTIME_CONFIG__")', }); - await injectConfig({ + await injectConfigIntoStatic({ ...baseOptions, appConfigs: [{ data: { x: 0 }, context: 'test' }], }); @@ -100,7 +101,7 @@ describe('injectConfig', () => { 'JSON.parse(/*__APP_INJECTED_CONFIG_MARKER__*/"[{\\"data\\":{\\"x\\":0},\\"context\\":\\"test\\"}]"/*__INJECTED_END__*/)', }); - await injectConfig({ + await injectConfigIntoStatic({ ...baseOptions, appConfigs: [{ data: { x: 1, y: 2 }, context: 'test' }], }); @@ -117,7 +118,7 @@ describe('injectConfig', () => { '({ a: JSON.parse("__APP_INJECTED_RUNTIME_CONFIG__"), b: JSON.parse("__APP_INJECTED_RUNTIME_CONFIG__") })', }); - await injectConfig({ + await injectConfigIntoStatic({ ...baseOptions, appConfigs: [{ data: { x: 0 }, context: 'test' }], }); @@ -127,7 +128,7 @@ describe('injectConfig', () => { '({ a: JSON.parse(/*__APP_INJECTED_CONFIG_MARKER__*/"[{\\"data\\":{\\"x\\":0},\\"context\\":\\"test\\"}]"/*__INJECTED_END__*/), b: JSON.parse(/*__APP_INJECTED_CONFIG_MARKER__*/"[{\\"data\\":{\\"x\\":0},\\"context\\":\\"test\\"}]"/*__INJECTED_END__*/) })', }); - await injectConfig({ + await injectConfigIntoStatic({ ...baseOptions, appConfigs: [{ data: { x: 1, y: 2 }, context: 'test' }], }); diff --git a/plugins/app-backend/src/lib/config/injectConfigIntoStatic.ts b/plugins/app-backend/src/lib/config/injectConfigIntoStatic.ts new file mode 100644 index 0000000000..29975b0c2a --- /dev/null +++ b/plugins/app-backend/src/lib/config/injectConfigIntoStatic.ts @@ -0,0 +1,61 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fs from 'fs-extra'; +import { resolve as resolvePath } from 'path'; +import { InjectOptions } from './types'; + +/** + * Injects configs into the app bundle, replacing any existing injected config. + */ +export async function injectConfigIntoStatic( + options: InjectOptions, +): Promise { + const { staticDir, logger, appConfigs } = options; + + const files = await fs.readdir(staticDir); + const jsFiles = files.filter(file => file.endsWith('.js')); + + const escapedData = JSON.stringify(appConfigs).replace(/("|'|\\)/g, '\\$1'); + const injected = `/*__APP_INJECTED_CONFIG_MARKER__*/"${escapedData}"/*__INJECTED_END__*/`; + + for (const jsFile of jsFiles) { + const path = resolvePath(staticDir, jsFile); + + const content = await fs.readFile(path, 'utf8'); + if (content.includes('__APP_INJECTED_RUNTIME_CONFIG__')) { + logger.info(`Injecting env config into ${jsFile}`); + + const newContent = content.replaceAll( + '"__APP_INJECTED_RUNTIME_CONFIG__"', + injected, + ); + await fs.writeFile(path, newContent, 'utf8'); + return path; + } else if (content.includes('__APP_INJECTED_CONFIG_MARKER__')) { + logger.info(`Replacing injected env config in ${jsFile}`); + + const newContent = content.replaceAll( + /\/\*__APP_INJECTED_CONFIG_MARKER__\*\/.*?\/\*__INJECTED_END__\*\//g, + injected, + ); + await fs.writeFile(path, newContent, 'utf8'); + return path; + } + } + logger.info('Env config not injected'); + return undefined; +} diff --git a/plugins/app-backend/src/lib/config.ts b/plugins/app-backend/src/lib/config/readFrontendConfig.ts similarity index 55% rename from plugins/app-backend/src/lib/config.ts rename to plugins/app-backend/src/lib/config/readFrontendConfig.ts index df1146e746..becd1c2f52 100644 --- a/plugins/app-backend/src/lib/config.ts +++ b/plugins/app-backend/src/lib/config/readFrontendConfig.ts @@ -23,69 +23,17 @@ import { loadConfigSchema, readEnvConfig, } from '@backstage/config-loader'; -import { LoggerService } from '@backstage/backend-plugin-api'; - -type InjectOptions = { - appConfigs: AppConfig[]; - // Directory of the static JS files to search for file to inject - staticDir: string; - logger: LoggerService; -}; - -/** - * Injects configs into the app bundle, replacing any existing injected config. - */ -export async function injectConfig( - options: InjectOptions, -): Promise { - const { staticDir, logger, appConfigs } = options; - - const files = await fs.readdir(staticDir); - const jsFiles = files.filter(file => file.endsWith('.js')); - - const escapedData = JSON.stringify(appConfigs).replace(/("|'|\\)/g, '\\$1'); - const injected = `/*__APP_INJECTED_CONFIG_MARKER__*/"${escapedData}"/*__INJECTED_END__*/`; - - for (const jsFile of jsFiles) { - const path = resolvePath(staticDir, jsFile); - - const content = await fs.readFile(path, 'utf8'); - if (content.includes('__APP_INJECTED_RUNTIME_CONFIG__')) { - logger.info(`Injecting env config into ${jsFile}`); - - const newContent = content.replaceAll( - '"__APP_INJECTED_RUNTIME_CONFIG__"', - injected, - ); - await fs.writeFile(path, newContent, 'utf8'); - return path; - } else if (content.includes('__APP_INJECTED_CONFIG_MARKER__')) { - logger.info(`Replacing injected env config in ${jsFile}`); - - const newContent = content.replaceAll( - /\/\*__APP_INJECTED_CONFIG_MARKER__\*\/.*?\/\*__INJECTED_END__\*\//g, - injected, - ); - await fs.writeFile(path, newContent, 'utf8'); - return path; - } - } - logger.info('Env config not injected'); - return undefined; -} - -type ReadOptions = { - env: { [name: string]: string | undefined }; - appDistDir: string; - config: Config; - schema?: ConfigSchema; -}; /** * Read config from environment and process the backend config using the * schema that is embedded in the frontend build. */ -export async function readConfigs(options: ReadOptions): Promise { +export async function readFrontendConfig(options: { + env: { [name: string]: string | undefined }; + appDistDir: string; + config: Config; + schema?: ConfigSchema; +}): Promise { const { env, appDistDir, config } = options; const appConfigs = readEnvConfig(env); diff --git a/packages/backend-tasks/src/database/tables.ts b/plugins/app-backend/src/lib/config/types.ts similarity index 59% rename from packages/backend-tasks/src/database/tables.ts rename to plugins/app-backend/src/lib/config/types.ts index 63aad6e42a..e6a0e9141b 100644 --- a/packages/backend-tasks/src/database/tables.ts +++ b/plugins/app-backend/src/lib/config/types.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,14 @@ * limitations under the License. */ -export const DB_MIGRATIONS_TABLE = 'backstage_backend_tasks__knex_migrations'; -export const DB_TASKS_TABLE = 'backstage_backend_tasks__tasks'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { AppConfig } from '@backstage/config'; -export type DbTasksRow = { - id: string; - settings_json: string; - next_run_start_at: Date; - current_run_ticket?: string; - current_run_started_at?: Date | string; - current_run_expires_at?: Date | string; -}; +export interface InjectOptions { + appConfigs: AppConfig[]; + /** Directory of the public web content */ + rootDir: string; + /** Directory of the static JS files to search for file to inject */ + staticDir: string; + logger: LoggerService; +} diff --git a/plugins/app-backend/src/service/router.test.ts b/plugins/app-backend/src/service/router.test.ts index b7ad65706c..cdb150e06c 100644 --- a/plugins/app-backend/src/service/router.test.ts +++ b/plugins/app-backend/src/service/router.test.ts @@ -25,7 +25,7 @@ import { mockServices } from '@backstage/backend-test-utils'; jest.mock('../lib/config', () => ({ injectConfig: jest.fn(), - readConfigs: jest.fn(), + readFrontendConfig: jest.fn(), })); global.__non_webpack_require__ = { @@ -120,11 +120,13 @@ describe('createRouter with static fallback handler', () => { describe('createRouter config schema test', () => { const libConfigs = require('../lib/config'); const libConfigsActual = jest.requireActual('../lib/config'); - const readConfigsMock: jest.Mock = libConfigs.readConfigs; + const readFrontendConfigMock: jest.Mock = libConfigs.readFrontendConfig; beforeEach(() => { jest.resetAllMocks(); - readConfigsMock.mockImplementation(libConfigsActual.readConfigs); + readFrontendConfigMock.mockImplementation( + libConfigsActual.readFrontendConfig, + ); }); it('uses an external schema', async () => { @@ -155,7 +157,7 @@ describe('createRouter config schema test', () => { }), }); - const results = readConfigsMock.mock.results; + const results = readFrontendConfigMock.mock.results; expect(results.length).toBe(1); const mockedResult = results[0]; @@ -177,7 +179,7 @@ describe('createRouter config schema test', () => { appPackageName: 'example-app', }); - const results = readConfigsMock.mock.results; + const results = readFrontendConfigMock.mock.results; expect(results.length).toBe(1); const mockedResult = results[0]; diff --git a/plugins/app-backend/src/service/router.ts b/plugins/app-backend/src/service/router.ts index b205f16203..cd1c0e4ee2 100644 --- a/plugins/app-backend/src/service/router.ts +++ b/plugins/app-backend/src/service/router.ts @@ -26,7 +26,6 @@ import express from 'express'; import Router from 'express-promise-router'; import fs from 'fs-extra'; import { resolve as resolvePath } from 'path'; -import { injectConfig, readConfigs } from '../lib/config'; import { createStaticAssetMiddleware, findStaticAssets, @@ -44,6 +43,7 @@ import { LoggerService, } from '@backstage/backend-plugin-api'; import { AuthenticationError } from '@backstage/errors'; +import { injectConfig, readFrontendConfig } from '../lib/config'; // express uses mime v1 while we only have types for mime v2 type Mime = { lookup(arg0: string): string }; @@ -147,7 +147,7 @@ export async function createRouter( const appConfigs = disableConfigInjection ? undefined - : await readConfigs({ + : await readFrontendConfig({ config, appDistDir, env: process.env, @@ -266,7 +266,8 @@ async function createEntryPointRouter({ const staticDir = resolvePath(rootDir, 'static'); const injectedConfigPath = - appConfigs && (await injectConfig({ appConfigs, logger, staticDir })); + appConfigs && + (await injectConfig({ appConfigs, logger, rootDir, staticDir })); const router = Router(); diff --git a/plugins/app-node/CHANGELOG.md b/plugins/app-node/CHANGELOG.md index 607aa68750..feae31a8ea 100644 --- a/plugins/app-node/CHANGELOG.md +++ b/plugins/app-node/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-app-node +## 0.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config-loader@1.9.0 + +## 0.1.25-next.0 + +### Patch Changes + +- d3f79d1: Fixing dependency metadata with the new `@backstage/plugin-app` package +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/config-loader@1.9.0 + ## 0.1.23 ### Patch Changes diff --git a/plugins/app-node/package.json b/plugins/app-node/package.json index 4e28a853ed..33af5bfba1 100644 --- a/plugins/app-node/package.json +++ b/plugins/app-node/package.json @@ -1,11 +1,12 @@ { "name": "@backstage/plugin-app-node", - "version": "0.1.23", + "version": "0.1.25-next.1", "description": "Node.js library for the app plugin", "backstage": { "role": "node-library", "pluginId": "app", "pluginPackages": [ + "@backstage/plugin-app", "@backstage/plugin-app-backend", "@backstage/plugin-app-node" ] diff --git a/plugins/app-visualizer/CHANGELOG.md b/plugins/app-visualizer/CHANGELOG.md index f7dad4bb44..2afc4a1651 100644 --- a/plugins/app-visualizer/CHANGELOG.md +++ b/plugins/app-visualizer/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-app-visualizer +## 0.1.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + +## 0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.9 ### Patch Changes diff --git a/plugins/app-visualizer/api-report.md b/plugins/app-visualizer/api-report.md index e01040a22a..e542674845 100644 --- a/plugins/app-visualizer/api-report.md +++ b/plugins/app-visualizer/api-report.md @@ -4,49 +4,51 @@ ```ts import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; // @public (undocumented) -const visualizerPlugin: BackstagePlugin< +const visualizerPlugin: FrontendPlugin< {}, {}, { - 'page:app-visualizer': ExtensionDefinition< - { + 'page:app-visualizer': ExtensionDefinition<{ + kind: 'page'; + namespace: undefined; + name: undefined; + config: { path: string | undefined; - }, - { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - {}, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; - 'nav-item:app-visualizer': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef< + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: {}; + }>; + 'nav-item:app-visualizer': ExtensionDefinition<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent; @@ -54,14 +56,9 @@ const visualizerPlugin: BackstagePlugin< }, 'core.nav-item.target', {} - >, - {}, - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - } - >; + >; + inputs: {}; + }>; } >; export default visualizerPlugin; diff --git a/plugins/app-visualizer/package.json b/plugins/app-visualizer/package.json index 7ee42ef335..3e24482eda 100644 --- a/plugins/app-visualizer/package.json +++ b/plugins/app-visualizer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-app-visualizer", - "version": "0.1.9", + "version": "0.1.10-next.1", "description": "Visualizes the Backstage app structure", "backstage": { "role": "frontend-plugin", diff --git a/plugins/app/.eslintrc.js b/plugins/app/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/app/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/app/CHANGELOG.md b/plugins/app/CHANGELOG.md new file mode 100644 index 0000000000..2ff8607a13 --- /dev/null +++ b/plugins/app/CHANGELOG.md @@ -0,0 +1,57 @@ +# @backstage/plugin-app + +## 0.1.0-next.1 + +### Patch Changes + +- 52f9c5a: Deprecated the `namespace` option for `createExtensionBlueprint` and `createExtension`, these are no longer required and will default to the `pluginId` instead. + + You can migrate some of your extensions that use `createExtensionOverrides` to using `createFrontendModule` instead and providing a `pluginId` there. + + ```ts + // Before + createExtensionOverrides({ + extensions: [ + createExtension({ + name: 'my-extension', + namespace: 'my-namespace', + kind: 'test', + ... + }) + ], + }); + + // After + createFrontendModule({ + pluginId: 'my-namespace', + extensions: [ + createExtension({ + name: 'my-extension', + kind: 'test', + ... + }) + ], + }); + ``` + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.25 + +## 0.1.0-next.0 + +### Minor Changes + +- 2bb9517: Introduce the `@backstage/plugin-app` package to hold all of the built-in extensions for easy consumption and overriding. + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-permission-react@0.4.25 diff --git a/plugins/app/README.md b/plugins/app/README.md new file mode 100644 index 0000000000..f54a8e0a4c --- /dev/null +++ b/plugins/app/README.md @@ -0,0 +1,9 @@ +# app + +Welcome to the app plugin! + +_This plugin was created through the Backstage CLI_ + +## Getting started + +Your plugin has been added to the example app in this repository, meaning you'll be able to access it by running `yarn start` in the root directory, and then navigating to [/app](http://localhost:3000/app). diff --git a/plugins/app/api-report.md b/plugins/app/api-report.md new file mode 100644 index 0000000000..6f2e6e0463 --- /dev/null +++ b/plugins/app/api-report.md @@ -0,0 +1,657 @@ +## API Report File for "@backstage/plugin-app" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { AnyApiFactory } from '@backstage/frontend-plugin-api'; +import { AnyExtensionDataRef } from '@backstage/frontend-plugin-api'; +import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; +import { AppTheme } from '@backstage/frontend-plugin-api'; +import { ComponentRef } from '@backstage/frontend-plugin-api'; +import { ComponentType } from 'react'; +import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; +import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; +import { ExtensionInput } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; +import { IconComponent } from '@backstage/core-plugin-api'; +import { IconComponent as IconComponent_2 } from '@backstage/frontend-plugin-api'; +import { JSX as JSX_2 } from 'react'; +import { ReactNode } from 'react'; +import { RouteRef } from '@backstage/frontend-plugin-api'; +import { SignInPageProps } from '@backstage/core-plugin-api'; +import { TranslationMessages } from '@backstage/frontend-plugin-api'; +import { TranslationResource } from '@backstage/frontend-plugin-api'; + +// @public (undocumented) +const appPlugin: FrontendPlugin< + {}, + {}, + { + app: ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: { + root: ExtensionInput< + ConfigurableExtensionDataRef, + { + singleton: true; + optional: false; + } + >; + }; + kind: undefined; + namespace: undefined; + name: undefined; + }>; + 'api:app/app-language': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'app-language'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'app/layout': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: { + nav: ExtensionInput< + ConfigurableExtensionDataRef, + { + singleton: true; + optional: false; + } + >; + content: ExtensionInput< + ConfigurableExtensionDataRef, + { + singleton: true; + optional: false; + } + >; + }; + kind: undefined; + namespace: undefined; + name: 'layout'; + }>; + 'app/nav': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: { + items: ExtensionInput< + ConfigurableExtensionDataRef< + { + title: string; + icon: IconComponent; + routeRef: RouteRef; + }, + 'core.nav-item.target', + {} + >, + { + singleton: false; + optional: false; + } + >; + logos: ExtensionInput< + ConfigurableExtensionDataRef< + { + logoIcon?: JSX.Element | undefined; + logoFull?: JSX.Element | undefined; + }, + 'core.nav-logo.logo-elements', + {} + >, + { + singleton: true; + optional: true; + } + >; + }; + kind: undefined; + namespace: undefined; + name: 'nav'; + }>; + 'app/root': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: { + router: ExtensionInput< + ConfigurableExtensionDataRef< + ComponentType<{ + children?: ReactNode; + }>, + 'app.router.wrapper', + {} + >, + { + singleton: true; + optional: true; + } + >; + signInPage: ExtensionInput< + ConfigurableExtensionDataRef< + ComponentType, + 'core.sign-in-page.component', + {} + >, + { + singleton: true; + optional: true; + } + >; + children: ExtensionInput< + ConfigurableExtensionDataRef, + { + singleton: true; + optional: false; + } + >; + elements: ExtensionInput< + ConfigurableExtensionDataRef, + { + singleton: false; + optional: false; + } + >; + wrappers: ExtensionInput< + ConfigurableExtensionDataRef< + ComponentType<{ + children?: ReactNode; + }>, + 'app.root.wrapper', + {} + >, + { + singleton: false; + optional: false; + } + >; + }; + kind: undefined; + namespace: undefined; + name: 'root'; + }>; + 'app/routes': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: { + routes: ExtensionInput< + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >, + { + singleton: false; + optional: false; + } + >; + }; + kind: undefined; + namespace: undefined; + name: 'routes'; + }>; + 'api:app/app-theme': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: { + themes: ExtensionInput< + ConfigurableExtensionDataRef, + { + singleton: false; + optional: false; + } + >; + }; + kind: 'api'; + namespace: undefined; + name: 'app-theme'; + }>; + 'theme:app/light': ExtensionDefinition<{ + kind: 'theme'; + namespace: undefined; + name: 'light'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef; + inputs: {}; + }>; + 'theme:app/dark': ExtensionDefinition<{ + kind: 'theme'; + namespace: undefined; + name: 'dark'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef; + inputs: {}; + }>; + 'api:app/components': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: { + components: ExtensionInput< + ConfigurableExtensionDataRef< + { + ref: ComponentRef; + impl: ComponentType; + }, + 'core.component.component', + {} + >, + { + singleton: false; + optional: false; + } + >; + }; + kind: 'api'; + namespace: undefined; + name: 'components'; + }>; + 'api:app/icons': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: { + icons: ExtensionInput< + ConfigurableExtensionDataRef< + { + [x: string]: IconComponent_2; + }, + 'core.icons', + {} + >, + { + singleton: false; + optional: false; + } + >; + }; + kind: 'api'; + namespace: undefined; + name: 'icons'; + }>; + 'api:app/feature-flags': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'feature-flags'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/translations': ExtensionDefinition<{ + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: { + translations: ExtensionInput< + ConfigurableExtensionDataRef< + | TranslationResource + | TranslationMessages< + string, + { + [x: string]: string; + }, + boolean + >, + 'core.translation.translation', + {} + >, + { + singleton: false; + optional: false; + } + >; + }; + kind: 'api'; + namespace: undefined; + name: 'translations'; + }>; + 'app-root-element:app/oauth-request-dialog': ExtensionDefinition<{ + kind: 'app-root-element'; + namespace: undefined; + name: 'oauth-request-dialog'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: {}; + }>; + 'app-root-element:app/alert-display': ExtensionDefinition<{ + config: { + transientTimeoutMs: number; + anchorOrigin: { + horizontal: 'center' | 'left' | 'right'; + vertical: 'top' | 'bottom'; + }; + }; + configInput: { + anchorOrigin?: + | { + horizontal?: 'center' | 'left' | 'right' | undefined; + vertical?: 'top' | 'bottom' | undefined; + } + | undefined; + transientTimeoutMs?: number | undefined; + }; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: { + [x: string]: ExtensionInput< + AnyExtensionDataRef, + { + optional: boolean; + singleton: boolean; + } + >; + }; + kind: 'app-root-element'; + namespace: undefined; + name: 'alert-display'; + }>; + 'api:app/discovery': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'discovery'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/alert': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'alert'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/analytics': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'analytics'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/error': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'error'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/storage': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'storage'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/fetch': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'fetch'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/oauth-request': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'oauth-request'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/google-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'google-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/microsoft-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'microsoft-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/github-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'github-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/okta-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'okta-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/gitlab-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'gitlab-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/onelogin-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'onelogin-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/bitbucket-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'bitbucket-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/bitbucket-server-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'bitbucket-server-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/atlassian-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'atlassian-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/vmware-cloud-auth': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'vmware-cloud-auth'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:app/permission': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'permission'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + } +>; +export default appPlugin; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/app/catalog-info.yaml b/plugins/app/catalog-info.yaml new file mode 100644 index 0000000000..5bae243ea7 --- /dev/null +++ b/plugins/app/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-app + title: '@backstage/plugin-app' +spec: + lifecycle: experimental + type: backstage-frontend-plugin + owner: maintainers diff --git a/plugins/app/package.json b/plugins/app/package.json new file mode 100644 index 0000000000..5912cc3781 --- /dev/null +++ b/plugins/app/package.json @@ -0,0 +1,65 @@ +{ + "name": "@backstage/plugin-app", + "version": "0.1.0-next.1", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/app" + }, + "backstage": { + "role": "frontend-plugin", + "pluginId": "app", + "pluginPackages": [ + "@backstage/plugin-app", + "@backstage/plugin-app-backend", + "@backstage/plugin-app-node" + ] + }, + "sideEffects": false, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/frontend-plugin-api": "workspace:^", + "@backstage/plugin-permission-react": "workspace:^", + "@backstage/theme": "workspace:^", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.61", + "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "react-router-dom": "6.0.0-beta.0 || ^6.3.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/frontend-test-utils": "workspace:^", + "@testing-library/jest-dom": "^6.0.0", + "@testing-library/react": "^15.0.0", + "@testing-library/user-event": "^14.0.0", + "msw": "^1.0.0", + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/app/src/defaultApis.ts b/plugins/app/src/defaultApis.ts new file mode 100644 index 0000000000..fd46ecf596 --- /dev/null +++ b/plugins/app/src/defaultApis.ts @@ -0,0 +1,382 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { + AlertApiForwarder, + NoOpAnalyticsApi, + ErrorApiForwarder, + ErrorAlerter, + GoogleAuth, + GithubAuth, + OktaAuth, + GitlabAuth, + MicrosoftAuth, + BitbucketAuth, + BitbucketServerAuth, + OAuthRequestManager, + WebStorage, + UrlPatternDiscovery, + OneLoginAuth, + UnhandledErrorForwarder, + AtlassianAuth, + createFetchApi, + FetchMiddlewares, + VMwareCloudAuth, +} from '../../../packages/core-app-api/src/apis/implementations'; + +import { + createApiFactory, + alertApiRef, + analyticsApiRef, + errorApiRef, + discoveryApiRef, + fetchApiRef, + identityApiRef, + oauthRequestApiRef, + googleAuthApiRef, + githubAuthApiRef, + oktaAuthApiRef, + gitlabAuthApiRef, + microsoftAuthApiRef, + storageApiRef, + configApiRef, + oneloginAuthApiRef, + bitbucketAuthApiRef, + bitbucketServerAuthApiRef, + atlassianAuthApiRef, + vmwareCloudAuthApiRef, +} from '@backstage/core-plugin-api'; +import { ApiBlueprint } from '@backstage/frontend-plugin-api'; +import { + permissionApiRef, + IdentityPermissionApi, +} from '@backstage/plugin-permission-react'; + +export const apis = [ + ApiBlueprint.make({ + name: 'discovery', + params: { + factory: createApiFactory({ + api: discoveryApiRef, + deps: { configApi: configApiRef }, + factory: ({ configApi }) => + UrlPatternDiscovery.compile( + `${configApi.getString('backend.baseUrl')}/api/{{ pluginId }}`, + ), + }), + }, + }), + ApiBlueprint.make({ + name: 'alert', + params: { + factory: createApiFactory({ + api: alertApiRef, + deps: {}, + factory: () => new AlertApiForwarder(), + }), + }, + }), + ApiBlueprint.make({ + name: 'analytics', + params: { + factory: createApiFactory({ + api: analyticsApiRef, + deps: {}, + factory: () => new NoOpAnalyticsApi(), + }), + }, + }), + ApiBlueprint.make({ + name: 'error', + params: { + factory: createApiFactory({ + api: errorApiRef, + deps: { alertApi: alertApiRef }, + factory: ({ alertApi }) => { + const errorApi = new ErrorAlerter(alertApi, new ErrorApiForwarder()); + UnhandledErrorForwarder.forward(errorApi, { hidden: false }); + return errorApi; + }, + }), + }, + }), + ApiBlueprint.make({ + name: 'storage', + params: { + factory: createApiFactory({ + api: storageApiRef, + deps: { errorApi: errorApiRef }, + factory: ({ errorApi }) => WebStorage.create({ errorApi }), + }), + }, + }), + ApiBlueprint.make({ + name: 'fetch', + params: { + factory: createApiFactory({ + api: fetchApiRef, + deps: { + configApi: configApiRef, + identityApi: identityApiRef, + discoveryApi: discoveryApiRef, + }, + factory: ({ configApi, identityApi, discoveryApi }) => { + return createFetchApi({ + middleware: [ + FetchMiddlewares.resolvePluginProtocol({ + discoveryApi, + }), + FetchMiddlewares.injectIdentityAuth({ + identityApi, + config: configApi, + }), + ], + }); + }, + }), + }, + }), + ApiBlueprint.make({ + name: 'oauth-request', + params: { + factory: createApiFactory({ + api: oauthRequestApiRef, + deps: {}, + factory: () => new OAuthRequestManager(), + }), + }, + }), + ApiBlueprint.make({ + name: 'google-auth', + params: { + factory: createApiFactory({ + api: googleAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => + GoogleAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + environment: configApi.getOptionalString('auth.environment'), + }), + }), + }, + }), + ApiBlueprint.make({ + name: 'microsoft-auth', + params: { + factory: createApiFactory({ + api: microsoftAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => + MicrosoftAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + environment: configApi.getOptionalString('auth.environment'), + }), + }), + }, + }), + ApiBlueprint.make({ + name: 'github-auth', + params: { + factory: createApiFactory({ + api: githubAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => + GithubAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + defaultScopes: ['read:user'], + environment: configApi.getOptionalString('auth.environment'), + }), + }), + }, + }), + ApiBlueprint.make({ + name: 'okta-auth', + params: { + factory: createApiFactory({ + api: oktaAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => + OktaAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + environment: configApi.getOptionalString('auth.environment'), + }), + }), + }, + }), + ApiBlueprint.make({ + name: 'gitlab-auth', + params: { + factory: createApiFactory({ + api: gitlabAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => + GitlabAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + environment: configApi.getOptionalString('auth.environment'), + }), + }), + }, + }), + ApiBlueprint.make({ + name: 'onelogin-auth', + params: { + factory: createApiFactory({ + api: oneloginAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => + OneLoginAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + environment: configApi.getOptionalString('auth.environment'), + }), + }), + }, + }), + ApiBlueprint.make({ + name: 'bitbucket-auth', + params: { + factory: createApiFactory({ + api: bitbucketAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => + BitbucketAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + defaultScopes: ['account'], + environment: configApi.getOptionalString('auth.environment'), + }), + }), + }, + }), + ApiBlueprint.make({ + name: 'bitbucket-server-auth', + params: { + factory: createApiFactory({ + api: bitbucketServerAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => + BitbucketServerAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + defaultScopes: ['REPO_READ'], + }), + }), + }, + }), + ApiBlueprint.make({ + name: 'atlassian-auth', + params: { + factory: createApiFactory({ + api: atlassianAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => { + return AtlassianAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + environment: configApi.getOptionalString('auth.environment'), + }); + }, + }), + }, + }), + ApiBlueprint.make({ + name: 'vmware-cloud-auth', + params: { + factory: createApiFactory({ + api: vmwareCloudAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + configApi: configApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi, configApi }) => { + return VMwareCloudAuth.create({ + configApi, + discoveryApi, + oauthRequestApi, + environment: configApi.getOptionalString('auth.environment'), + }); + }, + }), + }, + }), + ApiBlueprint.make({ + name: 'permission', + params: { + factory: createApiFactory({ + api: permissionApiRef, + deps: { + discovery: discoveryApiRef, + identity: identityApiRef, + config: configApiRef, + }, + factory: ({ config, discovery, identity }) => + IdentityPermissionApi.create({ config, discovery, identity }), + }), + }, + }), +] as const; diff --git a/packages/frontend-app-api/src/extensions/App.tsx b/plugins/app/src/extensions/App.tsx similarity index 60% rename from packages/frontend-app-api/src/extensions/App.tsx rename to plugins/app/src/extensions/App.tsx index 1eeba30f64..7f4b3d5ee1 100644 --- a/packages/frontend-app-api/src/extensions/App.tsx +++ b/plugins/app/src/extensions/App.tsx @@ -21,9 +21,12 @@ import { createExtension, createExtensionInput, } from '@backstage/frontend-plugin-api'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { ApiProvider } from '../../../../packages/core-app-api/src'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { AppThemeProvider } from '../../../../packages/core-app-api/src/app/AppThemeProvider'; export const App = createExtension({ - namespace: 'app', attachTo: { id: 'root', input: 'app' }, inputs: { root: createExtensionInput([coreExtensionData.reactElement], { @@ -31,11 +34,17 @@ export const App = createExtension({ }), }, output: [coreExtensionData.reactElement], - factory: ({ node, inputs }) => [ - coreExtensionData.reactElement( - - {inputs.root.get(coreExtensionData.reactElement)} - , - ), - ], + factory: ({ node, apis, inputs }) => { + return [ + coreExtensionData.reactElement( + + + + {inputs.root.get(coreExtensionData.reactElement)} + + + , + ), + ]; + }, }); diff --git a/packages/frontend-app-api/src/extensions/AppLanguageApi.ts b/plugins/app/src/extensions/AppLanguageApi.ts similarity index 90% rename from packages/frontend-app-api/src/extensions/AppLanguageApi.ts rename to plugins/app/src/extensions/AppLanguageApi.ts index ff12848d44..7a6c10db96 100644 --- a/packages/frontend-app-api/src/extensions/AppLanguageApi.ts +++ b/plugins/app/src/extensions/AppLanguageApi.ts @@ -15,7 +15,7 @@ */ // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { AppLanguageSelector } from '../../../core-app-api/src/apis/implementations/AppLanguageApi'; +import { AppLanguageSelector } from '../../../../packages/core-app-api/src/apis/implementations/AppLanguageApi'; import { appLanguageApiRef } from '@backstage/core-plugin-api/alpha'; import { ApiBlueprint, createApiFactory } from '@backstage/frontend-plugin-api'; diff --git a/packages/frontend-app-api/src/extensions/AppLayout.tsx b/plugins/app/src/extensions/AppLayout.tsx similarity index 98% rename from packages/frontend-app-api/src/extensions/AppLayout.tsx rename to plugins/app/src/extensions/AppLayout.tsx index 9fadba8a93..3a0560a807 100644 --- a/packages/frontend-app-api/src/extensions/AppLayout.tsx +++ b/plugins/app/src/extensions/AppLayout.tsx @@ -23,7 +23,6 @@ import { import { SidebarPage } from '@backstage/core-components'; export const AppLayout = createExtension({ - namespace: 'app', name: 'layout', attachTo: { id: 'app/root', input: 'children' }, inputs: { diff --git a/packages/frontend-app-api/src/extensions/AppNav.tsx b/plugins/app/src/extensions/AppNav.tsx similarity index 95% rename from packages/frontend-app-api/src/extensions/AppNav.tsx rename to plugins/app/src/extensions/AppNav.tsx index b80a537ef6..3e4fcebf8c 100644 --- a/packages/frontend-app-api/src/extensions/AppNav.tsx +++ b/plugins/app/src/extensions/AppNav.tsx @@ -33,9 +33,9 @@ import { SidebarItem, } from '@backstage/core-components'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import LogoIcon from '../../../app/src/components/Root/LogoIcon'; +import LogoIcon from '../../../../packages/app/src/components/Root/LogoIcon'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import LogoFull from '../../../app/src/components/Root/LogoFull'; +import LogoFull from '../../../../packages/app/src/components/Root/LogoFull'; const useSidebarLogoStyles = makeStyles({ root: { @@ -82,7 +82,6 @@ const SidebarNavItem = ( }; export const AppNav = createExtension({ - namespace: 'app', name: 'nav', attachTo: { id: 'app/layout', input: 'nav' }, inputs: { diff --git a/packages/frontend-app-api/src/extensions/AppRoot.tsx b/plugins/app/src/extensions/AppRoot.tsx similarity index 69% rename from packages/frontend-app-api/src/extensions/AppRoot.tsx rename to plugins/app/src/extensions/AppRoot.tsx index a158386d04..014f9a1354 100644 --- a/packages/frontend-app-api/src/extensions/AppRoot.tsx +++ b/plugins/app/src/extensions/AppRoot.tsx @@ -19,7 +19,6 @@ import React, { Fragment, PropsWithChildren, ReactNode, - useContext, useState, } from 'react'; import { @@ -27,24 +26,33 @@ import { RouterBlueprint, SignInPageBlueprint, coreExtensionData, + discoveryApiRef, + fetchApiRef, + errorApiRef, createExtension, createExtensionInput, + routeResolutionApiRef, } from '@backstage/frontend-plugin-api'; import { + DiscoveryApi, + ErrorApi, + FetchApi, IdentityApi, + ProfileInfo, SignInPageProps, configApiRef, + identityApiRef, useApi, } from '@backstage/core-plugin-api'; -import { InternalAppContext } from '../wiring/InternalAppContext'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { AppIdentityProxy } from '../../../core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy'; +import { isProtectedApp } from '../../../../packages/core-app-api/src/app/isProtectedApp'; import { BrowserRouter } from 'react-router-dom'; -import { RouteTracker } from '../routing/RouteTracker'; -import { getBasePath } from '../routing/getBasePath'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { RouteTracker } from '../../../../packages/frontend-app-api/src/routing/RouteTracker'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { getBasePath } from '../../../../packages/frontend-app-api/src/routing/getBasePath'; export const AppRoot = createExtension({ - namespace: 'app', name: 'root', attachTo: { id: 'app', input: 'root' }, inputs: { @@ -65,7 +73,28 @@ export const AppRoot = createExtension({ ]), }, output: [coreExtensionData.reactElement], - factory({ inputs }) { + factory({ inputs, apis }) { + if (isProtectedApp()) { + const identityApi = apis.get(identityApiRef); + if (!identityApi) { + throw new Error('App requires an Identity API implementation'); + } + const appIdentityProxy = toAppIdentityProxy(identityApi); + const discoveryApi = apis.get(discoveryApiRef); + const errorApi = apis.get(errorApiRef); + const fetchApi = apis.get(fetchApiRef); + if (!discoveryApi || !errorApi || !fetchApi) { + throw new Error( + 'App is running in protected mode but missing required APIs', + ); + } + appIdentityProxy.enableCookieAuth({ + discoveryApi, + errorApi, + fetchApi, + }); + } + let content: React.ReactNode = ( <> {inputs.elements.map(el => ( @@ -123,6 +152,33 @@ function SignInPageWrapper({ return <>{children}; } +type AppIdentityProxy = IdentityApi & { + enableCookieAuth(ctx: { + errorApi: ErrorApi; + fetchApi: FetchApi; + discoveryApi: DiscoveryApi; + }): void; + setTarget( + impl: IdentityApi & /* backwards compat stuff */ { + getUserId?(): string; + getIdToken?(): Promise; + getProfile?(): ProfileInfo; + }, + options: { signOutTargetUrl: string }, + ): void; +}; + +function toAppIdentityProxy(identityApi: IdentityApi): AppIdentityProxy { + if (!('enableCookieAuth' in identityApi)) { + throw new Error('Unexpected Identity API implementation'); + } + return identityApi as AppIdentityProxy; +} + +type RouteResolverProxy = { + getRouteObjects(): any[]; +}; + /** * Props for the {@link AppRouter} component. * @public @@ -157,12 +213,17 @@ export function AppRouter(props: AppRouterProps) { } = props; const configApi = useApi(configApiRef); + const appIdentityProxy = toAppIdentityProxy(useApi(identityApiRef)); + const routeResolutionsApi = useApi(routeResolutionApiRef); const basePath = getBasePath(configApi); - const internalAppContext = useContext(InternalAppContext); - if (!internalAppContext) { - throw new Error('AppRouter must be rendered within the AppProvider'); + + // TODO: Private access for now, probably replace with path -> node lookup method on the API + if (!('getRouteObjects' in routeResolutionsApi)) { + throw new Error('Unexpected route resolution API implementation'); } - const { routeObjects, appIdentityProxy } = internalAppContext; + const routeObjects = ( + routeResolutionsApi as RouteResolverProxy + ).getRouteObjects(); // If the app hasn't configured a sign-in page, we just continue as guest. if (!SignInPageComponent) { diff --git a/packages/frontend-app-api/src/extensions/AppRoutes.tsx b/plugins/app/src/extensions/AppRoutes.tsx similarity index 98% rename from packages/frontend-app-api/src/extensions/AppRoutes.tsx rename to plugins/app/src/extensions/AppRoutes.tsx index 6ef7e2a271..5880d6182e 100644 --- a/packages/frontend-app-api/src/extensions/AppRoutes.tsx +++ b/plugins/app/src/extensions/AppRoutes.tsx @@ -25,7 +25,6 @@ import { import { useRoutes } from 'react-router-dom'; export const AppRoutes = createExtension({ - namespace: 'app', name: 'routes', attachTo: { id: 'app/layout', input: 'content' }, inputs: { diff --git a/packages/frontend-app-api/src/extensions/AppThemeApi.tsx b/plugins/app/src/extensions/AppThemeApi.tsx similarity index 90% rename from packages/frontend-app-api/src/extensions/AppThemeApi.tsx rename to plugins/app/src/extensions/AppThemeApi.tsx index d0dcad34e8..a31e29e58b 100644 --- a/packages/frontend-app-api/src/extensions/AppThemeApi.tsx +++ b/plugins/app/src/extensions/AppThemeApi.tsx @@ -28,7 +28,8 @@ import { createApiFactory, appThemeApiRef, } from '@backstage/frontend-plugin-api'; -import { AppThemeSelector } from '@backstage/core-app-api'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { AppThemeSelector } from '../../../../packages/core-app-api/src/apis/implementations'; /** * Contains the themes installed into the app. @@ -36,7 +37,9 @@ import { AppThemeSelector } from '@backstage/core-app-api'; export const AppThemeApi = ApiBlueprint.makeWithOverrides({ name: 'app-theme', inputs: { - themes: createExtensionInput([ThemeBlueprint.dataRefs.theme]), + themes: createExtensionInput([ThemeBlueprint.dataRefs.theme], { + replaces: [{ id: 'app', input: 'themes' }], + }), }, factory: (originalFactory, { inputs }) => { return originalFactory({ diff --git a/packages/frontend-app-api/src/extensions/ComponentsApi.tsx b/plugins/app/src/extensions/ComponentsApi.tsx similarity index 78% rename from packages/frontend-app-api/src/extensions/ComponentsApi.tsx rename to plugins/app/src/extensions/ComponentsApi.tsx index 5803aacf95..b578429253 100644 --- a/packages/frontend-app-api/src/extensions/ComponentsApi.tsx +++ b/plugins/app/src/extensions/ComponentsApi.tsx @@ -21,7 +21,8 @@ import { createApiFactory, componentsApiRef, } from '@backstage/frontend-plugin-api'; -import { DefaultComponentsApi } from '../apis/implementations/ComponentsApi'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { DefaultComponentsApi } from '../../../../packages/frontend-app-api/src/apis/implementations/ComponentsApi'; /** * Contains the shareable components installed into the app. @@ -29,9 +30,10 @@ import { DefaultComponentsApi } from '../apis/implementations/ComponentsApi'; export const ComponentsApi = ApiBlueprint.makeWithOverrides({ name: 'components', inputs: { - components: createExtensionInput([ - createComponentExtension.componentDataRef, - ]), + components: createExtensionInput( + [createComponentExtension.componentDataRef], + { replaces: [{ id: 'app', input: 'components' }] }, + ), }, factory: (originalFactory, { inputs }) => { return originalFactory({ diff --git a/packages/frontend-app-api/src/extensions/FeatureFlagsApi.ts b/plugins/app/src/extensions/FeatureFlagsApi.ts similarity index 88% rename from packages/frontend-app-api/src/extensions/FeatureFlagsApi.ts rename to plugins/app/src/extensions/FeatureFlagsApi.ts index 8016521539..40a44d1348 100644 --- a/packages/frontend-app-api/src/extensions/FeatureFlagsApi.ts +++ b/plugins/app/src/extensions/FeatureFlagsApi.ts @@ -20,7 +20,7 @@ import { featureFlagsApiRef, } from '@backstage/frontend-plugin-api'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { LocalStorageFeatureFlags } from '../../../core-app-api/src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags'; +import { LocalStorageFeatureFlags } from '../../../../packages/core-app-api/src/apis/implementations/FeatureFlagsApi/LocalStorageFeatureFlags'; /** * Contains the shareable icons installed into the app. diff --git a/packages/frontend-app-api/src/extensions/IconsApi.ts b/plugins/app/src/extensions/IconsApi.ts similarity index 81% rename from packages/frontend-app-api/src/extensions/IconsApi.ts rename to plugins/app/src/extensions/IconsApi.ts index d770000197..e73a74132a 100644 --- a/packages/frontend-app-api/src/extensions/IconsApi.ts +++ b/plugins/app/src/extensions/IconsApi.ts @@ -21,9 +21,10 @@ import { createApiFactory, iconsApiRef, } from '@backstage/frontend-plugin-api'; -import { DefaultIconsApi } from '../apis/implementations/IconsApi'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { icons as defaultIcons } from '../../../app-defaults/src/defaults'; +import { DefaultIconsApi } from '../../../../packages/frontend-app-api/src/apis/implementations/IconsApi'; +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { icons as defaultIcons } from '../../../../packages/app-defaults/src/defaults'; /** * Contains the shareable icons installed into the app. @@ -31,7 +32,9 @@ import { icons as defaultIcons } from '../../../app-defaults/src/defaults'; export const IconsApi = ApiBlueprint.makeWithOverrides({ name: 'icons', inputs: { - icons: createExtensionInput([IconBundleBlueprint.dataRefs.icons]), + icons: createExtensionInput([IconBundleBlueprint.dataRefs.icons], { + replaces: [{ id: 'app', input: 'icons' }], + }), }, factory: (originalFactory, { inputs }) => { return originalFactory({ diff --git a/packages/frontend-app-api/src/extensions/TranslationsApi.tsx b/plugins/app/src/extensions/TranslationsApi.tsx similarity index 83% rename from packages/frontend-app-api/src/extensions/TranslationsApi.tsx rename to plugins/app/src/extensions/TranslationsApi.tsx index 9c13c3b063..ed7ab1abdb 100644 --- a/packages/frontend-app-api/src/extensions/TranslationsApi.tsx +++ b/plugins/app/src/extensions/TranslationsApi.tsx @@ -25,7 +25,7 @@ import { } from '@backstage/core-plugin-api/alpha'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { I18nextTranslationApi } from '../../../core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi'; +import { I18nextTranslationApi } from '../../../../packages/core-app-api/src/apis/implementations/TranslationApi/I18nextTranslationApi'; /** * Contains translations that are installed in the app. @@ -33,9 +33,10 @@ import { I18nextTranslationApi } from '../../../core-app-api/src/apis/implementa export const TranslationsApi = ApiBlueprint.makeWithOverrides({ name: 'translations', inputs: { - translations: createExtensionInput([ - TranslationBlueprint.dataRefs.translation, - ]), + translations: createExtensionInput( + [TranslationBlueprint.dataRefs.translation], + { replaces: [{ id: 'app', input: 'translations' }] }, + ), }, factory: (originalFactory, { inputs }) => { return originalFactory({ diff --git a/packages/frontend-app-api/src/extensions/components.tsx b/plugins/app/src/extensions/components.tsx similarity index 92% rename from packages/frontend-app-api/src/extensions/components.tsx rename to plugins/app/src/extensions/components.tsx index 4f6574ab3e..829cb99ea2 100644 --- a/packages/frontend-app-api/src/extensions/components.tsx +++ b/plugins/app/src/extensions/components.tsx @@ -24,8 +24,7 @@ import { } from '@backstage/frontend-plugin-api'; import { ErrorPanel } from '@backstage/core-components'; // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { components as defaultComponents } from '../../../app-defaults/src/defaults'; -// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { components as defaultComponents } from '../../../../packages/app-defaults/src/defaults'; export const DefaultProgressComponent = createComponentExtension({ ref: coreComponentRefs.progress, diff --git a/packages/frontend-app-api/src/extensions/elements.tsx b/plugins/app/src/extensions/elements.tsx similarity index 97% rename from packages/frontend-app-api/src/extensions/elements.tsx rename to plugins/app/src/extensions/elements.tsx index 1ab7f97ba2..bbb6374ebe 100644 --- a/packages/frontend-app-api/src/extensions/elements.tsx +++ b/plugins/app/src/extensions/elements.tsx @@ -19,7 +19,6 @@ import { AppRootElementBlueprint } from '@backstage/frontend-plugin-api'; import React from 'react'; export const oauthRequestDialogAppRootElement = AppRootElementBlueprint.make({ - namespace: 'app', name: 'oauth-request-dialog', params: { element: , @@ -28,7 +27,6 @@ export const oauthRequestDialogAppRootElement = AppRootElementBlueprint.make({ export const alertDisplayAppRootElement = AppRootElementBlueprint.makeWithOverrides({ - namespace: 'app', name: 'alert-display', config: { schema: { diff --git a/plugins/app/src/extensions/index.ts b/plugins/app/src/extensions/index.ts new file mode 100644 index 0000000000..157f7ddb62 --- /dev/null +++ b/plugins/app/src/extensions/index.ts @@ -0,0 +1,35 @@ +/* + * 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 { App } from './App'; +export { AppLanguageApi } from './AppLanguageApi'; +export { AppLayout } from './AppLayout'; +export { AppNav } from './AppNav'; +export { AppRoot } from './AppRoot'; +export { AppRoutes } from './AppRoutes'; +export { AppThemeApi, DarkTheme, LightTheme } from './AppThemeApi'; +export { ComponentsApi } from './ComponentsApi'; +export { IconsApi } from './IconsApi'; +export { FeatureFlagsApi } from './FeatureFlagsApi'; +export { TranslationsApi } from './TranslationsApi'; +export { + DefaultProgressComponent, + DefaultErrorBoundaryComponent, + DefaultNotFoundErrorPageComponent, +} from './components'; +export { + oauthRequestDialogAppRootElement, + alertDisplayAppRootElement, +} from './elements'; diff --git a/plugins/app/src/index.ts b/plugins/app/src/index.ts new file mode 100644 index 0000000000..24f65df618 --- /dev/null +++ b/plugins/app/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { appPlugin as default } from './plugin'; diff --git a/packages/backend-tasks/src/tasks/__testUtils__/createTestScopedSignal.ts b/plugins/app/src/plugin.test.ts similarity index 63% rename from packages/backend-tasks/src/tasks/__testUtils__/createTestScopedSignal.ts rename to plugins/app/src/plugin.test.ts index 6a497ea266..80588710a5 100644 --- a/packages/backend-tasks/src/tasks/__testUtils__/createTestScopedSignal.ts +++ b/plugins/app/src/plugin.test.ts @@ -1,5 +1,5 @@ /* - * Copyright 2023 The Backstage Authors + * Copyright 2024 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,16 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { appPlugin } from './plugin'; -export function createTestScopedSignal(): () => AbortSignal { - let testAbortController = new AbortController(); - - beforeEach(() => { - testAbortController = new AbortController(); +describe('app', () => { + it('should export plugin', () => { + expect(appPlugin).toBeDefined(); }); - afterEach(() => { - testAbortController.abort(); - }); - - return () => testAbortController.signal; -} +}); diff --git a/plugins/app/src/plugin.ts b/plugins/app/src/plugin.ts new file mode 100644 index 0000000000..ff0c69faec --- /dev/null +++ b/plugins/app/src/plugin.ts @@ -0,0 +1,64 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createFrontendPlugin } from '@backstage/frontend-plugin-api'; +import { + App, + AppLanguageApi, + AppLayout, + AppNav, + AppRoot, + AppRoutes, + AppThemeApi, + DarkTheme, + LightTheme, + ComponentsApi, + IconsApi, + FeatureFlagsApi, + TranslationsApi, + DefaultProgressComponent, + DefaultNotFoundErrorPageComponent, + DefaultErrorBoundaryComponent, + oauthRequestDialogAppRootElement, + alertDisplayAppRootElement, +} from './extensions'; +import { apis } from './defaultApis'; + +/** @public */ +export const appPlugin = createFrontendPlugin({ + id: 'app', + extensions: [ + ...apis, + App, + AppLanguageApi, + AppLayout, + AppNav, + AppRoot, + AppRoutes, + AppThemeApi, + DarkTheme, + LightTheme, + ComponentsApi, + IconsApi, + FeatureFlagsApi, + TranslationsApi, + DefaultProgressComponent, + DefaultNotFoundErrorPageComponent, + DefaultErrorBoundaryComponent, + oauthRequestDialogAppRootElement, + alertDisplayAppRootElement, + ], +}); diff --git a/plugins/app/src/setupTests.ts b/plugins/app/src/setupTests.ts new file mode 100644 index 0000000000..658016ffdd --- /dev/null +++ b/plugins/app/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; diff --git a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md index 779a96f093..294ab9204d 100644 --- a/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-atlassian-provider/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend-module-atlassian-provider +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-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/plugin-auth-node@0.5.2-next.0 + ## 0.2.4 ### Patch Changes diff --git a/plugins/auth-backend-module-atlassian-provider/package.json b/plugins/auth-backend-module-atlassian-provider/package.json index 4be0473a17..105e69150b 100644 --- a/plugins/auth-backend-module-atlassian-provider/package.json +++ b/plugins/auth-backend-module-atlassian-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-atlassian-provider", - "version": "0.2.4", + "version": "0.3.0-next.1", "description": "The atlassian-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md index 6f2dec2347..ef6008aa90 100644 --- a/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-aws-alb-provider/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-auth-backend-module-aws-alb-provider +## 0.2.0-next.1 + +### Patch Changes + +- 8d1fb8d: Throw correct error when email is missing from the claims +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/plugin-auth-backend@0.23.0-next.1 + +## 0.2.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 + +- ecbc47e: Fix a bug where the signer was checked from the payload instead of the header +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-auth-backend@0.23.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/errors@1.2.4 + ## 0.1.15 ### Patch Changes diff --git a/plugins/auth-backend-module-aws-alb-provider/package.json b/plugins/auth-backend-module-aws-alb-provider/package.json index 7b3498ceb2..de5fb31298 100644 --- a/plugins/auth-backend-module-aws-alb-provider/package.json +++ b/plugins/auth-backend-module-aws-alb-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-aws-alb-provider", - "version": "0.1.15", + "version": "0.2.0-next.1", "description": "The aws-alb provider module for the Backstage auth backend.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts index c0e32d37a3..73f859df52 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.test.ts @@ -35,7 +35,6 @@ describe('AwsAlbProvider', () => { email: 'user.name@email.test', exp: Date.now() + 10000, iss: 'ISSUER_URL', - signer: 'SIGNER_ARN', }; const signingKey = new TextEncoder().encode('signingKey'); let mockJwt: string; @@ -78,7 +77,7 @@ describe('AwsAlbProvider', () => { beforeEach(async () => { mockJwt = await new SignJWT(mockClaims) - .setProtectedHeader({ alg: 'HS256' }) + .setProtectedHeader({ alg: 'HS256', signer: 'SIGNER_ARN' }) .sign(signingKey); }); @@ -147,6 +146,34 @@ describe('AwsAlbProvider', () => { ); }); + it('Email is missing', async () => { + const jwt = await new SignJWT({ ...mockClaims, email: undefined }) + .setProtectedHeader({ alg: 'HS256', signer: 'SIGNER_ARN' }) + .sign(signingKey); + const req = { + header: jest.fn(name => { + if (name === ALB_JWT_HEADER) { + return jwt; + } else if (name === ALB_ACCESS_TOKEN_HEADER) { + return mockAccessToken; + } + return undefined; + }), + } as unknown as express.Request; + await expect( + awsAlbAuthenticator.authenticate( + { req }, + { + issuer: 'ISSUER_URL', + signer: undefined, + getKey: jest.fn().mockResolvedValue(signingKey), + }, + ), + ).rejects.toThrow( + 'Exception occurred during JWT processing: AuthenticationError: Missing email in the JWT token', + ); + }); + it('issuer is missing', async () => { const jwt = await new SignJWT({}) .setProtectedHeader({ alg: 'HS256' }) @@ -206,8 +233,8 @@ describe('AwsAlbProvider', () => { }); it('signer is invalid', async () => { - const jwt = await new SignJWT({ signer: 'INVALID_SIGNER_ARN' }) - .setProtectedHeader({ alg: 'HS256' }) + const jwt = await new SignJWT({}) + .setProtectedHeader({ alg: 'HS256', signer: 'INVALID_SIGNER_ARN' }) .sign(signingKey); const req = { header: jest.fn(name => { diff --git a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.ts b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.ts index f62fe4175b..2e7fe1cd26 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/authenticator.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/authenticator.ts @@ -15,11 +15,11 @@ */ import { AuthenticationError } from '@backstage/errors'; -import { AwsAlbClaims, AwsAlbResult } from './types'; +import { AwsAlbClaims, AwsAlbProtectedHeader, AwsAlbResult } from './types'; import { jwtVerify } from 'jose'; import { - PassportProfile, createProxyAuthenticator, + PassportProfile, } from '@backstage/plugin-auth-node'; import NodeCache from 'node-cache'; import { makeProfileInfo, provisionKeyCache } from './helpers'; @@ -60,14 +60,19 @@ export const awsAlbAuthenticator = createProxyAuthenticator({ try { const verifyResult = await jwtVerify(jwt, getKey); + const header = verifyResult.protectedHeader as AwsAlbProtectedHeader; const claims = verifyResult.payload as AwsAlbClaims; if (claims?.iss !== issuer) { throw new AuthenticationError('Issuer mismatch on JWT token'); - } else if (signer && claims?.signer !== signer) { + } else if (signer && header?.signer !== signer) { throw new AuthenticationError('Signer mismatch on JWT token'); } + if (!claims.email) { + throw new AuthenticationError(`Missing email in the JWT token`); + } + const fullProfile: PassportProfile = { provider: 'unknown', id: claims.sub, diff --git a/plugins/auth-backend-module-aws-alb-provider/src/types.ts b/plugins/auth-backend-module-aws-alb-provider/src/types.ts index 679535804e..b4c792a5f9 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/types.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/types.ts @@ -38,5 +38,10 @@ export type AwsAlbClaims = { email: string; exp: number; iss: string; - signer: string; +}; +/** + * @internal + */ +export type AwsAlbProtectedHeader = { + signer?: string; }; diff --git a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md index 3961bab52a..cb1f2da1fb 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-azure-easyauth-provider/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-auth-backend-module-azure-easyauth-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## 0.2.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/plugin-auth-node@0.5.2-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + ## 0.1.6 ### Patch Changes diff --git a/plugins/auth-backend-module-azure-easyauth-provider/package.json b/plugins/auth-backend-module-azure-easyauth-provider/package.json index df83acff7b..9688d88308 100644 --- a/plugins/auth-backend-module-azure-easyauth-provider/package.json +++ b/plugins/auth-backend-module-azure-easyauth-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-azure-easyauth-provider", - "version": "0.1.6", + "version": "0.2.0-next.1", "description": "The azure-easyauth-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md index ff2c8725be..92484e03fe 100644 --- a/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-bitbucket-provider/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend-module-bitbucket-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## 0.2.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/plugin-auth-node@0.5.2-next.0 + ## 0.1.6 ### Patch Changes diff --git a/plugins/auth-backend-module-bitbucket-provider/package.json b/plugins/auth-backend-module-bitbucket-provider/package.json index ed8cfa981a..e2385ca6ed 100644 --- a/plugins/auth-backend-module-bitbucket-provider/package.json +++ b/plugins/auth-backend-module-bitbucket-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-bitbucket-provider", - "version": "0.1.6", + "version": "0.2.0-next.1", "description": "The bitbucket-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md index 51f1ce5b17..1ed55e9d69 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-cloudflare-access-provider/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-auth-backend-module-cloudflare-access-provider +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + +## 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/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.2.0 ### Minor Changes diff --git a/plugins/auth-backend-module-cloudflare-access-provider/package.json b/plugins/auth-backend-module-cloudflare-access-provider/package.json index 646bf720a2..b40928a4bf 100644 --- a/plugins/auth-backend-module-cloudflare-access-provider/package.json +++ b/plugins/auth-backend-module-cloudflare-access-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-cloudflare-access-provider", - "version": "0.2.0", + "version": "0.3.0-next.1", "description": "The cloudflare-access-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md index 4099ad1c09..32de67cf73 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gcp-iap-provider/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-auth-backend-module-gcp-iap-provider +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.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/plugin-auth-node@0.5.2-next.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.18 ### Patch Changes diff --git a/plugins/auth-backend-module-gcp-iap-provider/package.json b/plugins/auth-backend-module-gcp-iap-provider/package.json index 41c8ccc2b8..94e52df683 100644 --- a/plugins/auth-backend-module-gcp-iap-provider/package.json +++ b/plugins/auth-backend-module-gcp-iap-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gcp-iap-provider", - "version": "0.2.18", + "version": "0.3.0-next.1", "description": "A GCP IAP auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-github-provider/CHANGELOG.md b/plugins/auth-backend-module-github-provider/CHANGELOG.md index 46387e4421..b898b8b23f 100644 --- a/plugins/auth-backend-module-github-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-github-provider/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend-module-github-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## 0.2.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/plugin-auth-node@0.5.2-next.0 + ## 0.1.20 ### Patch Changes diff --git a/plugins/auth-backend-module-github-provider/package.json b/plugins/auth-backend-module-github-provider/package.json index 5e0f0d527b..08e3acaf8f 100644 --- a/plugins/auth-backend-module-github-provider/package.json +++ b/plugins/auth-backend-module-github-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-github-provider", - "version": "0.1.20", + "version": "0.2.0-next.1", "description": "The github-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md index 0a9186b385..8cf6bbc41e 100644 --- a/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-gitlab-provider/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend-module-gitlab-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## 0.2.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/plugin-auth-node@0.5.2-next.0 + ## 0.1.20 ### Patch Changes diff --git a/plugins/auth-backend-module-gitlab-provider/package.json b/plugins/auth-backend-module-gitlab-provider/package.json index 4c48fd014c..dc562c16e8 100644 --- a/plugins/auth-backend-module-gitlab-provider/package.json +++ b/plugins/auth-backend-module-gitlab-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-gitlab-provider", - "version": "0.1.20", + "version": "0.2.0-next.1", "description": "The gitlab-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-google-provider/CHANGELOG.md b/plugins/auth-backend-module-google-provider/CHANGELOG.md index 3eb7e65ec6..72c422b3bc 100644 --- a/plugins/auth-backend-module-google-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-google-provider/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend-module-google-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## 0.2.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/plugin-auth-node@0.5.2-next.0 + ## 0.1.20 ### Patch Changes diff --git a/plugins/auth-backend-module-google-provider/package.json b/plugins/auth-backend-module-google-provider/package.json index 307246514f..3f4305d8e5 100644 --- a/plugins/auth-backend-module-google-provider/package.json +++ b/plugins/auth-backend-module-google-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-google-provider", - "version": "0.1.20", + "version": "0.2.0-next.1", "description": "A Google auth provider module for the Backstage auth backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-guest-provider/CHANGELOG.md b/plugins/auth-backend-module-guest-provider/CHANGELOG.md index 26dabc7b5c..69c7e94a3e 100644 --- a/plugins/auth-backend-module-guest-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-guest-provider/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-auth-backend-module-guest-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + +## 0.2.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-auth-node@0.5.2-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + ## 0.1.9 ### Patch Changes diff --git a/plugins/auth-backend-module-guest-provider/package.json b/plugins/auth-backend-module-guest-provider/package.json index d1b8caf3eb..d46324f4de 100644 --- a/plugins/auth-backend-module-guest-provider/package.json +++ b/plugins/auth-backend-module-guest-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-guest-provider", - "version": "0.1.9", + "version": "0.2.0-next.1", "description": "The guest-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md index 2c3e4f6d33..094eee92a8 100644 --- a/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-microsoft-provider/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-auth-backend-module-microsoft-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## 0.2.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 + +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + ## 0.1.18 ### Patch Changes diff --git a/plugins/auth-backend-module-microsoft-provider/api-report.md b/plugins/auth-backend-module-microsoft-provider/api-report.md index aa9bd8db5f..6aef395d7c 100644 --- a/plugins/auth-backend-module-microsoft-provider/api-report.md +++ b/plugins/auth-backend-module-microsoft-provider/api-report.md @@ -32,5 +32,9 @@ export namespace microsoftSignInResolvers { OAuthAuthenticatorResult, unknown >; + const userIdMatchingUserEntityAnnotation: SignInResolverFactory< + OAuthAuthenticatorResult, + unknown + >; } ``` diff --git a/plugins/auth-backend-module-microsoft-provider/package.json b/plugins/auth-backend-module-microsoft-provider/package.json index 8a1537771b..1a81038994 100644 --- a/plugins/auth-backend-module-microsoft-provider/package.json +++ b/plugins/auth-backend-module-microsoft-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-microsoft-provider", - "version": "0.1.18", + "version": "0.2.0-next.1", "description": "The microsoft-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-microsoft-provider/src/resolvers.ts b/plugins/auth-backend-module-microsoft-provider/src/resolvers.ts index 7ef4a57175..db7aa4f7f3 100644 --- a/plugins/auth-backend-module-microsoft-provider/src/resolvers.ts +++ b/plugins/auth-backend-module-microsoft-provider/src/resolvers.ts @@ -28,7 +28,7 @@ import { */ export namespace microsoftSignInResolvers { /** - * Looks up the user by matching their Microsoft username to the entity name. + * Looks up the user by matching their Microsoft email to the email entity annotation. */ export const emailMatchingUserEntityAnnotation = createSignInResolverFactory({ create() { @@ -50,4 +50,31 @@ export namespace microsoftSignInResolvers { }; }, }); + /** + * Looks up the user by matching their Microsoft user id to the user id entity annotation. + */ + export const userIdMatchingUserEntityAnnotation = createSignInResolverFactory( + { + create() { + return async ( + info: SignInInfo>, + ctx, + ) => { + const { result } = info; + + const id = result.fullProfile.id; + + if (!id) { + throw new Error('Microsoft profile contained no id'); + } + + return ctx.signInWithCatalogUser({ + annotations: { + 'graph.microsoft.com/user-id': id, + }, + }); + }; + }, + }, + ); } diff --git a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md index 7762658a12..1e91fac858 100644 --- a/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-provider/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend-module-oauth2-provider +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-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/plugin-auth-node@0.5.2-next.0 + ## 0.2.4 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-provider/package.json b/plugins/auth-backend-module-oauth2-provider/package.json index d37a00fccc..f5ad94f1b8 100644 --- a/plugins/auth-backend-module-oauth2-provider/package.json +++ b/plugins/auth-backend-module-oauth2-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-provider", - "version": "0.2.4", + "version": "0.3.0-next.1", "description": "The oauth2-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md index a10e533977..240a3853f2 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oauth2-proxy-provider/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-auth-backend-module-oauth2-proxy-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 + +## 0.2.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/plugin-auth-node@0.5.2-next.0 + - @backstage/errors@1.2.4 + ## 0.1.16 ### Patch Changes diff --git a/plugins/auth-backend-module-oauth2-proxy-provider/package.json b/plugins/auth-backend-module-oauth2-proxy-provider/package.json index 2235784779..9dce1fec17 100644 --- a/plugins/auth-backend-module-oauth2-proxy-provider/package.json +++ b/plugins/auth-backend-module-oauth2-proxy-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oauth2-proxy-provider", - "version": "0.1.16", + "version": "0.2.0-next.1", "description": "The oauth2-proxy-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md index 36fbf7e8c4..3b087761d0 100644 --- a/plugins/auth-backend-module-oidc-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-oidc-provider/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-auth-backend-module-oidc-provider +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-auth-backend@0.23.0-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/plugin-auth-backend@0.23.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + ## 0.2.4 ### Patch Changes diff --git a/plugins/auth-backend-module-oidc-provider/package.json b/plugins/auth-backend-module-oidc-provider/package.json index a90908c491..1a1d6c9c8a 100644 --- a/plugins/auth-backend-module-oidc-provider/package.json +++ b/plugins/auth-backend-module-oidc-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-oidc-provider", - "version": "0.2.4", + "version": "0.3.0-next.1", "description": "The oidc-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-okta-provider/CHANGELOG.md b/plugins/auth-backend-module-okta-provider/CHANGELOG.md index b66256f002..08d2ef1f2f 100644 --- a/plugins/auth-backend-module-okta-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-okta-provider/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend-module-okta-provider +## 0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## 0.1.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/plugin-auth-node@0.5.2-next.0 + ## 0.0.16 ### Patch Changes diff --git a/plugins/auth-backend-module-okta-provider/package.json b/plugins/auth-backend-module-okta-provider/package.json index d1330f2457..0965e1548d 100644 --- a/plugins/auth-backend-module-okta-provider/package.json +++ b/plugins/auth-backend-module-okta-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-okta-provider", - "version": "0.0.16", + "version": "0.1.0-next.1", "description": "The okta-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md index 7302199487..796813e0a3 100644 --- a/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-onelogin-provider/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-backend-module-onelogin-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + +## 0.2.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/plugin-auth-node@0.5.2-next.0 + ## 0.1.4 ### Patch Changes diff --git a/plugins/auth-backend-module-onelogin-provider/package.json b/plugins/auth-backend-module-onelogin-provider/package.json index 2e0a997e77..53e8e646ca 100644 --- a/plugins/auth-backend-module-onelogin-provider/package.json +++ b/plugins/auth-backend-module-onelogin-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-onelogin-provider", - "version": "0.1.4", + "version": "0.2.0-next.1", "description": "The onelogin-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md index 79ab8db9d5..ebbff3416d 100644 --- a/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-pinniped-provider/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-auth-backend-module-pinniped-provider +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + +## 0.2.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/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + ## 0.1.17 ### Patch Changes diff --git a/plugins/auth-backend-module-pinniped-provider/package.json b/plugins/auth-backend-module-pinniped-provider/package.json index bafbd82855..932ad93b38 100644 --- a/plugins/auth-backend-module-pinniped-provider/package.json +++ b/plugins/auth-backend-module-pinniped-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-pinniped-provider", - "version": "0.1.17", + "version": "0.2.0-next.1", "description": "The pinniped-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md index c7eefd4d0e..8b6540ddf3 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md +++ b/plugins/auth-backend-module-vmware-cloud-provider/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-auth-backend-module-vmware-cloud-provider +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + +## 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/plugin-auth-node@0.5.2-next.0 + - @backstage/catalog-model@1.6.0 + ## 0.2.4 ### Patch Changes diff --git a/plugins/auth-backend-module-vmware-cloud-provider/package.json b/plugins/auth-backend-module-vmware-cloud-provider/package.json index 7386056a3c..2f198ebacb 100644 --- a/plugins/auth-backend-module-vmware-cloud-provider/package.json +++ b/plugins/auth-backend-module-vmware-cloud-provider/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend-module-vmware-cloud-provider", - "version": "0.2.4", + "version": "0.3.0-next.1", "description": "The vmware-cloud-provider backend module for the auth plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index 925923d2fd..4244638abd 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,75 @@ # @backstage/plugin-auth-backend +## 0.23.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0-next.1 + - @backstage/plugin-auth-node@0.5.2-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/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-google-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0-next.1 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.0-next.1 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.0-next.1 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0-next.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## 0.23.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 + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- Updated dependencies + - @backstage/plugin-auth-backend-module-aws-alb-provider@0.2.0-next.0 + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-backend-module-microsoft-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-atlassian-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-bitbucket-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-github-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-gitlab-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-google-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-oauth2-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.0-next.0 + - @backstage/plugin-auth-backend-module-oidc-provider@0.3.0-next.0 + - @backstage/plugin-auth-backend-module-okta-provider@0.1.0-next.0 + - @backstage/plugin-auth-backend-module-onelogin-provider@0.2.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.22.10 ### Patch Changes diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index 1f33886759..51f80024ae 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -533,6 +533,7 @@ export const providers: Readonly<{ resolvers: Readonly<{ emailMatchingUserEntityProfileEmail: () => SignInResolver_2; emailLocalPartMatchingUserEntityName: () => SignInResolver_2; + userIdMatchingUserEntityAnnotation: () => SignInResolver_2; emailMatchingUserEntityAnnotation: () => SignInResolver_2; }>; }>; diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 8983d0983e..f090b86f4e 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-backend", - "version": "0.22.10", + "version": "0.23.0-next.1", "description": "A Backstage backend plugin that handles authentication", "backstage": { "role": "backend-plugin", diff --git a/plugins/auth-backend/src/identity/UserInfoDatabaseHandler.test.ts b/plugins/auth-backend/src/identity/UserInfoDatabaseHandler.test.ts index ef3d0f6c8b..4d696aa8f2 100644 --- a/plugins/auth-backend/src/identity/UserInfoDatabaseHandler.test.ts +++ b/plugins/auth-backend/src/identity/UserInfoDatabaseHandler.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { resolvePackagePath } from '@backstage/backend-common'; +import { resolvePackagePath } from '@backstage/backend-plugin-api'; import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; import { Knex } from 'knex'; import { UserInfoDatabaseHandler } from './UserInfoDatabaseHandler'; diff --git a/plugins/auth-backend/src/providers/microsoft/provider.ts b/plugins/auth-backend/src/providers/microsoft/provider.ts index f6a3a83bcb..f0b019d1c7 100644 --- a/plugins/auth-backend/src/providers/microsoft/provider.ts +++ b/plugins/auth-backend/src/providers/microsoft/provider.ts @@ -65,5 +65,7 @@ export const microsoft = createAuthProviderIntegration({ commonSignInResolvers.emailMatchingUserEntityProfileEmail(), emailMatchingUserEntityAnnotation: microsoftSignInResolvers.emailMatchingUserEntityAnnotation(), + userIdMatchingUserEntityAnnotation: + microsoftSignInResolvers.userIdMatchingUserEntityAnnotation(), }), }); diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 79c783d814..4565a93cf7 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-auth-node +## 0.5.2-next.1 + +### Patch Changes + +- c46eb0f: Extend the "unable to resolve user identity" message +- 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/errors@1.2.4 + - @backstage/types@1.1.1 + +## 0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.5.0 ### Minor Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index 781d930c21..23818fcc31 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.5.0", + "version": "0.5.2-next.1", "backstage": { "role": "node-library", "pluginId": "auth", diff --git a/plugins/auth-node/src/sign-in/readDeclarativeSignInResolver.ts b/plugins/auth-node/src/sign-in/readDeclarativeSignInResolver.ts index 82b4918326..ed8f4baeeb 100644 --- a/plugins/auth-node/src/sign-in/readDeclarativeSignInResolver.ts +++ b/plugins/auth-node/src/sign-in/readDeclarativeSignInResolver.ts @@ -66,6 +66,8 @@ export function readDeclarativeSignInResolver( } } - throw new Error('Failed to sign-in, unable to resolve user identity'); + throw new Error( + 'Failed to sign-in, unable to resolve user identity. Please verify that your catalog contains the expected User entities that would match your configured sign-in resolver.', + ); }; } diff --git a/plugins/auth-react/CHANGELOG.md b/plugins/auth-react/CHANGELOG.md index f88d6210a8..2aac588abe 100644 --- a/plugins/auth-react/CHANGELOG.md +++ b/plugins/auth-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-auth-react +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + ## 0.1.5 ### Patch Changes diff --git a/plugins/auth-react/package.json b/plugins/auth-react/package.json index ae534e89d9..2f76c289b3 100644 --- a/plugins/auth-react/package.json +++ b/plugins/auth-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-react", - "version": "0.1.5", + "version": "0.1.6-next.0", "description": "Web library for the auth plugin", "backstage": { "role": "web-library", diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index dcad12d670..aea8617e9b 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## 0.4.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.4.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 2de0cf81a7..1d9891ade3 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", - "version": "0.4.0", + "version": "0.4.2-next.1", "description": "A Backstage catalog backend module that helps integrate towards AWS", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 1d9e799c20..4215a5a156 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## 0.2.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.2.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 186e12e8e4..ce62913fe5 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", - "version": "0.2.0", + "version": "0.2.2-next.1", "description": "A Backstage catalog backend module that helps integrate towards Azure", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md index ccee7e4572..c04f478566 100644 --- a/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-backstage-openapi/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-catalog-backend-module-backstage-openapi +## 0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-openapi-utils@0.1.18-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## 0.4.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-openapi-utils@0.1.18-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.3.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-backstage-openapi/package.json b/plugins/catalog-backend-module-backstage-openapi/package.json index ca1e220c62..54de9a7b3b 100644 --- a/plugins/catalog-backend-module-backstage-openapi/package.json +++ b/plugins/catalog-backend-module-backstage-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-backstage-openapi", - "version": "0.3.0", + "version": "0.4.0-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 05b0f40fb7..8def9570bf 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.3.2-next.1 + +### Patch Changes + +- 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@1.14.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.3.2-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.3.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 13ee89e71c..04de284c56 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", - "version": "0.3.0", + "version": "0.3.2-next.1", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index 5946dace67..e45ac208c4 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## 0.2.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.2.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index c53dd1a1c3..ea2c30f112 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", - "version": "0.2.0", + "version": "0.2.2-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-gcp/CHANGELOG.md b/plugins/catalog-backend-module-gcp/CHANGELOG.md index 7b6ca7f55e..6af3647bd9 100644 --- a/plugins/catalog-backend-module-gcp/CHANGELOG.md +++ b/plugins/catalog-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-catalog-backend-module-gcp +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## 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/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.2.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-gcp/package.json b/plugins/catalog-backend-module-gcp/package.json index 4793e6b167..4441a7ca8b 100644 --- a/plugins/catalog-backend-module-gcp/package.json +++ b/plugins/catalog-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gcp", - "version": "0.2.0", + "version": "0.3.0-next.1", "description": "A Backstage catalog backend module that helps integrate towards GCP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 74977e4c9f..abbb586446 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## 0.2.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.2.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 6b6c9d1a5c..2937b47db0 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.2.0", + "version": "0.2.2-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "catalog", diff --git a/plugins/catalog-backend-module-github-org/CHANGELOG.md b/plugins/catalog-backend-module-github-org/CHANGELOG.md index c130f00d2b..5ade859371 100644 --- a/plugins/catalog-backend-module-github-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-github-org/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-catalog-backend-module-github-org +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.7.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-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/plugin-catalog-backend-module-github@0.7.3-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/config@1.2.0 + ## 0.2.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-github-org/package.json b/plugins/catalog-backend-module-github-org/package.json index a902d80c47..37d2804e60 100644 --- a/plugins/catalog-backend-module-github-org/package.json +++ b/plugins/catalog-backend-module-github-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github-org", - "version": "0.2.0", + "version": "0.3.0-next.1", "description": "The github-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index 4d7a38f5d7..b956c2e9e6 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-catalog-backend-module-github +## 0.7.3-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/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.7.3-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.7.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-github/api-report.md b/plugins/catalog-backend-module-github/api-report.md index dad81f8681..025d845644 100644 --- a/plugins/catalog-backend-module-github/api-report.md +++ b/plugins/catalog-backend-module-github/api-report.md @@ -5,6 +5,7 @@ ```ts import { AnalyzeOptions } from '@backstage/plugin-catalog-node'; import { AuthService } from '@backstage/backend-plugin-api'; +import { CatalogApi } from '@backstage/catalog-client'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; import { Config } from '@backstage/config'; @@ -129,6 +130,7 @@ export type GithubLocationAnalyzerOptions = { tokenManager?: TokenManager; auth?: AuthService; githubCredentialsProvider?: GithubCredentialsProvider; + catalog?: CatalogApi; }; // @public diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 81cc498ce5..16af5a72c5 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-github", - "version": "0.7.0", + "version": "0.7.3-next.1", "description": "A Backstage catalog backend module that helps integrate towards GitHub", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts index 7e6ac73054..b635878f92 100644 --- a/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts +++ b/plugins/catalog-backend-module-github/src/analyzers/GithubLocationAnalyzer.ts @@ -44,6 +44,7 @@ export type GithubLocationAnalyzerOptions = { tokenManager?: TokenManager; auth?: AuthService; githubCredentialsProvider?: GithubCredentialsProvider; + catalog?: CatalogApi; }; /** @public */ @@ -54,7 +55,8 @@ export class GithubLocationAnalyzer implements ScmLocationAnalyzer { private readonly auth: AuthService; constructor(options: GithubLocationAnalyzerOptions) { - this.catalogClient = new CatalogClient({ discoveryApi: options.discovery }); + this.catalogClient = + options.catalog ?? new CatalogClient({ discoveryApi: options.discovery }); this.integrations = ScmIntegrations.fromConfig(options.config); this.githubCredentialsProvider = options.githubCredentialsProvider || diff --git a/plugins/catalog-backend-module-github/src/module/githubCatalogModule.ts b/plugins/catalog-backend-module-github/src/module/githubCatalogModule.ts index 809a1a5094..15d36a3011 100644 --- a/plugins/catalog-backend-module-github/src/module/githubCatalogModule.ts +++ b/plugins/catalog-backend-module-github/src/module/githubCatalogModule.ts @@ -21,6 +21,7 @@ import { import { catalogAnalysisExtensionPoint, catalogProcessingExtensionPoint, + catalogServiceRef, } from '@backstage/plugin-catalog-node/alpha'; import { eventsServiceRef } from '@backstage/plugin-events-node'; import { GithubEntityProvider } from '../providers/GithubEntityProvider'; @@ -37,34 +38,37 @@ export const githubCatalogModule = createBackendModule({ register(env) { env.registerInit({ deps: { - analyzers: catalogAnalysisExtensionPoint, + catalogAnalyzers: catalogAnalysisExtensionPoint, auth: coreServices.auth, - catalog: catalogProcessingExtensionPoint, + catalogProcessing: catalogProcessingExtensionPoint, config: coreServices.rootConfig, discovery: coreServices.discovery, events: eventsServiceRef, logger: coreServices.logger, scheduler: coreServices.scheduler, + catalog: catalogServiceRef, }, async init({ - catalog, + catalogProcessing, config, events, logger, scheduler, - analyzers, + catalogAnalyzers, discovery, auth, + catalog, }) { - analyzers.addScmLocationAnalyzer( + catalogAnalyzers.addScmLocationAnalyzer( new GithubLocationAnalyzer({ discovery, config, auth, + catalog, }), ); - catalog.addEntityProvider( + catalogProcessing.addEntityProvider( GithubEntityProvider.fromConfig(config, { events, logger, diff --git a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md index b6000e7a6d..a96c08f602 100644 --- a/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab-org/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-catalog-backend-module-gitlab-org +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-catalog-backend-module-gitlab@0.4.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.2.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-catalog-backend-module-gitlab@0.4.2-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + ## 0.1.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-gitlab-org/package.json b/plugins/catalog-backend-module-gitlab-org/package.json index ba4fcd844b..563ae32df9 100644 --- a/plugins/catalog-backend-module-gitlab-org/package.json +++ b/plugins/catalog-backend-module-gitlab-org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab-org", - "version": "0.1.0", + "version": "0.2.0-next.1", "description": "The gitlab-org backend module for the catalog plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index e8e40a7391..2022e3e511 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.4.2-next.1 + +### Patch Changes + +- 53b24d9: Internal update to use the new cache manager +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.4.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- b446954: Remove dependency on backend-common +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.4.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index ef2bd69960..c99443a5d9 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", - "version": "0.4.0", + "version": "0.4.2-next.1", "description": "A Backstage catalog backend module that helps integrate towards GitLab", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.ts b/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.ts index 29914db705..01e8018845 100644 --- a/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.ts +++ b/plugins/catalog-backend-module-gitlab/src/GitLabDiscoveryProcessor.ts @@ -27,10 +27,7 @@ import { } from '@backstage/plugin-catalog-node'; import { GitLabClient, GitLabProject, paginated } from './lib'; import { CacheService, LoggerService } from '@backstage/backend-plugin-api'; -import { - CacheManager, - PluginCacheManager, -} from '@backstage/backend-defaults/cache'; +import { CacheManager } from '@backstage/backend-defaults/cache'; /** * Extracts repositories out of an GitLab instance. @@ -64,13 +61,13 @@ export class GitLabDiscoveryProcessor implements CatalogProcessor { private constructor(options: { integrations: ScmIntegrationRegistry; - pluginCache: PluginCacheManager; + pluginCache: CacheService; logger: LoggerService; skipReposWithoutExactFileMatch?: boolean; skipForkedRepos?: boolean; }) { this.integrations = options.integrations; - this.cache = options.pluginCache.getClient(); + this.cache = options.pluginCache; this.logger = options.logger; this.skipReposWithoutExactFileMatch = options.skipReposWithoutExactFileMatch || false; diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index b46b77b0c1..2b01b76534 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.5.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + +## 0.5.3-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 4b28e39: Updated the README to include documentation for the new backend support +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + ## 0.5.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/README.md b/plugins/catalog-backend-module-incremental-ingestion/README.md index 0894d32031..3b847d4ad7 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/README.md +++ b/plugins/catalog-backend-module-incremental-ingestion/README.md @@ -42,57 +42,25 @@ The Incremental Entity Provider backend is designed for data sources that provid ## Installation 1. Install `@backstage/plugin-catalog-backend-module-incremental-ingestion` with `yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-incremental-ingestion` from the Backstage root directory. -2. In your catalog.ts, import `IncrementalCatalogBuilder` from `@backstage/plugin-catalog-backend-module-incremental-ingestion` and instantiate it with `await IncrementalCatalogBuilder.create(env, builder)`. You have to pass `builder` into `IncrementalCatalogBuilder.create` function because `IncrementalCatalogBuilder` will convert an `IncrementalEntityProvider` into an `EntityProvider` and call `builder.addEntityProvider`. -```ts -const builder = CatalogBuilder.create(env); -// incremental builder receives builder because it'll register -// incremental entity providers with the builder -const incrementalBuilder = await IncrementalCatalogBuilder.create(env, builder); -``` +2. Add the following code to the `packages/backend/src/index.ts` file: -3. After building the regular `CatalogBuilder`, build the incremental builder: +```diff ++ import { catalogModuleCustomIncrementalIngestionProvider } from './extensions/catalogCustomIncrementalIngestion'; -```ts -// Must be run first to ensure CatalogBuilder database migrations run before Incremental Entity Provider database migrations -const { processingEngine, router } = await builder.build(); -// Returns an optional - but highly recommended - set of administrative routes -const { incrementalAdminRouter } = await incrementBuilder.build(); -``` +const backend = createBackend(); -The final result should look something like this, ++ backend.add( ++ import( ++ '@backstage/plugin-catalog-backend-module-incremental-ingestion/alpha' ++ ), ++ ); -```ts -import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; -import { ScaffolderEntitiesProcessor } from '@backstage/plugin-scaffolder-backend'; -import { IncrementalCatalogBuilder } from '@backstage/plugin-catalog-backend-module-incremental-ingestion'; -import { Router } from 'express'; -import { Duration } from 'luxon'; -import { PluginEnvironment } from '../types'; +// We have created this in section **Adding an Incremental Entity Provider to the catalog** ++ backend.add(catalogModuleCustomIncrementalIngestionProvider); -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const builder = CatalogBuilder.create(env); - // incremental builder receives builder because it'll register - // incremental entity providers with the builder - const incrementalBuilder = await IncrementalCatalogBuilder.create( - env, - builder, - ); - - builder.addProcessor(new ScaffolderEntitiesProcessor()); - - const { processingEngine, router } = await builder.build(); - const { incrementalAdminRouter } = await incrementalBuilder.build(); - - router.use(incrementalAdminRouter); - - await processingEngine.start(); - - return router; -} +backend.start(); ``` ## Administrative Routes @@ -116,7 +84,7 @@ In all cases, `:provider` is the name of the incremental entity provider. ## Writing an Incremental Entity Provider -To create an Incremental Entity Provider, you need to know how to retrieve a single page of the data that you wish to ingest into the Backstage catalog. If the API has pagination and you know how to make a paginated request to that API, you'll be able to implement an Incremental Entity Provider for this API. For more information about compatibility, check out the requirements section of this page. +To create an Incremental Entity Provider, you need to know how to retrieve a single page of the data that you wish to ingest into the Backstage catalog. If the API has pagination and you know how to make a paginated request to that API, you'll be able to implement an Incremental Entity Provider for this API. For more information about compatibility, check out the [requirements](#requirements) section of this page. Here is the type definition for an Incremental Entity Provider. @@ -309,45 +277,73 @@ Now that you have your new Incremental Entity Provider, we can connect it to the ## Adding an Incremental Entity Provider to the catalog -We'll assume you followed the Installation instructions. After you create your `incrementalBuilder`, you can instantiate your Entity Provider and pass it to the `addIncrementalEntityProvider` method. +We'll assume you followed the [Installation](#installation) instructions. Now create a module inside `packages/backend/src/extensions/catalogCustomIncrementalIngestion.ts`. ```ts -const incrementalBuilder = await IncrementalCatalogBuilder.create(env, builder); +import { + coreServices, + createBackendModule, +} from '@backstage/backend-plugin-api'; +import { incrementalIngestionProvidersExtensionPoint } from '@backstage/plugin-catalog-backend-module-incremental-ingestion/alpha'; -// Assuming the token for the API comes from config -const token = config.getString('myApiClient.token'); +export const catalogModuleCustomIncrementalIngestionProvider = + createBackendModule({ + pluginId: 'catalog', + moduleId: 'custom-incremental-ingestion-provider', + register(env) { + env.registerInit({ + deps: { + incrementalBuilder: incrementalIngestionProvidersExtensionPoint, + config: coreServices.rootConfig, + }, + async init({ incrementalBuilder, config }) { + // Assuming the token for the API comes from config + const token = config.getString('myApiClient.token'); + const myEntityProvider = new MyIncrementalEntityProvider(token); -const myEntityProvider = new MyIncrementalEntityProvider(token); + const options = { + // How long should it attempt to read pages from the API in a + // single burst? Keep this short. The Incremental Entity Provider + // will attempt to read as many pages as it can in this time + burstLength: { seconds: 3 }, -incrementalBuilder.addIncrementalEntityProvider(myEntityProvider, { - // How long should it attempt to read pages from the API in a - // single burst? Keep this short. The Incremental Entity Provider - // will attempt to read as many pages as it can in this time - burstLength: { seconds: 3 }, + // How long should it wait between bursts? + burstInterval: { seconds: 3 }, - // How long should it wait between bursts? - burstInterval: { seconds: 3 }, + // How long should it rest before re-ingesting again? + restLength: { day: 1 }, - // How long should it rest before re-ingesting again? - restLength: { day: 1 }, + // Optional back-off configuration - how long should it wait to retry + // in the event of an error? + backoff: [ + { seconds: 5 }, + { seconds: 30 }, + { minutes: 10 }, + { hours: 3 }, + ], - // Optional back-off configuration - how long should it wait to retry - // in the event of an error? - backoff: [{ seconds: 5 }, { seconds: 30 }, { minutes: 10 }, { hours: 3 }], + // Optional. Use this to prevent removal of entities above a given + // percentage. This can be helpful if a data source is flaky and + // sometimes returns a successful status, but fewer than expected + // assets to add or maintain in the catalog. + rejectRemovalsAbovePercentage: 5, - // Optional. Use this to prevent removal of entities above a given - // percentage. This can be helpful if a data source is flaky and - // sometimes returns a successful status, but fewer than expected - // assets to add or maintain in the catalog. - rejectRemovalsAbovePercentage: 5, + // Optional. Similar to rejectRemovalsAbovePercentage, except it + // applies to complete, 100% failure of a data source. If true, + // a data source that returns a successful status but does not + // provide any assets to turn into entities will have its empty + // data set rejected. + rejectEmptySourceCollections: true, + }; - // Optional. Similar to rejectRemovalsAbovePercentage, except it - // applies to complete, 100% failure of a data source. If true, - // a data source that returns a successful status but does not - // provide any assets to turn into entities will have its empty - // data set rejected. - rejectEmptySourceCollections: true, -}); + incrementalBuilder.addProvider({ + provider: myEntityProvider, + options, + }); + }, + }); + }, + }); ``` That's it!!! diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index 466aca22ec..fe7370ac8f 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", - "version": "0.5.0", + "version": "0.5.3-next.1", "description": "An entity provider for streaming large asset sources into the catalog", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 4abf2a3d3b..f48ab34ba4 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.9.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## 0.9.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/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.8.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index abb11f8096..c3e0f39e9f 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", - "version": "0.8.0", + "version": "0.9.0-next.1", "description": "A Backstage catalog backend module that helps integrate towards LDAP", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-logs/CHANGELOG.md b/plugins/catalog-backend-module-logs/CHANGELOG.md index a95b43851b..05d129c042 100644 --- a/plugins/catalog-backend-module-logs/CHANGELOG.md +++ b/plugins/catalog-backend-module-logs/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-catalog-backend-module-logs +## 0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.1.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/plugin-catalog-backend@1.25.3-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + ## 0.0.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-logs/package.json b/plugins/catalog-backend-module-logs/package.json index 43afb06dde..0d4bbf6e5d 100644 --- a/plugins/catalog-backend-module-logs/package.json +++ b/plugins/catalog-backend-module-logs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-logs", - "version": "0.0.2", + "version": "0.1.0-next.1", "description": "A module that subscribes to catalog releated events and logs them.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index a394664d88..9cc7e6207b 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.6.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## 0.6.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 3c2d690: Allow users without defined email to be ingested by the `msgraph` catalog plugin and add `userIdMatchingUserEntityAnnotation` sign-in resolver for the Microsoft auth provider to support sign-in for users without defined email. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.6.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 68e67c1cfc..cc8fc5abc8 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", - "version": "0.6.0", + "version": "0.6.2-next.1", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.test.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.test.ts index f123b75995..62aa758fed 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.test.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.test.ts @@ -90,4 +90,31 @@ describe('defaultTransformers', () => { }, }); }); + + it('tests defaultUserTransformer with no email', async () => { + const user: MicrosoftGraph.User = { + id: 'foo', + displayName: 'BAR', + userPrincipalName: 'test@upn', + }; + const userPhoto = 'test_photo'; + const result = await defaultUserTransformer(user, userPhoto); + expect(result).toEqual({ + apiVersion: 'backstage.io/v1alpha1', + kind: 'User', + metadata: { + annotations: { + 'graph.microsoft.com/user-id': 'foo', + }, + name: 'test_upn', + }, + spec: { + memberOf: [], + profile: { + displayName: 'BAR', + picture: 'test_photo', + }, + }, + }); + }); }); diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts index 7a8c4ec463..910d5a1d40 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/defaultTransformers.ts @@ -122,25 +122,25 @@ export async function defaultUserTransformer( user: MicrosoftGraph.User, userPhoto?: string, ): Promise { - if (!user.id || !user.displayName || !user.mail) { + if (!user.id || !user.displayName) { return undefined; } - const name = normalizeEntityName(user.mail); + const name = user.mail + ? normalizeEntityName(user.mail) + : normalizeEntityName(user.userPrincipalName!); const entity: UserEntity = { apiVersion: 'backstage.io/v1alpha1', kind: 'User', metadata: { name, annotations: { - [MICROSOFT_EMAIL_ANNOTATION]: user.mail!, [MICROSOFT_GRAPH_USER_ID_ANNOTATION]: user.id!, }, }, spec: { profile: { displayName: user.displayName!, - email: user.mail!, // TODO: Additional fields? // jobTitle: user.jobTitle || undefined, @@ -151,6 +151,11 @@ export async function defaultUserTransformer( }, }; + if (user.mail) { + entity.metadata.annotations![MICROSOFT_EMAIL_ANNOTATION] = user.mail; + entity.spec.profile!.email = user.mail; + } + if (userPhoto) { entity.spec.profile!.picture = userPhoto; } diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index c24a7bb60b..b1e1c3308c 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-catalog-backend@1.25.3-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## 0.2.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-catalog-backend@1.25.3-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.1.41 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 4bdfe575e2..f93f1e8119 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", - "version": "0.1.41", + "version": "0.2.0-next.1", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md index 0bb7df6890..cfcf1acec3 100644 --- a/plugins/catalog-backend-module-puppetdb/CHANGELOG.md +++ b/plugins/catalog-backend-module-puppetdb/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-catalog-backend-module-puppetdb +## 0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + +## 0.2.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.2.0 ### Minor Changes diff --git a/plugins/catalog-backend-module-puppetdb/package.json b/plugins/catalog-backend-module-puppetdb/package.json index 3a12da0e66..e9f322e4c1 100644 --- a/plugins/catalog-backend-module-puppetdb/package.json +++ b/plugins/catalog-backend-module-puppetdb/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-puppetdb", - "version": "0.2.0", + "version": "0.2.2-next.1", "description": "A Backstage catalog backend module that helps integrate towards PuppetDB", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md index 11075a73cf..d6e8c54549 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md +++ b/plugins/catalog-backend-module-scaffolder-entity-model/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-catalog-backend-module-scaffolder-entity-model +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-scaffolder-common@1.5.5 + +## 0.2.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/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-scaffolder-common@1.5.5 + ## 0.1.21 ### Patch Changes diff --git a/plugins/catalog-backend-module-scaffolder-entity-model/package.json b/plugins/catalog-backend-module-scaffolder-entity-model/package.json index fdb0027016..3855e64192 100644 --- a/plugins/catalog-backend-module-scaffolder-entity-model/package.json +++ b/plugins/catalog-backend-module-scaffolder-entity-model/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-scaffolder-entity-model", - "version": "0.1.21", + "version": "0.2.0-next.1", "description": "Adds support for the scaffolder specific entity model (e.g. the Template kind) to the catalog backend plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md index 0d7ab37983..401f93077d 100644 --- a/plugins/catalog-backend-module-unprocessed/CHANGELOG.md +++ b/plugins/catalog-backend-module-unprocessed/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-catalog-backend-module-unprocessed +## 0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + +## 0.5.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-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.4 + - @backstage/plugin-permission-common@0.8.1 + ## 0.4.10 ### Patch Changes diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index ad91bd573d..78a9c345ce 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-unprocessed", - "version": "0.4.10", + "version": "0.5.0-next.1", "description": "Backstage Catalog module to view unprocessed entities", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index c6347c35d3..d2987d1182 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,53 @@ # @backstage/plugin-catalog-backend +## 1.25.3-next.1 + +### Patch Changes + +- 1882cfe: Moved `getEntities` ordering to utilize database instead of having it inside catalog client + + Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change. + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/backend-openapi-utils@0.1.18-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.1 + +## 1.25.3-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 53cce86: Fixed an issue with the by-query call, where ordering by a field that does not exist on all entities led to not all results being returned +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-search-backend-module-catalog@0.2.2-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/backend-openapi-utils@0.1.18-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + ## 1.25.0 ### Minor Changes diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 4003fd2b6a..e3a09b65ec 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend", - "version": "1.25.0", + "version": "1.25.3-next.1", "description": "The Backstage backend plugin that provides the Backstage catalog", "backstage": { "role": "backend-plugin", diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts index 3c98f2a8bc..92acd9e3ce 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts @@ -1648,6 +1648,43 @@ describe('DefaultEntitiesCatalog', () => { expect(response5.totalItems).toBe(6); }, ); + + it.each(databases.eachSupportedId())( + 'should sort properly for fields that do not exist on all entities, %p', + async databaseId => { + await createDatabase(databaseId); + + await Promise.all([ + addEntityToSearch(entityFrom('AA', { uid: 'id1' })), + addEntityToSearch(entityFrom('BB', { uid: 'id2', title: 'YY' })), + addEntityToSearch(entityFrom('CC', { uid: 'id3', title: 'XX' })), + ]); + + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: mockServices.logger.mock(), + stitcher, + }); + + await expect( + catalog + .queryEntities({ + orderFields: [{ field: 'metadata.title', order: 'asc' }], + credentials: mockCredentials.none(), + }) + .then(r => r.items.map(e => e.metadata.name)), + ).resolves.toEqual(['CC', 'BB', 'AA']); // 'AA' has no title, ends up last + + await expect( + catalog + .queryEntities({ + orderFields: [{ field: 'metadata.title', order: 'desc' }], + credentials: mockCredentials.none(), + }) + .then(r => r.items.map(e => e.metadata.name)), + ).resolves.toEqual(['BB', 'CC', 'AA']); // 'AA' has no title, ends up last + }, + ); }); describe('removeEntityByUid', () => { diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts index 9049685d38..f9f731e3e4 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts @@ -249,7 +249,18 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { ]); } }); - entitiesQuery = entitiesQuery.orderBy('final_entities.entity_id', 'asc'); // stable sort + + if (!request?.order) { + entitiesQuery = entitiesQuery + .leftOuterJoin( + 'refresh_state', + 'refresh_state.entity_id', + 'final_entities.entity_id', + ) + .orderBy('refresh_state.entity_ref', 'asc'); // default sort + } else { + entitiesQuery.orderBy('final_entities.entity_id', 'asc'); // stable sort + } const { limit, offset } = parsePagination(request?.pagination); if (limit !== undefined) { @@ -379,12 +390,20 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { const [prevItemOrderFieldValue, prevItemUid] = cursor.orderFieldValues || []; - const dbQuery = db('search') - .join('final_entities', 'search.entity_id', 'final_entities.entity_id') - .where('search.key', sortField.field); + const dbQuery = db('final_entities').leftOuterJoin('search', qb => + qb + .on('search.entity_id', 'final_entities.entity_id') + .andOnVal('search.key', sortField.field), + ); if (cursor.filter) { - parseFilter(cursor.filter, dbQuery, db, false, 'search.entity_id'); + parseFilter( + cursor.filter, + dbQuery, + db, + false, + 'final_entities.entity_id', + ); } const normalizedFullTextFilterTerm = cursor.fullTextFilter?.term?.trim(); @@ -410,7 +429,7 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { `%${normalizedFullTextFilterTerm.toLocaleLowerCase('en-US')}%`, ); }); - dbQuery.andWhere('search.entity_id', 'in', matchQuery); + dbQuery.andWhere('final_entities.entity_id', 'in', matchQuery); } } @@ -427,32 +446,59 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { ) .orWhere('value', '=', prevItemOrderFieldValue) .andWhere( - 'search.entity_id', + 'final_entities.entity_id', isFetchingBackwards !== isOrderingDescending ? '<' : '>', prevItemUid, ); }); } - dbQuery - .orderBy([ + if (db.client.config.client === 'pg') { + // pg correctly orders by the column value and handling nulls in one go + dbQuery.orderBy([ { - column: 'value', + column: 'search.value', + order: isFetchingBackwards + ? invertOrder(sortField.order) + : sortField.order, + nulls: 'last', + }, + { + column: 'final_entities.entity_id', + order: isFetchingBackwards + ? invertOrder(sortField.order) + : sortField.order, + }, + ]); + } else { + // sqlite and mysql translate the above statement ONLY into "order by (value is null) asc" + // no matter what the order is, for some reason, so we have to manually add back the statement + // that translates to "order by value " while avoiding to give an order + dbQuery.orderBy([ + { + column: 'search.value', + order: undefined, + nulls: 'last', + }, + { + column: 'search.value', order: isFetchingBackwards ? invertOrder(sortField.order) : sortField.order, }, { - column: 'search.entity_id', + column: 'final_entities.entity_id', order: isFetchingBackwards ? invertOrder(sortField.order) : sortField.order, }, - ]) - // fetch an extra item to check if there are more items. - .limit(isFetchingBackwards ? limit : limit + 1); + ]); + } - countQuery.count('search.entity_id', { as: 'count' }); + // fetch an extra item to check if there are more items. + dbQuery.limit(isFetchingBackwards ? limit : limit + 1); + + countQuery.count('final_entities.entity_id', { as: 'count' }); const [rows, [{ count }]] = await Promise.all([ limit > 0 ? dbQuery : [], diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index a1715bbbca..dd6cfdaf24 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-catalog-graph +## 0.4.9-next.1 + +### Patch Changes + +- da91078: Fixed a bug in the `CatalogGraphPage` component where, after clicking on some nodes, clicking the back button would break the navigation. This issue caused the entire navigation to fail and behaved differently across various browsers. +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-compat-api@0.3.0-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + +## 0.4.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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + ## 0.4.8 ### Patch Changes diff --git a/plugins/catalog-graph/api-report-alpha.md b/plugins/catalog-graph/api-report-alpha.md index 6ab438def3..65f8af3764 100644 --- a/plugins/catalog-graph/api-report-alpha.md +++ b/plugins/catalog-graph/api-report-alpha.md @@ -5,18 +5,18 @@ ```ts import { AnyExtensionDataRef } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Direction } from '@backstage/plugin-catalog-graph'; import { Entity } from '@backstage/catalog-model'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; // @public (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< { catalogGraph: RouteRef; }, @@ -28,8 +28,8 @@ const _default: BackstagePlugin< }>; }, { - 'entity-card:catalog-graph/relations': ExtensionDefinition< - { + 'entity-card:catalog-graph/relations': ExtensionDefinition<{ + config: { kinds: string[] | undefined; relations: string[] | undefined; maxDepth: number | undefined; @@ -43,8 +43,8 @@ const _default: BackstagePlugin< height: number | undefined; } & { filter: string | undefined; - }, - { + }; + configInput: { height?: number | undefined; curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; direction?: Direction | undefined; @@ -58,27 +58,28 @@ const _default: BackstagePlugin< relationPairs?: [string, string][] | undefined; } & { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: { [x: string]: ExtensionInput< AnyExtensionDataRef, { @@ -86,15 +87,13 @@ const _default: BackstagePlugin< singleton: boolean; } >; - }, - { - kind: 'entity-card'; - namespace: undefined; - name: 'relations'; - } - >; - 'page:catalog-graph': ExtensionDefinition< - { + }; + kind: 'entity-card'; + namespace: undefined; + name: 'relations'; + }>; + 'page:catalog-graph': ExtensionDefinition<{ + config: { selectedKinds: string[] | undefined; selectedRelations: string[] | undefined; rootEntityRefs: string[] | undefined; @@ -110,8 +109,8 @@ const _default: BackstagePlugin< zoom: 'disabled' | 'enabled' | 'enable-on-click' | undefined; } & { path: string | undefined; - }, - { + }; + configInput: { curve?: 'curveStepBefore' | 'curveMonotoneX' | undefined; direction?: Direction | undefined; zoom?: 'disabled' | 'enabled' | 'enable-on-click' | undefined; @@ -127,21 +126,22 @@ const _default: BackstagePlugin< showFilters?: boolean | undefined; } & { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: { [x: string]: ExtensionInput< AnyExtensionDataRef, { @@ -149,13 +149,11 @@ const _default: BackstagePlugin< singleton: boolean; } >; - }, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; + }; + kind: 'page'; + namespace: undefined; + name: undefined; + }>; } >; export default _default; diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 326a80fdf2..74b9054492 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.4.8", + "version": "0.4.9-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-graph", diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.test.ts b/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.test.ts deleted file mode 100644 index a89fa353d6..0000000000 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.test.ts +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { RELATION_MEMBER_OF } from '@backstage/catalog-model'; -import { act, renderHook } from '@testing-library/react'; -import { useLocation as useLocationMocked } from 'react-router-dom'; -import { Direction } from '../EntityRelationsGraph'; -import { useCatalogGraphPage } from './useCatalogGraphPage'; - -jest.mock('react-router-dom', () => ({ - useLocation: jest.fn(), -})); - -jest.spyOn(window.history, 'replaceState'); -jest.spyOn(window.history, 'pushState'); - -const useLocation = useLocationMocked as jest.Mock< - ReturnType ->; -const windowHistoryReplaceState = window.history.replaceState as jest.Mock< - ReturnType ->; -const windowHistoryPushState = window.history.pushState as jest.Mock< - ReturnType ->; - -describe('useCatalogGraphPage', () => { - beforeEach(() => { - useLocation.mockReturnValue({ - search: '?', - state: {}, - key: '', - pathname: '', - hash: '', - }); - }); - - afterEach(() => jest.resetAllMocks()); - - test('should use initial state', () => { - const { result } = renderHook(() => - useCatalogGraphPage({ - initialState: { - rootEntityRefs: ['b:d/c'], - maxDepth: 2, - direction: Direction.RIGHT_LEFT, - mergeRelations: false, - unidirectional: false, - showFilters: false, - selectedKinds: ['API'], - selectedRelations: [RELATION_MEMBER_OF], - }, - }), - ); - - expect(result.current.rootEntityNames).toEqual([ - { kind: 'b', namespace: 'd', name: 'c' }, - ]); - expect(result.current.maxDepth).toEqual(2); - expect(result.current.direction).toEqual(Direction.RIGHT_LEFT); - expect(result.current.mergeRelations).toEqual(false); - expect(result.current.unidirectional).toEqual(false); - expect(result.current.showFilters).toEqual(false); - expect(result.current.selectedKinds).toEqual(['api']); - expect(result.current.selectedRelations).toEqual([RELATION_MEMBER_OF]); - }); - - test('should use state from url', () => { - useLocation.mockReturnValueOnce({ - search: - '?rootEntityRefs[]=b:d/c&maxDepth=2&direction=RL&mergeRelations=false&unidirectional=false&showFilters=false&selectedKinds[]=api&selectedRelations[]=memberOf', - state: {}, - key: '', - pathname: '', - hash: '', - }); - - const { result } = renderHook(() => useCatalogGraphPage({})); - - expect(result.current.rootEntityNames).toEqual([ - { kind: 'b', namespace: 'd', name: 'c' }, - ]); - expect(result.current.maxDepth).toEqual(2); - expect(result.current.direction).toEqual(Direction.RIGHT_LEFT); - expect(result.current.mergeRelations).toEqual(false); - expect(result.current.unidirectional).toEqual(false); - expect(result.current.showFilters).toEqual(false); - expect(result.current.selectedKinds).toEqual(['api']); - expect(result.current.selectedRelations).toEqual([RELATION_MEMBER_OF]); - }); - - test('should update state in url (replace if setting changes)', () => { - const { result } = renderHook(() => useCatalogGraphPage({})); - - act(() => result.current.setMaxDepth(5)); - - expect(windowHistoryReplaceState).toHaveBeenCalledWith( - null, - '', - '/?maxDepth=5&unidirectional=true&mergeRelations=true&direction=LR&showFilters=true', - ); - - act(() => result.current.setUnidirectional(false)); - - expect(windowHistoryReplaceState).toHaveBeenCalledWith( - null, - '', - '/?maxDepth=5&unidirectional=false&mergeRelations=true&direction=LR&showFilters=true', - ); - }); - - test('should update state in url (only push if different root entity)', () => { - const { result, rerender } = renderHook(() => - useCatalogGraphPage({ - initialState: { - rootEntityRefs: ['component:default/first'], - }, - }), - ); - - act(() => - result.current.setRootEntityNames([ - { kind: 'Component', namespace: 'default', name: 'my' }, - ]), - ); - - rerender(); - - expect(windowHistoryPushState).toHaveBeenCalledWith( - null, - '', - '/?rootEntityRefs%5B%5D=component%3Adefault%2Fmy&maxDepth=%E2%88%9E&unidirectional=true&mergeRelations=true&direction=LR&showFilters=true', - ); - }); -}); diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.test.tsx b/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.test.tsx new file mode 100644 index 0000000000..85cb606482 --- /dev/null +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.test.tsx @@ -0,0 +1,182 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { RELATION_MEMBER_OF } from '@backstage/catalog-model'; +import { renderHook, waitFor } from '@testing-library/react'; +import React from 'react'; +import { act } from 'react-dom/test-utils'; +import { BrowserRouter } from 'react-router-dom'; +import { Direction } from '../EntityRelationsGraph'; +import { useCatalogGraphPage } from './useCatalogGraphPage'; + +const wrapper = ({ children }: { children?: React.ReactNode }) => { + return {children}; +}; + +describe('useCatalogGraphPage', () => { + test('should use initial state', () => { + const { result } = renderHook(props => useCatalogGraphPage(props), { + initialProps: { + initialState: { + rootEntityRefs: ['b:d/c'], + maxDepth: 2, + direction: Direction.RIGHT_LEFT, + mergeRelations: false, + unidirectional: false, + showFilters: false, + selectedKinds: ['API'], + selectedRelations: [RELATION_MEMBER_OF], + }, + }, + wrapper, + }); + + expect(result.current.rootEntityNames).toEqual([ + { kind: 'b', namespace: 'd', name: 'c' }, + ]); + expect(result.current.maxDepth).toEqual(2); + expect(result.current.direction).toEqual(Direction.RIGHT_LEFT); + expect(result.current.mergeRelations).toEqual(false); + expect(result.current.unidirectional).toEqual(false); + expect(result.current.showFilters).toEqual(false); + expect(result.current.selectedKinds).toEqual(['api']); + expect(result.current.selectedRelations).toEqual([RELATION_MEMBER_OF]); + }); + + test('should use state from url', () => { + act(() => { + history.pushState( + {}, + '', + '?rootEntityRefs[]=b:d/c&maxDepth=2&direction=RL&mergeRelations=false&unidirectional=false&showFilters=false&selectedKinds[]=api&selectedRelations[]=memberOf', + ); + }); + + const { result } = renderHook(props => useCatalogGraphPage(props), { + initialProps: {}, + wrapper, + }); + + expect(result.current.rootEntityNames).toEqual([ + { kind: 'b', namespace: 'd', name: 'c' }, + ]); + expect(result.current.maxDepth).toEqual(2); + expect(result.current.direction).toEqual(Direction.RIGHT_LEFT); + expect(result.current.mergeRelations).toEqual(false); + expect(result.current.unidirectional).toEqual(false); + expect(result.current.showFilters).toEqual(false); + expect(result.current.selectedKinds).toEqual(['api']); + expect(result.current.selectedRelations).toEqual([RELATION_MEMBER_OF]); + }); + + test('should update state in url (replace if setting changes)', () => { + const { result } = renderHook(props => useCatalogGraphPage(props), { + wrapper, + initialProps: {}, + }); + + act(() => result.current.setMaxDepth(5)); + + expect(window.location.search).toEqual( + '?rootEntityRefs%5B%5D=b%3Ad%2Fc&maxDepth=5&selectedKinds%5B%5D=api&selectedRelations%5B%5D=memberOf&unidirectional=false&mergeRelations=false&direction=RL&showFilters=false&curve=curveMonotoneX', + ); + + act(() => result.current.setUnidirectional(false)); + + expect(window.location.search).toEqual( + '?rootEntityRefs%5B%5D=b%3Ad%2Fc&maxDepth=5&selectedKinds%5B%5D=api&selectedRelations%5B%5D=memberOf&unidirectional=false&mergeRelations=false&direction=RL&showFilters=false&curve=curveMonotoneX', + ); + }); + + test('should update state in url (only push if different root entity)', () => { + const oldLength = window.history.length; + const { result } = renderHook(props => useCatalogGraphPage(props), { + initialProps: { + initialState: { + rootEntityRefs: ['component:default/first'], + }, + }, + wrapper, + }); + + act(() => + result.current.setRootEntityNames([ + { kind: 'component', namespace: 'default', name: 'my' }, + ]), + ); + + expect(window.history.length).toEqual(oldLength + 1); + expect(window.location.search).toEqual( + '?rootEntityRefs%5B%5D=component%3Adefault%2Fmy&maxDepth=5&selectedKinds%5B%5D=api&selectedRelations%5B%5D=memberOf&unidirectional=false&mergeRelations=false&direction=RL&showFilters=false&curve=curveMonotoneX', + ); + }); + + test('should update state to last state on back', async () => { + const { result } = renderHook(props => useCatalogGraphPage(props), { + wrapper, + initialProps: { + initialState: { + rootEntityRefs: ['component:default/first'], + }, + }, + }); + + act(() => + result.current.setRootEntityNames([ + { kind: 'component', namespace: 'default', name: 'first' }, + ]), + ); + + expect(window.location.search).toEqual( + '?rootEntityRefs%5B%5D=component%3Adefault%2Ffirst&maxDepth=5&selectedKinds%5B%5D=api&selectedRelations%5B%5D=memberOf&unidirectional=false&mergeRelations=false&direction=RL&showFilters=false&curve=curveMonotoneX', + ); + + act(() => + result.current.setRootEntityNames([ + { kind: 'component', namespace: 'default', name: 'second' }, + ]), + ); + + expect(window.location.search).toEqual( + '?rootEntityRefs%5B%5D=component%3Adefault%2Fsecond&maxDepth=5&selectedKinds%5B%5D=api&selectedRelations%5B%5D=memberOf&unidirectional=false&mergeRelations=false&direction=RL&showFilters=false&curve=curveMonotoneX', + ); + + act(() => { + result.current.setRootEntityNames([ + { kind: 'component', namespace: 'default', name: 'third' }, + ]); + }); + + act(() => { + window.history.back(); + }); + + await waitFor(() => { + expect(result.current.rootEntityNames).toEqual([ + { kind: 'component', namespace: 'default', name: 'second' }, + ]); + }); + + act(() => { + window.history.back(); + }); + + await waitFor(() => { + expect(result.current.rootEntityNames).toEqual([ + { kind: 'component', namespace: 'default', name: 'first' }, + ]); + }); + }); +}); diff --git a/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.ts b/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.ts index 6e47dedc50..1f6fb74997 100644 --- a/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.ts +++ b/plugins/catalog-graph/src/components/CatalogGraphPage/useCatalogGraphPage.ts @@ -27,13 +27,12 @@ import { useMemo, useState, } from 'react'; -import { useLocation } from 'react-router-dom'; -import usePrevious from 'react-use/esm/usePrevious'; +import { useLocation, useNavigate } from 'react-router-dom'; import { Direction } from '../EntityRelationsGraph'; export type CatalogGraphPageValue = { rootEntityNames: CompoundEntityRef[]; - setRootEntityNames: Dispatch>; + setRootEntityNames: (value: CompoundEntityRef[]) => void; maxDepth: number; setMaxDepth: Dispatch>; selectedRelations: string[] | undefined; @@ -70,6 +69,8 @@ export function useCatalogGraphPage({ }; }): CatalogGraphPageValue { const location = useLocation(); + const navigate = useNavigate(); + const query = useMemo( () => (qs.parse(location.search, { arrayLimit: 0, ignoreQueryPrefix: true }) || @@ -87,19 +88,46 @@ export function useCatalogGraphPage({ [location.search], ); - // Initial state - const [rootEntityNames, setRootEntityNames] = useState( + const rootEntityNames = useMemo( () => (Array.isArray(query.rootEntityRefs) ? query.rootEntityRefs : initialState?.rootEntityRefs ?? [] ).map(r => parseEntityRef(r)), + [initialState?.rootEntityRefs, query.rootEntityRefs], ); + + const setRootEntityNames = useCallback( + (value: CompoundEntityRef[]) => { + const areSame = + rootEntityNames.length === value.length && + rootEntityNames.every( + (r, i) => stringifyEntityRef(r) === stringifyEntityRef(value[i]), + ); + + if (areSame) { + return; + } + + const newSearch = qs.stringify( + { + ...query, + rootEntityRefs: value.map(r => stringifyEntityRef(r)), + }, + { arrayFormat: 'brackets', addQueryPrefix: true }, + ); + + navigate(newSearch); + }, + [rootEntityNames, navigate, query], + ); + const [maxDepth, setMaxDepth] = useState(() => typeof query.maxDepth === 'string' ? parseMaxDepth(query.maxDepth) : initialState?.maxDepth ?? Number.POSITIVE_INFINITY, ); + const [selectedRelations, setSelectedRelations] = useState< string[] | undefined >(() => @@ -107,105 +135,53 @@ export function useCatalogGraphPage({ ? query.selectedRelations : initialState?.selectedRelations, ); + const [selectedKinds, setSelectedKinds] = useState(() => (Array.isArray(query.selectedKinds) ? query.selectedKinds : initialState?.selectedKinds )?.map(k => k.toLocaleLowerCase('en-US')), ); + const [unidirectional, setUnidirectional] = useState(() => typeof query.unidirectional === 'string' ? query.unidirectional === 'true' : initialState?.unidirectional ?? true, ); + const [mergeRelations, setMergeRelations] = useState(() => typeof query.mergeRelations === 'string' ? query.mergeRelations === 'true' : initialState?.mergeRelations ?? true, ); + const [direction, setDirection] = useState(() => typeof query.direction === 'string' ? query.direction : initialState?.direction ?? Direction.LEFT_RIGHT, ); + const [curve, setCurve] = useState<'curveStepBefore' | 'curveMonotoneX'>(() => typeof query.curve === 'string' ? query.curve : initialState?.curve ?? 'curveMonotoneX', ); + const [showFilters, setShowFilters] = useState(() => typeof query.showFilters === 'string' ? query.showFilters === 'true' : initialState?.showFilters ?? true, ); + const toggleShowFilters = useCallback( () => setShowFilters(s => !s), [setShowFilters], ); - // Update from query parameters - const prevQueryParams = usePrevious(location.search); useEffect(() => { - // Only respond to changes to url query params - if (location.search === prevQueryParams) { - return; - } - - if (Array.isArray(query.rootEntityRefs)) { - setRootEntityNames(query.rootEntityRefs.map(r => parseEntityRef(r))); - } - - if (typeof query.maxDepth === 'string') { - setMaxDepth(parseMaxDepth(query.maxDepth)); - } - - if (Array.isArray(query.selectedKinds)) { - setSelectedKinds(query.selectedKinds); - } - - if (Array.isArray(query.selectedRelations)) { - setSelectedRelations(query.selectedRelations); - } - - if (typeof query.unidirectional === 'string') { - setUnidirectional(query.unidirectional === 'true'); - } - - if (typeof query.mergeRelations === 'string') { - setMergeRelations(query.mergeRelations === 'true'); - } - - if (typeof query.direction === 'string') { - setDirection(query.direction); - } - - if (typeof query.showFilters === 'string') { - setShowFilters(query.showFilters === 'true'); - } - }, [ - prevQueryParams, - location.search, - query, - setRootEntityNames, - setMaxDepth, - setSelectedKinds, - setSelectedRelations, - setUnidirectional, - setMergeRelations, - setDirection, - setShowFilters, - ]); - - // Update query parameters - const previousRootEntityRefs = usePrevious( - rootEntityNames.map(e => stringifyEntityRef(e)), - ); - - useEffect(() => { - const rootEntityRefs = rootEntityNames.map(e => stringifyEntityRef(e)); const newParams = qs.stringify( { - rootEntityRefs, + rootEntityRefs: rootEntityNames.map(stringifyEntityRef), maxDepth: isFinite(maxDepth) ? maxDepth : '∞', selectedKinds, selectedRelations, @@ -213,36 +189,23 @@ export function useCatalogGraphPage({ mergeRelations, direction, showFilters, + curve, }, { arrayFormat: 'brackets', addQueryPrefix: true }, ); - const newUrl = `${window.location.pathname}${newParams}`; - // We directly manipulate window history here in order to not re-render - // infinitely (state => location => state => etc). The intention of this - // code is just to ensure the right query/filters are loaded when a user - // clicks the "back" button after clicking a result. - // Only push a new history entry if we switched to another entity, but not - // if we just changed a viewer setting. - if ( - !previousRootEntityRefs || - (rootEntityRefs.length === previousRootEntityRefs.length && - rootEntityRefs.every((v, i) => v === previousRootEntityRefs[i])) - ) { - window.history.replaceState(null, document.title, newUrl); - } else { - window.history.pushState(null, document.title, newUrl); - } + navigate(newParams, { replace: true }); }, [ - rootEntityNames, maxDepth, + curve, selectedKinds, selectedRelations, unidirectional, mergeRelations, direction, showFilters, - previousRootEntityRefs, + rootEntityNames, + navigate, ]); return { diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 1b8d14ff3f..0456c5ee24 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-catalog-import +## 0.12.3-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/catalog-client@1.6.7-next.0 + - @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/plugin-catalog-common@1.0.26 + +## 0.12.3-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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @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/plugin-catalog-common@1.0.26 + ## 0.12.2 ### Patch Changes diff --git a/plugins/catalog-import/api-report-alpha.md b/plugins/catalog-import/api-report-alpha.md index 9f82f39266..3eed9ce3e4 100644 --- a/plugins/catalog-import/api-report-alpha.md +++ b/plugins/catalog-import/api-report-alpha.md @@ -5,57 +5,58 @@ ```ts import { AnyApiFactory } from '@backstage/core-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; // @alpha (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< { importPage: RouteRef; }, {}, { - 'api:catalog-import': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: undefined; - } - >; - 'page:catalog-import': ExtensionDefinition< - { + 'api:catalog-import': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'page:catalog-import': ExtensionDefinition<{ + kind: 'page'; + namespace: undefined; + name: undefined; + config: { path: string | undefined; - }, - { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - {}, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: {}; + }>; } >; export default _default; diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 7909c33936..32e183e7d9 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-import", - "version": "0.12.2", + "version": "0.12.3-next.1", "description": "A Backstage plugin the helps you import entities into your catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index 1c77be04e9..b4472333fd 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-catalog-node +## 1.12.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## 1.12.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + ## 1.12.5 ### Patch Changes diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index ff4c0d17a8..25f8d699ab 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-node", - "version": "1.12.5", + "version": "1.12.7-next.1", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", "backstage": { "role": "node-library", diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 8cb8985542..5027678cbe 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/plugin-catalog-react +## 1.12.4-next.1 + +### Patch Changes + +- ae9b6cb: Small internal fix to better work with recent `lodash` versions +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-compat-api@0.3.0-next.1 + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.25 + +## 1.12.4-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-react@0.4.25 + ## 1.12.3 ### Patch Changes diff --git a/plugins/catalog-react/api-report-alpha.md b/plugins/catalog-react/api-report-alpha.md index b22d76cd15..5dec3ab99d 100644 --- a/plugins/catalog-react/api-report-alpha.md +++ b/plugins/catalog-react/api-report-alpha.md @@ -83,7 +83,7 @@ export function convertLegacyEntityCardExtension( | typeof EntityCardBlueprint.dataRefs.filterFunction.T | typeof EntityCardBlueprint.dataRefs.filterExpression.T; }, -): ExtensionDefinition; +): ExtensionDefinition; // @alpha (undocumented) export function convertLegacyEntityContentExtension( @@ -96,42 +96,41 @@ export function convertLegacyEntityContentExtension( defaultPath?: string; defaultTitle?: string; }, -): ExtensionDefinition; +): ExtensionDefinition; // @alpha -export const EntityCardBlueprint: ExtensionBlueprint< - { - kind: 'entity-card'; - namespace: undefined; - name: undefined; - }, - { +export const EntityCardBlueprint: ExtensionBlueprint<{ + kind: 'entity-card'; + namespace: undefined; + name: undefined; + params: { loader: () => Promise; filter?: string | ((entity: Entity) => boolean) | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - { + }; + dataRefs: { filterFunction: ConfigurableExtensionDataRef< (entity: Entity) => boolean, 'catalog.entity-filter-function', @@ -142,59 +141,58 @@ export const EntityCardBlueprint: ExtensionBlueprint< 'catalog.entity-filter-expression', {} >; - } ->; + }; +}>; // @alpha -export const EntityContentBlueprint: ExtensionBlueprint< - { - kind: 'entity-content'; - namespace: undefined; - name: undefined; - }, - { +export const EntityContentBlueprint: ExtensionBlueprint<{ + kind: 'entity-content'; + namespace: undefined; + name: undefined; + params: { loader: () => Promise; defaultPath: string; defaultTitle: string; routeRef?: RouteRef | undefined; filter?: string | ((entity: Entity) => boolean) | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + config: { path: string | undefined; title: string | undefined; filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; title?: string | undefined; path?: string | undefined; - }, - { + }; + dataRefs: { title: ConfigurableExtensionDataRef< string, 'catalog.entity-content-title', @@ -210,8 +208,8 @@ export const EntityContentBlueprint: ExtensionBlueprint< 'catalog.entity-filter-expression', {} >; - } ->; + }; +}>; // @alpha export function isOwnerOf(owner: Entity, entity: Entity): boolean; diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 7cf7464a88..ba4aff5c42 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-react", - "version": "1.12.3", + "version": "1.12.4-next.1", "description": "A frontend library that helps other Backstage plugins interact with the catalog", "backstage": { "role": "web-library", diff --git a/plugins/catalog-react/src/alpha/blueprints/EntityCardBlueprint.test.tsx b/plugins/catalog-react/src/alpha/blueprints/EntityCardBlueprint.test.tsx index 0cb7cdead8..2ab87b20ae 100644 --- a/plugins/catalog-react/src/alpha/blueprints/EntityCardBlueprint.test.tsx +++ b/plugins/catalog-react/src/alpha/blueprints/EntityCardBlueprint.test.tsx @@ -20,7 +20,10 @@ import { createExtension, createExtensionInput, } from '@backstage/frontend-plugin-api'; -import { createExtensionTester } from '@backstage/frontend-test-utils'; +import { + createExtensionTester, + renderInTestApp, +} from '@backstage/frontend-test-utils'; import { waitFor, screen } from '@testing-library/react'; import { Entity } from '@backstage/catalog-model'; @@ -37,6 +40,7 @@ describe('EntityCardBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "entity-content:catalog/overview", "input": "cards", @@ -163,9 +167,11 @@ describe('EntityCardBlueprint', () => { }, }); - createExtensionTester(extension, { config: { mock: 'mock test config' } }) - .add(mockExtension) - .render(); + renderInTestApp( + createExtensionTester(extension, { config: { mock: 'mock test config' } }) + .add(mockExtension) + .reactElement(), + ); await waitFor(() => { expect(screen.getByTestId('test')).toBeInTheDocument(); diff --git a/plugins/catalog-react/src/alpha/blueprints/EntityContentBlueprint.test.tsx b/plugins/catalog-react/src/alpha/blueprints/EntityContentBlueprint.test.tsx index 5d91f402de..cc86f01501 100644 --- a/plugins/catalog-react/src/alpha/blueprints/EntityContentBlueprint.test.tsx +++ b/plugins/catalog-react/src/alpha/blueprints/EntityContentBlueprint.test.tsx @@ -15,7 +15,10 @@ */ import React from 'react'; import { EntityContentBlueprint } from './EntityContentBlueprint'; -import { createExtensionTester } from '@backstage/frontend-test-utils'; +import { + createExtensionTester, + renderInTestApp, +} from '@backstage/frontend-test-utils'; import { coreExtensionData, createExtension, @@ -39,6 +42,7 @@ describe('EntityContentBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "page:catalog/entity", "input": "contents", @@ -211,9 +215,11 @@ describe('EntityContentBlueprint', () => { }, }); - createExtensionTester(extension, { config: { mock: 'mock test config' } }) - .add(mockExtension) - .render(); + renderInTestApp( + createExtensionTester(extension, { config: { mock: 'mock test config' } }) + .add(mockExtension) + .reactElement(), + ); await waitFor(() => { expect(screen.getByTestId('test')).toBeInTheDocument(); diff --git a/plugins/catalog-react/src/alpha/converters/convertLegacyEntityCardExtension.test.tsx b/plugins/catalog-react/src/alpha/converters/convertLegacyEntityCardExtension.test.tsx index 7dacd9c3e8..dd13318333 100644 --- a/plugins/catalog-react/src/alpha/converters/convertLegacyEntityCardExtension.test.tsx +++ b/plugins/catalog-react/src/alpha/converters/convertLegacyEntityCardExtension.test.tsx @@ -48,12 +48,11 @@ describe('convertLegacyEntityCardExtension', () => { ); const converted = convertLegacyEntityCardExtension(LegacyExtension); - expect(converted.kind).toBe('entity-card'); - expect(converted.namespace).toBe(undefined); - expect(converted.name).toBe('example'); const tester = createExtensionTester(converted); + expect(tester.query(converted).node.spec.id).toBe('entity-card:example'); + await renderInTestApp(tester.reactElement(), { mountedRoutes: { '/': convertLegacyRouteRef(routeRef), @@ -83,12 +82,11 @@ describe('convertLegacyEntityCardExtension', () => { name: 'other', filter: 'my-filter', }); - expect(converted.kind).toBe('entity-card'); - expect(converted.namespace).toBe(undefined); - expect(converted.name).toBe('other'); const tester = createExtensionTester(converted); + expect(tester.query(converted).node.spec.id).toBe('entity-card:other'); + await renderInTestApp(tester.reactElement(), { mountedRoutes: { '/': convertLegacyRouteRef(routeRef), @@ -106,7 +104,7 @@ describe('convertLegacyEntityCardExtension', () => { }); it('should support various naming patterns for entity card extensions', async () => { - const withName = (name: string) => { + const getDiscoveredId = (name: string) => { const converted = convertLegacyEntityCardExtension( legacyPlugin.provide( createRoutableExtension({ @@ -116,14 +114,14 @@ describe('convertLegacyEntityCardExtension', () => { }), ), ); - return converted.name; + return createExtensionTester(converted).query(converted).node.spec.id; }; - expect(withName('EntityTestCard')).toBe(undefined); - expect(withName('EntityTestTrimCard')).toBe('trim'); - expect(withName('EntityTeStTrimCard')).toBe('trim'); - expect(withName('EntityExampleCard')).toBe('example'); - expect(withName('EntityExAmpleCard')).toBe('ex-ample'); - expect(withName('ExampleCard')).toBe('example-card'); + expect(getDiscoveredId('EntityTestCard')).toBe('entity-card:test'); // falls back to test namespace + expect(getDiscoveredId('EntityTestTrimCard')).toBe('entity-card:trim'); + expect(getDiscoveredId('EntityTeStTrimCard')).toBe('entity-card:trim'); + expect(getDiscoveredId('EntityExampleCard')).toBe('entity-card:example'); + expect(getDiscoveredId('EntityExAmpleCard')).toBe('entity-card:ex-ample'); + expect(getDiscoveredId('ExampleCard')).toBe('entity-card:example-card'); }); }); diff --git a/plugins/catalog-react/src/alpha/converters/convertLegacyEntityCardExtension.tsx b/plugins/catalog-react/src/alpha/converters/convertLegacyEntityCardExtension.tsx index 76442f526d..ed92461736 100644 --- a/plugins/catalog-react/src/alpha/converters/convertLegacyEntityCardExtension.tsx +++ b/plugins/catalog-react/src/alpha/converters/convertLegacyEntityCardExtension.tsx @@ -30,7 +30,7 @@ export function convertLegacyEntityCardExtension( | typeof EntityCardBlueprint.dataRefs.filterFunction.T | typeof EntityCardBlueprint.dataRefs.filterExpression.T; }, -): ExtensionDefinition { +): ExtensionDefinition { const element = ; const extName = getComponentData(element, 'core.extensionName'); diff --git a/plugins/catalog-react/src/alpha/converters/convertLegacyEntityContentExtension.test.tsx b/plugins/catalog-react/src/alpha/converters/convertLegacyEntityContentExtension.test.tsx index 6d7c8f0420..d8ca126aa2 100644 --- a/plugins/catalog-react/src/alpha/converters/convertLegacyEntityContentExtension.test.tsx +++ b/plugins/catalog-react/src/alpha/converters/convertLegacyEntityContentExtension.test.tsx @@ -49,12 +49,11 @@ describe('convertLegacyEntityContentExtension', () => { ); const converted = convertLegacyEntityContentExtension(LegacyExtension); - expect(converted.kind).toBe('entity-content'); - expect(converted.namespace).toBe(undefined); - expect(converted.name).toBe('example'); const tester = createExtensionTester(converted); + expect(tester.query(converted).node.spec.id).toBe('entity-content:example'); + await renderInTestApp(tester.reactElement(), { mountedRoutes: { '/': convertLegacyRouteRef(routeRef), @@ -88,12 +87,11 @@ describe('convertLegacyEntityContentExtension', () => { defaultTitle: 'Other', filter: 'my-filter', }); - expect(converted.kind).toBe('entity-content'); - expect(converted.namespace).toBe(undefined); - expect(converted.name).toBe('other'); const tester = createExtensionTester(converted); + expect(tester.query(converted).node.spec.id).toBe('entity-content:other'); + await renderInTestApp(tester.reactElement(), { mountedRoutes: { '/': convertLegacyRouteRef(routeRef), @@ -123,14 +121,14 @@ describe('convertLegacyEntityContentExtension', () => { }), ), ); - return converted.name; + return createExtensionTester(converted).query(converted).node.spec.id; }; - expect(withName('EntityTestContent')).toBe(undefined); - expect(withName('EntityTestTrimContent')).toBe('trim'); - expect(withName('EntityTeStTrimContent')).toBe('trim'); - expect(withName('EntityExampleContent')).toBe('example'); - expect(withName('EntityExAmpleContent')).toBe('ex-ample'); - expect(withName('ExampleContent')).toBe('example-content'); + expect(withName('EntityTestContent')).toBe('entity-content:test'); // falls back to test namespace + expect(withName('EntityTestTrimContent')).toBe('entity-content:trim'); + expect(withName('EntityTeStTrimContent')).toBe('entity-content:trim'); + expect(withName('EntityExampleContent')).toBe('entity-content:example'); + expect(withName('EntityExAmpleContent')).toBe('entity-content:ex-ample'); + expect(withName('ExampleContent')).toBe('entity-content:example-content'); }); }); diff --git a/plugins/catalog-react/src/alpha/converters/convertLegacyEntityContentExtension.tsx b/plugins/catalog-react/src/alpha/converters/convertLegacyEntityContentExtension.tsx index e44b5671fc..02f5d104bc 100644 --- a/plugins/catalog-react/src/alpha/converters/convertLegacyEntityContentExtension.tsx +++ b/plugins/catalog-react/src/alpha/converters/convertLegacyEntityContentExtension.tsx @@ -40,7 +40,7 @@ export function convertLegacyEntityContentExtension( defaultPath?: string; defaultTitle?: string; }, -): ExtensionDefinition { +): ExtensionDefinition { const element = ; const extName = getComponentData(element, 'core.extensionName'); diff --git a/plugins/catalog-react/src/apis/EntityPresentationApi/defaultEntityPresentation.ts b/plugins/catalog-react/src/apis/EntityPresentationApi/defaultEntityPresentation.ts index 8d841f3c3c..b546f9aa93 100644 --- a/plugins/catalog-react/src/apis/EntityPresentationApi/defaultEntityPresentation.ts +++ b/plugins/catalog-react/src/apis/EntityPresentationApi/defaultEntityPresentation.ts @@ -71,6 +71,9 @@ export function defaultEntityPresentation( }; } +const isString = (value: unknown): value is string => + Boolean(value) && typeof value === 'string'; + // Try to extract display-worthy parts of an entity or ref as best we can, without throwing function getParts(entityOrRef: Entity | CompoundEntityRef | string): { kind?: string; @@ -99,35 +102,29 @@ function getParts(entityOrRef: Entity | CompoundEntityRef | string): { } if (typeof entityOrRef === 'object' && entityOrRef !== null) { - const kind = [get(entityOrRef, 'kind')].find( - candidate => candidate && typeof candidate === 'string', - ); + const kind = [get(entityOrRef, 'kind')].find(isString); const namespace = [ get(entityOrRef, 'metadata.namespace'), get(entityOrRef, 'namespace'), - ].find(candidate => candidate && typeof candidate === 'string'); + ].find(isString); const name = [ get(entityOrRef, 'metadata.name'), get(entityOrRef, 'name'), - ].find(candidate => candidate && typeof candidate === 'string'); + ].find(isString); - const title = [get(entityOrRef, 'metadata.title')].find( - candidate => candidate && typeof candidate === 'string', - ); + const title = [get(entityOrRef, 'metadata.title')].find(isString); const description = [get(entityOrRef, 'metadata.description')].find( - candidate => candidate && typeof candidate === 'string', + isString, ); const displayName = [get(entityOrRef, 'spec.profile.displayName')].find( - candidate => candidate && typeof candidate === 'string', + isString, ); - const type = [get(entityOrRef, 'spec.type')].find( - candidate => candidate && typeof candidate === 'string', - ); + const type = [get(entityOrRef, 'spec.type')].find(isString); return { kind, namespace, name, title, description, displayName, type }; } diff --git a/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts b/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts index 9bb27eab98..f43bba97c7 100644 --- a/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts +++ b/plugins/catalog-react/src/components/EntityOwnerPicker/useFacetsEntities.ts @@ -34,6 +34,9 @@ type FacetsInitialRequest = { text: string; }; +const maybeString = (value: unknown): string | undefined => + typeof value === 'string' ? value : undefined; + /** * This hook asynchronously loads the entity owners using the facets endpoint. * EntityOwnerPicker uses this hook when mode="owners-only" is passed as prop. @@ -67,11 +70,11 @@ export function useFacetsEntities({ enabled }: { enabled: boolean }) { 'en-US', ) || ( - get(a, 'spec.profile.displayName') || + maybeString(get(a, 'spec.profile.displayName')) || a.metadata.title || a.metadata.name ).localeCompare( - get(b, 'spec.profile.displayName') || + maybeString(get(b, 'spec.profile.displayName')) || b.metadata.title || b.metadata.name, 'en-US', diff --git a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx index 9ddba4a2cc..f0d59247ad 100644 --- a/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx +++ b/plugins/catalog-react/src/components/FavoriteEntity/FavoriteEntity.tsx @@ -16,24 +16,17 @@ import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import IconButton from '@material-ui/core/IconButton'; -import Tooltip from '@material-ui/core/Tooltip'; -import { withStyles } from '@material-ui/core/styles'; -import { StarIcon, UnstarredIcon } from '@backstage/core-components'; import React, { ComponentProps } from 'react'; import { useStarredEntity } from '../../hooks/useStarredEntity'; import { catalogReactTranslationRef } from '../../translation'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; +import { FavoriteToggle } from '@backstage/core-components'; /** @public */ export type FavoriteEntityProps = ComponentProps & { entity: Entity; }; -const FilledStar = withStyles(theme => ({ - root: { - color: theme.palette.entityStarButton.color, - }, -}))(StarIcon); /** * IconButton for showing if a current entity is starred and adding/removing it from the favorite entities * @param props - MaterialUI IconButton props extended by required `entity` prop @@ -54,16 +47,12 @@ export const FavoriteEntity = (props: FavoriteEntityProps) => { )}`; return ( - toggleStarredEntity()} - > - - {isStarredEntity ? : } - - + /> ); }; diff --git a/plugins/catalog-unprocessed-entities/CHANGELOG.md b/plugins/catalog-unprocessed-entities/CHANGELOG.md index 5b43a660d5..74cab9fbfb 100644 --- a/plugins/catalog-unprocessed-entities/CHANGELOG.md +++ b/plugins/catalog-unprocessed-entities/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-unprocessed-entities +## 0.2.8-next.0 + +### Patch Changes + +- 4f08c85: Show additional info on DevTools unprocessed entities table + + - Location path (so that it's easier to search the failed entity from the YAML URL) + - Time info of last discovery and next refresh time so that users can be aware of it and can sort the errors based on the time. + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + ## 0.2.7 ### Patch Changes diff --git a/plugins/catalog-unprocessed-entities/package.json b/plugins/catalog-unprocessed-entities/package.json index 1c028e05a6..ed3c14655e 100644 --- a/plugins/catalog-unprocessed-entities/package.json +++ b/plugins/catalog-unprocessed-entities/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-unprocessed-entities", - "version": "0.2.7", + "version": "0.2.8-next.0", "backstage": { "role": "frontend-plugin", "pluginId": "catalog-unprocessed-entities", @@ -45,6 +45,7 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.60", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", + "luxon": "^3.5.0", "react-use": "^17.2.4" }, "devDependencies": { diff --git a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx index 5d1800cb29..65e6eb731e 100644 --- a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx +++ b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import React, { useState } from 'react'; - +import { DateTime } from 'luxon'; import { ErrorPanel, MarkdownContent, @@ -88,6 +88,24 @@ const RenderErrorContext = ({ return null; }; +/** + * Converts input datetime which lacks timezone info into user's local time so that they can + * easily understand the times. + */ +const convertTimeToLocalTimezone = (strDateTime: string | Date) => { + const dateTime = DateTime.fromFormat( + strDateTime.toLocaleString(), + 'yyyy-MM-dd hh:mm:ss', + { + zone: 'UTC', + }, + ); + + const dateTimeLocalTz = dateTime.setZone(DateTime.local().zoneName); + + return dateTimeLocalTz.toFormat('yyyy-MM-dd hh:mm:ss ZZZZ'); +}; + export const FailedEntities = () => { const classes = useStyles(); const unprocessedApi = useApi(catalogUnprocessedEntitiesApiRef); @@ -140,6 +158,13 @@ export const FailedEntities = () => { render: (rowData: UnprocessedEntity | {}) => (rowData as UnprocessedEntity).entity_ref, }, + { + title: Location Path, + sorting: true, + field: 'location_key', + render: (rowData: UnprocessedEntity | {}) => + (rowData as UnprocessedEntity).location_key, + }, { title: Kind, sorting: true, @@ -156,7 +181,25 @@ export const FailedEntities = () => { 'unknown', }, { - title: Raw, + title: Last Discovery At, + sorting: true, + field: 'last_discovery_at', + render: (rowData: UnprocessedEntity | {}) => + convertTimeToLocalTimezone( + (rowData as UnprocessedEntity).last_discovery_at, + ) || 'unknown', + }, + { + title: Next Refresh At, + sorting: true, + field: 'next_update_at', + render: (rowData: UnprocessedEntity | {}) => + convertTimeToLocalTimezone( + (rowData as UnprocessedEntity).next_update_at, + ) || 'unknown', + }, + { + title: Raw Entity Definition, sorting: false, render: (rowData: UnprocessedEntity | {}) => ( diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 2185791a40..5aa877ad13 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,50 @@ # @backstage/plugin-catalog +## 1.22.1-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/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + +## 1.22.1-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- 180a45f: Entity presentation api now only fetches fields that are required to display entity title +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-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-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/integration-react@1.1.30 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + - @backstage/plugin-search-common@1.2.14 + ## 1.22.0 ### Minor Changes diff --git a/plugins/catalog/api-report-alpha.md b/plugins/catalog/api-report-alpha.md index 42f4355921..62e631dd4a 100644 --- a/plugins/catalog/api-report-alpha.md +++ b/plugins/catalog/api-report-alpha.md @@ -8,13 +8,13 @@ import { AnyApiFactory } from '@backstage/frontend-plugin-api'; import { AnyExtensionDataRef } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { ExtensionBlueprint } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; import { JSX as JSX_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; @@ -23,21 +23,19 @@ import { SearchResultItemExtensionPredicate } from '@backstage/plugin-search-rea import { TranslationRef } from '@backstage/core-plugin-api/alpha'; // @alpha -export const CatalogFilterBlueprint: ExtensionBlueprint< - { - kind: 'catalog-filter'; - namespace: undefined; - name: undefined; - }, - { +export const CatalogFilterBlueprint: ExtensionBlueprint<{ + kind: 'catalog-filter'; + namespace: undefined; + name: undefined; + params: { loader: () => Promise; - }, - ConfigurableExtensionDataRef, - {}, - {}, - {}, - never ->; + }; + output: ConfigurableExtensionDataRef; + inputs: {}; + config: {}; + configInput: {}; + dataRefs: never; +}>; // @alpha (undocumented) export const catalogTranslationRef: TranslationRef< @@ -125,7 +123,7 @@ export const catalogTranslationRef: TranslationRef< >; // @alpha (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< { catalogIndex: RouteRef; catalogEntity: RouteRef<{ @@ -148,10 +146,26 @@ const _default: BackstagePlugin< unregisterRedirect: ExternalRouteRef; }, { - 'nav-item:catalog': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef< + 'api:catalog': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'nav-item:catalog': ExtensionDefinition<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent; @@ -159,366 +173,356 @@ const _default: BackstagePlugin< }, 'core.nav-item.target', {} - >, - {}, - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - } - >; - 'api:catalog/starred-entities': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: 'starred-entities'; - } - >; - 'api:catalog/entity-presentation': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: 'entity-presentation'; - } - >; - 'entity-card:catalog/about': ExtensionDefinition< - { + >; + inputs: {}; + }>; + 'api:catalog/starred-entities': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'starred-entities'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:catalog/entity-presentation': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'entity-presentation'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'entity-card:catalog/about': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'about'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'about'; - } - >; - 'entity-card:catalog/links': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:catalog/links': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'links'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'links'; - } - >; - 'entity-card:catalog/labels': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:catalog/labels': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'labels'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'labels'; - } - >; - 'entity-card:catalog/depends-on-components': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:catalog/depends-on-components': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'depends-on-components'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'depends-on-components'; - } - >; - 'entity-card:catalog/depends-on-resources': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:catalog/depends-on-resources': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'depends-on-resources'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'depends-on-resources'; - } - >; - 'entity-card:catalog/has-components': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:catalog/has-components': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'has-components'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'has-components'; - } - >; - 'entity-card:catalog/has-resources': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:catalog/has-resources': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'has-resources'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'has-resources'; - } - >; - 'entity-card:catalog/has-subcomponents': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:catalog/has-subcomponents': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'has-subcomponents'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'has-subcomponents'; - } - >; - 'entity-card:catalog/has-subdomains': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:catalog/has-subdomains': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'has-subdomains'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'has-subdomains'; - } - >; - 'entity-card:catalog/has-systems': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:catalog/has-systems': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'has-systems'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'has-systems'; - } - >; - 'entity-content:catalog/overview': ExtensionDefinition< - { - [x: string]: any; - } & { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-content:catalog/overview': ExtensionDefinition<{ + config: { path: string | undefined; title: string | undefined; filter: string | undefined; - }, - { - [x: string]: any; - } & { + }; + configInput: { filter?: string | undefined; title?: string | undefined; path?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-content-title', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: { cards: ExtensionInput< | ConfigurableExtensionDataRef | ConfigurableExtensionDataRef< @@ -540,33 +544,37 @@ const _default: BackstagePlugin< optional: false; } >; - }, - { - kind: 'entity-content'; - namespace: undefined; - name: 'overview'; - } - >; - 'catalog-filter:catalog/tag': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'catalog-filter'; - namespace: undefined; - name: 'tag'; - } - >; - 'catalog-filter:catalog/kind': ExtensionDefinition< - { + }; + kind: 'entity-content'; + namespace: undefined; + name: 'overview'; + }>; + 'catalog-filter:catalog/tag': ExtensionDefinition<{ + kind: 'catalog-filter'; + namespace: undefined; + name: 'tag'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: {}; + }>; + 'catalog-filter:catalog/kind': ExtensionDefinition<{ + config: { initialFilter: string; - }, - { + }; + configInput: { initialFilter?: string | undefined; - }, - ConfigurableExtensionDataRef, - { + }; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: { [x: string]: ExtensionInput< AnyExtensionDataRef, { @@ -574,33 +582,37 @@ const _default: BackstagePlugin< singleton: boolean; } >; - }, - { - kind: 'catalog-filter'; - namespace: undefined; - name: 'kind'; - } - >; - 'catalog-filter:catalog/type': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'catalog-filter'; - namespace: undefined; - name: 'type'; - } - >; - 'catalog-filter:catalog/mode': ExtensionDefinition< - { + }; + kind: 'catalog-filter'; + namespace: undefined; + name: 'kind'; + }>; + 'catalog-filter:catalog/type': ExtensionDefinition<{ + kind: 'catalog-filter'; + namespace: undefined; + name: 'type'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: {}; + }>; + 'catalog-filter:catalog/mode': ExtensionDefinition<{ + config: { mode: 'all' | 'owners-only' | undefined; - }, - { + }; + configInput: { mode?: 'all' | 'owners-only' | undefined; - }, - ConfigurableExtensionDataRef, - { + }; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: { [x: string]: ExtensionInput< AnyExtensionDataRef, { @@ -608,55 +620,63 @@ const _default: BackstagePlugin< singleton: boolean; } >; - }, - { - kind: 'catalog-filter'; - namespace: undefined; - name: 'mode'; - } - >; - 'catalog-filter:catalog/namespace': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'catalog-filter'; - namespace: undefined; - name: 'namespace'; - } - >; - 'catalog-filter:catalog/lifecycle': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'catalog-filter'; - namespace: undefined; - name: 'lifecycle'; - } - >; - 'catalog-filter:catalog/processing-status': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'catalog-filter'; - namespace: undefined; - name: 'processing-status'; - } - >; - 'catalog-filter:catalog/list': ExtensionDefinition< - { + }; + kind: 'catalog-filter'; + namespace: undefined; + name: 'mode'; + }>; + 'catalog-filter:catalog/namespace': ExtensionDefinition<{ + kind: 'catalog-filter'; + namespace: undefined; + name: 'namespace'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: {}; + }>; + 'catalog-filter:catalog/lifecycle': ExtensionDefinition<{ + kind: 'catalog-filter'; + namespace: undefined; + name: 'lifecycle'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: {}; + }>; + 'catalog-filter:catalog/processing-status': ExtensionDefinition<{ + kind: 'catalog-filter'; + namespace: undefined; + name: 'processing-status'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: {}; + }>; + 'catalog-filter:catalog/list': ExtensionDefinition<{ + config: { initialFilter: 'all' | 'owned' | 'starred'; - }, - { + }; + configInput: { initialFilter?: 'all' | 'owned' | 'starred' | undefined; - }, - ConfigurableExtensionDataRef, - { + }; + output: ConfigurableExtensionDataRef< + JSX_2.Element, + 'core.reactElement', + {} + >; + inputs: { [x: string]: ExtensionInput< AnyExtensionDataRef, { @@ -664,34 +684,29 @@ const _default: BackstagePlugin< singleton: boolean; } >; - }, - { - kind: 'catalog-filter'; - namespace: undefined; - name: 'list'; - } - >; - 'page:catalog': ExtensionDefinition< - { - [x: string]: any; - } & { + }; + kind: 'catalog-filter'; + namespace: undefined; + name: 'list'; + }>; + 'page:catalog': ExtensionDefinition<{ + config: { path: string | undefined; - }, - { - [x: string]: any; - } & { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: { filters: ExtensionInput< ConfigurableExtensionDataRef, { @@ -699,34 +714,29 @@ const _default: BackstagePlugin< optional: false; } >; - }, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; - 'page:catalog/entity': ExtensionDefinition< - { - [x: string]: any; - } & { + }; + kind: 'page'; + namespace: undefined; + name: undefined; + }>; + 'page:catalog/entity': ExtensionDefinition<{ + config: { path: string | undefined; - }, - { - [x: string]: any; - } & { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: { contents: ExtensionInput< | ConfigurableExtensionDataRef | ConfigurableExtensionDataRef @@ -761,35 +771,31 @@ const _default: BackstagePlugin< optional: false; } >; - }, - { - kind: 'page'; - namespace: undefined; - name: 'entity'; - } - >; - 'search-result-list-item:catalog': ExtensionDefinition< - { + }; + kind: 'page'; + namespace: undefined; + name: 'entity'; + }>; + 'search-result-list-item:catalog': ExtensionDefinition<{ + kind: 'search-result-list-item'; + namespace: undefined; + name: undefined; + config: { noTrack: boolean; - }, - { + }; + configInput: { noTrack?: boolean | undefined; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< { predicate?: SearchResultItemExtensionPredicate | undefined; component: SearchResultItemExtensionComponent; }, 'search.search-result-list-item.item', {} - >, - {}, - { - kind: 'search-result-list-item'; - namespace: undefined; - name: undefined; - } - >; + >; + inputs: {}; + }>; } >; export default _default; diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index a592ae3fd5..50e897be8d 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog", - "version": "1.22.0", + "version": "1.22.1-next.1", "description": "The Backstage plugin for browsing the Backstage catalog", "backstage": { "role": "frontend-plugin", diff --git a/plugins/catalog/src/alpha/blueprints/CatalogFilterBlueprint.test.tsx b/plugins/catalog/src/alpha/blueprints/CatalogFilterBlueprint.test.tsx index 9cf8b65957..9e3616ff8c 100644 --- a/plugins/catalog/src/alpha/blueprints/CatalogFilterBlueprint.test.tsx +++ b/plugins/catalog/src/alpha/blueprints/CatalogFilterBlueprint.test.tsx @@ -20,7 +20,10 @@ import { createExtension, createExtensionInput, } from '@backstage/frontend-plugin-api'; -import { createExtensionTester } from '@backstage/frontend-test-utils'; +import { + createExtensionTester, + renderInTestApp, +} from '@backstage/frontend-test-utils'; import { waitFor, screen } from '@testing-library/react'; describe('CatalogFilterBlueprint', () => { @@ -33,6 +36,7 @@ describe('CatalogFilterBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "page:catalog", "input": "filters", @@ -89,9 +93,11 @@ describe('CatalogFilterBlueprint', () => { }, }); - createExtensionTester(extension, { config: { test: 'mock test config' } }) - .add(mockExtension) - .render(); + renderInTestApp( + createExtensionTester(extension, { config: { test: 'mock test config' } }) + .add(mockExtension) + .reactElement(), + ); await waitFor(() => { expect(screen.getByTestId('test')).toBeInTheDocument(); diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx index b136d98a82..38f50d9eb1 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx @@ -37,7 +37,6 @@ import { useStarredEntities, } from '@backstage/plugin-catalog-react'; import Typography from '@material-ui/core/Typography'; -import { withStyles } from '@material-ui/core/styles'; import { visuallyHidden } from '@mui/utils'; import Edit from '@material-ui/icons/Edit'; import OpenInNew from '@material-ui/icons/OpenInNew'; @@ -50,6 +49,7 @@ import { PaginatedCatalogTable } from './PaginatedCatalogTable'; import { defaultCatalogTableColumnsFunc } from './defaultCatalogTableColumnsFunc'; import { useTranslationRef } from '@backstage/core-plugin-api/alpha'; import { catalogTranslationRef } from '../../alpha/translation'; +import { FavoriteToggleIcon } from '@backstage/core-components'; /** * Props for {@link CatalogTable}. @@ -64,12 +64,6 @@ export interface CatalogTableProps { subtitle?: string; } -const FilledStar = withStyles(theme => ({ - root: { - color: theme.palette.entityStarButton.color, - }, -}))(StarIcon); - const refCompare = (a: Entity, b: Entity) => { const toRef = (entity: Entity) => entity.metadata.title || @@ -160,12 +154,7 @@ export const CatalogTable = (props: CatalogTableProps) => { return { cellStyle: { paddingLeft: '1em' }, - icon: () => ( - <> - {title} - {isStarred ? : } - - ), + icon: () => , tooltip: title, onClick: () => toggleStarredEntity(entity), }; diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index 28d63f63d7..d97d6b764d 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/plugin-config-schema +## 0.1.59-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + ## 0.1.58 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 7fd576a85f..614b80a190 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-config-schema", - "version": "0.1.58", + "version": "0.1.59-next.0", "description": "A Backstage plugin that lets you browse the configuration schema of your app", "backstage": { "role": "frontend-plugin", diff --git a/plugins/devtools-backend/CHANGELOG.md b/plugins/devtools-backend/CHANGELOG.md index ae25e3b15c..1f7e3996bb 100644 --- a/plugins/devtools-backend/CHANGELOG.md +++ b/plugins/devtools-backend/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-devtools-backend +## 0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## 0.4.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/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/cli-common@0.1.14 + - @backstage/config@1.2.0 + - @backstage/config-loader@1.9.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-common@0.8.1 + ## 0.3.9 ### Patch Changes diff --git a/plugins/devtools-backend/README.md b/plugins/devtools-backend/README.md index bf0eb64a98..d9ffb3e076 100644 --- a/plugins/devtools-backend/README.md +++ b/plugins/devtools-backend/README.md @@ -4,7 +4,30 @@ Welcome to the DevTools backend plugin! This plugin provides data for the [DevTo ## Setup -Here's how to get the DevTools Backend up and running: +Here's how to get the DevTools Backend up and running in the new backend system: + +1. First we need to add the `@backstage/plugin-devtools-backend` package to your backend: + + ```sh + # From the Backstage root directory + yarn --cwd packages/backend add @backstage/plugin-devtools-backend + ``` + +2. Then add the plugin to your backend index file: + + ```ts + // In packages/backend/src/index.ts + const backend = createBackend(); + // ... other feature additions + backend.add(import('@backstage/plugin-devtools-backend')); + ``` + +3. Now run `yarn start-backend` from the repo root +4. Finally open `http://localhost:7007/api/devtools/health` in a browser and it should return `{"status":"ok"}` + +## Old Backend System + +If you are still on the old backend system, please consider migrating to the new backend system. But to install this plugin in an old backend, see below. 1. First we need to add the `@backstage/plugin-devtools-backend` package to your backend: @@ -50,24 +73,6 @@ Here's how to get the DevTools Backend up and running: 4. Now run `yarn start-backend` from the repo root 5. Finally open `http://localhost:7007/api/devtools/health` in a browser and it should return `{"status":"ok"}` -### New Backend System - -The DevTools backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up: - -In your `packages/backend/src/index.ts` make the following changes: - -```diff - import { createBackend } from '@backstage/backend-defaults'; - - const backend = createBackend(); - - // ... other feature additions - -+ backend.add(import('@backstage/plugin-devtools-backend')); - - backend.start(); -``` - ## Links - [Frontend part of the plugin](https://github.com/backstage/backstage/tree/master/plugins/devtools) diff --git a/plugins/devtools-backend/package.json b/plugins/devtools-backend/package.json index 03b3df0c00..4bde07d5f7 100644 --- a/plugins/devtools-backend/package.json +++ b/plugins/devtools-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools-backend", - "version": "0.3.9", + "version": "0.4.0-next.1", "backstage": { "role": "backend-plugin", "pluginId": "devtools", diff --git a/plugins/devtools/CHANGELOG.md b/plugins/devtools/CHANGELOG.md index e1e3b11cf6..4fa8e6b609 100644 --- a/plugins/devtools/CHANGELOG.md +++ b/plugins/devtools/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-devtools +## 0.1.18-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/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-react@0.4.25 + +## 0.1.18-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- 019d9ad: Minor dockerfile syntax update +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/plugin-devtools-common@0.1.12 + - @backstage/plugin-permission-react@0.4.25 + ## 0.1.17 ### Patch Changes diff --git a/plugins/devtools/api-report-alpha.md b/plugins/devtools/api-report-alpha.md index 888faa29c7..7fb16734f1 100644 --- a/plugins/devtools/api-report-alpha.md +++ b/plugins/devtools/api-report-alpha.md @@ -5,62 +5,66 @@ ```ts import { AnyApiFactory } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; // @alpha (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< { root: RouteRef; }, {}, { - 'api:devtools': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: undefined; - } - >; - 'page:devtools': ExtensionDefinition< - { + 'api:devtools': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'page:devtools': ExtensionDefinition<{ + kind: 'page'; + namespace: undefined; + name: undefined; + config: { path: string | undefined; - }, - { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - {}, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; - 'nav-item:devtools': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef< + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: {}; + }>; + 'nav-item:devtools': ExtensionDefinition<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent; @@ -68,14 +72,9 @@ const _default: BackstagePlugin< }, 'core.nav-item.target', {} - >, - {}, - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - } - >; + >; + inputs: {}; + }>; } >; export default _default; diff --git a/plugins/devtools/package.json b/plugins/devtools/package.json index db6236f327..19ec9d93c6 100644 --- a/plugins/devtools/package.json +++ b/plugins/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-devtools", - "version": "0.1.17", + "version": "0.1.18-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "devtools", diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index 64db006eea..46182e1880 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.4.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.4.2-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.4.0 ### Minor Changes diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index 89d8c17c85..d84cb7d717 100644 --- a/plugins/events-backend-module-aws-sqs/package.json +++ b/plugins/events-backend-module-aws-sqs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-aws-sqs", - "version": "0.4.0", + "version": "0.4.2-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index efe13729b2..73e6a9c135 100644 --- a/plugins/events-backend-module-azure/CHANGELOG.md +++ b/plugins/events-backend-module-azure/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-events-backend-module-azure +## 0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + ## 0.2.9 ### Patch Changes diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 7a49aff69c..7fe1c40108 100644 --- a/plugins/events-backend-module-azure/package.json +++ b/plugins/events-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-azure", - "version": "0.2.9", + "version": "0.2.11-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index f84238c5b9..594e9a85dd 100644 --- a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-events-backend-module-bitbucket-cloud +## 0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + ## 0.2.9 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index 959639fdd9..25df31c5fc 100644 --- a/plugins/events-backend-module-bitbucket-cloud/package.json +++ b/plugins/events-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-bitbucket-cloud", - "version": "0.2.9", + "version": "0.2.11-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index 88c2ac91d8..f8b842415c 100644 --- a/plugins/events-backend-module-gerrit/CHANGELOG.md +++ b/plugins/events-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-events-backend-module-gerrit +## 0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + ## 0.2.9 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 10abf94085..3d1358f055 100644 --- a/plugins/events-backend-module-gerrit/package.json +++ b/plugins/events-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gerrit", - "version": "0.2.9", + "version": "0.2.11-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index f08743d3b3..9f7b6ae04b 100644 --- a/plugins/events-backend-module-github/CHANGELOG.md +++ b/plugins/events-backend-module-github/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-events-backend-module-github +## 0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/config@1.2.0 + ## 0.2.9 ### Patch Changes diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index 16238b7b93..877840e806 100644 --- a/plugins/events-backend-module-github/package.json +++ b/plugins/events-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-github", - "version": "0.2.9", + "version": "0.2.11-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index 85b62d9adf..4231baf2a8 100644 --- a/plugins/events-backend-module-gitlab/CHANGELOG.md +++ b/plugins/events-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-events-backend-module-gitlab +## 0.2.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.2.11-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/config@1.2.0 + ## 0.2.9 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index f0183783ec..86a988074a 100644 --- a/plugins/events-backend-module-gitlab/package.json +++ b/plugins/events-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-module-gitlab", - "version": "0.2.9", + "version": "0.2.11-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "events", diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index 3047079949..5dafcc9f52 100644 --- a/plugins/events-backend-test-utils/CHANGELOG.md +++ b/plugins/events-backend-test-utils/CHANGELOG.md @@ -1,5 +1,19 @@ # @backstage/plugin-events-backend-test-utils +## 0.1.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.1.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.0-next.0 + ## 0.1.33 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index 0fb0092bf0..b174bc989e 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend-test-utils", - "version": "0.1.33", + "version": "0.1.35-next.1", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", "backstage": { "role": "node-library", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index 763699805b..14fa485178 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-events-backend +## 0.3.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.3.12-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/config@1.2.0 + ## 0.3.10 ### Patch Changes diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index a0b2b17ba1..ee057c91fd 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.3.10", + "version": "0.3.12-next.1", "backstage": { "role": "backend-plugin", "pluginId": "events", diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index 5762c94e9e..15934678d6 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-events-node +## 0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + +## 0.4.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 + ## 0.3.9 ### Patch Changes diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index 2b51efd6af..ce31730b78 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-events-node", - "version": "0.3.9", + "version": "0.4.0-next.1", "description": "The plugin-events-node module for @backstage/plugin-events-backend", "backstage": { "role": "node-library", diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index 7c555c4754..3362c91a79 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @internal/plugin-todo-list-backend +## 1.0.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/errors@1.2.4 + +## 1.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/errors@1.2.4 + ## 1.0.30 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 8c378a814e..cf6e61f6ab 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-backend", - "version": "1.0.30", + "version": "1.0.31-next.1", "backstage": { "role": "backend-plugin", "pluginId": "todo-list", diff --git a/plugins/example-todo-list-backend/src/plugin.ts b/plugins/example-todo-list-backend/src/plugin.ts index 1c7bba929a..d05fa54c68 100644 --- a/plugins/example-todo-list-backend/src/plugin.ts +++ b/plugins/example-todo-list-backend/src/plugin.ts @@ -26,7 +26,7 @@ import { createRouter } from './service/router'; * @public */ export const exampleTodoListPlugin = createBackendPlugin({ - pluginId: 'exampleTodoList', + pluginId: 'todolist', register(env) { env.registerInit({ deps: { diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index c5ccfbcd54..b31862e9b3 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,13 @@ # @internal/plugin-todo-list +## 1.0.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 1.0.30 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index eb13f52c6b..df2fe42a29 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list", - "version": "1.0.30", + "version": "1.0.31-next.0", "backstage": { "role": "frontend-plugin", "pluginId": "todo-list", diff --git a/plugins/home-react/CHANGELOG.md b/plugins/home-react/CHANGELOG.md index 87ff61daf0..41a71ed633 100644 --- a/plugins/home-react/CHANGELOG.md +++ b/plugins/home-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-home-react +## 0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.16 ### Patch Changes diff --git a/plugins/home-react/package.json b/plugins/home-react/package.json index e720402766..566a9596b4 100644 --- a/plugins/home-react/package.json +++ b/plugins/home-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home-react", - "version": "0.1.16", + "version": "0.1.17-next.0", "description": "A Backstage plugin that contains react components helps you build a home page", "backstage": { "role": "web-library", @@ -46,7 +46,7 @@ "@backstage/core-plugin-api": "workspace:^", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", - "@rjsf/utils": "5.18.5", + "@rjsf/utils": "5.20.1", "@types/react": "^16.13.1 || ^17.0.0" }, "devDependencies": { diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index b2435eb5db..51c5abe7dd 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-home +## 0.7.10-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/catalog-client@1.6.7-next.0 + - @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-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-home-react@0.1.17-next.0 + +## 0.7.10-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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/plugin-home-react@0.1.16 + ## 0.7.9 ### Patch Changes diff --git a/plugins/home/api-report-alpha.md b/plugins/home/api-report-alpha.md index e32412168b..7b4b157eb2 100644 --- a/plugins/home/api-report-alpha.md +++ b/plugins/home/api-report-alpha.md @@ -4,43 +4,40 @@ ```ts import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; // @alpha (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< {}, {}, { - 'page:home': ExtensionDefinition< - { - [x: string]: any; - } & { + 'page:home': ExtensionDefinition<{ + config: { path: string | undefined; - }, - { - [x: string]: any; - } & { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: { props: ExtensionInput< | ConfigurableExtensionDataRef< React_2.JSX.Element, @@ -61,13 +58,11 @@ const _default: BackstagePlugin< optional: true; } >; - }, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; + }; + kind: 'page'; + namespace: undefined; + name: undefined; + }>; } >; export default _default; diff --git a/plugins/home/package.json b/plugins/home/package.json index 97d7597b99..f760ab8bd3 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-home", - "version": "0.7.9", + "version": "0.7.10-next.1", "description": "A Backstage plugin that helps you build a home page", "backstage": { "role": "frontend-plugin", @@ -70,10 +70,10 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", - "@rjsf/core": "5.18.5", - "@rjsf/material-ui": "5.18.5", - "@rjsf/utils": "5.18.5", - "@rjsf/validator-ajv8": "5.18.5", + "@rjsf/core": "5.20.1", + "@rjsf/material-ui": "5.20.1", + "@rjsf/utils": "5.20.1", + "@rjsf/validator-ajv8": "5.20.1", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "lodash": "^4.17.21", "luxon": "^3.4.3", diff --git a/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx b/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx index 234ae699ec..8081e71407 100644 --- a/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx +++ b/plugins/home/src/components/StarredEntityListItem/StarredEntityListItem.tsx @@ -17,15 +17,12 @@ import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { entityRouteParams } from '@backstage/plugin-catalog-react'; import ListItem from '@material-ui/core/ListItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; -import Tooltip from '@material-ui/core/Tooltip'; -import IconButton from '@material-ui/core/IconButton'; import ListItemText from '@material-ui/core/ListItemText'; import React from 'react'; import { Link } from 'react-router-dom'; import { entityRouteRef } from '@backstage/plugin-catalog-react'; import { useRouteRef } from '@backstage/core-plugin-api'; -import { StarIcon } from '@backstage/core-components'; -import { withStyles } from '@material-ui/core/styles'; +import { FavoriteToggle } from '@backstage/core-components'; type EntityListItemProps = { entity: Entity; @@ -38,24 +35,15 @@ export const StarredEntityListItem = ({ }: EntityListItemProps) => { const catalogEntityRoute = useRouteRef(entityRouteRef); - const FilledStar = withStyles(theme => ({ - root: { - color: theme.palette.entityStarButton.color, - }, - }))(StarIcon); - return ( - - onToggleStarredEntity(entity)} - > - - - + onToggleStarredEntity(entity)} + /> diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index e944ce6255..33447a6be2 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-kubernetes-backend +## 0.18.6-next.1 + +### Patch Changes + +- ca96b66: Skip start without proper config +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-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/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-node@0.1.19-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## 0.18.6-next.0 + +### Patch Changes + +- f55f8bf: The `KubernetesBuilder` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-kubernetes-node@0.1.19-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration-aws-node@0.1.12 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-permission-common@0.8.1 + ## 0.18.4 ### Patch Changes diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 978171e2ea..dc42a2b7b2 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-backend", - "version": "0.18.4", + "version": "0.18.6-next.1", "description": "A Backstage backend plugin that integrates towards Kubernetes", "backstage": { "role": "backend-plugin", diff --git a/plugins/kubernetes-backend/src/plugin.ts b/plugins/kubernetes-backend/src/plugin.ts index 57221e377c..284fa2e5e2 100644 --- a/plugins/kubernetes-backend/src/plugin.ts +++ b/plugins/kubernetes-backend/src/plugin.ts @@ -193,27 +193,33 @@ export const kubernetesPlugin = createBackendPlugin({ auth, httpAuth, }) { - // TODO: expose all of the customization & extension points of the builder here - const builder: KubernetesBuilder = KubernetesBuilder.createBuilder({ - logger, - config, - catalogApi, - permissions, - discovery, - auth, - httpAuth, - }) - .setObjectsProvider(extPointObjectsProvider.getObjectsProvider()) - .setClusterSupplier(extPointClusterSuplier.getClusterSupplier()) - .setFetcher(extPointFetcher.getFetcher()) - .setServiceLocator(extPointServiceLocator.getServiceLocator()); + if (config.has('kubernetes')) { + // TODO: expose all of the customization & extension points of the builder here + const builder: KubernetesBuilder = KubernetesBuilder.createBuilder({ + logger, + config, + catalogApi, + permissions, + discovery, + auth, + httpAuth, + }) + .setObjectsProvider(extPointObjectsProvider.getObjectsProvider()) + .setClusterSupplier(extPointClusterSuplier.getClusterSupplier()) + .setFetcher(extPointFetcher.getFetcher()) + .setServiceLocator(extPointServiceLocator.getServiceLocator()); - AuthStrategy.addAuthStrategiesFromArray( - extPointAuthStrategy.getAuthenticationStrategies(), - builder, - ); - const { router } = await builder.build(); - http.use(router); + AuthStrategy.addAuthStrategiesFromArray( + extPointAuthStrategy.getAuthenticationStrategies(), + builder, + ); + const { router } = await builder.build(); + http.use(router); + } else { + logger.warn( + 'Failed to initialize kubernetes backend: valid kubernetes config is missing', + ); + } }, }); }, diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts index 60683a74f3..3299d11e5d 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.test.ts @@ -728,6 +728,19 @@ metadata: const throwError = () => startTestBackend({ features: [ + mockServices.rootConfig.factory({ + data: { + kubernetes: { + serviceLocatorMethod: { type: 'multiTenant' }, + clusterLocatorMethods: [ + { + type: 'config', + clusters: [], + }, + ], + }, + }, + }), import('@backstage/plugin-kubernetes-backend/alpha'), createBackendModule({ pluginId: 'kubernetes', diff --git a/plugins/kubernetes-cluster/CHANGELOG.md b/plugins/kubernetes-cluster/CHANGELOG.md index a35b71719a..e5f1848841 100644 --- a/plugins/kubernetes-cluster/CHANGELOG.md +++ b/plugins/kubernetes-cluster/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-kubernetes-cluster +## 0.0.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-react@0.4.3-next.0 + +## 0.0.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-react@0.4.2 + ## 0.0.14 ### Patch Changes diff --git a/plugins/kubernetes-cluster/package.json b/plugins/kubernetes-cluster/package.json index c7eb6658b0..29c933be61 100644 --- a/plugins/kubernetes-cluster/package.json +++ b/plugins/kubernetes-cluster/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-cluster", - "version": "0.0.14", + "version": "0.0.15-next.1", "description": "A Backstage plugin that shows details of Kubernetes clusters", "backstage": { "role": "frontend-plugin", diff --git a/plugins/kubernetes-node/CHANGELOG.md b/plugins/kubernetes-node/CHANGELOG.md index 6d81f07df2..8259430ff5 100644 --- a/plugins/kubernetes-node/CHANGELOG.md +++ b/plugins/kubernetes-node/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-kubernetes-node +## 0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + +## 0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.1.17 ### Patch Changes diff --git a/plugins/kubernetes-node/package.json b/plugins/kubernetes-node/package.json index 5f9c9efa55..cc6aa3dd65 100644 --- a/plugins/kubernetes-node/package.json +++ b/plugins/kubernetes-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-node", - "version": "0.1.17", + "version": "0.1.19-next.1", "description": "Node.js library for the kubernetes plugin", "backstage": { "role": "node-library", diff --git a/plugins/kubernetes-react/CHANGELOG.md b/plugins/kubernetes-react/CHANGELOG.md index d76b454a4b..747360d3e4 100644 --- a/plugins/kubernetes-react/CHANGELOG.md +++ b/plugins/kubernetes-react/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/plugin-kubernetes-react +## 0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-kubernetes-common@0.8.2 + ## 0.4.2 ### Patch Changes diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index 936231da7c..8d60446945 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes-react", - "version": "0.4.2", + "version": "0.4.3-next.0", "description": "Web library for the kubernetes-react plugin", "backstage": { "role": "web-library", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index a2e47a6b1b..07a229d934 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-kubernetes +## 0.11.14-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/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-react@0.4.3-next.0 + +## 0.11.14-next.0 + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- bfc0f42: Make k8s entity content appear on components & resources only by default in new FE system +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-kubernetes-common@0.8.2 + - @backstage/plugin-kubernetes-react@0.4.2 + ## 0.11.13 ### Patch Changes diff --git a/plugins/kubernetes/api-report-alpha.md b/plugins/kubernetes/api-report-alpha.md index 15f7efaf1b..852a5c6c1a 100644 --- a/plugins/kubernetes/api-report-alpha.md +++ b/plugins/kubernetes/api-report-alpha.md @@ -7,118 +7,139 @@ import { AnyApiFactory } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { JSX as JSX_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; // @public (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< { kubernetes: RouteRef; }, {}, { - 'page:kubernetes': ExtensionDefinition< - { + 'api:kubernetes': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'page:kubernetes': ExtensionDefinition<{ + kind: 'page'; + namespace: undefined; + name: undefined; + config: { path: string | undefined; - }, - { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - {}, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; - 'entity-content:kubernetes/kubernetes': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-content:kubernetes/kubernetes': ExtensionDefinition<{ + kind: 'entity-content'; + namespace: undefined; + name: 'kubernetes'; + config: { path: string | undefined; title: string | undefined; filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; title?: string | undefined; path?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-content'; - namespace: undefined; - name: 'kubernetes'; - } - >; - 'api:kubernetes/proxy': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: 'proxy'; - } - >; - 'api:kubernetes/auth-providers': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: 'auth-providers'; - } - >; - 'api:kubernetes/cluster-link-formatter': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: 'cluster-link-formatter'; - } - >; + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-content-title', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'api:kubernetes/proxy': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'proxy'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:kubernetes/auth-providers': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'auth-providers'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'api:kubernetes/cluster-link-formatter': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'cluster-link-formatter'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; } >; export default _default; diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index c982e67d04..9020737fbd 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-kubernetes", - "version": "0.11.13", + "version": "0.11.14-next.1", "description": "A Backstage plugin that integrates towards Kubernetes", "backstage": { "role": "frontend-plugin", diff --git a/plugins/notifications-backend-module-email/CHANGELOG.md b/plugins/notifications-backend-module-email/CHANGELOG.md index b040e3fe5a..113c7b06b4 100644 --- a/plugins/notifications-backend-module-email/CHANGELOG.md +++ b/plugins/notifications-backend-module-email/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-notifications-backend-module-email +## 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 diff --git a/plugins/notifications-backend-module-email/package.json b/plugins/notifications-backend-module-email/package.json index 9c799503e8..9b910b0041 100644 --- a/plugins/notifications-backend-module-email/package.json +++ b/plugins/notifications-backend-module-email/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend-module-email", - "version": "0.2.0", + "version": "0.3.0-next.1", "description": "The email backend module for the notifications plugin.", "backstage": { "role": "backend-plugin-module", @@ -42,6 +42,7 @@ "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", "@backstage/integration-aws-node": "workspace:^", + "@backstage/plugin-catalog-node": "workspace:^", "@backstage/plugin-notifications-common": "workspace:^", "@backstage/plugin-notifications-node": "workspace:^", "@backstage/types": "workspace:^", diff --git a/plugins/notifications-backend-module-email/src/module.ts b/plugins/notifications-backend-module-email/src/module.ts index 6b74bf70e7..c83d27b6a3 100644 --- a/plugins/notifications-backend-module-email/src/module.ts +++ b/plugins/notifications-backend-module-email/src/module.ts @@ -17,7 +17,7 @@ import { coreServices, createBackendModule, } from '@backstage/backend-plugin-api'; -import { CatalogClient } from '@backstage/catalog-client'; +import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; import { notificationsProcessingExtensionPoint } from '@backstage/plugin-notifications-node'; import { NotificationsEmailProcessor } from './processor'; import { @@ -46,21 +46,17 @@ export const notificationsModuleEmail = createBackendModule({ deps: { config: coreServices.rootConfig, notifications: notificationsProcessingExtensionPoint, - discovery: coreServices.discovery, logger: coreServices.logger, auth: coreServices.auth, cache: coreServices.cache, + catalog: catalogServiceRef, }, - async init({ config, notifications, discovery, logger, auth, cache }) { - const catalogClient = new CatalogClient({ - discoveryApi: discovery, - }); - + async init({ config, notifications, logger, auth, cache, catalog }) { notifications.addProcessor( new NotificationsEmailProcessor( logger, config, - catalogClient, + catalog, auth, cache, templateRenderer, diff --git a/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts b/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts index a876a548d2..9337915ecc 100644 --- a/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts +++ b/plugins/notifications-backend-module-email/src/processor/NotificationsEmailProcessor.ts @@ -24,10 +24,7 @@ import { } from '@backstage/backend-plugin-api'; import { Config, readDurationFromConfig } from '@backstage/config'; import { durationToMilliseconds } from '@backstage/types'; -import { - CATALOG_FILTER_EXISTS, - CatalogClient, -} from '@backstage/catalog-client'; +import { CATALOG_FILTER_EXISTS, CatalogApi } from '@backstage/catalog-client'; import { getProcessorFiltersFromConfig, Notification, @@ -63,7 +60,7 @@ export class NotificationsEmailProcessor implements NotificationProcessor { constructor( private readonly logger: LoggerService, private readonly config: Config, - private readonly catalog: CatalogClient, + private readonly catalog: CatalogApi, private readonly auth: AuthService, private readonly cache?: CacheService, private readonly templateRenderer?: NotificationTemplateRenderer, diff --git a/plugins/notifications-backend/CHANGELOG.md b/plugins/notifications-backend/CHANGELOG.md index bd0323d5c2..b74489313d 100644 --- a/plugins/notifications-backend/CHANGELOG.md +++ b/plugins/notifications-backend/CHANGELOG.md @@ -1,5 +1,50 @@ # @backstage/plugin-notifications-backend +## 0.4.0-next.1 + +### Patch Changes + +- f195972: Validate notification link when new notification is created +- 5edd344: Refactor to use injected catalog client in the new backend system +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-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/errors@1.2.4 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.1 + - @backstage/plugin-signals-node@0.1.11-next.1 + +## 0.4.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-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-notifications-node@0.2.6-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-notifications-common@0.0.5 + ## 0.3.4 ### Patch Changes diff --git a/packages/backend-tasks/migrations/20240712211735_nullable_next_run.js b/plugins/notifications-backend/migrations/20240902_addIcon.js similarity index 57% rename from packages/backend-tasks/migrations/20240712211735_nullable_next_run.js rename to plugins/notifications-backend/migrations/20240902_addIcon.js index efbef1c76f..a5327f8d73 100644 --- a/packages/backend-tasks/migrations/20240712211735_nullable_next_run.js +++ b/plugins/notifications-backend/migrations/20240902_addIcon.js @@ -14,28 +14,20 @@ * limitations under the License. */ -// @ts-check - -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ exports.up = async function up(knex) { - await knex.schema.alterTable('backstage_backend_tasks__tasks', table => { - table.setNullable('next_run_start_at'); + await knex.schema.alterTable('notification', table => { + table.string('icon', 255).nullable(); + }); + await knex.schema.alterTable('broadcast', table => { + table.string('icon', 255).nullable(); }); }; -/** - * @param { import("knex").Knex } knex - * @returns { Promise } - */ exports.down = async function down(knex) { - await knex - .delete() - .from('backstage_backend_tasks__tasks') - .where({ next_run_start_at: null }); - await knex.schema.alterTable('backstage_backend_tasks__tasks', table => { - table.dropNullable('next_run_start_at'); + await knex.schema.alterTable('notification', table => { + table.dropColumn('icon'); + }); + await knex.schema.alterTable('broadcast', table => { + table.dropColumn('icon'); }); }; diff --git a/plugins/notifications-backend/package.json b/plugins/notifications-backend/package.json index faf3118ef8..d91f0f7aea 100644 --- a/plugins/notifications-backend/package.json +++ b/plugins/notifications-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-backend", - "version": "0.3.4", + "version": "0.4.0-next.1", "backstage": { "role": "backend-plugin", "pluginId": "notifications", @@ -45,6 +45,7 @@ "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", + "@backstage/plugin-catalog-node": "workspace:^", "@backstage/plugin-events-node": "workspace:^", "@backstage/plugin-notifications-common": "workspace:^", "@backstage/plugin-notifications-node": "workspace:^", diff --git a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts index d4e678c8f1..0c7193c1fc 100644 --- a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts +++ b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.test.ts @@ -68,6 +68,7 @@ const testNotification1: Notification = { topic: 'efgh-topic', link: '/catalog', severity: 'critical', + icon: 'docs', }, }; const testNotification2: Notification = { @@ -183,6 +184,7 @@ describe.each(databases.eachSupportedId())( expect(notification?.payload?.topic).toBe('efgh-topic'); expect(notification?.payload?.link).toBe('/catalog'); expect(notification?.payload?.severity).toBe('critical'); + expect(notification?.payload?.icon).toBe('docs'); }); }); diff --git a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts index b23f5254f4..40a76c7486 100644 --- a/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts +++ b/plugins/notifications-backend/src/database/DatabaseNotificationsStore.ts @@ -41,6 +41,7 @@ const NOTIFICATION_COLUMNS = [ 'origin', 'scope', 'topic', + 'icon', 'created', 'updated', 'user', @@ -119,6 +120,7 @@ export class DatabaseNotificationsStore implements NotificationsStore { description: notification.payload?.description, severity: normalizeSeverity(notification.payload?.severity), scope: notification.payload?.scope, + icon: notification.payload.icon, saved: notification.saved, read: notification.read, }; @@ -134,6 +136,7 @@ export class DatabaseNotificationsStore implements NotificationsStore { title: notification.payload?.title, description: notification.payload?.description, severity: normalizeSeverity(notification.payload?.severity), + icon: notification.payload.icon, scope: notification.payload?.scope, }; }; diff --git a/plugins/notifications-backend/src/plugin.ts b/plugins/notifications-backend/src/plugin.ts index c0344fb06f..84a200bae1 100644 --- a/plugins/notifications-backend/src/plugin.ts +++ b/plugins/notifications-backend/src/plugin.ts @@ -25,6 +25,7 @@ import { notificationsProcessingExtensionPoint, NotificationsProcessingExtensionPoint, } from '@backstage/plugin-notifications-node'; +import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; class NotificationsProcessingExtensionPointImpl implements NotificationsProcessingExtensionPoint @@ -65,8 +66,9 @@ export const notificationsPlugin = createBackendPlugin({ httpRouter: coreServices.httpRouter, logger: coreServices.logger, database: coreServices.database, - discovery: coreServices.discovery, signals: signalsServiceRef, + config: coreServices.rootConfig, + catalog: catalogServiceRef, }, async init({ auth, @@ -75,8 +77,9 @@ export const notificationsPlugin = createBackendPlugin({ httpRouter, logger, database, - discovery, signals, + config, + catalog, }) { httpRouter.use( await createRouter({ @@ -84,8 +87,9 @@ export const notificationsPlugin = createBackendPlugin({ httpAuth, userInfo, logger, + config, database, - discovery, + catalog, signals, processors: processingExtensions.processors, }), diff --git a/plugins/notifications-backend/src/service/router.test.ts b/plugins/notifications-backend/src/service/router.test.ts index 804b0ff088..b90ebcaf50 100644 --- a/plugins/notifications-backend/src/service/router.test.ts +++ b/plugins/notifications-backend/src/service/router.test.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { DatabaseManager, PluginDatabaseManager, @@ -23,7 +24,9 @@ import request from 'supertest'; import { createRouter } from './router'; import { ConfigReader } from '@backstage/config'; import { SignalsService } from '@backstage/plugin-signals-node'; -import { mockServices } from '@backstage/backend-test-utils'; +import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { NotificationSendOptions } from '@backstage/plugin-notifications-node'; +import { CatalogClient } from '@backstage/catalog-client'; function createDatabase(): PluginDatabaseManager { return DatabaseManager.fromConfig( @@ -45,20 +48,28 @@ describe('createRouter', () => { publish: jest.fn(), }; - const discovery = mockServices.discovery(); const userInfo = mockServices.userInfo(); - const httpAuth = mockServices.httpAuth(); + const httpAuth = mockServices.httpAuth({ + defaultCredentials: mockCredentials.service(), + }); const auth = mockServices.auth(); + const config = mockServices.rootConfig({ + data: { app: { baseUrl: 'http://localhost' } }, + }); + const catalog = new CatalogClient({ + discoveryApi: mockServices.discovery.mock(), + }); beforeAll(async () => { const router = await createRouter({ logger: mockServices.logger.mock(), database: createDatabase(), - discovery, signals: signalService, userInfo, + config, httpAuth, auth, + catalog, }); app = express().use(router); }); @@ -75,4 +86,80 @@ describe('createRouter', () => { expect(response.body).toEqual({ status: 'ok' }); }); }); + + describe('POST /', () => { + const sendNotification = async (data: NotificationSendOptions) => + request(app) + .post('/') + .send(data) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + it('returns error on invalid link', async () => { + const javascriptXSS = await sendNotification({ + recipients: { + type: 'broadcast', + }, + payload: { + title: 'test notification', + // eslint-disable-next-line no-script-url + link: 'javascript:alert(document.domain)', + }, + }); + + expect(javascriptXSS.status).toEqual(400); + + const ftpLink = await sendNotification({ + recipients: { + type: 'broadcast', + }, + payload: { + title: 'test notification', + link: 'ftp://example.com', + }, + }); + + expect(ftpLink.status).toEqual(400); + }); + + it('should accept absolute http links', async () => { + const httpLink = await sendNotification({ + recipients: { + type: 'broadcast', + }, + payload: { + title: 'test notification', + link: 'http://localhost/test', + }, + }); + + expect(httpLink.status).toEqual(200); + + const httpsLink = await sendNotification({ + recipients: { + type: 'broadcast', + }, + payload: { + title: 'test notification', + link: 'https://example.com', + }, + }); + + expect(httpsLink.status).toEqual(200); + }); + + it('should accept relative links', async () => { + const catalogLink = await sendNotification({ + recipients: { + type: 'broadcast', + }, + payload: { + title: 'test notification', + link: '/catalog', + }, + }); + + expect(catalogLink.status).toEqual(200); + }); + }); }); diff --git a/plugins/notifications-backend/src/service/router.ts b/plugins/notifications-backend/src/service/router.ts index abd7e2dc13..fb5aacb5f4 100644 --- a/plugins/notifications-backend/src/service/router.ts +++ b/plugins/notifications-backend/src/service/router.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { errorHandler, PluginDatabaseManager } from '@backstage/backend-common'; import express, { Request } from 'express'; import Router from 'express-promise-router'; @@ -22,7 +23,7 @@ import { NotificationGetOptions, } from '../database'; import { v4 as uuid } from 'uuid'; -import { CatalogApi, CatalogClient } from '@backstage/catalog-client'; +import { CatalogApi } from '@backstage/catalog-client'; import { NotificationProcessor, NotificationSendOptions, @@ -30,7 +31,6 @@ import { import { InputError } from '@backstage/errors'; import { AuthService, - DiscoveryService, HttpAuthService, LoggerService, UserInfoService, @@ -46,17 +46,18 @@ import { } from '@backstage/plugin-notifications-common'; import { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams'; import { getUsersForEntityRef } from './getUsersForEntityRef'; +import { Config } from '@backstage/config'; /** @internal */ export interface RouterOptions { logger: LoggerService; + config: Config; database: PluginDatabaseManager; - discovery: DiscoveryService; auth: AuthService; httpAuth: HttpAuthService; userInfo: UserInfoService; signals?: SignalsService; - catalog?: CatalogApi; + catalog: CatalogApi; processors?: NotificationProcessor[]; } @@ -65,20 +66,19 @@ export async function createRouter( options: RouterOptions, ): Promise { const { + config, logger, database, auth, httpAuth, userInfo, - discovery, catalog, processors = [], signals, } = options; - const catalogClient = - catalog ?? new CatalogClient({ discoveryApi: discovery }); const store = await DatabaseNotificationsStore.create({ database }); + const frontendBaseUrl = config.getString('app.baseUrl'); const getUser = async (req: Request) => { const credentials = await httpAuth.credentials(req, { allow: ['user'] }); @@ -177,6 +177,18 @@ export async function createRouter( } }; + const validateLink = (link: string) => { + const stripLeadingSlash = (s: string) => s.replace(/^\//, ''); + const ensureTrailingSlash = (s: string) => s.replace(/\/?$/, '/'); + const url = new URL( + stripLeadingSlash(link), + ensureTrailingSlash(frontendBaseUrl), + ); + if (url.protocol !== 'https:' && url.protocol !== 'http:') { + throw new Error('Only HTTP/HTTPS links are allowed'); + } + }; + // TODO: Move to use OpenAPI router instead const router = Router(); router.use(express.json()); @@ -419,13 +431,21 @@ export async function createRouter( allow: ['service'], }); - const { title } = payload; + const { title, link } = payload; if (!recipients || !title) { logger.error(`Invalid notification request received`); throw new InputError(`Invalid notification request received`); } + if (link) { + try { + validateLink(link); + } catch (e) { + throw new InputError('Invalid link provided', e); + } + } + const origin = credentials.principal.subject; const baseNotification = { payload: { @@ -450,7 +470,7 @@ export async function createRouter( users = await getUsersForEntityRef( entityRef, recipients.excludeEntityRef ?? [], - { auth, catalogClient }, + { auth, catalogClient: catalog }, ); } catch (e) { logger.error(`Failed to resolve notification receivers: ${e}`); diff --git a/plugins/notifications-node/CHANGELOG.md b/plugins/notifications-node/CHANGELOG.md index 1c98305038..7066316a04 100644 --- a/plugins/notifications-node/CHANGELOG.md +++ b/plugins/notifications-node/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-notifications-node +## 0.2.6-next.1 + +### Patch Changes + +- 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/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-node@0.1.11-next.1 + +## 0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/plugin-notifications-common@0.0.5 + ## 0.2.4 ### Patch Changes diff --git a/plugins/notifications-node/package.json b/plugins/notifications-node/package.json index 37d2663a3a..09008239ae 100644 --- a/plugins/notifications-node/package.json +++ b/plugins/notifications-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications-node", - "version": "0.2.4", + "version": "0.2.6-next.1", "description": "Node.js library for the notifications plugin", "backstage": { "role": "node-library", diff --git a/plugins/notifications/CHANGELOG.md b/plugins/notifications/CHANGELOG.md index 0f257047ba..945000c468 100644 --- a/plugins/notifications/CHANGELOG.md +++ b/plugins/notifications/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-notifications +## 0.3.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-signals-react@0.0.5-next.0 + +## 0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-signals-react@0.0.5-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-notifications-common@0.0.5 + ## 0.3.0 ### Minor Changes diff --git a/plugins/notifications/package.json b/plugins/notifications/package.json index c847fc605d..7dd72d0d97 100644 --- a/plugins/notifications/package.json +++ b/plugins/notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-notifications", - "version": "0.3.0", + "version": "0.3.1-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "notifications", diff --git a/plugins/notifications/src/components/NotificationsTable/NotificationIcon.tsx b/plugins/notifications/src/components/NotificationsTable/NotificationIcon.tsx new file mode 100644 index 0000000000..c89f920249 --- /dev/null +++ b/plugins/notifications/src/components/NotificationsTable/NotificationIcon.tsx @@ -0,0 +1,34 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { Notification } from '@backstage/plugin-notifications-common'; +import SvgIcon from '@material-ui/core/SvgIcon'; +import { useApp } from '@backstage/core-plugin-api'; +import { SeverityIcon } from './SeverityIcon'; + +export const NotificationIcon = ({ + notification, +}: { + notification: Notification; +}) => { + const app = useApp(); + + if (notification.payload.icon) { + const Icon = app.getSystemIcon(notification.payload.icon) ?? SvgIcon; + return ; + } + return ; +}; diff --git a/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx b/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx index 8a6cbd17d7..ee3e4e164d 100644 --- a/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx +++ b/plugins/notifications/src/components/NotificationsTable/NotificationsTable.tsx @@ -34,10 +34,9 @@ import { } from '@backstage/core-components'; import { notificationsApiRef } from '../../api'; - -import { SeverityIcon } from './SeverityIcon'; import { SelectAll } from './SelectAll'; import { BulkActions } from './BulkActions'; +import { NotificationIcon } from './NotificationIcon'; const ThrottleDelayMs = 1000; @@ -184,7 +183,6 @@ export const NotificationsTable = ({ const compactColumns = React.useMemo((): TableColumn[] => { const showToolbar = notifications.length > 0; - return [ { /* selection column */ @@ -220,7 +218,7 @@ export const NotificationsTable = ({ return ( - + diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index 4570bcf112..034384a4be 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-org-react +## 0.1.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + +## 0.1.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + ## 0.1.27 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index 607600fbaa..b0e983b324 100644 --- a/plugins/org-react/package.json +++ b/plugins/org-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org-react", - "version": "0.1.27", + "version": "0.1.28-next.1", "backstage": { "role": "web-library", "pluginId": "org", diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 55b9b3431a..a273d086a1 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-org +## 0.6.29-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/core-plugin-api@1.9.3 + - @backstage/plugin-catalog-common@1.0.26 + +## 0.6.29-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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/plugin-catalog-common@1.0.26 + ## 0.6.28 ### Patch Changes diff --git a/plugins/org/api-report-alpha.md b/plugins/org/api-report-alpha.md index 1187c8f0e3..a8c6bd70ec 100644 --- a/plugins/org/api-report-alpha.md +++ b/plugins/org/api-report-alpha.md @@ -3,152 +3,148 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExternalRouteRef } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { default as React_2 } from 'react'; // @alpha (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< {}, { catalogIndex: ExternalRouteRef; }, { - 'entity-card:org/group-profile': ExtensionDefinition< - { + 'entity-card:org/group-profile': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'group-profile'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'group-profile'; - } - >; - 'entity-card:org/members-list': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:org/members-list': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'members-list'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'members-list'; - } - >; - 'entity-card:org/ownership': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:org/ownership': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'ownership'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'ownership'; - } - >; - 'entity-card:org/user-profile': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-card:org/user-profile': ExtensionDefinition<{ + kind: 'entity-card'; + namespace: undefined; + name: 'user-profile'; + config: { filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-card'; - namespace: undefined; - name: 'user-profile'; - } - >; + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; } >; export default _default; diff --git a/plugins/org/package.json b/plugins/org/package.json index 3940932cbe..93957e54e1 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-org", - "version": "0.6.28", + "version": "0.6.29-next.1", "description": "A Backstage plugin that helps you create entity pages for your organization", "backstage": { "role": "frontend-plugin", diff --git a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md index 6d2a77fb3c..1534a2d605 100644 --- a/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md +++ b/plugins/permission-backend-module-policy-allow-all/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-permission-backend-module-allow-all-policy +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## 0.2.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/plugin-permission-node@0.8.3-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-permission-common@0.8.1 + ## 0.1.20 ### Patch Changes diff --git a/plugins/permission-backend-module-policy-allow-all/package.json b/plugins/permission-backend-module-policy-allow-all/package.json index 637843cdeb..866e2fe744 100644 --- a/plugins/permission-backend-module-policy-allow-all/package.json +++ b/plugins/permission-backend-module-policy-allow-all/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend-module-allow-all-policy", - "version": "0.1.20", + "version": "0.2.0-next.1", "description": "Allow all policy backend module for the permission plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index 2f43217d5d..a1008cf37c 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-permission-backend +## 0.5.49-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + +## 0.5.49-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- fcb9356: Deprecated `createRouter` and its router options in favour of the new backend system. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + ## 0.5.47 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index 4b6287d7d2..282af7cc0b 100644 --- a/plugins/permission-backend/package.json +++ b/plugins/permission-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-backend", - "version": "0.5.47", + "version": "0.5.49-next.1", "backstage": { "role": "backend-plugin", "pluginId": "permission", diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index 79b6af785b..729f32104f 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-permission-node +## 0.8.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + +## 0.8.3-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + ## 0.8.1 ### Patch Changes diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index 1d3a9089aa..0323950376 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-node", - "version": "0.8.1", + "version": "0.8.3-next.1", "description": "Common permission and authorization utilities for backend plugins", "backstage": { "role": "node-library", diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index 3db9b519fa..07cd16bbdd 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-proxy-backend +## 0.5.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + +## 0.5.6-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- d298e6e: Deprecated `createRouter` and its router options in favour of the new backend system. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.5.4 ### Patch Changes diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index fdddaa6283..c23ea0fca4 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-proxy-backend", - "version": "0.5.4", + "version": "0.5.6-next.1", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", "backstage": { "role": "backend-plugin", diff --git a/plugins/scaffolder-backend-module-azure/CHANGELOG.md b/plugins/scaffolder-backend-module-azure/CHANGELOG.md index b6610a9638..f3bb21a181 100644 --- a/plugins/scaffolder-backend-module-azure/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-azure/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-scaffolder-backend-module-azure +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.1.15 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-azure/package.json b/plugins/scaffolder-backend-module-azure/package.json index 43cdd10a96..d76df5f0eb 100644 --- a/plugins/scaffolder-backend-module-azure/package.json +++ b/plugins/scaffolder-backend-module-azure/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-azure", - "version": "0.1.15", + "version": "0.2.0-next.1", "description": "The azure module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md index dfec3e29aa..391eaed947 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-cloud +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + ## 0.1.13 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json index cfedc6048a..316dcc867c 100644 --- a/plugins/scaffolder-backend-module-bitbucket-cloud/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-cloud/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud", - "version": "0.1.13", + "version": "0.2.0-next.1", "description": "The Bitbucket Cloud module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md index 8c12baad68..5bbe594290 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket-server +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.1.13 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket-server/package.json b/plugins/scaffolder-backend-module-bitbucket-server/package.json index 76d00d0ea3..a6650512e0 100644 --- a/plugins/scaffolder-backend-module-bitbucket-server/package.json +++ b/plugins/scaffolder-backend-module-bitbucket-server/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket-server", - "version": "0.1.13", + "version": "0.2.0-next.1", "description": "The Bitbucket Server module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md index 5f36050fff..e68474476c 100644 --- a/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-scaffolder-backend-module-bitbucket +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.1 + - @backstage/plugin-scaffolder-node@0.4.11-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/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.2.13 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-bitbucket/package.json b/plugins/scaffolder-backend-module-bitbucket/package.json index d222e24fc3..56596b59bc 100644 --- a/plugins/scaffolder-backend-module-bitbucket/package.json +++ b/plugins/scaffolder-backend-module-bitbucket/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-bitbucket", - "version": "0.2.13", + "version": "0.3.0-next.1", "description": "The bitbucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md index 3fbba8f6da..9c945e4faf 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-scaffolder-backend-module-confluence-to-markdown +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-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-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.2.24 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/README.md b/plugins/scaffolder-backend-module-confluence-to-markdown/README.md index 1e64004041..aa7b9fee79 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/README.md +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/README.md @@ -15,47 +15,16 @@ From your Backstage root directory run: yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-confluence-to-markdown ``` -Then configure the action: -(you can check the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to see all options): +Then ensure that both the scaffolder and this module are added to your backend: ```typescript -// packages/backend/src/plugins/scaffolder.ts - -import { createBuiltinActions } from '@backstage/plugin-scaffolder-backend'; -import { ScmIntegrations } from '@backstage/integration'; -import { createConfluenceToMarkdownAction } from '@backstage/plugin-scaffolder-backend-module-confluence-to-markdown'; - -export default async function createPlugin( - env: PluginEnvironment, -): Promise { - const catalogClient = new CatalogClient({ discoveryApi: env.discovery }); - const integrations = ScmIntegrations.fromConfig(env.config); - - const builtInActions = createBuiltinActions({ - integrations, - catalogClient, - config: env.config, - reader: env.reader, - }); - - const actions = [ - ...builtInActions, - createConfluenceToMarkdownAction({ - integrations, - config: env.config, - reader: env.reader, - }), - ]; - - return createRouter({ - actions, - catalogClient: catalogClient, - logger: env.logger, - config: env.config, - database: env.database, - reader: env.reader, - }); -} +// In packages/backend/src/index.ts +const backend = createBackend(); +// ... +backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); +backend.add( + import('@backstage/plugin-scaffolder-backend-module-confluence-to-markdown'), +); ``` ### Configuration diff --git a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json index a85e032cea..05383eb557 100644 --- a/plugins/scaffolder-backend-module-confluence-to-markdown/package.json +++ b/plugins/scaffolder-backend-module-confluence-to-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown", - "version": "0.2.24", + "version": "0.3.0-next.1", "description": "The confluence-to-markdown module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 38b4185f16..e41bf64fdc 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-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-defaults@0.5.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + ## 0.2.47 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/README.md b/plugins/scaffolder-backend-module-cookiecutter/README.md index 643154c826..ba2cd14cb2 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/README.md +++ b/plugins/scaffolder-backend-module-cookiecutter/README.md @@ -13,31 +13,14 @@ You need to configure the action in your backend: yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-cookiecutter ``` -Configure the action: -(you can check the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to see all options): +Then ensure that both the scaffolder and this module are added to your backend: ```typescript -// packages/backend/src/plugins/scaffolder.ts - -const actions = [ - createFetchCookiecutterAction({ - integrations, - reader: env.reader, - }), - ...createBuiltInActions({ - ... - }) -]; - -return await createRouter({ - containerRunner, - catalogClient, - actions, - logger: env.logger, - config: env.config, - database: env.database, - reader: env.reader, -}); +// In packages/backend/src/index.ts +const backend = createBackend(); +// ... +backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); +backend.add(import('@backstage/plugin-scaffolder-backend-module-cookiecutter')); ``` After that you can use the action in your template: diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index 4e30c0cf98..48a106d5db 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", - "version": "0.2.47", + "version": "0.3.0-next.1", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md index 46c3fe7957..4eaf48a537 100644 --- a/plugins/scaffolder-backend-module-gcp/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gcp/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-scaffolder-backend-module-gcp +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.1.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gcp/package.json b/plugins/scaffolder-backend-module-gcp/package.json index 71f16f4b96..f0a5114dc0 100644 --- a/plugins/scaffolder-backend-module-gcp/package.json +++ b/plugins/scaffolder-backend-module-gcp/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gcp", - "version": "0.1.1", + "version": "0.2.0-next.1", "description": "The GCP Bucket module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md index 7db14044e9..1dd8dff942 100644 --- a/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-scaffolder-backend-module-gerrit +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.2.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 + +- 9e5923d: Added test cases for publish:gerrit action examples +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.1.15 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gerrit/package.json b/plugins/scaffolder-backend-module-gerrit/package.json index 3557ac6719..b09b9101b9 100644 --- a/plugins/scaffolder-backend-module-gerrit/package.json +++ b/plugins/scaffolder-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gerrit", - "version": "0.1.15", + "version": "0.2.0-next.1", "description": "The gerrit module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md index dd0f55ce6c..f3474b406e 100644 --- a/plugins/scaffolder-backend-module-gitea/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitea/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-scaffolder-backend-module-gitea +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.1.13 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitea/package.json b/plugins/scaffolder-backend-module-gitea/package.json index 51055aae54..3269b54a8d 100644 --- a/plugins/scaffolder-backend-module-gitea/package.json +++ b/plugins/scaffolder-backend-module-gitea/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitea", - "version": "0.1.13", + "version": "0.2.0-next.1", "description": "The gitea module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-github/CHANGELOG.md b/plugins/scaffolder-backend-module-github/CHANGELOG.md index 3c96c7b73d..5c93531f01 100644 --- a/plugins/scaffolder-backend-module-github/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-github/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-scaffolder-backend-module-github +## 0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.5.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-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.4.1 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-github/package.json b/plugins/scaffolder-backend-module-github/package.json index e8dd77bd5f..2664a1a667 100644 --- a/plugins/scaffolder-backend-module-github/package.json +++ b/plugins/scaffolder-backend-module-github/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-github", - "version": "0.4.1", + "version": "0.5.0-next.1", "description": "The github module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md index 4c9aa96b19..c8875fe3ea 100644 --- a/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-scaffolder-backend-module-gitlab +## 0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.5.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-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + ## 0.4.5 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-gitlab/README.md b/plugins/scaffolder-backend-module-gitlab/README.md index 3aee2b6681..3f991bf308 100644 --- a/plugins/scaffolder-backend-module-gitlab/README.md +++ b/plugins/scaffolder-backend-module-gitlab/README.md @@ -13,50 +13,17 @@ Here you can find all Gitlab related features to improve your scaffolder: yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-gitlab ``` -Configure the action: -(you can check the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to see all options): +Then ensure that both the scaffolder and this module are added to your backend: ```typescript -// packages/backend/src/plugins/scaffolder.ts - -import { - createGitlabProjectAccessTokenAction, - createGitlabProjectDeployTokenAction, - createGitlabProjectVariableAction, - createGitlabGroupEnsureExistsAction, - createGitlabIssueAction, -} from '@backstage/plugin-scaffolder-backend-module-gitlab'; - -// Create BuiltIn Actions -const builtInActions = createBuiltinActions({ - integrations, - catalogClient, - config: env.config, - reader: env.reader, -}); - -// Add Gitlab Actions -const actions = [ - ...builtInActions, - createGitlabProjectAccessTokenAction({ integrations: integrations }), - createGitlabProjectDeployTokenAction({ integrations: integrations }), - createGitlabProjectVariableAction({ integrations: integrations }), - createGitlabGroupEnsureExistsAction({ integrations: integrations }), - createGitlabIssueAction({ integrations: integrations }), -]; - -// Create Scaffolder Router -return await createRouter({ - catalogClient, - actions, - logger: env.logger, - config: env.config, - database: env.database, - reader: env.reader, -}); +// In packages/backend/src/index.ts +const backend = createBackend(); +// ... +backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); +backend.add(import('@backstage/plugin-scaffolder-backend-module-gitlab')); ``` -After that you can use the action in your template: +After that you can use the actions in your template: ```yaml apiVersion: scaffolder.backstage.io/v1beta3 diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index 8db4f1ade5..6b711c0f5f 100644 --- a/plugins/scaffolder-backend-module-gitlab/package.json +++ b/plugins/scaffolder-backend-module-gitlab/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-gitlab", - "version": "0.4.5", + "version": "0.5.0-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts index 3eda50a924..46e60584c9 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabMergeRequest.test.ts @@ -408,7 +408,7 @@ describe('createGitLabMergeRequest', () => { 'owner/repo', 'new-mr', 'Create my new MR', - [ + expect.arrayContaining([ { action: 'create', filePath: 'irrelevant/bar.txt', @@ -423,7 +423,7 @@ describe('createGitLabMergeRequest', () => { content: 'SGVsbG8gdGhlcmUh', execute_filemode: false, }, - ], + ]), ); }); }); @@ -450,7 +450,7 @@ describe('createGitLabMergeRequest', () => { 'owner/repo', 'new-mr', 'Create my new MR', - [ + expect.arrayContaining([ { action: 'update', filePath: 'source/auto.txt', @@ -465,7 +465,7 @@ describe('createGitLabMergeRequest', () => { encoding: 'base64', execute_filemode: false, }, - ], + ]), ); }); }); @@ -562,7 +562,7 @@ describe('createGitLabMergeRequest', () => { 'owner/repo', 'new-mr', 'Create my new MR', - [ + expect.arrayContaining([ { action: 'update', filePath: 'source/auto.txt', @@ -577,7 +577,7 @@ describe('createGitLabMergeRequest', () => { encoding: 'base64', execute_filemode: false, }, - ], + ]), ); }); @@ -604,7 +604,7 @@ describe('createGitLabMergeRequest', () => { 'owner/repo', 'new-mr', 'Create my new MR', - [ + expect.arrayContaining([ { action: 'update', filePath: 'source/auto.txt', @@ -619,7 +619,7 @@ describe('createGitLabMergeRequest', () => { encoding: 'base64', execute_filemode: false, }, - ], + ]), ); }); diff --git a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md index c6feaf8741..4a3d53c896 100644 --- a/plugins/scaffolder-backend-module-notifications/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-notifications/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-scaffolder-backend-module-notifications +## 0.1.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/plugin-notifications-common@0.0.5 + - @backstage/plugin-notifications-node@0.2.6-next.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.1.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/plugin-notifications-common@0.0.5 + ## 0.0.6 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-notifications/package.json b/plugins/scaffolder-backend-module-notifications/package.json index 58c70478f2..65b8da39dd 100644 --- a/plugins/scaffolder-backend-module-notifications/package.json +++ b/plugins/scaffolder-backend-module-notifications/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-notifications", - "version": "0.0.6", + "version": "0.1.0-next.1", "description": "The notifications backend module for the scaffolder plugin.", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index 1cb678999e..651ad36d61 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.5.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.5.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-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + ## 0.4.40 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/README.md b/plugins/scaffolder-backend-module-rails/README.md index 18e16a7567..27db5656c5 100644 --- a/plugins/scaffolder-backend-module-rails/README.md +++ b/plugins/scaffolder-backend-module-rails/README.md @@ -18,26 +18,14 @@ You need to configure the action in your backend: yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-rails ``` -Configure the action (you can check -the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to -see all options): +Then ensure that both the scaffolder and this module are added to your backend: ```typescript -const actions = [ - createFetchRailsAction({ - integrations, - reader: env.reader, - }), -]; - -return await createRouter({ - catalogClient, - actions, - logger: env.logger, - config: env.config, - database: env.database, - reader: env.reader, -}); +// In packages/backend/src/index.ts +const backend = createBackend(); +// ... +backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); +backend.add(import('@backstage/plugin-scaffolder-backend-module-rails')); ``` After that you can use the action in your template: @@ -244,16 +232,3 @@ steps: system: ${{ parameters.system }} railsArguments: ${{ parameters.railsArguments }} ``` - -You also need to configure the list of allowed images as part of the creating the action for the scaffolder backend: - -```typescript -const actions = [ - createFetchRailsAction({ - integrations, - reader: env.reader, - containerRunner, - allowedImageNames: ['repository/rails:tag'], - }), -]; -``` diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index f92cdb2c4f..09e0f0dc93 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", - "version": "0.4.40", + "version": "0.5.0-next.1", "description": "A module for the scaffolder backend that lets you template projects using Rails", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index 3a1c970c87..0a98cd391f 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.2.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + ## 0.1.31 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/README.md b/plugins/scaffolder-backend-module-sentry/README.md index 5cb1f1b810..d13f923a2a 100644 --- a/plugins/scaffolder-backend-module-sentry/README.md +++ b/plugins/scaffolder-backend-module-sentry/README.md @@ -15,28 +15,14 @@ You need to configure the action in your backend: yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-sentry ``` -Configure the action (you can check -the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to -see all options): +Then ensure that both the scaffolder and this module are added to your backend: ```typescript -const actions = [ - createSentryCreateProjectAction({ - integrations, - reader: env.reader, - containerRunner, - }), -]; - -return await createRouter({ - containerRunner, - catalogClient, - actions, - logger: env.logger, - config: env.config, - database: env.database, - reader: env.reader, -}); +// In packages/backend/src/index.ts +const backend = createBackend(); +// ... +backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); +backend.add(import('@backstage/plugin-scaffolder-backend-module-sentry')); ``` You need to define your Sentry API Token in your `app-config.yaml`: diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index 9c2f40628e..f0935fbb05 100644 --- a/plugins/scaffolder-backend-module-sentry/package.json +++ b/plugins/scaffolder-backend-module-sentry/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-sentry", - "version": "0.1.31", + "version": "0.2.0-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 97fdd27e4a..35f01d25c6 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.4.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.12-next.1 + +## 0.4.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/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node-test-utils@0.1.12-next.0 + ## 0.3.7 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/README.md b/plugins/scaffolder-backend-module-yeoman/README.md index 05bbf6064b..3a32dd2124 100644 --- a/plugins/scaffolder-backend-module-yeoman/README.md +++ b/plugins/scaffolder-backend-module-yeoman/README.md @@ -13,32 +13,14 @@ You need to configure the action in your backend: yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-yeoman ``` -Configure the action: -(you can check the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to see all options): +Then ensure that both the scaffolder and this module are added to your backend: ```typescript -// packages/backend/src/plugins/scaffolder.ts - -const actions = [ - createRunYeomanAction(), - ...createBuiltInActions({ - containerRunner, - catalogClient, - integrations, - config: env.config, - reader: env.reader, - }), -]; - -return await createRouter({ - containerRunner, - catalogClient, - actions, - logger: env.logger, - config: env.config, - database: env.database, - reader: env.reader, -}); +// In packages/backend/src/index.ts +const backend = createBackend(); +// ... +backend.add(import('@backstage/plugin-scaffolder-backend/alpha')); +backend.add(import('@backstage/plugin-scaffolder-backend-module-yeoman')); ``` After that you can use the action in your template: diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 2599de5921..6a5599f6a4 100644 --- a/plugins/scaffolder-backend-module-yeoman/package.json +++ b/plugins/scaffolder-backend-module-yeoman/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend-module-yeoman", - "version": "0.3.7", + "version": "0.4.0-next.1", "backstage": { "role": "backend-plugin-module", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index afa0291723..36f4facf93 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,74 @@ # @backstage/plugin-scaffolder-backend +## 1.25.0-next.1 + +### Patch Changes + +- f865103: Updated dependency `esbuild` to `^0.23.0`. +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-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/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.1 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.0-next.1 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.1 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.1 + - @backstage/plugin-scaffolder-common@1.5.5 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 1.25.0-next.0 + +### Minor Changes + +- 62898bd: `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. + +### Patch Changes + +- c160951: Found the issue during testing the clean up of the workspace for the database implementation. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.0-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.5.0-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.5.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-bitbucket-cloud-common@0.2.22 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-scaffolder-common@1.5.5 + ## 1.24.0 ### Minor Changes diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 25b717b6ca..4017dc760b 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-backend", - "version": "1.24.0", + "version": "1.25.0-next.1", "description": "The Backstage backend plugin that helps you create new things", "backstage": { "role": "backend-plugin", @@ -124,7 +124,7 @@ "@types/nunjucks": "^3.1.4", "@types/supertest": "^2.0.8", "@types/zen-observable": "^0.8.0", - "esbuild": "^0.21.0", + "esbuild": "^0.23.0", "strip-ansi": "^7.1.0", "supertest": "^6.1.3", "wait-for-expect": "^3.0.2" diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts index ba675b2cc7..23fe793432 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseTaskStore.ts @@ -532,8 +532,8 @@ export class DatabaseTaskStore implements TaskStore { } async cleanWorkspace({ taskId }: { taskId: string }): Promise { - await this.db('tasks').where({ id: taskId }).update({ - workspace: undefined, + await this.db('tasks').where({ id: taskId }).update({ + workspace: null, }); } @@ -542,10 +542,11 @@ export class DatabaseTaskStore implements TaskStore { taskId: string; }): Promise { if (options.path) { + const workspace = (await serializeWorkspace(options)).contents; await this.db('tasks') .where({ id: options.taskId }) .update({ - workspace: (await serializeWorkspace(options)).contents, + workspace, }); } } diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseWorkspaceProvider.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseWorkspaceProvider.ts index 69f90b3d7e..b3c3c24975 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseWorkspaceProvider.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/DatabaseWorkspaceProvider.ts @@ -29,7 +29,7 @@ export class DatabaseWorkspaceProvider implements WorkspaceProvider { path: string; taskId: string; }): Promise { - this.storage.serializeWorkspace?.(options); + await this.storage.serializeWorkspace?.(options); } public async rehydrateWorkspace(options: { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index 3d7d8b8b1d..09fc162ea6 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -509,11 +509,11 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { const output = this.render(task.spec.output, context, renderTemplate); await taskTrack.markSuccessful(); + await task.cleanWorkspace?.(); return { output }; } finally { if (workspacePath) { - await task.cleanWorkspace?.(); await fs.remove(workspacePath); } } diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index 51e11d630f..9673d19255 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -44,9 +44,12 @@ import { AuthorizeResult, PermissionEvaluator, } from '@backstage/plugin-permission-common'; -import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { + mockCredentials, + mockErrorHandler, + mockServices, +} from '@backstage/backend-test-utils'; import { AutocompleteHandler } from '@backstage/plugin-scaffolder-node/alpha'; -import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter'; import { UrlReaders } from '@backstage/backend-defaults/urlReader'; const mockAccess = jest.fn(); @@ -1501,8 +1504,6 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ results: [{ title: 'blob' }], }); - const logger = mockServices.logger.mock(); - const middleware = MiddlewareFactory.create({ config, logger }); const router = await createRouter({ logger: loggerToWinstonLogger(mockServices.logger.mock()), config: new ConfigReader({}), @@ -1519,7 +1520,7 @@ data: {"id":1,"taskId":"a-random-id","type":"completion","createdAt":"","body":{ }, }); - app = express().use(router).use(middleware.error()); + app = express().use(router).use(mockErrorHandler()); }); it('should throw an error when the provider is not registered', async () => { diff --git a/plugins/scaffolder-node-test-utils/CHANGELOG.md b/plugins/scaffolder-node-test-utils/CHANGELOG.md index dd4ed1e2a1..fef8549682 100644 --- a/plugins/scaffolder-node-test-utils/CHANGELOG.md +++ b/plugins/scaffolder-node-test-utils/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-scaffolder-node-test-utils +## 0.1.12-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-test-utils@0.6.0-next.1 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-node@0.4.11-next.1 + +## 0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.0 + - @backstage/backend-test-utils@0.6.0-next.0 + - @backstage/plugin-scaffolder-node@0.4.11-next.0 + - @backstage/types@1.1.1 + ## 0.1.10 ### Patch Changes diff --git a/plugins/scaffolder-node-test-utils/package.json b/plugins/scaffolder-node-test-utils/package.json index 9675a689ab..4b32bf3d95 100644 --- a/plugins/scaffolder-node-test-utils/package.json +++ b/plugins/scaffolder-node-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node-test-utils", - "version": "0.1.10", + "version": "0.1.12-next.1", "backstage": { "role": "node-library", "pluginId": "scaffolder", diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index d04d7f16e0..887fac33d1 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-scaffolder-node +## 0.4.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.5 + +## 0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/types@1.1.1 + - @backstage/plugin-scaffolder-common@1.5.5 + ## 0.4.9 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index 52964f814a..42291dd081 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-node", - "version": "0.4.9", + "version": "0.4.11-next.1", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", "backstage": { "role": "node-library", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index 57799ab836..991cc8d10e 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-scaffolder-react +## 1.12.0-next.1 + +### Patch Changes + +- c2cbe1e: Updated dependency `use-immer` to `^0.10.0`. +- Updated dependencies + - @backstage/catalog-client@1.6.7-next.0 + - @backstage/core-components@0.14.11-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + +## 1.12.0-next.0 + +### Minor Changes + +- 4512f71: Add `ui:backstage.review.name` option for custom item names on scaffolder review page, and also add support for rendering the `title` property instead of the key name. + +### Patch Changes + +- 3ebb64f: - Fix secret widget field not displaying as required. + - Fix secret widget not able to be required inside nested objects. + - Fix secret widget not able to be disabled. + - Support `minLength` and `maxLength` properties for secret widget. +- 8dd6ef6: Fix an issue where keys with duplicate final key parts are not all displayed in the `ReviewState`. Change the way the keys are formatted to include the full schema path, separated by `>`. +- 9a0672a: Scaffolder review page shows static amount of asterisks for secret fields. +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-permission-react@0.4.25 + - @backstage/plugin-scaffolder-common@1.5.5 + ## 1.11.0 ### Minor Changes diff --git a/plugins/scaffolder-react/api-report.md b/plugins/scaffolder-react/api-report.md index a19a656d17..f73365f0ac 100644 --- a/plugins/scaffolder-react/api-report.md +++ b/plugins/scaffolder-react/api-report.md @@ -128,7 +128,12 @@ export interface FieldExtensionUiSchema // @public export type FormProps = Pick< FormProps_2, - 'transformErrors' | 'noHtml5Validate' | 'uiSchema' | 'formContext' + | 'transformErrors' + | 'noHtml5Validate' + | 'uiSchema' + | 'formContext' + | 'omitExtraData' + | 'liveOmit' >; // @public diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index 97e04c8d42..17fe2a5524 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-scaffolder-react", - "version": "1.11.0", + "version": "1.12.0-next.1", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", "backstage": { "role": "web-library", @@ -72,10 +72,10 @@ "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.61", "@react-hookz/web": "^24.0.0", - "@rjsf/core": "5.18.5", - "@rjsf/material-ui": "5.18.5", - "@rjsf/utils": "5.18.5", - "@rjsf/validator-ajv8": "5.18.5", + "@rjsf/core": "5.20.1", + "@rjsf/material-ui": "5.20.1", + "@rjsf/utils": "5.20.1", + "@rjsf/validator-ajv8": "5.20.1", "@types/json-schema": "^7.0.9", "@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0", "ajv-errors": "^3.0.0", @@ -88,7 +88,7 @@ "luxon": "^3.0.0", "qs": "^6.9.4", "react-use": "^17.2.4", - "use-immer": "^0.9.0", + "use-immer": "^0.10.0", "zen-observable": "^0.10.0", "zod": "^3.22.4", "zod-to-json-schema": "^3.20.4" diff --git a/plugins/scaffolder-react/src/components/types.ts b/plugins/scaffolder-react/src/components/types.ts index d5d317015d..3df6209cad 100644 --- a/plugins/scaffolder-react/src/components/types.ts +++ b/plugins/scaffolder-react/src/components/types.ts @@ -32,7 +32,12 @@ export type TemplateGroupFilter = { */ export type FormProps = Pick< SchemaFormProps, - 'transformErrors' | 'noHtml5Validate' | 'uiSchema' | 'formContext' + | 'transformErrors' + | 'noHtml5Validate' + | 'uiSchema' + | 'formContext' + | 'omitExtraData' + | 'liveOmit' >; /** diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx index 69b651e672..a3fcecbe2b 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.test.tsx @@ -434,4 +434,67 @@ describe('ReviewState', () => { queryByRole('row', { name: 'Name > Example > Test type6' }), ).not.toBeInTheDocument(); }); + + it('should allow using the title property', async () => { + const formState = { + foo: 'test', + }; + + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + foo: { + type: 'string', + title: 'Test Thing', + }, + }, + }, + schema: {}, + title: 'test', + uiSchema: {}, + }, + ]; + + const { queryByRole } = render( + , + ); + + expect(queryByRole('row', { name: 'Test Thing test' })).toBeInTheDocument(); + }); + + it('should allow custom review name', async () => { + const formState = { + foo: 'test', + }; + + const schemas: ParsedTemplateSchema[] = [ + { + mergedSchema: { + type: 'object', + properties: { + foo: { + type: 'string', + 'ui:backstage': { + review: { + name: 'bar', + }, + }, + }, + }, + }, + schema: {}, + title: 'test', + uiSchema: {}, + }, + ]; + + const { queryByRole } = render( + , + ); + + expect(queryByRole('row', { name: 'Bar test' })).toBeInTheDocument(); + expect(queryByRole('row', { name: 'Foo test' })).not.toBeInTheDocument(); + }); }); diff --git a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx index fb6a592dce..7d2c6042dc 100644 --- a/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx +++ b/plugins/scaffolder-react/src/next/components/ReviewState/ReviewState.tsx @@ -41,11 +41,16 @@ function processSchema( data: formState, }); + const name = + definitionInSchema?.['ui:backstage']?.review?.name ?? + definitionInSchema?.title ?? + key; + if (definitionInSchema) { const backstageReviewOptions = definitionInSchema['ui:backstage']?.review; if (backstageReviewOptions) { if (backstageReviewOptions.mask) { - return [[key, backstageReviewOptions.mask]]; + return [[name, backstageReviewOptions.mask]]; } if (backstageReviewOptions.show === false) { return []; @@ -56,13 +61,13 @@ function processSchema( definitionInSchema['ui:widget'] === 'password' || definitionInSchema['ui:field']?.toLocaleLowerCase('en-us') === 'secret' ) { - return [[key, '******']]; + return [[name, '******']]; } if (definitionInSchema.enum && definitionInSchema.enumNames) { return [ [ - key, + name, definitionInSchema.enumNames[ definitionInSchema.enum.indexOf(value) ] || value, @@ -78,7 +83,7 @@ function processSchema( } } - return [[key, value]]; + return [[name, value]]; } /** diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx index 78aef3428f..b2ec74c41a 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.test.tsx @@ -13,16 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { renderInTestApp } from '@backstage/test-utils'; +import { JsonValue } from '@backstage/types'; +import { act, fireEvent, waitFor } from '@testing-library/react'; import React from 'react'; + +import { LayoutTemplate } from '../../../layouts'; +import { SecretsContextProvider } from '../../../secrets'; import { TemplateParameterSchema } from '../../../types'; import { Stepper } from './Stepper'; -import { renderInTestApp } from '@backstage/test-utils'; -import { act, fireEvent } from '@testing-library/react'; + import type { RJSFValidationError } from '@rjsf/utils'; -import { JsonValue } from '@backstage/types'; -import { FieldExtensionComponentProps } from '../../../extensions'; -import { SecretsContextProvider } from '../../../secrets'; -import { LayoutTemplate } from '../../../layouts'; describe('Stepper', () => { it('should render the step titles for each step of the manifest', async () => { @@ -63,7 +64,7 @@ describe('Stepper', () => { expect(getByRole('button', { name: 'Next' })).toBeInTheDocument(); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Next' })); + fireEvent.click(getByRole('button', { name: 'Next' })); }); expect(getByRole('button', { name: 'Review' })).toBeInTheDocument(); @@ -102,16 +103,15 @@ describe('Stepper', () => { , ); - await fireEvent.change(getByRole('textbox', { name: 'name' }), { - target: { value: 'im a test value' }, + await act(async () => { + fireEvent.change(getByRole('textbox', { name: 'name' }), { + target: { value: 'im a test value' }, + }); + fireEvent.click(getByRole('button', { name: 'Next' })); }); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Next' })); - }); - - await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Back' })); + fireEvent.click(getByRole('button', { name: 'Back' })); }); expect(getByRole('textbox', { name: 'name' })).toHaveValue( @@ -152,16 +152,15 @@ describe('Stepper', () => { , ); - await fireEvent.change(getByRole('textbox', { name: 'name' }), { - target: { value: 'im a test value' }, + await act(async () => { + fireEvent.change(getByRole('textbox', { name: 'name' }), { + target: { value: 'im a test value' }, + }); + fireEvent.click(getByRole('button', { name: 'Next' })); }); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Next' })); - }); - - await act(async () => { - await fireEvent.click(getByLabelText('Step 1')); + fireEvent.click(getByLabelText('Step 1')); }); expect(getByRole('textbox', { name: 'name' })).toHaveValue( @@ -169,38 +168,107 @@ describe('Stepper', () => { ); }); - it('should merge nested formData correctly in multiple steps', async () => { - const Repo = ({ - onChange, - }: FieldExtensionComponentProps<{ repository: string }, any>) => ( - onChange({ repository: e.target.value })} - defaultValue="" - /> + it('should omit properties that are no longer pertinent to the current step', async () => { + const manifest: TemplateParameterSchema = { + title: 'Conditional Input Form', + steps: [ + { + title: 'Conditional Input step', + schema: { + type: 'object', + properties: { + moreInfo: { + type: 'boolean', + title: 'More info', + }, + }, + dependencies: { + moreInfo: { + oneOf: [ + { + properties: { + moreInfo: { + const: true, + }, + description: { + type: 'string', + title: 'Description', + }, + }, + required: ['description'], + }, + { + properties: { + moreInfo: { + not: { + const: true, + }, + }, + }, + }, + ], + }, + }, + }, + }, + ], + }; + + const onCreate = jest.fn(); + + const { getByRole, queryByRole } = await renderInTestApp( + + + , ); - const Owner = ({ - onChange, - }: FieldExtensionComponentProps<{ owner: string }, any>) => ( - onChange({ owner: e.target.value })} - defaultValue="" - /> - ); + await act(async () => { + fireEvent.click(getByRole('checkbox', { name: 'More info' })); + fireEvent.change(getByRole('textbox', { name: 'Description' }), { + target: { value: 'My Test Description' }, + }); + fireEvent.click(getByRole('button', { name: 'Review' })); + }); + expect( + getByRole('cell', { name: 'My Test Description' }), + ).toBeInTheDocument(); + + await act(async () => { + fireEvent.click(getByRole('button', { name: 'Back' })); + }); + + await act(async () => { + fireEvent.click(getByRole('checkbox', { name: 'More info' })); + fireEvent.click(getByRole('button', { name: 'Review' })); + }); + + expect( + queryByRole('cell', { name: 'My Test Description' }), + ).not.toBeInTheDocument(); + + await act(async () => { + fireEvent.click(getByRole('button', { name: 'Create' })); + }); + + expect(onCreate).toHaveBeenCalledWith({ moreInfo: false }); + }); + + it('should merge and overwrite nested formData correctly', async () => { const manifest: TemplateParameterSchema = { steps: [ { title: 'Step 1', schema: { properties: { - first: { - type: 'object', - 'ui:field': 'Repo', + foo: { + type: 'string', + title: 'Foo - 1', }, }, }, @@ -209,9 +277,13 @@ describe('Stepper', () => { title: 'Step 2', schema: { properties: { - second: { - type: 'object', - 'ui:field': 'Owner', + foo: { + type: 'string', + title: 'Foo - 2', + }, + bar: { + type: 'string', + title: 'Bar - 2', }, }, }, @@ -220,47 +292,39 @@ describe('Stepper', () => { title: 'React JSON Schema Form Test', }; - const onCreate = jest.fn(async (values: Record) => { - expect(values).toEqual({ - first: { repository: 'Repo' }, - second: { owner: 'Owner' }, - }); - }); + const onCreate = jest.fn(); const { getByRole } = await renderInTestApp( - + , ); - await fireEvent.change(getByRole('textbox', { name: 'repo' }), { - target: { value: 'Repo' }, + await act(async () => { + fireEvent.change(getByRole('textbox', { name: 'Foo - 1' }), { + target: { value: 'value 1' }, + }); + fireEvent.click(getByRole('button', { name: 'Next' })); }); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Next' })); - }); - - await fireEvent.change(getByRole('textbox', { name: 'owner' }), { - target: { value: 'Owner' }, + fireEvent.change(getByRole('textbox', { name: 'Foo - 2' }), { + target: { value: 'value 2' }, + }); + fireEvent.change(getByRole('textbox', { name: 'Bar - 2' }), { + target: { value: 'value 2' }, + }); + fireEvent.click(getByRole('button', { name: 'Review' })); }); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.click(getByRole('button', { name: 'Create' })); }); - await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Create' })); + expect(onCreate).toHaveBeenCalledWith({ + foo: 'value 2', + bar: 'value 2', }); - - expect(onCreate).toHaveBeenCalled(); }); it('should render custom field extensions properly', async () => { @@ -335,13 +399,11 @@ describe('Stepper', () => { /> , ); - - act(() => { - fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.click(getByRole('button', { name: 'Review' })); + await waitFor(() => { + expect(getByRole('progressbar')).toBeInTheDocument(); // Check if progress bar is rendered + expect(getByRole('button', { name: 'Review' })).toBeDisabled(); // Check if the button is disabled }); - - expect(getByRole('progressbar')).toBeInTheDocument(); - expect(getByRole('button', { name: 'Review' })).toBeDisabled(); }); it('should transform default error message', async () => { @@ -381,12 +443,11 @@ describe('Stepper', () => { , ); - await fireEvent.change(getByRole('textbox', { name: 'postcode' }), { - target: { value: 'invalid' }, - }); - await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.change(getByRole('textbox', { name: 'postcode' }), { + target: { value: 'invalid' }, + }); + fireEvent.click(getByRole('button', { name: 'Review' })); }); expect(getByText('invalid postcode')).toBeInTheDocument(); @@ -421,12 +482,12 @@ describe('Stepper', () => { , ); - await fireEvent.change(getByRole('textbox', { name: 'postcode' }), { - target: { value: 'invalid' }, - }); - await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.change(getByRole('textbox', { name: 'postcode' }), { + target: { value: 'invalid' }, + }); + + fireEvent.click(getByRole('button', { name: 'Review' })); }); expect(getByText('invalid postcode')).toBeInTheDocument(); @@ -494,13 +555,13 @@ describe('Stepper', () => { ); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Review' })); + fireEvent.click(getByRole('button', { name: 'Review' })); }); expect(getByRole('button', { name: 'Create' })).toBeInTheDocument(); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Create' })); + fireEvent.click(getByRole('button', { name: 'Create' })); }); // flush promises @@ -539,13 +600,13 @@ describe('Stepper', () => { ); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Inspect' })); + fireEvent.click(getByRole('button', { name: 'Inspect' })); }); expect(getByRole('button', { name: 'Make' })).toBeInTheDocument(); await act(async () => { - await fireEvent.click(getByRole('button', { name: 'Make' })); + fireEvent.click(getByRole('button', { name: 'Make' })); }); }); diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index 3a8858144b..a1b31d0089 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -115,11 +115,16 @@ export const Stepper = (stepperProps: StepperProps) => { const apiHolder = useApiHolder(); const [activeStep, setActiveStep] = useState(0); const [isValidating, setIsValidating] = useState(false); - const [formState, setFormState] = useFormDataFromQuery(props.initialState); + const [initialState] = useFormDataFromQuery(props.initialState); + const [formState, setFormState] = useState<{ + [step: string]: Record; + }>(); const [errors, setErrors] = useState(); const styles = useStyles(); + const makeStepKey = (step: string | number) => `step-${step}`; + const backLabel = presentation?.buttonLabels?.backButtonText ?? backButtonText; const createLabel = @@ -155,16 +160,15 @@ export const Stepper = (stepperProps: StepperProps) => { }; const handleChange = useCallback( - (e: IChangeEvent) => - setFormState(current => ({ ...current, ...e.formData })), - [setFormState], + (e: IChangeEvent) => { + setFormState(current => ({ + ...current, + [makeStepKey(activeStep)]: e.formData, + })); + }, + [setFormState, activeStep], ); - const handleCreate = useCallback(() => { - props.onCreate(formState); - analytics.captureEvent('click', `${createLabel}`); - }, [props, formState, analytics, createLabel]); - const currentStep = useTransformSchemaToProps(steps[activeStep], { layouts }); const handleNext = async ({ @@ -191,7 +195,10 @@ export const Stepper = (stepperProps: StepperProps) => { return stepNum; }); } - setFormState(current => ({ ...current, ...formData })); + setFormState(current => ({ + ...current, + [makeStepKey(activeStep)]: formData, + })); }; const { @@ -202,6 +209,24 @@ export const Stepper = (stepperProps: StepperProps) => { const mergedUiSchema = merge({}, propUiSchema, currentStep?.uiSchema); + const mergedState = useMemo(() => { + if (!formState) { + return initialState; + } + const { [makeStepKey(activeStep)]: activeState, ...historicalState } = + formState; + const chronologicalState = { + ...historicalState, + [makeStepKey(activeStep)]: activeState, + }; + return merge({}, ...Object.values(chronologicalState)); + }, [formState, activeStep, initialState]); + + const handleCreate = useCallback(() => { + props.onCreate(mergedState); + analytics.captureEvent('click', `${createLabel}`); + }, [props, mergedState, analytics, createLabel]); + return ( <> {isValidating && } @@ -237,8 +262,8 @@ export const Stepper = (stepperProps: StepperProps) => {
    { ReviewStepComponent ? ( {}} steps={steps} @@ -282,7 +307,7 @@ export const Stepper = (stepperProps: StepperProps) => { /> ) : ( <> - +
    @@ -206,7 +209,7 @@ export function TemplateEditorForm(props: TemplateEditorFormProps) { export function TemplateEditorFormDirectoryEditorDryRun( props: Pick< TemplateEditorFormProps, - 'setErrorText' | 'fieldExtensions' | 'layouts' + 'setErrorText' | 'fieldExtensions' | 'layouts' | 'formProps' >, ) { const { setErrorText, fieldExtensions = [], layouts } = props; @@ -245,6 +248,7 @@ export function TemplateEditorFormDirectoryEditorDryRun( setErrorText={setErrorText} content={content} layouts={layouts} + formProps={props.formProps} /> ); } diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx index 6e7c921e91..03d656c98d 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx @@ -24,6 +24,7 @@ import { TemplateEditor } from './TemplateEditor'; import { TemplateFormPreviewer } from './TemplateFormPreviewer'; import { FieldExtensionOptions, + FormProps, type LayoutOptions, } from '@backstage/plugin-scaffolder-react'; import { TemplateEditorIntro } from './TemplateEditorIntro'; @@ -54,6 +55,7 @@ interface TemplateEditorPageProps { defaultPreviewTemplate?: string; customFieldExtensions?: FieldExtensionOptions[]; layouts?: LayoutOptions[]; + formProps?: FormProps; } export function TemplateEditorPage(props: TemplateEditorPageProps) { @@ -79,6 +81,7 @@ export function TemplateEditorPage(props: TemplateEditorPageProps) { fieldExtensions={props.customFieldExtensions} onClose={() => setSelection(undefined)} layouts={props.layouts} + formProps={props.formProps} /> ); } else if (selection?.type === 'form') { @@ -88,6 +91,7 @@ export function TemplateEditorPage(props: TemplateEditorPageProps) { customFieldExtensions={props.customFieldExtensions} onClose={() => setSelection(undefined)} layouts={props.layouts} + formProps={props.formProps} /> ); } else if (selection?.type === 'field-explorer') { diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx index 07f2fd7f07..610d2a22f0 100644 --- a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx @@ -33,6 +33,7 @@ import yaml from 'yaml'; import { LayoutOptions, FieldExtensionOptions, + FormProps, } from '@backstage/plugin-scaffolder-react'; import { TemplateEditorForm } from './TemplateEditorForm'; import { TemplateEditorTextArea } from './TemplateEditorTextArea'; @@ -114,11 +115,13 @@ export const TemplateFormPreviewer = ({ customFieldExtensions = [], onClose, layouts = [], + formProps, }: { defaultPreviewTemplate?: string; customFieldExtensions?: FieldExtensionOptions[]; onClose?: () => void; layouts?: LayoutOptions[]; + formProps?: FormProps; }) => { const classes = useStyles(); const { t } = useTranslationRef(scaffolderTranslationRef); @@ -213,6 +216,7 @@ export const TemplateFormPreviewer = ({ fieldExtensions={customFieldExtensions} setErrorText={setErrorText} layouts={layouts} + formProps={formProps} />
    diff --git a/plugins/search-backend-module-catalog/CHANGELOG.md b/plugins/search-backend-module-catalog/CHANGELOG.md index 3c737cb65e..89de3f2ba5 100644 --- a/plugins/search-backend-module-catalog/CHANGELOG.md +++ b/plugins/search-backend-module-catalog/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-search-backend-module-catalog +## 0.2.2-next.1 + +### Patch Changes + +- 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/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## 0.2.2-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5726390: The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: + + - `DefaultCatalogCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-catalog/README.md#installation; + - `ToolDocumentCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-explore/README.md#installation; + - `DefaultTechDocsCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-techdocs/README.md#installation. + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + ## 0.2.0 ### Minor Changes diff --git a/plugins/search-backend-module-catalog/package.json b/plugins/search-backend-module-catalog/package.json index fadfc99535..6bc3cfd753 100644 --- a/plugins/search-backend-module-catalog/package.json +++ b/plugins/search-backend-module-catalog/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-catalog", - "version": "0.2.0", + "version": "0.2.2-next.1", "description": "A module for the search backend that exports catalog modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index 70cdbc0e93..ef70474a2e 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.5.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## 1.5.6-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5726390: Internal refactor to use `LoggerService` and `DatabaseService` instead of the legacy `Logger` and `PluginDatabaseManager` types. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + ## 1.5.4 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index fc236cd24b..670f10a5f3 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", - "version": "1.5.4", + "version": "1.5.6-next.1", "description": "A module for the search backend that implements search using ElasticSearch", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-explore/CHANGELOG.md b/plugins/search-backend-module-explore/CHANGELOG.md index 41062f760d..9e22c2cdec 100644 --- a/plugins/search-backend-module-explore/CHANGELOG.md +++ b/plugins/search-backend-module-explore/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-search-backend-module-explore +## 0.2.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## 0.2.2-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5726390: The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: + + - `DefaultCatalogCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-catalog/README.md#installation; + - `ToolDocumentCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-explore/README.md#installation; + - `DefaultTechDocsCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-techdocs/README.md#installation. + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + ## 0.2.0 ### Minor Changes diff --git a/plugins/search-backend-module-explore/package.json b/plugins/search-backend-module-explore/package.json index 1f7611c46d..418d1927fa 100644 --- a/plugins/search-backend-module-explore/package.json +++ b/plugins/search-backend-module-explore/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-explore", - "version": "0.2.0", + "version": "0.2.2-next.1", "description": "A module for the search backend that exports explore modules", "backstage": { "role": "backend-plugin-module", @@ -48,7 +48,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage-community/plugin-explore-common": "^0.0.4", + "@backstage-community/plugin-explore-common": "^0.0.5", "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index 6c96b4e32c..f2cc0b4ca4 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-search-backend-module-pg +## 0.5.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## 0.5.35-next.0 + +### Patch Changes + +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5726390: Internal refactor to use `LoggerService` and `DatabaseService` instead of the legacy `Logger` and `PluginDatabaseManager` types. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + ## 0.5.33 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 60cfedcd70..a37fcf98d5 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-pg", - "version": "0.5.33", + "version": "0.5.35-next.1", "description": "A module for the search backend that implements search using PostgreSQL", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md index 35ff0312ab..46f03fc870 100644 --- a/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md +++ b/plugins/search-backend-module-stack-overflow-collator/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-search-backend-module-stack-overflow-collator +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## 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-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/plugin-search-common@1.2.14 + ## 0.2.0 ### Minor Changes diff --git a/plugins/search-backend-module-stack-overflow-collator/package.json b/plugins/search-backend-module-stack-overflow-collator/package.json index 36d948c34e..d6614573db 100644 --- a/plugins/search-backend-module-stack-overflow-collator/package.json +++ b/plugins/search-backend-module-stack-overflow-collator/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-stack-overflow-collator", - "version": "0.2.0", + "version": "0.3.0-next.1", "description": "A module for the search backend that exports stack overflow modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-module-techdocs/CHANGELOG.md b/plugins/search-backend-module-techdocs/CHANGELOG.md index de280174fa..699d069a2c 100644 --- a/plugins/search-backend-module-techdocs/CHANGELOG.md +++ b/plugins/search-backend-module-techdocs/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-search-backend-module-techdocs +## 0.2.2-next.1 + +### Patch Changes + +- 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/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-node@1.12.11-next.1 + +## 0.2.2-next.0 + +### Patch Changes + +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 5726390: The following collator factories are deprecated, please [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) to the new backend system and follow the instructions below to install collators via module: + + - `DefaultCatalogCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-catalog/README.md#installation; + - `ToolDocumentCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-explore/README.md#installation; + - `DefaultTechDocsCollatorFactory`: https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-techdocs/README.md#installation. + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-techdocs-node@1.12.11-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-catalog-node@1.12.7-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + ## 0.2.0 ### Minor Changes diff --git a/plugins/search-backend-module-techdocs/package.json b/plugins/search-backend-module-techdocs/package.json index cb95652355..32295f9d91 100644 --- a/plugins/search-backend-module-techdocs/package.json +++ b/plugins/search-backend-module-techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-module-techdocs", - "version": "0.2.0", + "version": "0.2.2-next.1", "description": "A module for the search backend that exports techdocs modules", "backstage": { "role": "backend-plugin-module", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index 3c566e48d3..82ab3b006c 100644 --- a/plugins/search-backend-node/CHANGELOG.md +++ b/plugins/search-backend-node/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-search-backend-node +## 1.3.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + +## 1.3.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + ## 1.3.0 ### Minor Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index e951243136..8833f15c6c 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend-node", - "version": "1.3.0", + "version": "1.3.2-next.1", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", "backstage": { "role": "node-library", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index 679c2777ef..6325f6bb73 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-search-backend +## 1.5.17-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/backend-common@0.25.0-next.1 + - @backstage/backend-openapi-utils@0.1.18-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-permission-node@0.8.3-next.1 + - @backstage/plugin-search-backend-node@1.3.2-next.1 + - @backstage/plugin-search-common@1.2.14 + +## 1.5.17-next.0 + +### Patch Changes + +- 5726390: Deprecate create router as the legacy backend system will no longer be supported. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-permission-node@0.8.3-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/backend-openapi-utils@0.1.18-next.0 + - @backstage/plugin-search-backend-node@1.3.2-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-common@1.2.14 + ## 1.5.15 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 819523ecb5..c3689b9478 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-backend", - "version": "1.5.15", + "version": "1.5.17-next.1", "description": "The Backstage backend plugin that provides your backstage app with search", "backstage": { "role": "backend-plugin", diff --git a/plugins/search-backend/src/service/router.test.ts b/plugins/search-backend/src/service/router.test.ts index d5a2b89f1e..d22fc17e54 100644 --- a/plugins/search-backend/src/service/router.test.ts +++ b/plugins/search-backend/src/service/router.test.ts @@ -25,9 +25,12 @@ import request from 'supertest'; import { createRouter } from './router'; import { wrapInOpenApiTestServer } from '@backstage/backend-openapi-utils'; import { Server } from 'http'; -import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { + mockCredentials, + mockErrorHandler, + mockServices, +} from '@backstage/backend-test-utils'; import { DiscoveryService } from '@backstage/backend-plugin-api'; -import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter'; const mockPermissionEvaluator: PermissionEvaluator = { authorize: () => { @@ -84,11 +87,9 @@ describe('createRouter', () => { auth: mockServices.auth(), httpAuth: mockServices.httpAuth(), }); - const errorHandler = MiddlewareFactory.create({ - config: mockServices.rootConfig(), - logger: mockServices.rootLogger(), - }).error(); - app = wrapInOpenApiTestServer(express().use(router).use(errorHandler)); + app = wrapInOpenApiTestServer( + express().use(router).use(mockErrorHandler()), + ); }); beforeEach(() => { diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index fa409b56b0..407c207559 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-search-react +## 1.8.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.1 + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.14 + +## 1.8.0-next.0 + +### Minor Changes + +- 9d66d8c: Make use of the `useApp` hook to retrieve the specified search icon in the SearchBar + +### Patch Changes + +- fec8b57: Updated exports to use the new type parameters for extensions and extension blueprints. +- f26ff99: Slight type tweak to match newer React versions better +- 5446061: The `/alpha` export no longer export extension creators for the new frontend system, existing usage should be switched to use the equivalent extension blueprint instead. For more information see the [new frontend system 1.30 migration documentation](https://backstage.io/docs/frontend-system/architecture/migrations#130). +- Updated dependencies + - @backstage/frontend-plugin-api@0.8.0-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.14 + ## 1.7.14 ### Patch Changes diff --git a/plugins/search-react/api-report-alpha.md b/plugins/search-react/api-report-alpha.md index 57bf03114f..51c98a8d93 100644 --- a/plugins/search-react/api-report-alpha.md +++ b/plugins/search-react/api-report-alpha.md @@ -30,29 +30,27 @@ export type SearchResultItemExtensionPredicate = ( ) => boolean; // @alpha -export const SearchResultListItemBlueprint: ExtensionBlueprint< - { - kind: 'search-result-list-item'; - namespace: undefined; - name: undefined; - }, - SearchResultListItemBlueprintParams, - ConfigurableExtensionDataRef< +export const SearchResultListItemBlueprint: ExtensionBlueprint<{ + kind: 'search-result-list-item'; + namespace: undefined; + name: undefined; + params: SearchResultListItemBlueprintParams; + output: ConfigurableExtensionDataRef< { predicate?: SearchResultItemExtensionPredicate | undefined; component: SearchResultItemExtensionComponent; }, 'search.search-result-list-item.item', {} - >, - {}, - { + >; + inputs: {}; + config: { noTrack: boolean; - }, - { + }; + configInput: { noTrack?: boolean | undefined; - }, - { + }; + dataRefs: { item: ConfigurableExtensionDataRef< { predicate?: SearchResultItemExtensionPredicate | undefined; @@ -61,8 +59,8 @@ export const SearchResultListItemBlueprint: ExtensionBlueprint< 'search.search-result-list-item.item', {} >; - } ->; + }; +}>; // @alpha (undocumented) export interface SearchResultListItemBlueprintParams { diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 5a77cd3840..749a4f62c1 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.7.14", + "version": "1.8.0-next.1", "backstage": { "role": "web-library", "pluginId": "search", diff --git a/plugins/search-react/src/alpha/blueprints/SearchResultListItemBlueprint.test.tsx b/plugins/search-react/src/alpha/blueprints/SearchResultListItemBlueprint.test.tsx index 4f3b7501b4..6b8f75d70c 100644 --- a/plugins/search-react/src/alpha/blueprints/SearchResultListItemBlueprint.test.tsx +++ b/plugins/search-react/src/alpha/blueprints/SearchResultListItemBlueprint.test.tsx @@ -16,7 +16,10 @@ import React from 'react'; import { SearchResultListItemBlueprint } from './SearchResultListItemBlueprint'; -import { createExtensionTester } from '@backstage/frontend-test-utils'; +import { + createExtensionTester, + renderInTestApp, +} from '@backstage/frontend-test-utils'; import { PageBlueprint, createExtensionInput, @@ -37,6 +40,7 @@ describe('SearchResultListItemBlueprint', () => { expect(extension).toMatchInlineSnapshot(` { "$$type": "@backstage/ExtensionDefinition", + "T": undefined, "attachTo": { "id": "page:search", "input": "items", @@ -83,7 +87,7 @@ describe('SearchResultListItemBlueprint', () => { }); const mockSearchPage = PageBlueprint.makeWithOverrides({ - namespace: 'search', + name: 'search', inputs: { items: createExtensionInput([searchResultListItemDataRef]), }, @@ -107,17 +111,17 @@ describe('SearchResultListItemBlueprint', () => { }); await expect( - createExtensionTester(mockSearchPage) - .add(extension) - .render() - .findByText('noTrack: false'), + renderInTestApp( + createExtensionTester(mockSearchPage).add(extension).reactElement(), + ).findByText('noTrack: false'), ).resolves.toBeInTheDocument(); await expect( - createExtensionTester(mockSearchPage) - .add(extension, { config: { noTrack: true } }) - .render() - .findByText('noTrack: true'), + renderInTestApp( + createExtensionTester(mockSearchPage) + .add(extension, { config: { noTrack: true } }) + .reactElement(), + ).findByText('noTrack: true'), ).resolves.toBeInTheDocument(); }); }); diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 526354244a..63397834bf 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-search +## 1.4.16-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/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-search-react@1.8.0-next.1 + +## 1.4.16-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/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/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/version-bridge@1.0.8 + - @backstage/plugin-search-common@1.2.14 + ## 1.4.15 ### Patch Changes diff --git a/plugins/search/api-report-alpha.md b/plugins/search/api-report-alpha.md index 6aa956f131..fe06873bd4 100644 --- a/plugins/search/api-report-alpha.md +++ b/plugins/search/api-report-alpha.md @@ -5,10 +5,10 @@ ```ts import { AnyApiFactory } from '@backstage/core-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; @@ -16,27 +16,32 @@ import { SearchResultItemExtensionComponent } from '@backstage/plugin-search-rea import { SearchResultItemExtensionPredicate } from '@backstage/plugin-search-react/alpha'; // @alpha (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< { root: RouteRef; }, {}, { - 'api:search': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: undefined; - } - >; - 'nav-item:search': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef< + 'api:search': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'nav-item:search': ExtensionDefinition<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent; @@ -44,39 +49,35 @@ const _default: BackstagePlugin< }, 'core.nav-item.target', {} - >, - {}, - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - } - >; - 'page:search': ExtensionDefinition< - { + >; + inputs: {}; + }>; + 'page:search': ExtensionDefinition<{ + config: { noTrack: boolean; } & { path: string | undefined; - }, - { + }; + configInput: { noTrack?: boolean | undefined; } & { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: { items: ExtensionInput< ConfigurableExtensionDataRef< { @@ -91,35 +92,34 @@ const _default: BackstagePlugin< optional: false; } >; - }, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; + }; + kind: 'page'; + namespace: undefined; + name: undefined; + }>; } >; export default _default; // @alpha (undocumented) -export const searchApi: ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: undefined; - } ->; +export const searchApi: ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef; + inputs: {}; +}>; // @alpha (undocumented) -export const searchNavItem: ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef< +export const searchNavItem: ExtensionDefinition<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent; @@ -127,37 +127,33 @@ export const searchNavItem: ExtensionDefinition< }, 'core.nav-item.target', {} - >, - {}, - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - } ->; + >; + inputs: {}; +}>; // @alpha (undocumented) -export const searchPage: ExtensionDefinition< - { +export const searchPage: ExtensionDefinition<{ + config: { noTrack: boolean; } & { path: string | undefined; - }, - { + }; + configInput: { noTrack?: boolean | undefined; } & { path?: string | undefined; - }, - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: { items: ExtensionInput< ConfigurableExtensionDataRef< { @@ -172,13 +168,11 @@ export const searchPage: ExtensionDefinition< optional: false; } >; - }, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } ->; + }; + kind: 'page'; + namespace: undefined; + name: undefined; +}>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/search/package.json b/plugins/search/package.json index 3dbe5931e9..b8a76d61b8 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search", - "version": "1.4.15", + "version": "1.4.16-next.1", "description": "The Backstage plugin that provides your backstage app with search", "backstage": { "role": "frontend-plugin", diff --git a/plugins/signals-backend/CHANGELOG.md b/plugins/signals-backend/CHANGELOG.md index e6d8d44aa3..9f67f6bcb0 100644 --- a/plugins/signals-backend/CHANGELOG.md +++ b/plugins/signals-backend/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-signals-backend +## 0.2.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + - @backstage/plugin-signals-node@0.1.11-next.1 + +## 0.2.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 + +- 3ec5ccb: The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- 19ff127: Internal refactor to remove dependencies on the identity and token manager services, which have been removed. Public APIs no longer require the identity service or token manager to be provided. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.1.9 ### Patch Changes diff --git a/plugins/signals-backend/package.json b/plugins/signals-backend/package.json index 2bac39bb30..be39008ad4 100644 --- a/plugins/signals-backend/package.json +++ b/plugins/signals-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-backend", - "version": "0.1.9", + "version": "0.2.0-next.1", "backstage": { "role": "backend-plugin", "pluginId": "signals", diff --git a/plugins/signals-backend/src/service/router.test.ts b/plugins/signals-backend/src/service/router.test.ts index b5c26a3408..8584a06dea 100644 --- a/plugins/signals-backend/src/service/router.test.ts +++ b/plugins/signals-backend/src/service/router.test.ts @@ -24,8 +24,7 @@ import { UserInfoService, } from '@backstage/backend-plugin-api'; import { ConfigReader } from '@backstage/config'; -import { mockServices } from '@backstage/backend-test-utils'; -import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter'; +import { mockErrorHandler, mockServices } from '@backstage/backend-test-utils'; const eventsServiceMock: jest.Mocked = { subscribe: jest.fn(), @@ -53,11 +52,7 @@ describe('createRouter', () => { config: new ConfigReader({}), auth: mockServices.auth(), }); - const errorHandler = MiddlewareFactory.create({ - config: mockServices.rootConfig(), - logger: mockServices.rootLogger(), - }).error(); - app = express().use(router).use(errorHandler); + app = express().use(router).use(mockErrorHandler()); }); beforeEach(() => { diff --git a/plugins/signals-node/CHANGELOG.md b/plugins/signals-node/CHANGELOG.md index d0e1a31ae6..6737179922 100644 --- a/plugins/signals-node/CHANGELOG.md +++ b/plugins/signals-node/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-signals-node +## 0.1.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.25.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + - @backstage/plugin-events-node@0.4.0-next.1 + +## 0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/plugin-events-node@0.4.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/config@1.2.0 + - @backstage/types@1.1.1 + ## 0.1.9 ### Patch Changes diff --git a/plugins/signals-node/package.json b/plugins/signals-node/package.json index 98bce96f68..705e29eb90 100644 --- a/plugins/signals-node/package.json +++ b/plugins/signals-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-node", - "version": "0.1.9", + "version": "0.1.11-next.1", "description": "Node.js library for the signals plugin", "backstage": { "role": "node-library", diff --git a/plugins/signals-react/CHANGELOG.md b/plugins/signals-react/CHANGELOG.md index 7d2af3c4d6..09e4260019 100644 --- a/plugins/signals-react/CHANGELOG.md +++ b/plugins/signals-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/plugin-signals-react +## 0.0.5-next.0 + +### Patch Changes + +- 0389801: Fix for `useSignal` returning the inverse value for `isSignalsAvailable`. +- Updated dependencies + - @backstage/core-plugin-api@1.9.3 + - @backstage/types@1.1.1 + ## 0.0.4 ### Patch Changes diff --git a/plugins/signals-react/package.json b/plugins/signals-react/package.json index b970c8e5dd..fdea501041 100644 --- a/plugins/signals-react/package.json +++ b/plugins/signals-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals-react", - "version": "0.0.4", + "version": "0.0.5-next.0", "description": "Web library for the signals plugin", "backstage": { "role": "web-library", diff --git a/plugins/signals-react/src/hooks/useSignal.ts b/plugins/signals-react/src/hooks/useSignal.ts index 6fb0f4696f..dcf86ca25c 100644 --- a/plugins/signals-react/src/hooks/useSignal.ts +++ b/plugins/signals-react/src/hooks/useSignal.ts @@ -46,7 +46,7 @@ export const useSignal = ( }, [signals, channel]); // Can be used to fallback (for example to long polling) if signals are not available in the system - const isSignalsAvailable = useMemo(() => !signals, [signals]); + const isSignalsAvailable = useMemo(() => !!signals, [signals]); return { lastSignal, isSignalsAvailable }; }; diff --git a/plugins/signals/CHANGELOG.md b/plugins/signals/CHANGELOG.md index 1ccf349862..f06315faab 100644 --- a/plugins/signals/CHANGELOG.md +++ b/plugins/signals/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/plugin-signals +## 0.0.10-next.1 + +### Patch Changes + +- 3e9b1a4: Put a name on the `SignalsDisplay` component extension +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.5-next.0 + +## 0.0.10-next.0 + +### Patch Changes + +- 5add8e1: Added a `SignalsDisplay` extension to allows the signals plugin to be installed in an app as follows: + + ```tsx + export default app.createRoot( + <> + + + + + + {routes} + + , + ); + ``` + + With this in place you can remove the explicit installation via the `plugins` option for `createApp`. + +- Updated dependencies + - @backstage/plugin-signals-react@0.0.5-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + ## 0.0.9 ### Patch Changes diff --git a/plugins/signals/api-report.md b/plugins/signals/api-report.md index 1af1063433..ca7695aeec 100644 --- a/plugins/signals/api-report.md +++ b/plugins/signals/api-report.md @@ -30,6 +30,9 @@ export class SignalClient implements SignalApi { ): SignalSubscriber; } +// @public (undocumented) +export const SignalsDisplay: () => null; + // @public (undocumented) export const signalsPlugin: BackstagePlugin<{}, {}>; diff --git a/plugins/signals/package.json b/plugins/signals/package.json index ffd72fd2fd..95cab2df40 100644 --- a/plugins/signals/package.json +++ b/plugins/signals/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-signals", - "version": "0.0.9", + "version": "0.0.10-next.1", "backstage": { "role": "frontend-plugin", "pluginId": "signals", diff --git a/plugins/signals/src/index.ts b/plugins/signals/src/index.ts index ddf8afb9c6..2c5aa9c0f1 100644 --- a/plugins/signals/src/index.ts +++ b/plugins/signals/src/index.ts @@ -13,5 +13,5 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { signalsPlugin } from './plugin'; +export { signalsPlugin, SignalsDisplay } from './plugin'; export * from './api'; diff --git a/plugins/signals/src/plugin.ts b/plugins/signals/src/plugin.ts index eb3f9126e2..274287591d 100644 --- a/plugins/signals/src/plugin.ts +++ b/plugins/signals/src/plugin.ts @@ -15,6 +15,7 @@ */ import { createApiFactory, + createComponentExtension, createPlugin, discoveryApiRef, identityApiRef, @@ -41,3 +42,14 @@ export const signalsPlugin = createPlugin({ }), ], }); + +/** @public */ +export const SignalsDisplay = signalsPlugin.provide( + createComponentExtension({ + name: 'SignalsDisplay', + component: { + // No-op for now, this is just a placeholder to avoid the need for an explicit plugin installation + sync: () => null, + }, + }), +); diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index dff41d1b88..05c53b5302 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.38-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.12.4-next.1 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/plugin-catalog@1.22.1-next.1 + - @backstage/plugin-search-react@1.8.0-next.1 + - @backstage/plugin-techdocs@1.10.9-next.1 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + +## 1.0.38-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-search-react@1.8.0-next.0 + - @backstage/plugin-techdocs@1.10.9-next.0 + - @backstage/plugin-catalog@1.22.1-next.0 + - @backstage/test-utils@1.6.0-next.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration-react@1.1.30 + ## 1.0.37 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index b41d9652ca..8ecfdfe90e 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.37", + "version": "1.0.38-next.1", "backstage": { "role": "web-library", "pluginId": "techdocs-addons", diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 745071c589..703f151823 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/plugin-techdocs-backend +## 1.10.13-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/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-catalog-node@1.12.7-next.1 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.1 + - @backstage/plugin-techdocs-common@0.1.0 + - @backstage/plugin-techdocs-node@1.12.11-next.1 + +## 1.10.13-next.0 + +### Patch Changes + +- 086c32d: Dedicated token for techdocs cache sync +- 5b679ac: The `createRouter` and its related types has been marked as deprecared. This backend should instead be initialized using the new backend system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/plugin-techdocs-node@1.12.11-next.0 + - @backstage/plugin-search-backend-module-techdocs@0.2.2-next.0 + - @backstage/backend-common@0.25.0-next.0 + - @backstage/catalog-client@1.6.6 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/plugin-catalog-common@1.0.26 + - @backstage/plugin-permission-common@0.8.1 + - @backstage/plugin-techdocs-common@0.1.0 + ## 1.10.10 ### Patch Changes diff --git a/plugins/techdocs-backend/api-report.md b/plugins/techdocs-backend/api-report.md index ec3c2ada82..dceb0a4d9a 100644 --- a/plugins/techdocs-backend/api-report.md +++ b/plugins/techdocs-backend/api-report.md @@ -5,9 +5,9 @@ ```ts import { AuthService } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; -import { CatalogClient } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { DefaultTechDocsCollatorFactory as DefaultTechDocsCollatorFactory_2 } from '@backstage/plugin-search-backend-module-techdocs'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; import { DocsBuildStrategy as DocsBuildStrategy_2 } from '@backstage/plugin-techdocs-node'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; @@ -17,7 +17,6 @@ import { Knex } from 'knex'; import { Logger } from 'winston'; import { Permission } from '@backstage/plugin-permission-common'; import { PluginCacheManager } from '@backstage/backend-common'; -import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { PreparerBuilder } from '@backstage/plugin-techdocs-node'; import { PublisherBase } from '@backstage/plugin-techdocs-node'; import type { TechDocsCollatorFactoryOptions as TechDocsCollatorFactoryOptions_2 } from '@backstage/plugin-search-backend-module-techdocs'; @@ -25,7 +24,7 @@ import { TechDocsDocument as TechDocsDocument_2 } from '@backstage/plugin-techdo import { TokenManager } from '@backstage/backend-common'; import * as winston from 'winston'; -// @public +// @public @deprecated export function createRouter(options: RouterOptions): Promise; // @public @deprecated @@ -60,32 +59,32 @@ export type OutOfTheBoxDeploymentOptions = { generators: GeneratorBuilder; publisher: PublisherBase; logger: winston.Logger; - discovery: PluginEndpointDiscovery; + discovery: DiscoveryService; database?: Knex; config: Config; cache: PluginCacheManager; docsBuildStrategy?: DocsBuildStrategy_2; buildLogTransport?: winston.transport; - catalogClient?: CatalogClient; + catalogClient?: CatalogApi; httpAuth?: HttpAuthService; auth?: AuthService; }; -// @public +// @public @deprecated export type RecommendedDeploymentOptions = { publisher: PublisherBase; logger: winston.Logger; - discovery: PluginEndpointDiscovery; + discovery: DiscoveryService; config: Config; cache: PluginCacheManager; docsBuildStrategy?: DocsBuildStrategy_2; buildLogTransport?: winston.transport; - catalogClient?: CatalogClient; + catalogClient?: CatalogApi; httpAuth?: HttpAuthService; auth?: AuthService; }; -// @public +// @public @deprecated export type RouterOptions = | RecommendedDeploymentOptions | OutOfTheBoxDeploymentOptions; @@ -100,7 +99,7 @@ export type TechDocsCollatorFactoryOptions = TechDocsCollatorFactoryOptions_2; // @public export type TechDocsCollatorOptions = { - discovery: PluginEndpointDiscovery; + discovery: DiscoveryService; logger: Logger; tokenManager: TokenManager; locationTemplate?: string; diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index f1312f1e05..468b349f11 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-backend", - "version": "1.10.10", + "version": "1.10.13-next.1", "description": "The Backstage backend plugin that renders technical documentation for your components", "backstage": { "role": "backend-plugin", @@ -66,6 +66,7 @@ "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-catalog-common": "workspace:^", + "@backstage/plugin-catalog-node": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-search-backend-module-techdocs": "workspace:^", "@backstage/plugin-techdocs-common": "workspace:^", diff --git a/plugins/techdocs-backend/src/cache/TechDocsCache.test.ts b/plugins/techdocs-backend/src/cache/TechDocsCache.test.ts index 7dff7069db..1cdd0174b5 100644 --- a/plugins/techdocs-backend/src/cache/TechDocsCache.test.ts +++ b/plugins/techdocs-backend/src/cache/TechDocsCache.test.ts @@ -14,10 +14,10 @@ * limitations under the License. */ -import { CacheClient, loggerToWinstonLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { CacheInvalidationError, TechDocsCache } from './TechDocsCache'; import { mockServices } from '@backstage/backend-test-utils'; +import { CacheService } from '@backstage/backend-plugin-api'; const cached = (str: string): string => { return Buffer.from(str).toString('base64'); @@ -25,7 +25,7 @@ const cached = (str: string): string => { describe('TechDocsCache', () => { let CacheUnderTest: TechDocsCache; - let MockClient: jest.Mocked; + let MockClient: jest.Mocked; beforeEach(() => { MockClient = { @@ -36,7 +36,7 @@ describe('TechDocsCache', () => { }; CacheUnderTest = TechDocsCache.fromConfig(new ConfigReader({}), { cache: MockClient, - logger: loggerToWinstonLogger(mockServices.logger.mock()), + logger: mockServices.logger.mock(), }); }); @@ -83,7 +83,7 @@ describe('TechDocsCache', () => { }), { cache: MockClient, - logger: loggerToWinstonLogger(mockServices.logger.mock()), + logger: mockServices.logger.mock(), }, ); diff --git a/plugins/techdocs-backend/src/cache/TechDocsCache.ts b/plugins/techdocs-backend/src/cache/TechDocsCache.ts index 807d6ca87b..a5eb4d37be 100644 --- a/plugins/techdocs-backend/src/cache/TechDocsCache.ts +++ b/plugins/techdocs-backend/src/cache/TechDocsCache.ts @@ -13,16 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { CacheClient } from '@backstage/backend-common'; import { assertError, CustomErrorBase } from '@backstage/errors'; import { Config } from '@backstage/config'; -import { Logger } from 'winston'; +import { CacheService, LoggerService } from '@backstage/backend-plugin-api'; export class CacheInvalidationError extends CustomErrorBase {} export class TechDocsCache { - protected readonly cache: CacheClient; - protected readonly logger: Logger; + protected readonly cache: CacheService; + protected readonly logger: LoggerService; protected readonly readTimeout: number; private constructor({ @@ -30,8 +29,8 @@ export class TechDocsCache { logger, readTimeout, }: { - cache: CacheClient; - logger: Logger; + cache: CacheService; + logger: LoggerService; readTimeout: number; }) { this.cache = cache; @@ -41,7 +40,7 @@ export class TechDocsCache { static fromConfig( config: Config, - { cache, logger }: { cache: CacheClient; logger: Logger }, + { cache, logger }: { cache: CacheService; logger: LoggerService }, ) { const timeout = config.getOptionalNumber('techdocs.cache.readTimeout'); const readTimeout = timeout === undefined ? 1000 : timeout; @@ -67,7 +66,7 @@ export class TechDocsCache { } catch (e) { assertError(e); this.logger.warn(`Error getting cache entry ${path}: ${e.message}`); - this.logger.debug(e.stack); + this.logger.debug(e.message, e); return undefined; } } diff --git a/plugins/techdocs-backend/src/cache/cacheMiddleware.test.ts b/plugins/techdocs-backend/src/cache/cacheMiddleware.test.ts index 1d814c3caa..d64c08e072 100644 --- a/plugins/techdocs-backend/src/cache/cacheMiddleware.test.ts +++ b/plugins/techdocs-backend/src/cache/cacheMiddleware.test.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { loggerToWinstonLogger } from '@backstage/backend-common'; import express from 'express'; import request from 'supertest'; import { createCacheMiddleware } from './cacheMiddleware'; @@ -58,7 +57,7 @@ describe('createCacheMiddleware', () => { invalidateMultiple: jest.fn().mockResolvedValue(undefined), } as unknown as jest.Mocked; const router = await createCacheMiddleware({ - logger: loggerToWinstonLogger(mockServices.logger.mock()), + logger: mockServices.logger.mock(), cache, }); app = express().use(router); diff --git a/plugins/techdocs-backend/src/cache/cacheMiddleware.ts b/plugins/techdocs-backend/src/cache/cacheMiddleware.ts index 51cce6d220..02b35cf7bf 100644 --- a/plugins/techdocs-backend/src/cache/cacheMiddleware.ts +++ b/plugins/techdocs-backend/src/cache/cacheMiddleware.ts @@ -15,12 +15,12 @@ */ import { Router } from 'express'; import router from 'express-promise-router'; -import { Logger } from 'winston'; import { TechDocsCache } from './TechDocsCache'; +import { LoggerService } from '@backstage/backend-plugin-api'; type CacheMiddlewareOptions = { cache: TechDocsCache; - logger: Logger; + logger: LoggerService; }; type ErrorCallback = (err?: Error) => void; diff --git a/plugins/techdocs-backend/src/plugin.ts b/plugins/techdocs-backend/src/plugin.ts index fd0574fedc..0f3def79b1 100644 --- a/plugins/techdocs-backend/src/plugin.ts +++ b/plugins/techdocs-backend/src/plugin.ts @@ -22,7 +22,6 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; - import { DocsBuildStrategy, Generators, @@ -39,6 +38,7 @@ import { techdocsPublisherExtensionPoint, } from '@backstage/plugin-techdocs-node'; import { createRouter } from '@backstage/plugin-techdocs-backend'; +import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; import * as winston from 'winston'; /** @@ -108,6 +108,7 @@ export const techdocsPlugin = createBackendPlugin({ cache: coreServices.cache, httpAuth: coreServices.httpAuth, auth: coreServices.auth, + catalog: catalogServiceRef, }, async init({ config, @@ -118,6 +119,7 @@ export const techdocsPlugin = createBackendPlugin({ cache, httpAuth, auth, + catalog, }) { const winstonLogger = loggerToWinstonLogger(logger); // Preparers are responsible for fetching source files for documentation. @@ -161,6 +163,7 @@ export const techdocsPlugin = createBackendPlugin({ discovery, httpAuth, auth, + catalogClient: catalog, }), ); diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts index 96f8cfd696..e010856792 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.test.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - PluginEndpointDiscovery, - TokenManager, - loggerToWinstonLogger, -} from '@backstage/backend-common'; +import { TokenManager, loggerToWinstonLogger } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { DefaultTechDocsCollator } from './DefaultTechDocsCollator'; import { @@ -29,6 +25,7 @@ import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { ConfigReader } from '@backstage/config'; import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; const logger = loggerToWinstonLogger(mockServices.logger.mock()); @@ -83,7 +80,7 @@ describe('TechDocs Collator', () => { registerMswTestHooks(worker); describe('DefaultTechDocsCollator with legacyPathCasing configuration', () => { - let mockDiscoveryApi: jest.Mocked; + let mockDiscoveryApi: jest.Mocked; let mockTokenManager: jest.Mocked; let collator: DefaultTechDocsCollator; @@ -147,7 +144,7 @@ describe('TechDocs Collator', () => { }); describe('DefaultTechDocsCollator', () => { - let mockDiscoveryApi: jest.Mocked; + let mockDiscoveryApi: jest.Mocked; let mockTokenManager: jest.Mocked; let collator: DefaultTechDocsCollator; diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts index 527846df79..635833676c 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - PluginEndpointDiscovery, - TokenManager, -} from '@backstage/backend-common'; +import { TokenManager } from '@backstage/backend-common'; import { Entity, parseEntityRef, @@ -38,6 +35,7 @@ import { } from '@backstage/catalog-client'; import { TechDocsDocument } from '@backstage/plugin-techdocs-node'; import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; interface MkSearchIndexDoc { title: string; @@ -51,7 +49,7 @@ interface MkSearchIndexDoc { * @public */ export type TechDocsCollatorOptions = { - discovery: PluginEndpointDiscovery; + discovery: DiscoveryService; logger: Logger; tokenManager: TokenManager; locationTemplate?: string; diff --git a/plugins/techdocs-backend/src/service/CachedEntityLoader.test.ts b/plugins/techdocs-backend/src/service/CachedEntityLoader.test.ts index 57e4dccbd4..c4673c6fa4 100644 --- a/plugins/techdocs-backend/src/service/CachedEntityLoader.test.ts +++ b/plugins/techdocs-backend/src/service/CachedEntityLoader.test.ts @@ -13,17 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { CacheService } from '@backstage/backend-plugin-api'; import { CachedEntityLoader } from './CachedEntityLoader'; -import { CatalogClient } from '@backstage/catalog-client'; -import { CacheClient } from '@backstage/backend-common'; +import { CatalogApi } from '@backstage/catalog-client'; import { CompoundEntityRef } from '@backstage/catalog-model'; describe('CachedEntityLoader', () => { - const catalog: jest.Mocked = { + const catalog: jest.Mocked = { getEntityByRef: jest.fn(), } as any; - const cache: jest.Mocked = { + const cache: jest.Mocked = { get: jest.fn(), set: jest.fn(), } as any; diff --git a/plugins/techdocs-backend/src/service/CachedEntityLoader.ts b/plugins/techdocs-backend/src/service/CachedEntityLoader.ts index 424d9b9541..7541509907 100644 --- a/plugins/techdocs-backend/src/service/CachedEntityLoader.ts +++ b/plugins/techdocs-backend/src/service/CachedEntityLoader.ts @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { CatalogClient } from '@backstage/catalog-client'; -import { CacheClient } from '@backstage/backend-common'; + +import { CacheService } from '@backstage/backend-plugin-api'; +import { CatalogApi } from '@backstage/catalog-client'; import { Entity, CompoundEntityRef, @@ -22,13 +23,13 @@ import { } from '@backstage/catalog-model'; export type CachedEntityLoaderOptions = { - catalog: CatalogClient; - cache: CacheClient; + catalog: CatalogApi; + cache: CacheService; }; export class CachedEntityLoader { - private readonly catalog: CatalogClient; - private readonly cache: CacheClient; + private readonly catalog: CatalogApi; + private readonly cache: CacheService; private readonly readTimeout = 1000; constructor({ catalog, cache }: CachedEntityLoaderOptions) { diff --git a/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts b/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts index bb66c303b7..a611613716 100644 --- a/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts +++ b/plugins/techdocs-backend/src/service/DocsSynchronizer.test.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - loggerToWinstonLogger, - PluginEndpointDiscovery, -} from '@backstage/backend-common'; +import { loggerToWinstonLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { ScmIntegrations } from '@backstage/integration'; import { @@ -31,6 +28,7 @@ import { TechDocsCache } from '../cache'; import { DocsBuilder, shouldCheckForUpdate } from '../DocsBuilder'; import { DocsSynchronizer, DocsSynchronizerSyncOpts } from './DocsSynchronizer'; import { mockServices } from '@backstage/backend-test-utils'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; jest.mock('../DocsBuilder'); jest.useFakeTimers(); @@ -66,7 +64,7 @@ describe('DocsSynchronizer', () => { hasDocsBeenGenerated: jest.fn(), publish: jest.fn(), }; - const discovery: jest.Mocked = { + const discovery: jest.Mocked = { getBaseUrl: jest.fn(), getExternalBaseUrl: jest.fn(), }; diff --git a/plugins/techdocs-backend/src/service/DocsSynchronizer.ts b/plugins/techdocs-backend/src/service/DocsSynchronizer.ts index 7859b55e3f..e4b67e920e 100644 --- a/plugins/techdocs-backend/src/service/DocsSynchronizer.ts +++ b/plugins/techdocs-backend/src/service/DocsSynchronizer.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { DEFAULT_NAMESPACE, Entity, @@ -38,6 +37,7 @@ import { DocsBuilder, shouldCheckForUpdate, } from '../DocsBuilder'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; export type DocsSynchronizerSyncOpts = { log: (message: string) => void; @@ -189,7 +189,7 @@ export class DocsSynchronizer { entity, }: { responseHandler: DocsSynchronizerSyncOpts; - discovery: PluginEndpointDiscovery; + discovery: DiscoveryService; token: string | undefined; entity: Entity; }) { diff --git a/plugins/techdocs-backend/src/service/router.test.ts b/plugins/techdocs-backend/src/service/router.test.ts index 72da3023b0..631efe06ea 100644 --- a/plugins/techdocs-backend/src/service/router.test.ts +++ b/plugins/techdocs-backend/src/service/router.test.ts @@ -15,10 +15,8 @@ */ import { - errorHandler, - loggerToWinstonLogger, PluginCacheManager, - PluginEndpointDiscovery, + loggerToWinstonLogger, } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { @@ -33,7 +31,8 @@ import { DocsSynchronizer, DocsSynchronizerSyncOpts } from './DocsSynchronizer'; import { CachedEntityLoader } from './CachedEntityLoader'; import { createEventStream, createRouter, RouterOptions } from './router'; import { TechDocsCache } from '../cache'; -import { mockServices } from '@backstage/backend-test-utils'; +import { mockErrorHandler, mockServices } from '@backstage/backend-test-utils'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; jest.mock('@backstage/catalog-client'); jest.mock('@backstage/config'); @@ -76,7 +75,7 @@ const getMockHttpResponseFor = (content: string): Buffer => { const createApp = async (options: RouterOptions) => { const app = express(); app.use(await createRouter(options)); - app.use(errorHandler()); + app.use(mockErrorHandler()); return app; }; @@ -112,7 +111,7 @@ describe('createRouter', () => { hasDocsBeenGenerated: jest.fn(), publish: jest.fn(), }; - const discovery: jest.Mocked = { + const discovery: jest.Mocked = { getBaseUrl: jest.fn(), getExternalBaseUrl: jest.fn(), }; diff --git a/plugins/techdocs-backend/src/service/router.ts b/plugins/techdocs-backend/src/service/router.ts index fff55a9ed1..b99579e0eb 100644 --- a/plugins/techdocs-backend/src/service/router.ts +++ b/plugins/techdocs-backend/src/service/router.ts @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { - PluginEndpointDiscovery, - PluginCacheManager, createLegacyAuthAdapters, + PluginCacheManager, } from '@backstage/backend-common'; -import { CatalogClient } from '@backstage/catalog-client'; +import { CatalogApi, CatalogClient } from '@backstage/catalog-client'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { NotFoundError } from '@backstage/errors'; @@ -38,7 +38,11 @@ import { createCacheMiddleware, TechDocsCache } from '../cache'; import { CachedEntityLoader } from './CachedEntityLoader'; import { DefaultDocsBuildStrategy } from './DefaultDocsBuildStrategy'; import * as winston from 'winston'; -import { AuthService, HttpAuthService } from '@backstage/backend-plugin-api'; +import { + AuthService, + DiscoveryService, + HttpAuthService, +} from '@backstage/backend-plugin-api'; /** * Required dependencies for running TechDocs in the "out-of-the-box" @@ -51,13 +55,13 @@ export type OutOfTheBoxDeploymentOptions = { generators: GeneratorBuilder; publisher: PublisherBase; logger: winston.Logger; - discovery: PluginEndpointDiscovery; + discovery: DiscoveryService; database?: Knex; // TODO: Make database required when we're implementing database stuff. config: Config; cache: PluginCacheManager; docsBuildStrategy?: DocsBuildStrategy; buildLogTransport?: winston.transport; - catalogClient?: CatalogClient; + catalogClient?: CatalogApi; httpAuth?: HttpAuthService; auth?: AuthService; }; @@ -67,16 +71,17 @@ export type OutOfTheBoxDeploymentOptions = { * configuration (prepare/generate handled externally in CI/CD). * * @public + * @deprecated This type is only exported for legacy reasons and will be removed in the future. */ export type RecommendedDeploymentOptions = { publisher: PublisherBase; logger: winston.Logger; - discovery: PluginEndpointDiscovery; + discovery: DiscoveryService; config: Config; cache: PluginCacheManager; docsBuildStrategy?: DocsBuildStrategy; buildLogTransport?: winston.transport; - catalogClient?: CatalogClient; + catalogClient?: CatalogApi; httpAuth?: HttpAuthService; auth?: AuthService; }; @@ -85,6 +90,7 @@ export type RecommendedDeploymentOptions = { * One of the two deployment configurations must be provided. * * @public + * @deprecated This type is only exported for legacy reasons and will be removed in the future. */ export type RouterOptions = | RecommendedDeploymentOptions @@ -94,7 +100,7 @@ export type RouterOptions = * Typeguard to help createRouter() understand when we are in a "recommended" * deployment vs. when we are in an out-of-the-box deployment configuration. * - * * @public + * @public */ function isOutOfTheBoxOption( opt: RouterOptions, @@ -106,6 +112,8 @@ function isOutOfTheBoxOption( * Creates a techdocs router. * * @public + * @deprecated This function is only exported for legacy reasons and will be removed in the future. + * Please {@link https://backstage.io/docs/backend-system/building-backends/migrating | migrate } to use the new backend system and follow these {@link https://backstage.io/docs/features/techdocs/getting-started#new-backend-system | instructions } to install the user settings backend plugin. */ export async function createRouter( options: RouterOptions, diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 1d73053f4e..80a556378d 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration@1.14.0 + - @backstage/integration-react@1.1.30 + - @backstage/plugin-techdocs-react@1.2.8-next.1 + +## 1.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-react@1.2.8-next.0 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/integration@1.14.0 + - @backstage/integration-react@1.1.30 + ## 1.1.13 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index a682740923..db2fc00ed9 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", - "version": "1.1.13", + "version": "1.1.14-next.1", "description": "Plugin module for contributed TechDocs Addons", "backstage": { "role": "frontend-plugin-module", diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index 8a12d40ffb..5df6fd23cc 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-techdocs-node +## 1.12.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + +## 1.12.11-next.0 + +### Patch Changes + +- 4417dd4: Fix typo and unify TechDocs casing in doc strings +- 33ebb28: As the `@backstage/backend-common` package is deprecated, we have updated the `techdocs-node` package to stop depending on it. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/integration@1.14.0 + - @backstage/integration-aws-node@0.1.12 + - @backstage/plugin-search-common@1.2.14 + - @backstage/plugin-techdocs-common@0.1.0 + ## 1.12.9 ### Patch Changes diff --git a/plugins/techdocs-node/api-report.md b/plugins/techdocs-node/api-report.md index 6c7f05e900..ea93ddfc98 100644 --- a/plugins/techdocs-node/api-report.md +++ b/plugins/techdocs-node/api-report.md @@ -7,13 +7,13 @@ import { CompoundEntityRef } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; -import { ContainerRunner } from '@backstage/backend-common'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; import { Entity } from '@backstage/catalog-model'; import express from 'express'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { IndexableDocument } from '@backstage/plugin-search-common'; import { Logger } from 'winston'; -import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { UrlReaderService } from '@backstage/backend-plugin-api'; import * as winston from 'winston'; @@ -48,8 +48,8 @@ export type GeneratorBuilder = { // @public export type GeneratorOptions = { - logger: Logger; - containerRunner?: ContainerRunner; + logger: LoggerService; + containerRunner?: TechDocsContainerRunner; }; // @public @@ -71,8 +71,8 @@ export class Generators implements GeneratorBuilder { static fromConfig( config: Config, options: { - logger: Logger; - containerRunner?: ContainerRunner; + logger: LoggerService; + containerRunner?: TechDocsContainerRunner; customGenerator?: TechdocsGenerator; }, ): Promise; @@ -86,7 +86,7 @@ export const getDocFilesFromRepository: ( entity: Entity, opts?: { etag?: string; - logger?: Logger; + logger?: LoggerService; }, ) => Promise; @@ -156,13 +156,13 @@ export type PreparerBuilder = { // @public export type PreparerConfig = { - logger: Logger; + logger: LoggerService; reader: UrlReaderService; }; // @public export type PreparerOptions = { - logger?: Logger; + logger?: LoggerService; etag?: ETag; }; @@ -214,8 +214,8 @@ export type PublisherBuilder = { // @public export type PublisherFactory = { - logger: Logger; - discovery: PluginEndpointDiscovery; + logger: LoggerService; + discovery: DiscoveryService; customPublisher?: PublisherBase | undefined; }; @@ -261,6 +261,32 @@ export interface TechdocsBuildsExtensionPoint { // @public export const techdocsBuildsExtensionPoint: ExtensionPoint; +// @public +export interface TechDocsContainerRunner { + runContainer(opts: { + imageName: string; + command?: string | string[]; + args: string[]; + logStream?: Writable; + mountDirs?: Record; + workingDir?: string; + envVars?: Record; + pullImage?: boolean; + defaultUser?: boolean; + pullOptions?: { + authconfig?: { + username?: string; + password?: string; + auth?: string; + email?: string; + serveraddress?: string; + [key: string]: unknown; + }; + [key: string]: unknown; + }; + }): Promise; +} + // @public export interface TechDocsDocument extends IndexableDocument { kind: string; @@ -274,8 +300,8 @@ export interface TechDocsDocument extends IndexableDocument { // @public export class TechdocsGenerator implements GeneratorBase { constructor(options: { - logger: Logger; - containerRunner?: ContainerRunner; + logger: LoggerService; + containerRunner?: TechDocsContainerRunner; config: Config; scmIntegrations: ScmIntegrationRegistry; }); diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index edef992e6b..8fa90e66d8 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-node", - "version": "1.12.9", + "version": "1.12.11-next.1", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", "backstage": { "role": "node-library", @@ -53,7 +53,6 @@ "@aws-sdk/types": "^3.347.0", "@azure/identity": "^4.0.0", "@azure/storage-blob": "^12.5.0", - "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", diff --git a/plugins/techdocs-node/src/helpers.ts b/plugins/techdocs-node/src/helpers.ts index d4816e1f72..67bb862c62 100644 --- a/plugins/techdocs-node/src/helpers.ts +++ b/plugins/techdocs-node/src/helpers.ts @@ -14,8 +14,11 @@ * limitations under the License. */ -import { UrlReaderService } from '@backstage/backend-plugin-api'; -import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; +import { + LoggerService, + UrlReaderService, + resolveSafeChildPath, +} from '@backstage/backend-plugin-api'; import { Entity, getEntitySourceLocation, @@ -25,7 +28,6 @@ import { InputError } from '@backstage/errors'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; import path from 'path'; -import { Logger } from 'winston'; import { PreparerResponse, RemoteProtocol } from './stages/prepare/types'; /** @@ -145,7 +147,7 @@ export const getLocationForEntity = ( export const getDocFilesFromRepository = async ( reader: UrlReaderService, entity: Entity, - opts?: { etag?: string; logger?: Logger }, + opts?: { etag?: string; logger?: LoggerService }, ): Promise => { const { target } = parseReferenceAnnotation(TECHDOCS_ANNOTATION, entity); diff --git a/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts b/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts index b7cb7f1c86..a9fe55d85f 100644 --- a/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts +++ b/plugins/techdocs-node/src/stages/generate/DockerContainerRunner.ts @@ -76,12 +76,17 @@ export class DockerContainerRunner { this.dockerClient.pull(imageName, {}, (err, stream) => { if (err) { reject(err); - return; + } else if (!stream) { + reject( + new Error( + 'Unexpeected error: no stream returned from Docker while pulling image', + ), + ); + } else { + pipeline(stream, logStream, { end: false }) + .then(resolve) + .catch(reject); } - - pipeline(stream, logStream, { end: false }) - .then(resolve) - .catch(reject); }); }); } @@ -112,7 +117,7 @@ export class DockerContainerRunner { } // Create docker environment variables array - const Env = []; + const Env = new Array(); for (const [key, value] of Object.entries(envVars)) { Env.push(`${key}=${value}`); } diff --git a/plugins/techdocs-node/src/stages/generate/generators.test.ts b/plugins/techdocs-node/src/stages/generate/generators.test.ts index f80f070796..3e46eb9f9d 100644 --- a/plugins/techdocs-node/src/stages/generate/generators.test.ts +++ b/plugins/techdocs-node/src/stages/generate/generators.test.ts @@ -14,13 +14,12 @@ * limitations under the License. */ -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { Generators } from './generators'; import { TechdocsGenerator } from './techdocs'; import { mockServices } from '@backstage/backend-test-utils'; -const logger = loggerToWinstonLogger(mockServices.logger.mock()); +const logger = mockServices.logger.mock(); const mockEntity = { apiVersion: 'version', diff --git a/plugins/techdocs-node/src/stages/generate/generators.ts b/plugins/techdocs-node/src/stages/generate/generators.ts index 0c20ac1588..7c8d169d1e 100644 --- a/plugins/techdocs-node/src/stages/generate/generators.ts +++ b/plugins/techdocs-node/src/stages/generate/generators.ts @@ -14,10 +14,8 @@ * limitations under the License. */ -import { ContainerRunner } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; -import { Logger } from 'winston'; import { getGeneratorKey } from './helpers'; import { TechdocsGenerator } from './techdocs'; import { @@ -25,6 +23,8 @@ import { GeneratorBuilder, SupportedGeneratorKey, } from './types'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { TechDocsContainerRunner } from '../publish/types'; /** * Collection of docs generators @@ -41,8 +41,8 @@ export class Generators implements GeneratorBuilder { static async fromConfig( config: Config, options: { - logger: Logger; - containerRunner?: ContainerRunner; + logger: LoggerService; + containerRunner?: TechDocsContainerRunner; customGenerator?: TechdocsGenerator; }, ): Promise { diff --git a/plugins/techdocs-node/src/stages/generate/helpers.test.ts b/plugins/techdocs-node/src/stages/generate/helpers.test.ts index 695f5b8f2c..755cd9d1a6 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.test.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.test.ts @@ -37,7 +37,6 @@ import { patchMkdocsYmlWithPlugins, } from './mkdocsPatchers'; import yaml from 'js-yaml'; -import { loggerToWinstonLogger } from '@backstage/backend-common'; const mockEntity = { apiVersion: 'version', @@ -93,7 +92,7 @@ const mkdocsYmlWithAdditionalPluginsWithConfig = fs.readFileSync( const mkdocsYmlWithEnvTag = fs.readFileSync( resolvePath(__filename, '../__fixtures__/mkdocs_with_env_tag.yml'), ); -const mockLogger = loggerToWinstonLogger(mockServices.logger.mock()); +const mockLogger = mockServices.logger.mock(); const warn = jest.spyOn(mockLogger, 'warn'); const scmIntegrations = ScmIntegrations.fromConfig(new ConfigReader({})); diff --git a/plugins/techdocs-node/src/stages/generate/helpers.ts b/plugins/techdocs-node/src/stages/generate/helpers.ts index 9c1996a772..d62b6dcccd 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { isChildPath } from '@backstage/backend-plugin-api'; +import { isChildPath, LoggerService } from '@backstage/backend-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { assertError, ForwardedError } from '@backstage/errors'; import { ScmIntegrationRegistry } from '@backstage/integration'; @@ -24,7 +24,6 @@ import gitUrlParse from 'git-url-parse'; import yaml, { DEFAULT_SCHEMA, Type } from 'js-yaml'; import path, { resolve as resolvePath } from 'path'; import { PassThrough, Writable } from 'stream'; -import { Logger } from 'winston'; import { ParsedLocationAnnotation } from '../../helpers'; import { DefaultMkdocsContent, SupportedGeneratorKey } from './types'; import { getFileTreeRecursively } from '../publish/helpers'; @@ -298,7 +297,7 @@ export const patchIndexPreBuild = async ({ docsDir = 'docs', }: { inputDir: string; - logger: Logger; + logger: LoggerService; docsDir?: string; }) => { const docsPath = path.join(inputDir, docsDir); @@ -342,7 +341,7 @@ export const patchIndexPreBuild = async ({ */ export const createOrUpdateMetadata = async ( techdocsMetadataPath: string, - logger: Logger, + logger: LoggerService, ): Promise => { const techdocsMetadataDir = techdocsMetadataPath .split(path.sep) diff --git a/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts b/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts index fb95c19a9c..804c06f129 100644 --- a/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts +++ b/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Logger } from 'winston'; import fs from 'fs-extra'; import yaml from 'js-yaml'; import { ParsedLocationAnnotation } from '../../helpers'; import { getRepoUrlFromLocationAnnotation, MKDOCS_SCHEMA } from './helpers'; import { assertError } from '@backstage/errors'; import { ScmIntegrationRegistry } from '@backstage/integration'; +import { LoggerService } from '@backstage/backend-plugin-api'; type MkDocsObject = { plugins?: string[]; @@ -30,7 +30,7 @@ type MkDocsObject = { const patchMkdocsFile = async ( mkdocsYmlPath: string, - logger: Logger, + logger: LoggerService, updateAction: (mkdocsYml: MkDocsObject) => boolean, ) => { // We only want to override the mkdocs.yml if it has actually changed. This is relevant if @@ -103,7 +103,7 @@ const patchMkdocsFile = async ( */ export const patchMkdocsYmlPreBuild = async ( mkdocsYmlPath: string, - logger: Logger, + logger: LoggerService, parsedLocationAnnotation: ParsedLocationAnnotation, scmIntegrations: ScmIntegrationRegistry, ) => { @@ -149,7 +149,7 @@ export const patchMkdocsYmlPreBuild = async ( */ export const patchMkdocsYmlWithPlugins = async ( mkdocsYmlPath: string, - logger: Logger, + logger: LoggerService, defaultPlugins: string[] = ['techdocs-core'], ) => { await patchMkdocsFile(mkdocsYmlPath, logger, mkdocsYml => { diff --git a/plugins/techdocs-node/src/stages/generate/techdocs.ts b/plugins/techdocs-node/src/stages/generate/techdocs.ts index 599457ee5a..554f1c29bd 100644 --- a/plugins/techdocs-node/src/stages/generate/techdocs.ts +++ b/plugins/techdocs-node/src/stages/generate/techdocs.ts @@ -16,7 +16,6 @@ import { Config } from '@backstage/config'; import path from 'path'; -import { Logger } from 'winston'; import { ScmIntegrationRegistry, ScmIntegrations, @@ -43,7 +42,8 @@ import { } from './types'; import { ForwardedError } from '@backstage/errors'; import { DockerContainerRunner } from './DockerContainerRunner'; -import { ContainerRunner } from '@backstage/backend-common'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { TechDocsContainerRunner } from '../publish/types'; /** * Generates documentation files @@ -55,8 +55,8 @@ export class TechdocsGenerator implements GeneratorBase { * and static so that techdocs-node consumers can use the same version. */ public static readonly defaultDockerImage = 'spotify/techdocs:v1.2.4'; - private readonly logger: Logger; - private readonly containerRunner?: ContainerRunner; + private readonly logger: LoggerService; + private readonly containerRunner?: TechDocsContainerRunner; private readonly options: GeneratorConfig; private readonly scmIntegrations: ScmIntegrationRegistry; @@ -77,8 +77,8 @@ export class TechdocsGenerator implements GeneratorBase { } constructor(options: { - logger: Logger; - containerRunner?: ContainerRunner; + logger: LoggerService; + containerRunner?: TechDocsContainerRunner; config: Config; scmIntegrations: ScmIntegrationRegistry; }) { @@ -216,7 +216,7 @@ export class TechdocsGenerator implements GeneratorBase { export function readGeneratorConfig( config: Config, - logger: Logger, + logger: LoggerService, ): GeneratorConfig { const legacyGeneratorType = config.getOptionalString( 'techdocs.generators.techdocs', diff --git a/plugins/techdocs-node/src/stages/generate/types.ts b/plugins/techdocs-node/src/stages/generate/types.ts index ca816d560f..c7513d2710 100644 --- a/plugins/techdocs-node/src/stages/generate/types.ts +++ b/plugins/techdocs-node/src/stages/generate/types.ts @@ -18,7 +18,8 @@ import { Entity } from '@backstage/catalog-model'; import { Writable } from 'stream'; import { Logger } from 'winston'; import { ParsedLocationAnnotation } from '../../helpers'; -import { ContainerRunner } from '@backstage/backend-common'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { TechDocsContainerRunner } from '../publish/types'; // Determines where the generator will be run export type GeneratorRunInType = 'docker' | 'local'; @@ -28,12 +29,12 @@ export type GeneratorRunInType = 'docker' | 'local'; * @public */ export type GeneratorOptions = { - logger: Logger; + logger: LoggerService; /** * @deprecated containerRunner is now instantiated in * the generator and this option will be removed in the future */ - containerRunner?: ContainerRunner; + containerRunner?: TechDocsContainerRunner; }; /** diff --git a/plugins/techdocs-node/src/stages/prepare/dir.test.ts b/plugins/techdocs-node/src/stages/prepare/dir.test.ts index df470d7da6..2dadfa6ece 100644 --- a/plugins/techdocs-node/src/stages/prepare/dir.test.ts +++ b/plugins/techdocs-node/src/stages/prepare/dir.test.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; import { ConfigReader } from '@backstage/config'; import { DirectoryPreparer } from './dir'; @@ -31,7 +30,7 @@ jest.mock('../../helpers', () => ({ ...jest.requireActual<{}>('../../helpers'), })); -const logger = loggerToWinstonLogger(mockServices.logger.mock()); +const logger = mockServices.logger.mock(); const createMockEntity = (annotations: {}) => { return { diff --git a/plugins/techdocs-node/src/stages/prepare/dir.ts b/plugins/techdocs-node/src/stages/prepare/dir.ts index cecd2564e6..033b62a6a0 100644 --- a/plugins/techdocs-node/src/stages/prepare/dir.ts +++ b/plugins/techdocs-node/src/stages/prepare/dir.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { UrlReaderService } from '@backstage/backend-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { InputError } from '@backstage/errors'; @@ -23,7 +22,6 @@ import { ScmIntegrations, } from '@backstage/integration'; import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common'; -import { Logger } from 'winston'; import { parseReferenceAnnotation, transformDirLocation } from '../../helpers'; import { PreparerBase, @@ -31,6 +29,7 @@ import { PreparerOptions, PreparerResponse, } from './types'; +import { LoggerService, UrlReaderService } from '@backstage/backend-plugin-api'; /** * Preparer used to retrieve documentation files from a local directory @@ -54,7 +53,7 @@ export class DirectoryPreparer implements PreparerBase { private constructor( config: Config, - _logger: Logger | null, + _logger: LoggerService | null, reader: UrlReaderService, ) { this.reader = reader; diff --git a/plugins/techdocs-node/src/stages/prepare/types.ts b/plugins/techdocs-node/src/stages/prepare/types.ts index 14ec185c97..30b4b310ed 100644 --- a/plugins/techdocs-node/src/stages/prepare/types.ts +++ b/plugins/techdocs-node/src/stages/prepare/types.ts @@ -15,8 +15,7 @@ */ import type { Entity } from '@backstage/catalog-model'; -import { UrlReaderService } from '@backstage/backend-plugin-api'; -import { Logger } from 'winston'; +import { LoggerService, UrlReaderService } from '@backstage/backend-plugin-api'; /** * A unique identifier of the tree blob, usually the commit SHA or etag from the target. @@ -29,7 +28,7 @@ export type ETag = string; * @public */ export type PreparerConfig = { - logger: Logger; + logger: LoggerService; reader: UrlReaderService; }; @@ -41,7 +40,7 @@ export type PreparerOptions = { /** * An instance of the logger */ - logger?: Logger; + logger?: LoggerService; /** * see {@link ETag} */ diff --git a/plugins/techdocs-node/src/stages/prepare/url.ts b/plugins/techdocs-node/src/stages/prepare/url.ts index 24480d2703..260ed454e8 100644 --- a/plugins/techdocs-node/src/stages/prepare/url.ts +++ b/plugins/techdocs-node/src/stages/prepare/url.ts @@ -15,9 +15,7 @@ */ import { assertError } from '@backstage/errors'; -import { UrlReaderService } from '@backstage/backend-plugin-api'; import { Entity } from '@backstage/catalog-model'; -import { Logger } from 'winston'; import { getDocFilesFromRepository } from '../../helpers'; import { PreparerBase, @@ -25,13 +23,14 @@ import { PreparerOptions, PreparerResponse, } from './types'; +import { LoggerService, UrlReaderService } from '@backstage/backend-plugin-api'; /** * Preparer used to retrieve documentation files from a remote repository * @public */ export class UrlPreparer implements PreparerBase { - private readonly logger: Logger; + private readonly logger: LoggerService; private readonly reader: UrlReaderService; /** @@ -42,7 +41,7 @@ export class UrlPreparer implements PreparerBase { return new UrlPreparer(options.reader, options.logger); } - private constructor(reader: UrlReaderService, logger: Logger) { + private constructor(reader: UrlReaderService, logger: LoggerService) { this.logger = logger; this.reader = reader; } diff --git a/plugins/techdocs-node/src/stages/publish/awsS3.test.ts b/plugins/techdocs-node/src/stages/publish/awsS3.test.ts index e43b303dd4..6fb855d199 100644 --- a/plugins/techdocs-node/src/stages/publish/awsS3.test.ts +++ b/plugins/techdocs-node/src/stages/publish/awsS3.test.ts @@ -42,7 +42,6 @@ import { createMockDirectory, mockServices, } from '@backstage/backend-test-utils'; -import { loggerToWinstonLogger } from '@backstage/backend-common'; const env = process.env; let s3Mock: AwsClientStub; @@ -90,7 +89,7 @@ class ErrorReadable extends Readable { } } -const logger = loggerToWinstonLogger(mockServices.logger.mock()); +const logger = mockServices.logger.mock(); const loggerInfoSpy = jest.spyOn(logger, 'info'); const loggerErrorSpy = jest.spyOn(logger, 'error'); diff --git a/plugins/techdocs-node/src/stages/publish/awsS3.ts b/plugins/techdocs-node/src/stages/publish/awsS3.ts index 29a5277682..05902c999f 100644 --- a/plugins/techdocs-node/src/stages/publish/awsS3.ts +++ b/plugins/techdocs-node/src/stages/publish/awsS3.ts @@ -42,7 +42,6 @@ import JSON5 from 'json5'; import createLimiter from 'p-limit'; import path from 'path'; import { Readable } from 'stream'; -import { Logger } from 'winston'; import { bulkStorageOperation, getCloudPathForLocalPath, @@ -60,6 +59,7 @@ import { ReadinessResponse, TechDocsMetadata, } from './types'; +import { LoggerService } from '@backstage/backend-plugin-api'; const streamToBuffer = (stream: Readable): Promise => { return new Promise((resolve, reject) => { @@ -80,7 +80,7 @@ export class AwsS3Publish implements PublisherBase { private readonly storageClient: S3Client; private readonly bucketName: string; private readonly legacyPathCasing: boolean; - private readonly logger: Logger; + private readonly logger: LoggerService; private readonly bucketRootPath: string; private readonly sse?: 'aws:kms' | 'AES256'; @@ -88,7 +88,7 @@ export class AwsS3Publish implements PublisherBase { storageClient: S3Client; bucketName: string; legacyPathCasing: boolean; - logger: Logger; + logger: LoggerService; bucketRootPath: string; sse?: 'aws:kms' | 'AES256'; }) { @@ -102,7 +102,7 @@ export class AwsS3Publish implements PublisherBase { static async fromConfig( config: Config, - logger: Logger, + logger: LoggerService, ): Promise { let bucketName = ''; try { @@ -524,7 +524,7 @@ export class AwsS3Publish implements PublisherBase { } try { - this.logger.verbose(`Migrating ${file}`); + this.logger.debug(`Migrating ${file}`); await this.storageClient.send( new CopyObjectCommand({ Bucket: this.bucketName, diff --git a/plugins/techdocs-node/src/stages/publish/azureBlobStorage.test.ts b/plugins/techdocs-node/src/stages/publish/azureBlobStorage.test.ts index 6cbfa76c81..83e707fd54 100644 --- a/plugins/techdocs-node/src/stages/publish/azureBlobStorage.test.ts +++ b/plugins/techdocs-node/src/stages/publish/azureBlobStorage.test.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { Entity, DEFAULT_NAMESPACE } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import express from 'express'; @@ -224,8 +223,7 @@ const getEntityRootDir = (entity: Entity) => { return mockDir.resolve(namespace || DEFAULT_NAMESPACE, kind, name); }; -const logger = loggerToWinstonLogger(mockServices.logger.mock()); -jest.spyOn(logger, 'error').mockReturnValue(logger); +const logger = mockServices.logger.mock(); const createPublisherFromConfig = ({ accountName = 'accountName', diff --git a/plugins/techdocs-node/src/stages/publish/azureBlobStorage.ts b/plugins/techdocs-node/src/stages/publish/azureBlobStorage.ts index 39a50e963a..863a4fc533 100644 --- a/plugins/techdocs-node/src/stages/publish/azureBlobStorage.ts +++ b/plugins/techdocs-node/src/stages/publish/azureBlobStorage.ts @@ -26,7 +26,6 @@ import express from 'express'; import JSON5 from 'json5'; import limiterFactory from 'p-limit'; import { default as path, default as platformPath } from 'path'; -import { Logger } from 'winston'; import { bulkStorageOperation, getCloudPathForLocalPath, @@ -43,6 +42,7 @@ import { ReadinessResponse, TechDocsMetadata, } from './types'; +import { LoggerService } from '@backstage/backend-plugin-api'; // The number of batches that may be ongoing at the same time. const BATCH_CONCURRENCY = 3; @@ -51,13 +51,13 @@ export class AzureBlobStoragePublish implements PublisherBase { private readonly storageClient: BlobServiceClient; private readonly containerName: string; private readonly legacyPathCasing: boolean; - private readonly logger: Logger; + private readonly logger: LoggerService; constructor(options: { storageClient: BlobServiceClient; containerName: string; legacyPathCasing: boolean; - logger: Logger; + logger: LoggerService; }) { this.storageClient = options.storageClient; this.containerName = options.containerName; @@ -65,7 +65,7 @@ export class AzureBlobStoragePublish implements PublisherBase { this.logger = options.logger; } - static fromConfig(config: Config, logger: Logger): PublisherBase { + static fromConfig(config: Config, logger: LoggerService): PublisherBase { let storageClient: BlobServiceClient; let containerName = ''; try { @@ -421,7 +421,7 @@ export class AzureBlobStoragePublish implements PublisherBase { if (originalPath === newPath) return; try { - this.logger.verbose(`Migrating ${originalPath}`); + this.logger.debug(`Migrating ${originalPath}`); await this.renameBlob(originalPath, newPath, removeOriginal); } catch (e) { assertError(e); diff --git a/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts b/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts index 0c94a69d6a..f09ba160d9 100644 --- a/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts +++ b/plugins/techdocs-node/src/stages/publish/googleStorage.test.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { Entity, DEFAULT_NAMESPACE } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; import express from 'express'; @@ -139,9 +138,7 @@ const getEntityRootDir = (entity: Entity) => { return mockDir.resolve(namespace || DEFAULT_NAMESPACE, kind, name); }; -const logger = loggerToWinstonLogger(mockServices.logger.mock()); -jest.spyOn(logger, 'info').mockReturnValue(logger); -jest.spyOn(logger, 'error').mockReturnValue(logger); +const logger = mockServices.logger.mock(); const createPublisherFromConfig = ({ bucketName = 'bucketName', diff --git a/plugins/techdocs-node/src/stages/publish/googleStorage.ts b/plugins/techdocs-node/src/stages/publish/googleStorage.ts index cd07f6204e..bc75a4c8bb 100644 --- a/plugins/techdocs-node/src/stages/publish/googleStorage.ts +++ b/plugins/techdocs-node/src/stages/publish/googleStorage.ts @@ -26,7 +26,6 @@ import express from 'express'; import JSON5 from 'json5'; import path from 'path'; import { Readable } from 'stream'; -import { Logger } from 'winston'; import { getFileTreeRecursively, getHeadersForFileExtension, @@ -45,19 +44,20 @@ import { ReadinessResponse, TechDocsMetadata, } from './types'; +import { LoggerService } from '@backstage/backend-plugin-api'; export class GoogleGCSPublish implements PublisherBase { private readonly storageClient: Storage; private readonly bucketName: string; private readonly legacyPathCasing: boolean; - private readonly logger: Logger; + private readonly logger: LoggerService; private readonly bucketRootPath: string; constructor(options: { storageClient: Storage; bucketName: string; legacyPathCasing: boolean; - logger: Logger; + logger: LoggerService; bucketRootPath: string; }) { this.storageClient = options.storageClient; @@ -67,7 +67,7 @@ export class GoogleGCSPublish implements PublisherBase { this.bucketRootPath = options.bucketRootPath; } - static fromConfig(config: Config, logger: Logger): PublisherBase { + static fromConfig(config: Config, logger: LoggerService): PublisherBase { let bucketName = ''; try { bucketName = config.getString('techdocs.publisher.googleGcs.bucketName'); diff --git a/plugins/techdocs-node/src/stages/publish/index.ts b/plugins/techdocs-node/src/stages/publish/index.ts index f342ccf0ae..8b6465c719 100644 --- a/plugins/techdocs-node/src/stages/publish/index.ts +++ b/plugins/techdocs-node/src/stages/publish/index.ts @@ -18,10 +18,11 @@ export type { PublisherBase, PublisherType, PublisherFactory, + PublisherBuilder, PublishRequest, PublishResponse, MigrateRequest, ReadinessResponse, TechDocsMetadata, - PublisherBuilder, + TechDocsContainerRunner, } from './types'; diff --git a/plugins/techdocs-node/src/stages/publish/local.test.ts b/plugins/techdocs-node/src/stages/publish/local.test.ts index e5e71c51ec..a6dc9c09c4 100644 --- a/plugins/techdocs-node/src/stages/publish/local.test.ts +++ b/plugins/techdocs-node/src/stages/publish/local.test.ts @@ -13,10 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - loggerToWinstonLogger, - PluginEndpointDiscovery, -} from '@backstage/backend-common'; import { overridePackagePathResolution } from '@backstage/backend-plugin-api/testUtils'; import { ConfigReader } from '@backstage/config'; import express from 'express'; @@ -28,6 +24,7 @@ import { createMockDirectory, mockServices, } from '@backstage/backend-test-utils'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; const createMockEntity = (annotations = {}, lowerCase = false) => { return { @@ -42,7 +39,7 @@ const createMockEntity = (annotations = {}, lowerCase = false) => { }; }; -const testDiscovery: jest.Mocked = { +const testDiscovery: jest.Mocked = { getBaseUrl: jest.fn().mockResolvedValue('http://localhost:7007/api/techdocs'), getExternalBaseUrl: jest.fn(), }; @@ -56,7 +53,7 @@ overridePackagePathResolution({ }, }); -const logger = loggerToWinstonLogger(mockServices.logger.mock()); +const logger = mockServices.logger.mock(); describe('local publisher', () => { const mockDir = createMockDirectory(); diff --git a/plugins/techdocs-node/src/stages/publish/local.ts b/plugins/techdocs-node/src/stages/publish/local.ts index 37f41080b4..863bf12560 100644 --- a/plugins/techdocs-node/src/stages/publish/local.ts +++ b/plugins/techdocs-node/src/stages/publish/local.ts @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { PluginEndpointDiscovery } from '@backstage/backend-common'; + import { + DiscoveryService, + LoggerService, resolvePackagePath, resolveSafeChildPath, } from '@backstage/backend-plugin-api'; @@ -29,7 +31,6 @@ import fs from 'fs-extra'; import os from 'os'; import createLimiter from 'p-limit'; import path from 'path'; -import { Logger } from 'winston'; import { PublisherBase, PublishRequest, @@ -51,13 +52,13 @@ import { ForwardedError } from '@backstage/errors'; */ export class LocalPublish implements PublisherBase { private readonly legacyPathCasing: boolean; - private readonly logger: Logger; - private readonly discovery: PluginEndpointDiscovery; + private readonly logger: LoggerService; + private readonly discovery: DiscoveryService; private readonly staticDocsDir: string; constructor(options: { - logger: Logger; - discovery: PluginEndpointDiscovery; + logger: LoggerService; + discovery: DiscoveryService; legacyPathCasing: boolean; staticDocsDir: string; }) { @@ -69,8 +70,8 @@ export class LocalPublish implements PublisherBase { static fromConfig( config: Config, - logger: Logger, - discovery: PluginEndpointDiscovery, + logger: LoggerService, + discovery: DiscoveryService, ): PublisherBase { const legacyPathCasing = config.getOptionalBoolean( @@ -299,7 +300,7 @@ export class LocalPublish implements PublisherBase { // Otherwise, copy or move the file. await new Promise(resolve => { const migrate = removeOriginal ? fs.move : fs.copyFile; - this.logger.verbose(`Migrating ${relativeFile}`); + this.logger.debug(`Migrating ${relativeFile}`); migrate(file, newFile, err => { if (err) { this.logger.warn( diff --git a/plugins/techdocs-node/src/stages/publish/migrations/GoogleMigration.ts b/plugins/techdocs-node/src/stages/publish/migrations/GoogleMigration.ts index 69d5353f9f..f8ae8c316e 100644 --- a/plugins/techdocs-node/src/stages/publish/migrations/GoogleMigration.ts +++ b/plugins/techdocs-node/src/stages/publish/migrations/GoogleMigration.ts @@ -17,20 +17,24 @@ import { assertError } from '@backstage/errors'; import { File } from '@google-cloud/storage'; import { Writable } from 'stream'; -import { Logger } from 'winston'; import { lowerCaseEntityTripletInStoragePath } from '../helpers'; +import { LoggerService } from '@backstage/backend-plugin-api'; /** * Writable stream to handle object copy/move operations. This implementation * ensures we don't read in files from GCS faster than GCS can copy/move them. */ export class MigrateWriteStream extends Writable { - protected logger: Logger; + protected logger: LoggerService; protected removeOriginal: boolean; protected maxConcurrency: number; protected inFlight = 0; - constructor(logger: Logger, removeOriginal: boolean, concurrency: number) { + constructor( + logger: LoggerService, + removeOriginal: boolean, + concurrency: number, + ) { super({ objectMode: true }); this.logger = logger; this.removeOriginal = removeOriginal; @@ -66,7 +70,7 @@ export class MigrateWriteStream extends Writable { const migrate = this.removeOriginal ? file.move.bind(file) : file.copy.bind(file); - this.logger.verbose(`Migrating ${file.name}`); + this.logger.debug(`Migrating ${file.name}`); migrate(newFile) .catch(e => this.logger.warn(`Unable to migrate ${file.name}: ${e.message}`), diff --git a/plugins/techdocs-node/src/stages/publish/openStackSwift.test.ts b/plugins/techdocs-node/src/stages/publish/openStackSwift.test.ts index aa0e5f0afa..4d9972390f 100644 --- a/plugins/techdocs-node/src/stages/publish/openStackSwift.test.ts +++ b/plugins/techdocs-node/src/stages/publish/openStackSwift.test.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { loggerToWinstonLogger } from '@backstage/backend-common'; import { Entity, CompoundEntityRef, @@ -172,7 +171,7 @@ const getPosixEntityRootDir = (entity: Entity) => { ); }; -const logger = loggerToWinstonLogger(mockServices.logger.mock()); +const logger = mockServices.logger.mock(); let publisher: PublisherBase; diff --git a/plugins/techdocs-node/src/stages/publish/openStackSwift.ts b/plugins/techdocs-node/src/stages/publish/openStackSwift.ts index 734a7e4451..43e7deb2f9 100644 --- a/plugins/techdocs-node/src/stages/publish/openStackSwift.ts +++ b/plugins/techdocs-node/src/stages/publish/openStackSwift.ts @@ -23,7 +23,7 @@ import path from 'path'; import { SwiftClient } from '@trendyol-js/openstack-swift-sdk'; import { NotFound } from '@trendyol-js/openstack-swift-sdk/lib/types'; import { Stream, Readable } from 'stream'; -import { Logger } from 'winston'; + import { getFileTreeRecursively, getHeadersForFileExtension, @@ -37,6 +37,7 @@ import { TechDocsMetadata, } from './types'; import { assertError, ForwardedError } from '@backstage/errors'; +import { LoggerService } from '@backstage/backend-plugin-api'; const streamToBuffer = (stream: Stream | Readable): Promise => { return new Promise((resolve, reject) => { @@ -61,19 +62,19 @@ const bufferToStream = (buffer: Buffer): Readable => { export class OpenStackSwiftPublish implements PublisherBase { private readonly storageClient: SwiftClient; private readonly containerName: string; - private readonly logger: Logger; + private readonly logger: LoggerService; constructor(options: { storageClient: SwiftClient; containerName: string; - logger: Logger; + logger: LoggerService; }) { this.storageClient = options.storageClient; this.containerName = options.containerName; this.logger = options.logger; } - static fromConfig(config: Config, logger: Logger): PublisherBase { + static fromConfig(config: Config, logger: LoggerService): PublisherBase { let containerName = ''; try { containerName = config.getString( @@ -326,7 +327,7 @@ export class OpenStackSwiftPublish implements PublisherBase { } try { - this.logger.verbose(`Migrating ${file} to ${newPath}`); + this.logger.debug(`Migrating ${file} to ${newPath}`); await this.storageClient.copy( this.containerName, file, diff --git a/plugins/techdocs-node/src/stages/publish/publish.test.ts b/plugins/techdocs-node/src/stages/publish/publish.test.ts index 0063839e2f..408a171fe0 100644 --- a/plugins/techdocs-node/src/stages/publish/publish.test.ts +++ b/plugins/techdocs-node/src/stages/publish/publish.test.ts @@ -13,10 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - PluginEndpointDiscovery, - loggerToWinstonLogger, -} from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { Publisher } from './publish'; import { LocalPublish } from './local'; @@ -26,9 +22,10 @@ import { AzureBlobStoragePublish } from './azureBlobStorage'; import { OpenStackSwiftPublish } from './openStackSwift'; import { mockServices } from '@backstage/backend-test-utils'; import { PublisherBase } from './types'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; -const logger = loggerToWinstonLogger(mockServices.logger.mock()); -const discovery: jest.Mocked = { +const logger = mockServices.logger.mock(); +const discovery: jest.Mocked = { getBaseUrl: jest.fn().mockResolvedValueOnce('http://localhost:7007'), getExternalBaseUrl: jest.fn(), }; diff --git a/plugins/techdocs-node/src/stages/publish/types.ts b/plugins/techdocs-node/src/stages/publish/types.ts index 3acd48a468..89af730404 100644 --- a/plugins/techdocs-node/src/stages/publish/types.ts +++ b/plugins/techdocs-node/src/stages/publish/types.ts @@ -13,19 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Entity, CompoundEntityRef } from '@backstage/catalog-model'; -import { PluginEndpointDiscovery } from '@backstage/backend-common'; -import { Logger } from 'winston'; +import { Writable } from 'stream'; import express from 'express'; import { Config } from '@backstage/config'; +import { DiscoveryService, LoggerService } from '@backstage/backend-plugin-api'; +import { Entity, CompoundEntityRef } from '@backstage/catalog-model'; /** * Options for building publishers * @public */ export type PublisherFactory = { - logger: Logger; - discovery: PluginEndpointDiscovery; + logger: LoggerService; + discovery: DiscoveryService; customPublisher?: PublisherBase | undefined; }; @@ -168,3 +168,36 @@ export type PublisherBuilder = { register(type: PublisherType, publisher: PublisherBase): void; get(config: Config): PublisherBase; }; + +/** + * Handles the running of containers, on behalf of others. + * + * @public + */ +export interface TechDocsContainerRunner { + /** + * Runs a container image to completion. + */ + runContainer(opts: { + imageName: string; + command?: string | string[]; + args: string[]; + logStream?: Writable; + mountDirs?: Record; + workingDir?: string; + envVars?: Record; + pullImage?: boolean; + defaultUser?: boolean; + pullOptions?: { + authconfig?: { + username?: string; + password?: string; + auth?: string; + email?: string; + serveraddress?: string; + [key: string]: unknown; + }; + [key: string]: unknown; + }; + }): Promise; +} diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 0163217d65..93ad0932d8 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-techdocs-react +## 1.2.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.14.11-next.0 + - @backstage/catalog-model@1.6.0 + - @backstage/config@1.2.0 + - @backstage/core-plugin-api@1.9.3 + - @backstage/version-bridge@1.0.8 + +## 1.2.8-next.0 + +### Patch Changes + +- 5ee3d27: Fixed issue in useShadowRootElements which could lead to unlimited render loops +- Updated dependencies + - @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/version-bridge@1.0.8 + ## 1.2.7 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 4c5a013fcd..df95b38138 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-react", - "version": "1.2.7", + "version": "1.2.8-next.1", "description": "Shared frontend utilities for TechDocs and Addons", "backstage": { "role": "web-library", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index d1b1a559b5..56fdbed8eb 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,50 @@ # @backstage/plugin-techdocs +## 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 diff --git a/plugins/techdocs/api-report-alpha.md b/plugins/techdocs/api-report-alpha.md index 27d09e53e0..6a22a9fce9 100644 --- a/plugins/techdocs/api-report-alpha.md +++ b/plugins/techdocs/api-report-alpha.md @@ -6,11 +6,11 @@ import { AnyApiFactory } from '@backstage/frontend-plugin-api'; import { AnyExtensionDataRef } from '@backstage/frontend-plugin-api'; import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; @@ -18,7 +18,7 @@ import { SearchResultItemExtensionComponent } from '@backstage/plugin-search-rea import { SearchResultItemExtensionPredicate } from '@backstage/plugin-search-react/alpha'; // @alpha (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< { root: RouteRef; docRoot: RouteRef<{ @@ -30,10 +30,52 @@ const _default: BackstagePlugin< }, {}, { - 'nav-item:techdocs': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef< + 'api:techdocs': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'page:techdocs': ExtensionDefinition<{ + kind: 'page'; + namespace: undefined; + name: undefined; + config: { + path: string | undefined; + }; + configInput: { + path?: string | undefined; + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: {}; + }>; + 'nav-item:techdocs': ExtensionDefinition<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent; @@ -41,51 +83,48 @@ const _default: BackstagePlugin< }, 'core.nav-item.target', {} - >, - {}, - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - } - >; - 'api:techdocs/storage': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef, - {}, - { - kind: 'api'; - namespace: undefined; - name: 'storage'; - } - >; - 'search-result-list-item:techdocs': ExtensionDefinition< - { + >; + inputs: {}; + }>; + 'api:techdocs/storage': ExtensionDefinition<{ + kind: 'api'; + namespace: undefined; + name: 'storage'; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< + AnyApiFactory, + 'core.api.factory', + {} + >; + inputs: {}; + }>; + 'search-result-list-item:techdocs': ExtensionDefinition<{ + config: { title: string | undefined; lineClamp: number; asLink: boolean; asListItem: boolean; } & { noTrack: boolean; - }, - { + }; + configInput: { title?: string | undefined; lineClamp?: number | undefined; asListItem?: boolean | undefined; asLink?: boolean | undefined; } & { noTrack?: boolean | undefined; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< { predicate?: SearchResultItemExtensionPredicate | undefined; component: SearchResultItemExtensionComponent; }, 'search.search-result-list-item.item', {} - >, - { + >; + inputs: { [x: string]: ExtensionInput< AnyExtensionDataRef, { @@ -93,117 +132,117 @@ const _default: BackstagePlugin< singleton: boolean; } >; - }, - { - kind: 'search-result-list-item'; - namespace: undefined; - name: undefined; - } - >; - 'page:techdocs/reader': ExtensionDefinition< - { + }; + kind: 'search-result-list-item'; + namespace: undefined; + name: undefined; + }>; + 'page:techdocs/reader': ExtensionDefinition<{ + kind: 'page'; + namespace: undefined; + name: 'reader'; + config: { path: string | undefined; - }, - { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - {}, - { - kind: 'page'; - namespace: undefined; - name: 'reader'; - } - >; - 'entity-content:techdocs': ExtensionDefinition< - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: {}; + }>; + 'entity-content:techdocs': ExtensionDefinition<{ + kind: 'entity-content'; + namespace: undefined; + name: undefined; + config: { path: string | undefined; title: string | undefined; filter: string | undefined; - }, - { + }; + configInput: { filter?: string | undefined; title?: string | undefined; path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - (entity: Entity) => boolean, - 'catalog.entity-filter-function', - { - optional: true; - } - > - | ConfigurableExtensionDataRef< - string, - 'catalog.entity-filter-expression', - { - optional: true; - } - >, - {}, - { - kind: 'entity-content'; - namespace: undefined; - name: undefined; - } - >; + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-content-title', + {} + > + | ConfigurableExtensionDataRef< + (entity: Entity) => boolean, + 'catalog.entity-filter-function', + { + optional: true; + } + > + | ConfigurableExtensionDataRef< + string, + 'catalog.entity-filter-expression', + { + optional: true; + } + >; + inputs: {}; + }>; } >; export default _default; // @alpha (undocumented) -export const techDocsSearchResultListItemExtension: ExtensionDefinition< - { +export const techDocsSearchResultListItemExtension: ExtensionDefinition<{ + config: { title: string | undefined; lineClamp: number; asLink: boolean; asListItem: boolean; } & { noTrack: boolean; - }, - { + }; + configInput: { title?: string | undefined; lineClamp?: number | undefined; asListItem?: boolean | undefined; asLink?: boolean | undefined; } & { noTrack?: boolean | undefined; - }, - ConfigurableExtensionDataRef< + }; + output: ConfigurableExtensionDataRef< { predicate?: SearchResultItemExtensionPredicate | undefined; component: SearchResultItemExtensionComponent; }, 'search.search-result-list-item.item', {} - >, - { + >; + inputs: { [x: string]: ExtensionInput< AnyExtensionDataRef, { @@ -211,13 +250,11 @@ export const techDocsSearchResultListItemExtension: ExtensionDefinition< singleton: boolean; } >; - }, - { - kind: 'search-result-list-item'; - namespace: undefined; - name: undefined; - } ->; + }; + kind: 'search-result-list-item'; + namespace: undefined; + name: undefined; +}>; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 525ba58caa..cefc822ebf 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs", - "version": "1.10.8", + "version": "1.10.9-next.1", "description": "The Backstage plugin that renders technical documentation for your components", "backstage": { "role": "frontend-plugin", diff --git a/plugins/techdocs/src/home/components/Tables/actions.tsx b/plugins/techdocs/src/home/components/Tables/actions.tsx index c3eaa038c8..bc89d76560 100644 --- a/plugins/techdocs/src/home/components/Tables/actions.tsx +++ b/plugins/techdocs/src/home/components/Tables/actions.tsx @@ -17,14 +17,7 @@ import React from 'react'; import ShareIcon from '@material-ui/icons/Share'; import { DocsTableRow } from './types'; -import { withStyles } from '@material-ui/core/styles'; -import { StarIcon, UnstarredIcon } from '@backstage/core-components'; - -const FilledStar = withStyles(theme => ({ - root: { - color: theme.palette.entityStarButton.color, - }, -}))(StarIcon); +import { FavoriteToggleIcon } from '@backstage/core-components'; /** * Not directly exported, but through DocsTable.actions and EntityListDocsTable.actions @@ -51,7 +44,7 @@ export const actionFactories = { const isStarred = isStarredEntity(entity); return { cellStyle: { paddingLeft: '1em' }, - icon: () => (isStarred ? : ), + icon: () => , tooltip: isStarred ? 'Remove from favorites' : 'Add to favorites', onClick: () => toggleStarredEntity(entity), }; diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts b/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts index c682008a4d..680e58e182 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts @@ -113,6 +113,7 @@ ${headings.reduce((style, heading) => { border: 1px solid var(--md-default-fg-color); border-bottom: none; border-collapse: collapse; + border-radius: ${theme.shape.borderRadius}px; } .md-typeset table:not([class]) th { font-weight: bold; diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts b/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts index 3999430efb..7ffe76c5fb 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/variables.ts @@ -139,7 +139,7 @@ export default ({ theme }: RuleOptions) => ` --md-typeset-color: var(--md-default-fg-color); --md-typeset-a-color: ${theme.palette.link}; --md-typeset-table-color: ${theme.palette.text.primary}; - --md-typeset-table-color--light: ${alpha(theme.palette.text.primary, 0.5)}; + --md-typeset-table-color--light: ${alpha(theme.palette.text.primary, 0.05)}; --md-typeset-del-color: ${ theme.palette.type === 'dark' ? alpha(theme.palette.error.dark, 0.5) diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 0a6359e1c8..5b6283c103 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-user-settings-backend +## 0.2.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.5.0-next.1 + - @backstage/plugin-auth-node@0.5.2-next.1 + - @backstage/backend-plugin-api@0.9.0-next.1 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-node@0.1.11-next.1 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.2.24-next.0 + +### Patch Changes + +- 164ce3e: In preparation to stop supporting to the legacy backend system, the `createRouter` function is now deprecated and we strongly recommend you [migrate](https://backstage.io/docs/backend-system/building-backends/migrating) your backend to the new system. +- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature. +- 1b98099: Replaced usage of the deprecated identity service with the new HTTP auth service for the new backend system. +- Updated dependencies + - @backstage/backend-plugin-api@0.9.0-next.0 + - @backstage/backend-defaults@0.5.0-next.0 + - @backstage/plugin-auth-node@0.5.2-next.0 + - @backstage/plugin-signals-node@0.1.11-next.0 + - @backstage/config@1.2.0 + - @backstage/errors@1.2.4 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.2.22 ### Patch Changes diff --git a/plugins/user-settings-backend/README.md b/plugins/user-settings-backend/README.md index a1fb504415..249edec592 100644 --- a/plugins/user-settings-backend/README.md +++ b/plugins/user-settings-backend/README.md @@ -10,48 +10,16 @@ Install the backend plugin ```bash # From your Backstage root directory -yarn --cwd packages/backend add @backstage/plugin-user-settings-backend +yarn --cwd packages/backend add @backstage/plugin-user-settings-backend @backstage/plugin-signals-backend ``` -### New backend - Add the plugin to your backend in `packages/backend/src/index.ts`: ```ts backend.add(import('@backstage/plugin-user-settings-backend/alpha')); -``` - -To get real-time updates of the user settings across different user sessions, you must also install -the `@backstage/plugin-signals-backend` plugin. - -### Old backend - -1. Configure the routes by adding a new `userSettings.ts` file in - `packages/backend/src/plugins/`: - -```ts -// packages/backend/src/plugins/userSettings.ts -import { createRouter } from '@backstage/plugin-user-settings-backend'; -import { PluginEnvironment } from '../types'; - -export default async function createPlugin(env: PluginEnvironment) { - return await createRouter({ - database: env.database, - identity: env.identity, - }); -} -``` - -2. Add the new routes to your backend by modifying `packages/backend/src/index.ts`: - -```diff - // packages/backend/src/index.ts -+import userSettings from './plugins/userSettings'; - async function main() { -+ const userSettingsEnv = useHotMemoize(module, () => createEnv('user-settings')); - const apiRouter = Router(); -+ apiRouter.use('/user-settings', await userSettings(userSettingsEnv)); -} +// The signals backend is technically optional but enables real-time update of user +// settings across different sessions +backend.add(import('@backstage/plugin-signals-backend')); ``` ## Setup app diff --git a/plugins/user-settings-backend/api-report.md b/plugins/user-settings-backend/api-report.md index 06dad6a82a..04aecca574 100644 --- a/plugins/user-settings-backend/api-report.md +++ b/plugins/user-settings-backend/api-report.md @@ -8,18 +8,15 @@ import express from 'express'; import { IdentityApi } from '@backstage/plugin-auth-node'; import { SignalsService } from '@backstage/plugin-signals-node'; -// @public +// @public @deprecated export function createRouter(options: RouterOptions): Promise; -// @public (undocumented) -export interface RouterOptions { - // (undocumented) +// @public @deprecated +export type RouterOptions = { database: DatabaseService; - // (undocumented) identity: IdentityApi; - // (undocumented) signals?: SignalsService; -} +}; // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index ab91735143..dcbd3dac2d 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings-backend", - "version": "0.2.22", + "version": "0.2.24-next.1", "description": "The Backstage backend plugin to manage user settings", "backstage": { "role": "backend-plugin", @@ -52,7 +52,7 @@ "test": "backstage-cli package test" }, "dependencies": { - "@backstage/backend-common": "workspace:^", + "@backstage/backend-defaults": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", @@ -64,7 +64,6 @@ "express": "^4.17.1", "express-promise-router": "^4.1.0", "knex": "^3.0.0", - "winston": "^3.2.1", "yn": "^4.0.0" }, "devDependencies": { diff --git a/plugins/user-settings-backend/src/database/DatabaseUserSettingsStore.ts b/plugins/user-settings-backend/src/database/DatabaseUserSettingsStore.ts index 99c4b2cff4..5a051e8806 100644 --- a/plugins/user-settings-backend/src/database/DatabaseUserSettingsStore.ts +++ b/plugins/user-settings-backend/src/database/DatabaseUserSettingsStore.ts @@ -14,8 +14,10 @@ * limitations under the License. */ -import { PluginDatabaseManager } from '@backstage/backend-common'; -import { resolvePackagePath } from '@backstage/backend-plugin-api'; +import { + resolvePackagePath, + DatabaseService, +} from '@backstage/backend-plugin-api'; import { NotFoundError } from '@backstage/errors'; import { JsonValue } from '@backstage/types'; import { Knex } from 'knex'; @@ -43,7 +45,7 @@ export type RawDbUserSettingsRow = { */ export class DatabaseUserSettingsStore implements UserSettingsStore { static async create(options: { - database: PluginDatabaseManager; + database: DatabaseService; }): Promise { const { database } = options; const client = await database.getClient(); diff --git a/plugins/user-settings-backend/src/deprecated.ts b/plugins/user-settings-backend/src/deprecated.ts new file mode 100644 index 0000000000..2631236d44 --- /dev/null +++ b/plugins/user-settings-backend/src/deprecated.ts @@ -0,0 +1,47 @@ +/* + * 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 express from 'express'; +import { DatabaseService } from '@backstage/backend-plugin-api'; +import { SignalsService } from '@backstage/plugin-signals-node'; + +import { createRouter as internalCreateRouter } from './service'; +import { IdentityApi } from '@backstage/plugin-auth-node'; + +/** + * Type for the options passed to the "createRouter" function. + * + * @public + * @deprecated This type is only exported for legacy reasons and will be removed in the future. + */ +export type RouterOptions = { + database: DatabaseService; + identity: IdentityApi; + signals?: SignalsService; +}; + +/** + * Create the user settings backend routes. + * + * @public + * @deprecated This function is only exported for legacy reasons and will be removed in the future. + * Please {@link https://backstage.io/docs/backend-system/building-backends/migrating | migrate } to use the new backend system and follow these {@link https://github.com/backstage/backstage/tree/master/plugins/user-settings-backend#new-backend | instructions } to install the user settings backend plugin. + */ +export async function createRouter( + options: RouterOptions, +): Promise { + return await internalCreateRouter(options); +} diff --git a/plugins/user-settings-backend/src/index.ts b/plugins/user-settings-backend/src/index.ts index 04d8accdaf..395a8570bf 100644 --- a/plugins/user-settings-backend/src/index.ts +++ b/plugins/user-settings-backend/src/index.ts @@ -14,5 +14,5 @@ * limitations under the License. */ -export * from './service'; +export * from './deprecated'; export * from './database'; diff --git a/plugins/user-settings-backend/src/service/router.test.ts b/plugins/user-settings-backend/src/service/router.test.ts index 90b6fb587f..366d3828a0 100644 --- a/plugins/user-settings-backend/src/service/router.test.ts +++ b/plugins/user-settings-backend/src/service/router.test.ts @@ -19,7 +19,11 @@ import request from 'supertest'; import { UserSettingsStore } from '../database/UserSettingsStore'; import { createRouterInternal } from './router'; import { SignalsService } from '@backstage/plugin-signals-node'; -import { mockCredentials, mockServices } from '@backstage/backend-test-utils'; +import { + mockCredentials, + mockServices, + mockErrorHandler, +} from '@backstage/backend-test-utils'; describe('createRouter', () => { const userSettingsStore: jest.Mocked = { @@ -40,7 +44,7 @@ describe('createRouter', () => { signals: signalService as SignalsService, }); - app = express().use(router); + app = express().use(router).use(mockErrorHandler()); }); afterEach(() => { diff --git a/plugins/user-settings-backend/src/service/router.ts b/plugins/user-settings-backend/src/service/router.ts index 3efb7da0f9..eacc35a5ae 100644 --- a/plugins/user-settings-backend/src/service/router.ts +++ b/plugins/user-settings-backend/src/service/router.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { errorHandler } from '@backstage/backend-common'; import { AuthenticationError, InputError } from '@backstage/errors'; import { IdentityApi } from '@backstage/plugin-auth-node'; import express, { Request } from 'express'; @@ -156,7 +155,5 @@ export async function createRouterInternal( res.status(204).end(); }); - router.use(errorHandler()); - return router; } diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 71182f1289..7716030af1 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-user-settings +## 0.8.12-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/core-app-api@1.14.2 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-signals-react@0.0.5-next.0 + - @backstage/plugin-user-settings-common@0.0.1 + +## 0.8.12-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/core-compat-api@0.2.9-next.0 + - @backstage/plugin-catalog-react@1.12.4-next.0 + - @backstage/plugin-signals-react@0.0.5-next.0 + - @backstage/core-app-api@1.14.2 + - @backstage/core-components@0.14.10 + - @backstage/core-plugin-api@1.9.3 + - @backstage/errors@1.2.4 + - @backstage/theme@0.5.6 + - @backstage/types@1.1.1 + - @backstage/plugin-user-settings-common@0.0.1 + ## 0.8.11 ### Patch Changes diff --git a/plugins/user-settings/api-report-alpha.md b/plugins/user-settings/api-report-alpha.md index f14c014a1e..199dbba582 100644 --- a/plugins/user-settings/api-report-alpha.md +++ b/plugins/user-settings/api-report-alpha.md @@ -4,26 +4,29 @@ ```ts import { AnyRouteRefParams } from '@backstage/frontend-plugin-api'; -import { BackstagePlugin } from '@backstage/frontend-plugin-api'; import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionDefinition } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; +import { FrontendPlugin } from '@backstage/frontend-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; import { default as React_2 } from 'react'; import { RouteRef } from '@backstage/frontend-plugin-api'; import { TranslationRef } from '@backstage/core-plugin-api/alpha'; // @alpha (undocumented) -const _default: BackstagePlugin< +const _default: FrontendPlugin< { root: RouteRef; }, {}, { - 'nav-item:user-settings': ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef< + 'nav-item:user-settings': ExtensionDefinition<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent; @@ -31,39 +34,31 @@ const _default: BackstagePlugin< }, 'core.nav-item.target', {} - >, - {}, - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - } - >; - 'page:user-settings': ExtensionDefinition< - { - [x: string]: any; - } & { + >; + inputs: {}; + }>; + 'page:user-settings': ExtensionDefinition<{ + config: { path: string | undefined; - }, - { - [x: string]: any; - } & { + }; + configInput: { path?: string | undefined; - }, - | ConfigurableExtensionDataRef< - React_2.JSX.Element, - 'core.reactElement', - {} - > - | ConfigurableExtensionDataRef - | ConfigurableExtensionDataRef< - RouteRef, - 'core.routing.ref', - { - optional: true; - } - >, - { + }; + output: + | ConfigurableExtensionDataRef< + React_2.JSX.Element, + 'core.reactElement', + {} + > + | ConfigurableExtensionDataRef + | ConfigurableExtensionDataRef< + RouteRef, + 'core.routing.ref', + { + optional: true; + } + >; + inputs: { providerSettings: ExtensionInput< ConfigurableExtensionDataRef< React_2.JSX.Element, @@ -75,22 +70,23 @@ const _default: BackstagePlugin< optional: true; } >; - }, - { - kind: 'page'; - namespace: undefined; - name: undefined; - } - >; + }; + kind: 'page'; + namespace: undefined; + name: undefined; + }>; } >; export default _default; // @alpha (undocumented) -export const settingsNavItem: ExtensionDefinition< - {}, - {}, - ConfigurableExtensionDataRef< +export const settingsNavItem: ExtensionDefinition<{ + kind: 'nav-item'; + namespace: undefined; + name: undefined; + config: {}; + configInput: {}; + output: ConfigurableExtensionDataRef< { title: string; icon: IconComponent; @@ -98,14 +94,9 @@ export const settingsNavItem: ExtensionDefinition< }, 'core.nav-item.target', {} - >, - {}, - { - kind: 'nav-item'; - namespace: undefined; - name: undefined; - } ->; + >; + inputs: {}; +}>; // @alpha (undocumented) export const userSettingsTranslationRef: TranslationRef< diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 1e2972674d..404024730c 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-user-settings", - "version": "0.8.11", + "version": "0.8.12-next.1", "description": "A Backstage plugin that provides a settings page", "backstage": { "role": "frontend-plugin", diff --git a/scripts/create-release-tag.js b/scripts/create-release-tag.js index 311b46d4e5..a65018e1c0 100755 --- a/scripts/create-release-tag.js +++ b/scripts/create-release-tag.js @@ -59,8 +59,9 @@ async function createGitTag(octokit, commitSha, tagName) { } async function main() { - if (!process.env.GITHUB_SHA) { - throw new Error('GITHUB_SHA is not set'); + const commitSha = process.env.RELEASE_SHA ?? process.env.GITHUB_SHA; + if (!commitSha) { + throw new Error('RELEASE_SHA or GITHUB_SHA is not set'); } if (!process.env.GITHUB_TOKEN) { throw new Error('GITHUB_TOKEN is not set'); @@ -69,7 +70,6 @@ async function main() { throw new Error('GITHUB_OUTPUT environment variable not set'); } - const commitSha = process.env.GITHUB_SHA; const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN }); const releaseVersion = await getCurrentReleaseTag(); diff --git a/scripts/verify-local-dependencies.js b/scripts/verify-local-dependencies.js index 963bc40c9c..045abcff57 100755 --- a/scripts/verify-local-dependencies.js +++ b/scripts/verify-local-dependencies.js @@ -60,6 +60,9 @@ const roleRules = [ targetRole: 'frontend-plugin', except: [ // TODO(freben): Address these + '@backstage/frontend-defaults', + '@backstage/frontend-app-api', + '@backstage/frontend-test-utils', '@backstage/plugin-api-docs', '@backstage/plugin-techdocs-addons-test-utils', ], @@ -73,6 +76,7 @@ const roleRules = [ '@backstage/app-defaults', '@backstage/core-compat-api', '@backstage/dev-utils', + '@backstage/frontend-defaults', '@backstage/frontend-app-api', '@backstage/frontend-test-utils', '@backstage/test-utils', diff --git a/storybook/yarn.lock b/storybook/yarn.lock index ce259e11aa..0bb6696bae 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -2849,92 +2849,92 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-arm64@npm:1.5.29" +"@swc/core-darwin-arm64@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-darwin-arm64@npm:1.7.23" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-x64@npm:1.5.29" +"@swc/core-darwin-x64@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-darwin-x64@npm:1.7.23" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.29" +"@swc/core-linux-arm-gnueabihf@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.23" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-gnu@npm:1.5.29" +"@swc/core-linux-arm64-gnu@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-arm64-gnu@npm:1.7.23" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-musl@npm:1.5.29" +"@swc/core-linux-arm64-musl@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-arm64-musl@npm:1.7.23" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-gnu@npm:1.5.29" +"@swc/core-linux-x64-gnu@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-x64-gnu@npm:1.7.23" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-musl@npm:1.5.29" +"@swc/core-linux-x64-musl@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-x64-musl@npm:1.7.23" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-arm64-msvc@npm:1.5.29" +"@swc/core-win32-arm64-msvc@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-win32-arm64-msvc@npm:1.7.23" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-ia32-msvc@npm:1.5.29" +"@swc/core-win32-ia32-msvc@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-win32-ia32-msvc@npm:1.7.23" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-x64-msvc@npm:1.5.29" +"@swc/core-win32-x64-msvc@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-win32-x64-msvc@npm:1.7.23" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.5.29 - resolution: "@swc/core@npm:1.5.29" + version: 1.7.23 + resolution: "@swc/core@npm:1.7.23" dependencies: - "@swc/core-darwin-arm64": 1.5.29 - "@swc/core-darwin-x64": 1.5.29 - "@swc/core-linux-arm-gnueabihf": 1.5.29 - "@swc/core-linux-arm64-gnu": 1.5.29 - "@swc/core-linux-arm64-musl": 1.5.29 - "@swc/core-linux-x64-gnu": 1.5.29 - "@swc/core-linux-x64-musl": 1.5.29 - "@swc/core-win32-arm64-msvc": 1.5.29 - "@swc/core-win32-ia32-msvc": 1.5.29 - "@swc/core-win32-x64-msvc": 1.5.29 + "@swc/core-darwin-arm64": 1.7.23 + "@swc/core-darwin-x64": 1.7.23 + "@swc/core-linux-arm-gnueabihf": 1.7.23 + "@swc/core-linux-arm64-gnu": 1.7.23 + "@swc/core-linux-arm64-musl": 1.7.23 + "@swc/core-linux-x64-gnu": 1.7.23 + "@swc/core-linux-x64-musl": 1.7.23 + "@swc/core-win32-arm64-msvc": 1.7.23 + "@swc/core-win32-ia32-msvc": 1.7.23 + "@swc/core-win32-x64-msvc": 1.7.23 "@swc/counter": ^0.1.3 - "@swc/types": ^0.1.8 + "@swc/types": ^0.1.12 peerDependencies: "@swc/helpers": "*" dependenciesMeta: @@ -2961,7 +2961,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 19e3f8525ce4f4d9f6f3f62825b1f13e1e76146390930b6d5e663c0bb2c5e95ef3bf30268110d1444ea92b99dd95bfe5a3c6e2a3c0dd79291505dc7da1ed3dab + checksum: a21e9a67d305ad9b49b6def9f9698b374db6c15b2ded5e5cf29390221181fc6b91bfa317b53fd41d9cca989d85b79bbbca5ab27635df1e0232cad4681f618fa5 languageName: node linkType: hard @@ -2972,12 +2972,12 @@ __metadata: languageName: node linkType: hard -"@swc/types@npm:^0.1.8": - version: 0.1.8 - resolution: "@swc/types@npm:0.1.8" +"@swc/types@npm:^0.1.12": + version: 0.1.12 + resolution: "@swc/types@npm:0.1.12" dependencies: "@swc/counter": ^0.1.3 - checksum: e564d0e37b0e28546973c6d50c7a179395912a97168d695cfe9cf1051199c8b828680cdafcb8d43948f76d3703873bafb88dfb5bc2dfe0596b4ad18fcaf90c80 + checksum: cf7f89e46f859864075d7965582baea9c5f98830f45b1046251568c9bdf1ca484b1bf37f6d3c32b7c82ecf8cd5df89d22f05268c391819c44e49911bb1a8e71a languageName: node linkType: hard @@ -3020,33 +3020,6 @@ __metadata: languageName: node linkType: hard -"@types/eslint-scope@npm:^3.7.3": - version: 3.7.4 - resolution: "@types/eslint-scope@npm:3.7.4" - dependencies: - "@types/eslint": "*" - "@types/estree": "*" - checksum: ea6a9363e92f301cd3888194469f9ec9d0021fe0a397a97a6dd689e7545c75de0bd2153dfb13d3ab532853a278b6572c6f678ce846980669e41029d205653460 - languageName: node - linkType: hard - -"@types/eslint@npm:*": - version: 8.4.6 - resolution: "@types/eslint@npm:8.4.6" - dependencies: - "@types/estree": "*" - "@types/json-schema": "*" - checksum: bfaf27b00031b2238139003965475d023306119e467947f7a43a41e380918e365618e2ae6a6ae638697f6421a6bb1571db078695ff5e548f23618000b38acd23 - languageName: node - linkType: hard - -"@types/estree@npm:*, @types/estree@npm:^1.0.5": - version: 1.0.5 - resolution: "@types/estree@npm:1.0.5" - checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a - languageName: node - linkType: hard - "@types/estree@npm:^0.0.51": version: 0.0.51 resolution: "@types/estree@npm:0.0.51" @@ -3054,6 +3027,13 @@ __metadata: languageName: node linkType: hard +"@types/estree@npm:^1.0.5": + version: 1.0.5 + resolution: "@types/estree@npm:1.0.5" + checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a + languageName: node + linkType: hard + "@types/glob@npm:*, @types/glob@npm:^7.1.1": version: 7.2.0 resolution: "@types/glob@npm:7.2.0" @@ -3101,7 +3081,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8": +"@types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8": version: 7.0.11 resolution: "@types/json-schema@npm:7.0.11" checksum: 527bddfe62db9012fccd7627794bd4c71beb77601861055d87e3ee464f2217c85fca7a4b56ae677478367bbd248dbde13553312b7d4dbc702a2f2bbf60c4018d @@ -3441,12 +3421,12 @@ __metadata: languageName: node linkType: hard -"acorn-import-assertions@npm:^1.9.0": - version: 1.9.0 - resolution: "acorn-import-assertions@npm:1.9.0" +"acorn-import-attributes@npm:^1.9.5": + version: 1.9.5 + resolution: "acorn-import-attributes@npm:1.9.5" peerDependencies: acorn: ^8 - checksum: 944fb2659d0845c467066bdcda2e20c05abe3aaf11972116df457ce2627628a81764d800dd55031ba19de513ee0d43bb771bc679cc0eda66dc8b4fade143bc0c + checksum: 1c0c49b6a244503964ae46ae850baccf306e84caf99bc2010ed6103c69a423987b07b520a6c619f075d215388bd4923eccac995886a54309eda049ab78a4be95 languageName: node linkType: hard @@ -5366,13 +5346,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.16.0": - version: 5.16.0 - resolution: "enhanced-resolve@npm:5.16.0" +"enhanced-resolve@npm:^5.17.1": + version: 5.17.1 + resolution: "enhanced-resolve@npm:5.17.1" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: ccfd01850ecf2aa51e8554d539973319ff7d8a539ef1e0ba3460a0ccad6223c4ef6e19165ee64161b459cd8a48df10f52af4434c60023c65fde6afa32d475f7e + checksum: 4bc38cf1cea96456f97503db7280394177d1bc46f8f87c267297d04f795ac5efa81e48115a2f5b6273c781027b5b6bfc5f62b54df629e4d25fa7001a86624f59 languageName: node linkType: hard @@ -11788,19 +11768,18 @@ __metadata: linkType: hard "webpack@npm:^5.73.0": - version: 5.91.0 - resolution: "webpack@npm:5.91.0" + version: 5.94.0 + resolution: "webpack@npm:5.94.0" dependencies: - "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.5 "@webassemblyjs/ast": ^1.12.1 "@webassemblyjs/wasm-edit": ^1.12.1 "@webassemblyjs/wasm-parser": ^1.12.1 acorn: ^8.7.1 - acorn-import-assertions: ^1.9.0 + acorn-import-attributes: ^1.9.5 browserslist: ^4.21.10 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.16.0 + enhanced-resolve: ^5.17.1 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 @@ -11820,7 +11799,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: f1073715dbb1ed5c070affef293d800a867708bcbc5aba4d8baee87660e0cf53c55966a6f36fab078d1d6c9567cdcd0a9086bdfb607cab87ea68c6449791b9a3 + checksum: 6a3d667be304a69cd6dcb8d676bc29f47642c0d389af514cfcd646eaaa809961bc6989fc4b2621a717dfc461130f29c6e20006d62a32e012dafaa9517813a4e6 languageName: node linkType: hard diff --git a/tsconfig.json b/tsconfig.json index 789743363d..8d72a3315b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,9 @@ "extends": "@backstage/cli/config/tsconfig.json", "include": [ "packages/*/src", + "packages/*/config.d.ts", "plugins/*/src", + "plugins/*/config.d.ts", "plugins/*/dev", "plugins/*/migrations" ], diff --git a/yarn.lock b/yarn.lock index 7218090260..c6e425a2ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,10 +12,10 @@ __metadata: languageName: node linkType: hard -"@adobe/css-tools@npm:^4.3.2": - version: 4.3.2 - resolution: "@adobe/css-tools@npm:4.3.2" - checksum: 9667d61d55dc3b0a315c530ae84e016ce5267c4dd8ac00abb40108dc98e07b98e3090ce8b87acd51a41a68d9e84dcccb08cdf21c902572a9cf9dcaf830da4ae3 +"@adobe/css-tools@npm:^4.4.0": + version: 4.4.0 + resolution: "@adobe/css-tools@npm:4.4.0" + checksum: 1f08fb49bf17fc7f2d1a86d3e739f29ca80063d28168307f1b0a962ef37501c5667271f6771966578897f2e94e43c4770fd802728a6e6495b812da54112d506a languageName: node linkType: hard @@ -203,7 +203,18 @@ __metadata: languageName: node linkType: hard -"@apidevtools/json-schema-ref-parser@npm:^9.0.6, @apidevtools/json-schema-ref-parser@npm:^9.1.2": +"@apidevtools/json-schema-ref-parser@npm:^11.7.0": + version: 11.7.0 + resolution: "@apidevtools/json-schema-ref-parser@npm:11.7.0" + dependencies: + "@jsdevtools/ono": ^7.1.3 + "@types/json-schema": ^7.0.15 + js-yaml: ^4.1.0 + checksum: ee1c9e7c1bbf0b8d935522f9407c382e20a54464414fa65326fa8f56239e5a6f2b911f48c65fe2888a94d3445dced46ba36c286da435d47cefc8699d4a5b0ae2 + languageName: node + linkType: hard + +"@apidevtools/json-schema-ref-parser@npm:^9.0.6": version: 9.1.2 resolution: "@apidevtools/json-schema-ref-parser@npm:9.1.2" dependencies: @@ -489,144 +500,144 @@ __metadata: linkType: hard "@aws-sdk/client-codecommit@npm:^3.350.0": - version: 3.621.0 - resolution: "@aws-sdk/client-codecommit@npm:3.621.0" + version: 3.645.0 + resolution: "@aws-sdk/client-codecommit@npm:3.645.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.621.0 - "@aws-sdk/client-sts": 3.621.0 - "@aws-sdk/core": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/client-sso-oidc": 3.645.0 + "@aws-sdk/client-sts": 3.645.0 + "@aws-sdk/core": 3.635.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/middleware-host-header": 3.620.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-node": ^3.0.3 "@smithy/invalid-dependency": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: be8a5ebbe178f7d81c44a34f7e1ee54b8f7d3912c92de570855be4612cf60a02444957373eb9d9abfbf606f9998fc34acf020a2fb1d7be1e0e77be6c30388408 + checksum: 237f37d78618a3e385e1f48b37f99ea35394b009a6d7703c20cf4e9c39dc8905b0fb2e19137c284f6ed5790d4910d19af37e89351f128d24d0779f6cc20f0a2d languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.621.0" +"@aws-sdk/client-cognito-identity@npm:3.645.0": + version: 3.645.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.645.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.621.0 - "@aws-sdk/client-sts": 3.621.0 - "@aws-sdk/core": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/client-sso-oidc": 3.645.0 + "@aws-sdk/client-sts": 3.645.0 + "@aws-sdk/core": 3.635.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/middleware-host-header": 3.620.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-node": ^3.0.3 "@smithy/invalid-dependency": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 227fb03620396c3d5f9ca36fd463fc2e3e2e04909f5dea59b90e25a89d110d3a869e89e870237b808b494156bba06fb966406d2dc192a8ad6a072b7abdd4d81c + checksum: 77270145fd39384181933815b94f52d97ea7c9dccdaa02d74cf59783d27a308798de5ffab8a34149f9b731dfaebe737073394b53b15181d5c75d3538b1ced532 languageName: node linkType: hard "@aws-sdk/client-eks@npm:^3.350.0": - version: 3.621.0 - resolution: "@aws-sdk/client-eks@npm:3.621.0" + version: 3.645.0 + resolution: "@aws-sdk/client-eks@npm:3.645.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.621.0 - "@aws-sdk/client-sts": 3.621.0 - "@aws-sdk/core": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/client-sso-oidc": 3.645.0 + "@aws-sdk/client-sts": 3.645.0 + "@aws-sdk/core": 3.635.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/middleware-host-header": 3.620.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-node": ^3.0.3 "@smithy/invalid-dependency": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 @@ -634,70 +645,70 @@ __metadata: "@smithy/util-waiter": ^3.1.2 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: a69d67d1d6c447e541baebc06f2e5e4ac6532933422a0af2850c916075986c555d1e3ba9f397c1c35e95efd770642b5985d6f2c73d38cd566c4425fecc0dc2fa + checksum: 77b4841984ce3fc500660095e04392ea333e7b79785f793af3916f51cd74c4775a5ea8bfaf596a30a6b6f812892967e69e5087431d1c59926c579869218b600a languageName: node linkType: hard "@aws-sdk/client-organizations@npm:^3.350.0": - version: 3.621.0 - resolution: "@aws-sdk/client-organizations@npm:3.621.0" + version: 3.645.0 + resolution: "@aws-sdk/client-organizations@npm:3.645.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.621.0 - "@aws-sdk/client-sts": 3.621.0 - "@aws-sdk/core": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/client-sso-oidc": 3.645.0 + "@aws-sdk/client-sts": 3.645.0 + "@aws-sdk/core": 3.635.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/middleware-host-header": 3.620.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-node": ^3.0.3 "@smithy/invalid-dependency": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 28db7d0490cc93a512cc2299afa67ce01d60f2f07ec4a59f9e826c86ef0769164ac103128c0c8617ea86f0a4d2a7be2468803aace84e054e1db7a00c871f7783 + checksum: 93be30563c9c6dbf885e9e571ad8de84a09e2d29d9491936e8519265a3cfcf06e56a16a24fce4bec6209d0bc654880d42f03a2003845dba8e0b2cfc9c34ff9b3 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.350.0": - version: 3.621.0 - resolution: "@aws-sdk/client-s3@npm:3.621.0" + version: 3.645.0 + resolution: "@aws-sdk/client-s3@npm:3.645.0" dependencies: "@aws-crypto/sha1-browser": 5.2.0 "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.621.0 - "@aws-sdk/client-sts": 3.621.0 - "@aws-sdk/core": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/client-sso-oidc": 3.645.0 + "@aws-sdk/client-sts": 3.645.0 + "@aws-sdk/core": 3.635.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/middleware-bucket-endpoint": 3.620.0 "@aws-sdk/middleware-expect-continue": 3.620.0 "@aws-sdk/middleware-flexible-checksums": 3.620.0 @@ -705,22 +716,21 @@ __metadata: "@aws-sdk/middleware-location-constraint": 3.609.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-sdk-s3": 3.621.0 - "@aws-sdk/middleware-signing": 3.620.0 + "@aws-sdk/middleware-sdk-s3": 3.635.0 "@aws-sdk/middleware-ssec": 3.609.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 - "@aws-sdk/signature-v4-multi-region": 3.621.0 + "@aws-sdk/signature-v4-multi-region": 3.635.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@aws-sdk/xml-builder": 3.609.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 - "@smithy/eventstream-serde-browser": ^3.0.5 + "@smithy/core": ^2.4.0 + "@smithy/eventstream-serde-browser": ^3.0.6 "@smithy/eventstream-serde-config-resolver": ^3.0.3 - "@smithy/eventstream-serde-node": ^3.0.4 + "@smithy/eventstream-serde-node": ^3.0.5 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-blob-browser": ^3.1.2 "@smithy/hash-node": ^3.0.3 @@ -729,301 +739,303 @@ __metadata: "@smithy/md5-js": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 + "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 "@smithy/util-stream": ^3.1.3 "@smithy/util-utf8": ^3.0.0 "@smithy/util-waiter": ^3.1.2 tslib: ^2.6.2 - checksum: 120bfaa142a61a8dbc2f82d6fe5e36cb2ec0acdb12390795d15326dfad4f67b0d2e95515afb04da34b3f686fef0368f7a79a20c85735b28df654cbc5bdb1f04c + checksum: 9088ffbd8d95666d6830c8b3d155641c137fc008e4ab11ecae0b13db17da27d20e531cff47f5968f7892d8f10b3794059b23f64a743a1b975aea444c1ea29c1c languageName: node linkType: hard "@aws-sdk/client-ses@npm:^3.550.0": - version: 3.621.0 - resolution: "@aws-sdk/client-ses@npm:3.621.0" + version: 3.645.0 + resolution: "@aws-sdk/client-ses@npm:3.645.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.621.0 - "@aws-sdk/client-sts": 3.621.0 - "@aws-sdk/core": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/client-sso-oidc": 3.645.0 + "@aws-sdk/client-sts": 3.645.0 + "@aws-sdk/core": 3.635.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/middleware-host-header": 3.620.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-node": ^3.0.3 "@smithy/invalid-dependency": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 "@smithy/util-waiter": ^3.1.2 tslib: ^2.6.2 - checksum: 40de6b66fc6ac93eae26906cfb77b9a9d4bfd1a990e68f5bdc1a7024a624397e470149c1054e904c181b87b09e1a9d1ec4308dc206ffdfa5740113c0a199b5eb + checksum: 22719e939f0f8b84a867e08ca823c13f43e2ac25da78fd51133b62acc5b305a6f651a76b3363b2bbeed9e4e6f2f9cde7596e58ebc8df72a3ec9a8918ce96746c languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.350.0": - version: 3.621.0 - resolution: "@aws-sdk/client-sqs@npm:3.621.0" + version: 3.645.0 + resolution: "@aws-sdk/client-sqs@npm:3.645.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.621.0 - "@aws-sdk/client-sts": 3.621.0 - "@aws-sdk/core": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/client-sso-oidc": 3.645.0 + "@aws-sdk/client-sts": 3.645.0 + "@aws-sdk/core": 3.635.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/middleware-host-header": 3.620.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-sdk-sqs": 3.621.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-sdk-sqs": 3.635.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-node": ^3.0.3 "@smithy/invalid-dependency": ^3.0.3 "@smithy/md5-js": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 293d3164570623e6228fc9e14c803b20e7ca5e562ce470f6f8ee3adf2b9a4cffd886ab69859d60afa1cf46f2df8cd9e0190a081335c1c2be21fee0739f21ce9f + checksum: 6e2e0b07dce77cfd3eace0bb0a088c014f36cf645f09aa9b478fd1aa98ad70ade7b6f1db69a78bb52678a92b3db930a57f8446d61f8e5b0457b48de6b8a14b24 languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.621.0" +"@aws-sdk/client-sso-oidc@npm:3.645.0": + version: 3.645.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.645.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/core": 3.635.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/middleware-host-header": 3.620.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-node": ^3.0.3 "@smithy/invalid-dependency": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-sts": ^3.621.0 - checksum: 12aa50a56f2498a9202b877b0b789fa95c038707b648dc3c9e93976c209ed3d4518868279707ee8fe12f42858eba7181098bdbf68556341c9017bd5e31f89135 + "@aws-sdk/client-sts": ^3.645.0 + checksum: 00e1b0bba75365fbd0ea5752111e97960701553e0402bf4fc4eba3849fdc121801edd16792cd38b8cd4bdb38f3ee41dc64ecf9d6654f7f9864c4120178afb094 languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/client-sso@npm:3.621.0" +"@aws-sdk/client-sso@npm:3.645.0": + version: 3.645.0 + resolution: "@aws-sdk/client-sso@npm:3.645.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/core": 3.621.0 + "@aws-sdk/core": 3.635.0 "@aws-sdk/middleware-host-header": 3.620.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-node": ^3.0.3 "@smithy/invalid-dependency": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: fe72875685c07b9cf42b7fcde06502d42a5398161b37de87c5360f10a0d28cf7b32fc95f5eecdf782cff04c8109bd7a20d9644bfacc78e3521b6a7670ed76b40 + checksum: c27e82109dbe89f6d7dfb1e1a670ebadc687cc9536298618e75cdc2ef431c4698ceba2331ae660d1bc1aca213e4ca9246621645d87e88cb518ac681aa19de341 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.621.0, @aws-sdk/client-sts@npm:^3.350.0": - version: 3.621.0 - resolution: "@aws-sdk/client-sts@npm:3.621.0" +"@aws-sdk/client-sts@npm:3.645.0, @aws-sdk/client-sts@npm:^3.350.0": + version: 3.645.0 + resolution: "@aws-sdk/client-sts@npm:3.645.0" dependencies: "@aws-crypto/sha256-browser": 5.2.0 "@aws-crypto/sha256-js": 5.2.0 - "@aws-sdk/client-sso-oidc": 3.621.0 - "@aws-sdk/core": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/client-sso-oidc": 3.645.0 + "@aws-sdk/core": 3.635.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/middleware-host-header": 3.620.0 "@aws-sdk/middleware-logger": 3.609.0 "@aws-sdk/middleware-recursion-detection": 3.620.0 - "@aws-sdk/middleware-user-agent": 3.620.0 + "@aws-sdk/middleware-user-agent": 3.645.0 "@aws-sdk/region-config-resolver": 3.614.0 "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@aws-sdk/util-user-agent-browser": 3.609.0 "@aws-sdk/util-user-agent-node": 3.614.0 "@smithy/config-resolver": ^3.0.5 - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/hash-node": ^3.0.3 "@smithy/invalid-dependency": ^3.0.3 "@smithy/middleware-content-length": ^3.0.5 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/middleware-stack": ^3.0.3 "@smithy/node-config-provider": ^3.1.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/url-parser": ^3.0.3 "@smithy/util-base64": ^3.0.0 "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-body-length-node": ^3.0.0 - "@smithy/util-defaults-mode-browser": ^3.0.13 - "@smithy/util-defaults-mode-node": ^3.0.13 + "@smithy/util-defaults-mode-browser": ^3.0.15 + "@smithy/util-defaults-mode-node": ^3.0.15 "@smithy/util-endpoints": ^2.0.5 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 35f543e1c4b419dc598489b4ce4dfbce22ad726ffe8f807876de13c0e8b5db10684835f7b95841e988d4f16aeb921935133e5775d35b47186c18cced6715a82a + checksum: af36231a2fcda67323ec3611630643f8005b04f0c2f326a181e7000a813d010dba7c2d541adfbea0798d7c337ea70b5a57a2b61ce77bb4ece6dd7b01879174ed languageName: node linkType: hard -"@aws-sdk/core@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/core@npm:3.621.0" +"@aws-sdk/core@npm:3.635.0": + version: 3.635.0 + resolution: "@aws-sdk/core@npm:3.635.0" dependencies: - "@smithy/core": ^2.3.1 + "@smithy/core": ^2.4.0 "@smithy/node-config-provider": ^3.1.4 + "@smithy/property-provider": ^3.1.3 "@smithy/protocol-http": ^4.1.0 "@smithy/signature-v4": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/util-middleware": ^3.0.3 fast-xml-parser: 4.4.1 tslib: ^2.6.2 - checksum: 789409227f2aa0f3c735e0f1bebf1d900b359e589bad50324e2fbec20ddb30435e1dcf9132501dad7aaf793829530980d1670257208c5e407c78be5f831e796d + checksum: 580fd8416a9f569b4923d3ad4031eb2cd12bd0f76cd38aaf6e3e5f735bcd01d26fc27d1560a92d123b7e3e0af7b21311fafa68d24b75cd959f4d3af53a0020e0 languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.621.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.645.0": + version: 3.645.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.645.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.621.0 + "@aws-sdk/client-cognito-identity": 3.645.0 "@aws-sdk/types": 3.609.0 "@smithy/property-provider": ^3.1.3 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: e8a913d61ac4e772e07cd1a6144ef8680e630894c2192aed81d06f36fb9607c4de3b95386155d52f050b99d8b4d78ceb69eb7fa0987d339631765cc1dc8c9588 + checksum: 5a70bab9d26aa95ba8f95e201bf237f0fe51b4776e499cadfcbda90bdb26be77b22252d1e1d2317cd1137fc21dfad5a08502307371ab21b7dd6b1515f761754b languageName: node linkType: hard @@ -1039,31 +1051,31 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.621.0" +"@aws-sdk/credential-provider-http@npm:3.635.0": + version: 3.635.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.635.0" dependencies: "@aws-sdk/types": 3.609.0 "@smithy/fetch-http-handler": ^3.2.4 "@smithy/node-http-handler": ^3.1.4 "@smithy/property-provider": ^3.1.3 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/util-stream": ^3.1.3 tslib: ^2.6.2 - checksum: bc45dfe7d0a6868978d71fa73731784af1839f822c09ef13b5a08ad74fa57c008dd874dd1765317df61ab022f9470bf509df38a70dd0aa5262d1d2234cc5eda2 + checksum: 7b5b35da0ec78b0bb4b697edba8bd713aeee90b651f201313197daf9e6349b9332d03954dfd7c4bfbfa140c4f0bf90c13ae262ed180ce209f0de3b17a954dbca languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.621.0" +"@aws-sdk/credential-provider-ini@npm:3.645.0": + version: 3.645.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.645.0" dependencies: "@aws-sdk/credential-provider-env": 3.620.1 - "@aws-sdk/credential-provider-http": 3.621.0 + "@aws-sdk/credential-provider-http": 3.635.0 "@aws-sdk/credential-provider-process": 3.620.1 - "@aws-sdk/credential-provider-sso": 3.621.0 + "@aws-sdk/credential-provider-sso": 3.645.0 "@aws-sdk/credential-provider-web-identity": 3.621.0 "@aws-sdk/types": 3.609.0 "@smithy/credential-provider-imds": ^3.2.0 @@ -1072,20 +1084,20 @@ __metadata: "@smithy/types": ^3.3.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-sts": ^3.621.0 - checksum: a3db43adfbdb2ea1d6d80b1ca6789e48b729fce2499039f99721f504322cba325e4b48ed842bd26ae6f49ca771e5817016b75cda31cf247fd3e2bd0ac235b332 + "@aws-sdk/client-sts": ^3.645.0 + checksum: ef0cae8931a38eebab6009f8cfb4a42313cb277670f0b06e3d5b1a2526089fa6cc50ad50b78c79c8fbbf132010fffa67622963fe5fe04a73401f84faa146495f languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.621.0, @aws-sdk/credential-provider-node@npm:^3.350.0": - version: 3.621.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.621.0" +"@aws-sdk/credential-provider-node@npm:3.645.0, @aws-sdk/credential-provider-node@npm:^3.350.0": + version: 3.645.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.645.0" dependencies: "@aws-sdk/credential-provider-env": 3.620.1 - "@aws-sdk/credential-provider-http": 3.621.0 - "@aws-sdk/credential-provider-ini": 3.621.0 + "@aws-sdk/credential-provider-http": 3.635.0 + "@aws-sdk/credential-provider-ini": 3.645.0 "@aws-sdk/credential-provider-process": 3.620.1 - "@aws-sdk/credential-provider-sso": 3.621.0 + "@aws-sdk/credential-provider-sso": 3.645.0 "@aws-sdk/credential-provider-web-identity": 3.621.0 "@aws-sdk/types": 3.609.0 "@smithy/credential-provider-imds": ^3.2.0 @@ -1093,7 +1105,7 @@ __metadata: "@smithy/shared-ini-file-loader": ^3.1.4 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: aada1f0624caee0e00b9ba287e66120031c8f5095acbcd80723b2ab6b5e4bffcd662665fffe62b7f2091bfb89d33ea13212a82893318005699914f13fbed70c3 + checksum: f8ccaacbee4b7ed3a635bba85cbba764e7ea8c46e45d1e6cb2df3c8d3f97d4f093e65c501487aefd8c89ea5d32560ee4a9265947b8a3dba38f0374897a37d410 languageName: node linkType: hard @@ -1110,18 +1122,18 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.621.0" +"@aws-sdk/credential-provider-sso@npm:3.645.0": + version: 3.645.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.645.0" dependencies: - "@aws-sdk/client-sso": 3.621.0 + "@aws-sdk/client-sso": 3.645.0 "@aws-sdk/token-providers": 3.614.0 "@aws-sdk/types": 3.609.0 "@smithy/property-provider": ^3.1.3 "@smithy/shared-ini-file-loader": ^3.1.4 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 4602308a0bf74bda9dd7b92caf02868b855935deb703a8894d052c81864ef9c9359408ec84569f71527c1b204577940ebe1a9f6cbba8de677471eb590d91c3ba + checksum: 26a119c106d58bc7cb6cfc273f5f8eca9f2399ec462556516947bd12e1502e6c98d29032d2e9e18b72bee57f0dc82f56c141ebe419e6f30b668097d4c44bef6e languageName: node linkType: hard @@ -1140,26 +1152,26 @@ __metadata: linkType: hard "@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.621.0 - resolution: "@aws-sdk/credential-providers@npm:3.621.0" + version: 3.645.0 + resolution: "@aws-sdk/credential-providers@npm:3.645.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.621.0 - "@aws-sdk/client-sso": 3.621.0 - "@aws-sdk/client-sts": 3.621.0 - "@aws-sdk/credential-provider-cognito-identity": 3.621.0 + "@aws-sdk/client-cognito-identity": 3.645.0 + "@aws-sdk/client-sso": 3.645.0 + "@aws-sdk/client-sts": 3.645.0 + "@aws-sdk/credential-provider-cognito-identity": 3.645.0 "@aws-sdk/credential-provider-env": 3.620.1 - "@aws-sdk/credential-provider-http": 3.621.0 - "@aws-sdk/credential-provider-ini": 3.621.0 - "@aws-sdk/credential-provider-node": 3.621.0 + "@aws-sdk/credential-provider-http": 3.635.0 + "@aws-sdk/credential-provider-ini": 3.645.0 + "@aws-sdk/credential-provider-node": 3.645.0 "@aws-sdk/credential-provider-process": 3.620.1 - "@aws-sdk/credential-provider-sso": 3.621.0 + "@aws-sdk/credential-provider-sso": 3.645.0 "@aws-sdk/credential-provider-web-identity": 3.621.0 "@aws-sdk/types": 3.609.0 "@smithy/credential-provider-imds": ^3.2.0 "@smithy/property-provider": ^3.1.3 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 152a8911ca52a0663e4552e720f73bef2d93088d7b9fc58da88cf2aac91ebc3b720ea8abc5d28228d1658888903bd737dbba88e7d5cc97e2a2c7fdc0e5243c6f + checksum: 5f48a6cad85f05f92feb1112aad9915b294ef18b0cb30c2dc201cd6172d265f0365656f644a327cd1d909ead9869c98e401fb943877e178fd9553ce24d484720 languageName: node linkType: hard @@ -1185,19 +1197,19 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.350.0": - version: 3.621.0 - resolution: "@aws-sdk/lib-storage@npm:3.621.0" + version: 3.645.0 + resolution: "@aws-sdk/lib-storage@npm:3.645.0" dependencies: "@smithy/abort-controller": ^3.1.1 "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 tslib: ^2.6.2 peerDependencies: - "@aws-sdk/client-s3": ^3.621.0 - checksum: 6c84a1601bcbea53aabad52c2453afd3c577e3935eda4bb13a7d9d4b1405289a3f2f4747327fc30c5eeaf482a9a78d56dfb4453c4c892f876f491e677d0f6c95 + "@aws-sdk/client-s3": ^3.645.0 + checksum: 26badfa298a20044f9d78e01cd678e5d068a8e1ed8f80d9e5ce84192f8f966af795ca20c4e8b46385f17ffa11146878feef404e41eb712ac384d228011fbab3d languageName: node linkType: hard @@ -1303,36 +1315,39 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.621.0" +"@aws-sdk/middleware-sdk-s3@npm:3.635.0": + version: 3.635.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.635.0" dependencies: + "@aws-sdk/core": 3.635.0 "@aws-sdk/types": 3.609.0 "@aws-sdk/util-arn-parser": 3.568.0 + "@smithy/core": ^2.4.0 "@smithy/node-config-provider": ^3.1.4 "@smithy/protocol-http": ^4.1.0 "@smithy/signature-v4": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/util-config-provider": ^3.0.0 + "@smithy/util-middleware": ^3.0.3 "@smithy/util-stream": ^3.1.3 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: 2db38ad1575e9209f053474ff69731d0c0910304fc14dcdf22a09c06a849cbada0b18f36879d96e3020c0e050f80b02e47c45137da561a3f243cc080f6df4f3a + checksum: c892374e0d9f64e9c0387efff645df1b50c7fb4bdca9aea0fd61696fd6b6e7f2e275d523939c0d2eda1db4c7ef81b7ec930376a8ec3cf96d2aa3e5838bca2d41 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.621.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.635.0": + version: 3.635.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.635.0" dependencies: "@aws-sdk/types": 3.609.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/util-hex-encoding": ^3.0.0 "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: d0cad52b1ffbfc6078fd62865bb88b4ac3b3a06d883ad5ef0a419dfaefe11d33314892f862150801d57e8c277e3a1465f8e798a1176c1ad6090765faf325c1d0 + checksum: 5ef3130983332fc3d7362f253091a6558bbee0b2300188fcf0d795c2ce2e064fa7425cc55bc500bd4f557f4666ae0b28578cc46791641f2e5cb8d8e04cca70b8 languageName: node linkType: hard @@ -1346,21 +1361,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.620.0": - version: 3.620.0 - resolution: "@aws-sdk/middleware-signing@npm:3.620.0" - dependencies: - "@aws-sdk/types": 3.609.0 - "@smithy/property-provider": ^3.1.3 - "@smithy/protocol-http": ^4.1.0 - "@smithy/signature-v4": ^4.1.0 - "@smithy/types": ^3.3.0 - "@smithy/util-middleware": ^3.0.3 - tslib: ^2.6.2 - checksum: ef2365b282ccfe8dc29983b620ca6cd5f2e41f5f8d12b84d2e3cb73866535ba3f7383579e561ec5a3c422d3fefdfbb2f3461ae7806a9f87e4fe92fd10a929386 - languageName: node - linkType: hard - "@aws-sdk/middleware-ssec@npm:3.609.0": version: 3.609.0 resolution: "@aws-sdk/middleware-ssec@npm:3.609.0" @@ -1372,16 +1372,16 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.620.0": - version: 3.620.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.620.0" +"@aws-sdk/middleware-user-agent@npm:3.645.0": + version: 3.645.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.645.0" dependencies: "@aws-sdk/types": 3.609.0 - "@aws-sdk/util-endpoints": 3.614.0 + "@aws-sdk/util-endpoints": 3.645.0 "@smithy/protocol-http": ^4.1.0 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 137a969b5c17ebf172aa1f5a393812c443425dd9833fdf786a3039af5b3197e7d17139659891858b268ff723d9f2c5fbc840e8ac6a7af4b1cb566a3d54746a51 + checksum: 7b0ba381c01625c0448370d5181fd322132e913d0844f6eab2fd846b394d3033a2f3f758c26ad4d8c6846cbcd0618f7ec9b9470941094d347c2c60b04f1cab66 languageName: node linkType: hard @@ -1443,17 +1443,17 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.621.0": - version: 3.621.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.621.0" +"@aws-sdk/signature-v4-multi-region@npm:3.635.0": + version: 3.635.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.635.0" dependencies: - "@aws-sdk/middleware-sdk-s3": 3.621.0 + "@aws-sdk/middleware-sdk-s3": 3.635.0 "@aws-sdk/types": 3.609.0 "@smithy/protocol-http": ^4.1.0 "@smithy/signature-v4": ^4.1.0 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 741c07e65341da4c807d55b0bc6f1ec0064190c6fceb7571b0796f6ec94cc156a6214c0f308a93ad364884adae48502d248d30bd0ef43e7a4542586f264982c4 + checksum: c2f5c9e6be2f1ea9abbcb7d767d6cf2035ef1e4785ef4399180d6eb3663c2653109cabc9079f40e47067eedaa61a30b7e8b94e55659654280fea5976e1788aea languageName: node linkType: hard @@ -1538,15 +1538,15 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.614.0": - version: 3.614.0 - resolution: "@aws-sdk/util-endpoints@npm:3.614.0" +"@aws-sdk/util-endpoints@npm:3.645.0": + version: 3.645.0 + resolution: "@aws-sdk/util-endpoints@npm:3.645.0" dependencies: "@aws-sdk/types": 3.609.0 "@smithy/types": ^3.3.0 "@smithy/util-endpoints": ^2.0.5 tslib: ^2.6.2 - checksum: 9d9973ceee59bf30af85c7f4328083daea033a987ec396dcb89eb7649f470ceb19c6b96635e121f3557e726f7ec7453236c956cf43f22128883c277f17d2a13f + checksum: 3f2cda6f58d713c57f6add3073e32307e243a5554133b693ad3a83a1b1802d40a6a21778658f2001bf252567dd5d2089251e4745ee89b51b7896643bd93fbca8 languageName: node linkType: hard @@ -1748,12 +1748,12 @@ __metadata: languageName: node linkType: hard -"@azure/core-tracing@npm:^1.0.0, @azure/core-tracing@npm:^1.0.1": - version: 1.0.1 - resolution: "@azure/core-tracing@npm:1.0.1" +"@azure/core-tracing@npm:^1.0.0, @azure/core-tracing@npm:^1.0.1, @azure/core-tracing@npm:^1.1.2": + version: 1.1.2 + resolution: "@azure/core-tracing@npm:1.1.2" dependencies: - tslib: ^2.2.0 - checksum: ae4309f8ab0b52c37f699594d58ee095782649f538bd6a0ee03e3fea042f55df7ad95c2e6dec22f5b8c3907e4bcf98d6ca98faaf480d446b73d41bbc1519d891 + tslib: ^2.6.2 + checksum: dc4133115051460748e281c80fdf90a6052350e558716f1afef4b3f8973c4fdd93538ba99c58613b390e9013d0c738108a0155e1903bbbdd8f7910a7a3be1c21 languageName: node linkType: hard @@ -1843,8 +1843,8 @@ __metadata: linkType: hard "@azure/storage-blob@npm:^12.5.0": - version: 12.23.0 - resolution: "@azure/storage-blob@npm:12.23.0" + version: 12.24.0 + resolution: "@azure/storage-blob@npm:12.24.0" dependencies: "@azure/abort-controller": ^1.0.0 "@azure/core-auth": ^1.4.0 @@ -1853,13 +1853,13 @@ __metadata: "@azure/core-lro": ^2.2.0 "@azure/core-paging": ^1.1.1 "@azure/core-rest-pipeline": ^1.10.1 - "@azure/core-tracing": ^1.0.0 + "@azure/core-tracing": ^1.1.2 "@azure/core-util": ^1.6.1 "@azure/core-xml": ^1.3.2 "@azure/logger": ^1.0.0 events: ^3.0.0 tslib: ^2.2.0 - checksum: 7f09b4bfae0d73f7cf8f383038edeaf8bc8610960bc24a9b8c140f4084bb3afd62971fb56e2ff5e013168165dcfff7b9a545f6cc837fe2669618184e4b77c107 + checksum: 2ffe51b991f8ed6dd0003b22b9507956c215b06284645fda161d2c2147f368a6ba899e4e2f74e49033dc92f719275301b64e836386ba878b31a7183b1208ea5d languageName: node linkType: hard @@ -1882,54 +1882,54 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/compat-data@npm:7.24.7" - checksum: 1fc276825dd434fe044877367dfac84171328e75a8483a6976aa28bf833b32367e90ee6df25bdd97c287d1aa8019757adcccac9153de70b1932c0d243a978ae9 +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.25.2": + version: 7.25.4 + resolution: "@babel/compat-data@npm:7.25.4" + checksum: b12a91d27c3731a4b0bdc9312a50b1911f41f7f728aaf0d4b32486e2257fd2cb2d3ea1a295e98449600c48f2c7883a3196ca77cda1cef7d97a10c2e83d037974 languageName: node linkType: hard -"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.19.6, @babel/core@npm:^7.23.0, @babel/core@npm:^7.24.5": - version: 7.24.7 - resolution: "@babel/core@npm:7.24.7" +"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.19.6, @babel/core@npm:^7.24.7": + version: 7.25.2 + resolution: "@babel/core@npm:7.25.2" dependencies: "@ampproject/remapping": ^2.2.0 "@babel/code-frame": ^7.24.7 - "@babel/generator": ^7.24.7 - "@babel/helper-compilation-targets": ^7.24.7 - "@babel/helper-module-transforms": ^7.24.7 - "@babel/helpers": ^7.24.7 - "@babel/parser": ^7.24.7 - "@babel/template": ^7.24.7 - "@babel/traverse": ^7.24.7 - "@babel/types": ^7.24.7 + "@babel/generator": ^7.25.0 + "@babel/helper-compilation-targets": ^7.25.2 + "@babel/helper-module-transforms": ^7.25.2 + "@babel/helpers": ^7.25.0 + "@babel/parser": ^7.25.0 + "@babel/template": ^7.25.0 + "@babel/traverse": ^7.25.2 + "@babel/types": ^7.25.2 convert-source-map: ^2.0.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.3 semver: ^6.3.1 - checksum: 017497e2a1b4683a885219eef7d2aee83c1c0cf353506b2e180b73540ec28841d8ef1ea1837fa69f8c561574b24ddd72f04764b27b87afedfe0a07299ccef24d + checksum: 9a1ef604a7eb62195f70f9370cec45472a08114e3934e3eaaedee8fd754edf0730e62347c7b4b5e67d743ce57b5bb8cf3b92459482ca94d06e06246ef021390a languageName: node linkType: hard -"@babel/generator@npm:^7.24.7, @babel/generator@npm:^7.7.2": - version: 7.24.7 - resolution: "@babel/generator@npm:7.24.7" +"@babel/generator@npm:^7.25.0, @babel/generator@npm:^7.25.4, @babel/generator@npm:^7.7.2": + version: 7.25.5 + resolution: "@babel/generator@npm:7.25.5" dependencies: - "@babel/types": ^7.24.7 + "@babel/types": ^7.25.4 "@jridgewell/gen-mapping": ^0.3.5 "@jridgewell/trace-mapping": ^0.3.25 jsesc: ^2.5.1 - checksum: 0ff31a73b15429f1287e4d57b439bba4a266f8c673bb445fe313b82f6d110f586776997eb723a777cd7adad9d340edd162aea4973a90112c5d0cfcaf6686844b + checksum: d7713f02536a8144eca810e9b13ae854b05fec462348eaf52e7b50df2c0a312bc43bfff0e8e10d6dd982e8986d61175ac8e67d7358a8b4dad9db4d6733bf0c9c languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.16.0, @babel/helper-annotate-as-pure@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" +"@babel/helper-annotate-as-pure@npm:^7.16.0, @babel/helper-annotate-as-pure@npm:^7.22.5, @babel/helper-annotate-as-pure@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-annotate-as-pure@npm:7.24.7" dependencies: - "@babel/types": ^7.22.5 - checksum: 53da330f1835c46f26b7bf4da31f7a496dee9fd8696cca12366b94ba19d97421ce519a74a837f687749318f94d1a37f8d1abcbf35e8ed22c32d16373b2f6198d + "@babel/types": ^7.24.7 + checksum: 6178566099a6a0657db7a7fa601a54fb4731ca0b8614fbdccfd8e523c210c13963649bc8fdfd53ce7dd14d05e3dda2fb22dea5b30113c488b9eb1a906d60212e languageName: node linkType: hard @@ -1942,35 +1942,33 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.10, @babel/helper-compilation-targets@npm:^7.22.5, @babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-compilation-targets@npm:7.24.7" +"@babel/helper-compilation-targets@npm:^7.22.10, @babel/helper-compilation-targets@npm:^7.22.5, @babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-compilation-targets@npm:7.25.2" dependencies: - "@babel/compat-data": ^7.24.7 - "@babel/helper-validator-option": ^7.24.7 - browserslist: ^4.22.2 + "@babel/compat-data": ^7.25.2 + "@babel/helper-validator-option": ^7.24.8 + browserslist: ^4.23.1 lru-cache: ^5.1.1 semver: ^6.3.1 - checksum: dfc88bc35e223ade796c7267901728217c665adc5bc2e158f7b0ae850de14f1b7941bec4fe5950ae46236023cfbdeddd9c747c276acf9b39ca31f8dd97dc6cc6 + checksum: aed33c5496cb9db4b5e2d44e26bf8bc474074cc7f7bb5ebe1d4a20fdeb362cb3ba9e1596ca18c7484bcd6e5c3a155ab975e420d520c0ae60df81f9de04d0fd16 languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.22.11, @babel/helper-create-class-features-plugin@npm:^7.22.15, @babel/helper-create-class-features-plugin@npm:^7.22.5": - version: 7.22.15 - resolution: "@babel/helper-create-class-features-plugin@npm:7.22.15" +"@babel/helper-create-class-features-plugin@npm:^7.22.11, @babel/helper-create-class-features-plugin@npm:^7.25.0, @babel/helper-create-class-features-plugin@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/helper-create-class-features-plugin@npm:7.25.4" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-environment-visitor": ^7.22.5 - "@babel/helper-function-name": ^7.22.5 - "@babel/helper-member-expression-to-functions": ^7.22.15 - "@babel/helper-optimise-call-expression": ^7.22.5 - "@babel/helper-replace-supers": ^7.22.9 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 - "@babel/helper-split-export-declaration": ^7.22.6 + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-member-expression-to-functions": ^7.24.8 + "@babel/helper-optimise-call-expression": ^7.24.7 + "@babel/helper-replace-supers": ^7.25.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + "@babel/traverse": ^7.25.4 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 52c500d8d164abb3a360b1b7c4b8fff77bc4a5920d3a2b41ae6e1d30617b0dc0b972c1f5db35b1752007e04a748908b4a99bc872b73549ae837e87dcdde005a3 + checksum: 4544ebda4516eb25efdebd47ca024bd7bdb1eb6e7cc3ad89688c8ef8e889734c2f4411ed78981899c641394f013f246f2af63d92a0e9270f6c453309b4cb89ba languageName: node linkType: hard @@ -2002,7 +2000,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.22.5, @babel/helper-environment-visitor@npm:^7.24.7": +"@babel/helper-environment-visitor@npm:^7.22.5": version: 7.24.7 resolution: "@babel/helper-environment-visitor@npm:7.24.7" dependencies: @@ -2011,7 +2009,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.24.7": +"@babel/helper-function-name@npm:^7.22.5": version: 7.24.7 resolution: "@babel/helper-function-name@npm:7.24.7" dependencies: @@ -2021,7 +2019,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-hoist-variables@npm:^7.22.5, @babel/helper-hoist-variables@npm:^7.24.7": +"@babel/helper-hoist-variables@npm:^7.22.5": version: 7.24.7 resolution: "@babel/helper-hoist-variables@npm:7.24.7" dependencies: @@ -2030,12 +2028,13 @@ __metadata: languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.22.15, @babel/helper-member-expression-to-functions@npm:^7.22.5": - version: 7.23.0 - resolution: "@babel/helper-member-expression-to-functions@npm:7.23.0" +"@babel/helper-member-expression-to-functions@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" dependencies: - "@babel/types": ^7.23.0 - checksum: 494659361370c979ada711ca685e2efe9460683c36db1b283b446122596602c901e291e09f2f980ecedfe6e0f2bd5386cb59768285446530df10c14df1024e75 + "@babel/traverse": ^7.24.8 + "@babel/types": ^7.24.8 + checksum: bf923d05d81b06857f4ca4fe9c528c9c447a58db5ea39595bb559eae2fce01a8266173db0fd6a2ec129d7bbbb9bb22f4e90008252f7c66b422c76630a878a4bc languageName: node linkType: hard @@ -2049,34 +2048,33 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.22.9, @babel/helper-module-transforms@npm:^7.23.3, @babel/helper-module-transforms@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-module-transforms@npm:7.24.7" +"@babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.22.9, @babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-module-transforms@npm:7.25.2" dependencies: - "@babel/helper-environment-visitor": ^7.24.7 "@babel/helper-module-imports": ^7.24.7 "@babel/helper-simple-access": ^7.24.7 - "@babel/helper-split-export-declaration": ^7.24.7 "@babel/helper-validator-identifier": ^7.24.7 + "@babel/traverse": ^7.25.2 peerDependencies: "@babel/core": ^7.0.0 - checksum: ddff3b41c2667876b4e4e73d961168f48a5ec9560c95c8c2d109e6221f9ca36c6f90c6317eb7a47f2a3c99419c356e529a86b79174cad0d4f7a61960866b88ca + checksum: 282d4e3308df6746289e46e9c39a0870819630af5f84d632559171e4fae6045684d771a65f62df3d569e88ccf81dc2def78b8338a449ae3a94bb421aa14fc367 languageName: node linkType: hard -"@babel/helper-optimise-call-expression@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-optimise-call-expression@npm:7.22.5" - dependencies: - "@babel/types": ^7.22.5 - checksum: c70ef6cc6b6ed32eeeec4482127e8be5451d0e5282d5495d5d569d39eb04d7f1d66ec99b327f45d1d5842a9ad8c22d48567e93fc502003a47de78d122e355f7c - languageName: node - linkType: hard - -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": +"@babel/helper-optimise-call-expression@npm:^7.22.5, @babel/helper-optimise-call-expression@npm:^7.24.7": version: 7.24.7 - resolution: "@babel/helper-plugin-utils@npm:7.24.7" - checksum: 81f2a15751d892e4a8fce25390f973363a5b27596167861d2d6eab0f61856eb2ba389b031a9f19f669c0bd4dd601185828d3cebafd25431be7a1696f2ce3ef68 + resolution: "@babel/helper-optimise-call-expression@npm:7.24.7" + dependencies: + "@babel/types": ^7.24.7 + checksum: 280654eaf90e92bf383d7eed49019573fb35a98c9e992668f701ad099957246721044be2068cf6840cb2299e0ad393705a1981c88c23a1048096a8d59e5f79a3 + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.7, @babel/helper-plugin-utils@npm:^7.24.8, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": + version: 7.24.8 + resolution: "@babel/helper-plugin-utils@npm:7.24.8" + checksum: 73b1a83ba8bcee21dc94de2eb7323207391715e4369fd55844bb15cf13e3df6f3d13a40786d990e6370bf0f571d94fc31f70dec96c1d1002058258c35ca3767a languageName: node linkType: hard @@ -2093,20 +2091,20 @@ __metadata: languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.22.5, @babel/helper-replace-supers@npm:^7.22.9": - version: 7.22.9 - resolution: "@babel/helper-replace-supers@npm:7.22.9" +"@babel/helper-replace-supers@npm:^7.22.5, @babel/helper-replace-supers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-replace-supers@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": ^7.22.5 - "@babel/helper-member-expression-to-functions": ^7.22.5 - "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/helper-member-expression-to-functions": ^7.24.8 + "@babel/helper-optimise-call-expression": ^7.24.7 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: d41471f56ff2616459d35a5df1900d5f0756ae78b1027040365325ef332d66e08e3be02a9489756d870887585ff222403a228546e93dd7019e19e59c0c0fe586 + checksum: f669fc2487c22d40b808f94b9c3ee41129484d5ef0ba689bdd70f216ff91e10b6b021d2f8cd37e7bdd700235a2a6ae6622526344f064528190383bf661ac65f8 languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.22.5, @babel/helper-simple-access@npm:^7.24.7": +"@babel/helper-simple-access@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-simple-access@npm:7.24.7" dependencies: @@ -2116,16 +2114,17 @@ __metadata: languageName: node linkType: hard -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5" +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5, @babel/helper-skip-transparent-expression-wrappers@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.24.7" dependencies: - "@babel/types": ^7.22.5 - checksum: 1012ef2295eb12dc073f2b9edf3425661e9b8432a3387e62a8bc27c42963f1f216ab3124228015c748770b2257b4f1fda882ca8fa34c0bf485e929ae5bc45244 + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 11b28fe534ce2b1a67c4d8e51a7b5711a2a0a0cae802f74614eee54cca58c744d9a62f6f60103c41759e81c537d270bfd665bf368a6bea214c6052f2094f8407 languageName: node linkType: hard -"@babel/helper-split-export-declaration@npm:^7.22.6, @babel/helper-split-export-declaration@npm:^7.24.7": +"@babel/helper-split-export-declaration@npm:^7.22.6": version: 7.24.7 resolution: "@babel/helper-split-export-declaration@npm:7.24.7" dependencies: @@ -2134,10 +2133,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-string-parser@npm:7.24.7" - checksum: 09568193044a578743dd44bf7397940c27ea693f9812d24acb700890636b376847a611cdd0393a928544e79d7ad5b8b916bd8e6e772bc8a10c48a647a96e7b1a +"@babel/helper-string-parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-string-parser@npm:7.24.8" + checksum: 39b03c5119216883878655b149148dc4d2e284791e969b19467a9411fccaa33f7a713add98f4db5ed519535f70ad273cdadfd2eb54d47ebbdeac5083351328ce languageName: node linkType: hard @@ -2148,10 +2147,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.22.15, @babel/helper-validator-option@npm:^7.22.5, @babel/helper-validator-option@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-validator-option@npm:7.24.7" - checksum: 9689166bf3f777dd424c026841c8cd651e41b21242dbfd4569a53086179a3e744c8eddd56e9d10b54142270141c91581b53af0d7c00c82d552d2540e2a919f7e +"@babel/helper-validator-option@npm:^7.22.5, @babel/helper-validator-option@npm:^7.24.7, @babel/helper-validator-option@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-validator-option@npm:7.24.8" + checksum: a52442dfa74be6719c0608fee3225bd0493c4057459f3014681ea1a4643cd38b68ff477fe867c4b356da7330d085f247f0724d300582fa4ab9a02efaf34d107c languageName: node linkType: hard @@ -2166,13 +2165,13 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helpers@npm:7.24.7" +"@babel/helpers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helpers@npm:7.25.0" dependencies: - "@babel/template": ^7.24.7 - "@babel/types": ^7.24.7 - checksum: 934da58098a3670ca7f9f42425b9c44d0ca4f8fad815c0f51d89fc7b64c5e0b4c7d5fec038599de691229ada737edeaf72fad3eba8e16dd5842e8ea447f76b66 + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 739e3704ff41a30f5eaac469b553f4d3ab02be6ced083f5925851532dfbd9efc5c347728e77b754ed0b262a4e5e384e60932a62c192d338db7e4b7f3adf9f4a7 languageName: node linkType: hard @@ -2188,12 +2187,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/parser@npm:7.24.7" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.7, @babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/parser@npm:7.25.4" + dependencies: + "@babel/types": ^7.25.4 bin: parser: ./bin/babel-parser.js - checksum: fc9d2c4c8712f89672edc55c0dc5cf640dcec715b56480f111f85c2bc1d507e251596e4110d65796690a96ac37a4b60432af90b3e97bb47e69d4ef83872dbbd6 + checksum: fe4f083d4ad34f019dd7fad672cd007003004fb0a3df9b7315a5da9a5e8e56c1fed95acab6862e7d76cfccb2e8e364bcc307e9117718e6bb6dfb2e87ad065abf languageName: node linkType: hard @@ -2296,14 +2297,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-flow@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-syntax-flow@npm:7.23.3" +"@babel/plugin-syntax-flow@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-syntax-flow@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c6e6f355d6ace5f4a9e7bb19f1fed2398aeb9b62c4c671a189d81b124f9f5bb77c4225b6e85e19339268c60a021c1e49104e450375de5e6bb70612190d9678af + checksum: 43b78b5fcdedb2a6d80c3d02a1a564fbfde86b73b442d616a8f318f673caa6ce0151513af5a00fcae42a512f144e70ef259d368b9537ee35d40336a6c895a7d4 languageName: node linkType: hard @@ -2351,14 +2352,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.23.3, @babel/plugin-syntax-jsx@npm:^7.7.2": - version: 7.23.3 - resolution: "@babel/plugin-syntax-jsx@npm:7.23.3" +"@babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.24.7, @babel/plugin-syntax-jsx@npm:^7.7.2": + version: 7.24.7 + resolution: "@babel/plugin-syntax-jsx@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 89037694314a74e7f0e7a9c8d3793af5bf6b23d80950c29b360db1c66859d67f60711ea437e70ad6b5b4b29affe17eababda841b6c01107c2b638e0493bafb4e + checksum: 7a5ca629d8ca1e1ee78705a78e58c12920d07ed8006d7e7232b31296a384ff5e41d7b649bde5561196041037bbb9f9715be1d1c20975df87ca204f34ad15b965 languageName: node linkType: hard @@ -2450,14 +2451,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.23.3, @babel/plugin-syntax-typescript@npm:^7.7.2": - version: 7.23.3 - resolution: "@babel/plugin-syntax-typescript@npm:7.23.3" +"@babel/plugin-syntax-typescript@npm:^7.24.7, @babel/plugin-syntax-typescript@npm:^7.7.2": + version: 7.25.4 + resolution: "@babel/plugin-syntax-typescript@npm:7.25.4" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: abfad3a19290d258b028e285a1f34c9b8a0cbe46ef79eafed4ed7ffce11b5d0720b5e536c82f91cbd8442cde35a3dd8e861fa70366d87ff06fdc0d4756e30876 + checksum: 9b89b8930cd5983f64251d75c9fcdc17a8dc73837d6de12220ff972888ecff4054a6467cf0c423cad242aa96c0f0564a39a0823073728cc02239b80d13f02230 languageName: node linkType: hard @@ -2533,15 +2534,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-class-properties@npm:7.22.5" +"@babel/plugin-transform-class-properties@npm:^7.22.5, @babel/plugin-transform-class-properties@npm:^7.24.7": + version: 7.25.4 + resolution: "@babel/plugin-transform-class-properties@npm:7.25.4" dependencies: - "@babel/helper-create-class-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.25.4 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b830152dfc2ff2f647f0abe76e6251babdfbef54d18c4b2c73a6bf76b1a00050a5d998dac80dc901a48514e95604324943a9dd39317073fe0928b559e0e0c579 + checksum: b73f7d968639c6c2dfc13f4c5a8fe45cefd260f0faa7890ae12e65d41211072544ff5e128c8b61a86887b29ffd3df8422dbdfbf61648488e71d4bb599c41f4a5 languageName: node linkType: hard @@ -2659,15 +2660,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-flow-strip-types@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-transform-flow-strip-types@npm:7.23.3" +"@babel/plugin-transform-flow-strip-types@npm:^7.24.7": + version: 7.25.2 + resolution: "@babel/plugin-transform-flow-strip-types@npm:7.25.2" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/plugin-syntax-flow": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/plugin-syntax-flow": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: de38cc5cf948bc19405ea041292181527a36f59f08d787a590415fac36e9b0c7992f0d3e2fd3b9402089bafdaa1a893291a0edf15beebfd29bdedbbe582fee9b + checksum: 9f7b96cbd374077eaf04b59e468976d2e89ec353807d7ac28f129f686945447df92aeb5b60acf906f3ec0f9ebef5d9f88735c7aa39af97033a6ab96c79c9a909 languageName: node linkType: hard @@ -2753,16 +2754,16 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.22.5, @babel/plugin-transform-modules-commonjs@npm:^7.23.0, @babel/plugin-transform-modules-commonjs@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.23.3" +"@babel/plugin-transform-modules-commonjs@npm:^7.22.5, @babel/plugin-transform-modules-commonjs@npm:^7.24.7": + version: 7.24.8 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.8" dependencies: - "@babel/helper-module-transforms": ^7.23.3 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-simple-access": ^7.22.5 + "@babel/helper-module-transforms": ^7.24.8 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-simple-access": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 720a231ceade4ae4d2632478db4e7fecf21987d444942b72d523487ac8d715ca97de6c8f415c71e939595e1a4776403e7dc24ed68fe9125ad4acf57753c9bff7 + checksum: a4cf95b1639c33382064b44558f73ee5fac023f2a94d16e549d2bb55ceebd5cbc10fcddd505d08cd5bc97f5a64af9fd155512358b7dcf7b1a0082e8945cf21c5 languageName: node linkType: hard @@ -2815,15 +2816,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.11, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.5": - version: 7.23.3 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.23.3" +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.5, @babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.7 "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ea844a12a3ae5647d6d2ae0685fde48ae53e724ef9ce5d9fbf36e8f1ff0107f76a5349ef34c2a06984b3836c001748caf9701afb172bd7ba71a5dff79e16b434 + checksum: 4a9221356401d87762afbc37a9e8e764afc2daf09c421117537820f8cfbed6876888372ad3a7bcfae2d45c95f026651f050ab4020b777be31d3ffb00908dbdd3 languageName: node linkType: hard @@ -2878,16 +2879,16 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.22.10, @babel/plugin-transform-optional-chaining@npm:^7.22.5, @babel/plugin-transform-optional-chaining@npm:^7.23.0": - version: 7.23.3 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.23.3" +"@babel/plugin-transform-optional-chaining@npm:^7.22.10, @babel/plugin-transform-optional-chaining@npm:^7.22.5, @babel/plugin-transform-optional-chaining@npm:^7.24.7": + version: 7.24.8 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.8" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 "@babel/plugin-syntax-optional-chaining": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 98529b9d10b5502ceb87259b538e5649d111ec1582c4c49c620f3181d53489c1ff887075fb208245baa43fa45ae85c9950f0db47be00e55b52c9bcd36271d701 + checksum: 45e55e3a2fffb89002d3f89aef59c141610f23b60eee41e047380bffc40290b59f64fc649aa7ec5281f73d41b2065410d788acc6afaad2a9f44cad6e8af04442 languageName: node linkType: hard @@ -2902,15 +2903,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.22.5": - version: 7.22.5 - resolution: "@babel/plugin-transform-private-methods@npm:7.22.5" +"@babel/plugin-transform-private-methods@npm:^7.22.5, @babel/plugin-transform-private-methods@npm:^7.24.7": + version: 7.25.4 + resolution: "@babel/plugin-transform-private-methods@npm:7.25.4" dependencies: - "@babel/helper-create-class-features-plugin": ^7.22.5 - "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.25.4 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 321479b4fcb6d3b3ef622ab22fd24001e43d46e680e8e41324c033d5810c84646e470f81b44cbcbef5c22e99030784f7cac92f1829974da7a47a60a7139082c3 + checksum: cb1dabfc03e2977990263d65bc8f43a9037dffbb5d9a5f825c00d05447ff68015099408c1531d9dd88f18a41a90f5062dc48f3a1d52b415d2d2ee4827dedff09 languageName: node linkType: hard @@ -2972,28 +2973,6 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-self@npm:^7.24.5": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-jsx-self@npm:7.24.7" - dependencies: - "@babel/helper-plugin-utils": ^7.24.7 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 2d72c33664e614031b8a03fc2d4cfd185e99efb1d681cbde4b0b4ab379864b31d83ee923509892f6d94b2c5893c309f0217d33bcda3e470ed42297f958138381 - languageName: node - linkType: hard - -"@babel/plugin-transform-react-jsx-source@npm:^7.24.1": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-jsx-source@npm:7.24.7" - dependencies: - "@babel/helper-plugin-utils": ^7.24.7 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: c9afcb2259dd124a2de76f8a578589c18bd2f24dbcf78fe02b53c5cbc20c493c4618369604720e4e699b52be10ba0751b97140e1ef8bc8f0de0a935280e9d5b7 - languageName: node - linkType: hard - "@babel/plugin-transform-react-jsx@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-react-jsx@npm:7.22.5" @@ -3100,17 +3079,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-transform-typescript@npm:7.23.3" +"@babel/plugin-transform-typescript@npm:^7.24.7": + version: 7.25.2 + resolution: "@babel/plugin-transform-typescript@npm:7.25.2" dependencies: - "@babel/helper-annotate-as-pure": ^7.22.5 - "@babel/helper-create-class-features-plugin": ^7.22.15 - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/plugin-syntax-typescript": ^7.23.3 + "@babel/helper-annotate-as-pure": ^7.24.7 + "@babel/helper-create-class-features-plugin": ^7.25.0 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 + "@babel/plugin-syntax-typescript": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 01ba1d5d41c6b41c139fc6f2df744a82e7572335209976a75f0007ebbaea02dcb3265c44123afe09cc3f4aafb177bcb967a20af0218a95eae4fd883f6dd9d0d6 + checksum: b0267128d93560a4350919f7230a3b497e20fb8611d9f04bb3560d6b38877305ccad4c40903160263361c6930a84dbcb5b21b8ea923531bda51f67bffdc2dd0b languageName: node linkType: hard @@ -3251,16 +3231,16 @@ __metadata: languageName: node linkType: hard -"@babel/preset-flow@npm:^7.22.15": - version: 7.23.3 - resolution: "@babel/preset-flow@npm:7.23.3" +"@babel/preset-flow@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/preset-flow@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-validator-option": ^7.22.15 - "@babel/plugin-transform-flow-strip-types": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-validator-option": ^7.24.7 + "@babel/plugin-transform-flow-strip-types": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 60b5dde79621ae89943af459c4dc5b6030795f595a20ca438c8100f8d82c9ebc986881719030521ff5925799518ac5aa7f3fe62af8c33ab96be3681a71f88d03 + checksum: 4caca02a6e0a477eb22994d686a1fbf65b5ab0240ae77530696434dba7efff4c5dcbf9186a774168dd4c492423141a22af3f2874c356aa22429f3c83eaf34419 languageName: node linkType: hard @@ -3293,33 +3273,33 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:^7.18.6, @babel/preset-typescript@npm:^7.23.0": - version: 7.23.3 - resolution: "@babel/preset-typescript@npm:7.23.3" +"@babel/preset-typescript@npm:^7.18.6, @babel/preset-typescript@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/preset-typescript@npm:7.24.7" dependencies: - "@babel/helper-plugin-utils": ^7.22.5 - "@babel/helper-validator-option": ^7.22.15 - "@babel/plugin-syntax-jsx": ^7.23.3 - "@babel/plugin-transform-modules-commonjs": ^7.23.3 - "@babel/plugin-transform-typescript": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-validator-option": ^7.24.7 + "@babel/plugin-syntax-jsx": ^7.24.7 + "@babel/plugin-transform-modules-commonjs": ^7.24.7 + "@babel/plugin-transform-typescript": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 105a2d39bbc464da0f7e1ad7f535c77c5f62d6b410219355b20e552e7d29933567a5c55339b5d0aec1a5c7a0a7dfdf1b54aae601a4fe15a157d54dcbfcb3e854 + checksum: 12929b24757f3bd6548103475f86478eda4c872bc7cefd920b29591eee8f4a4f350561d888e133d632d0c9402b8615fdcec9138e5127a6567dcb22f804ff207f languageName: node linkType: hard -"@babel/register@npm:^7.22.15": - version: 7.22.15 - resolution: "@babel/register@npm:7.22.15" +"@babel/register@npm:^7.24.6": + version: 7.24.6 + resolution: "@babel/register@npm:7.24.6" dependencies: clone-deep: ^4.0.1 find-cache-dir: ^2.0.0 make-dir: ^2.1.0 - pirates: ^4.0.5 + pirates: ^4.0.6 source-map-support: ^0.5.16 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5497be6773608cd2d874210edd14499fce464ddbea170219da55955afe4c9173adb591164193458fd639e43b7d1314088a6186f4abf241476c59b3f0da6afd6f + checksum: 446316c80969df89ad3515576937ddf746cd4927810f226101a8d7f476b399c14c26847e77637e09355399c645fbf413d6e53ac6987b8cf240de7932a9372cb5 languageName: node linkType: hard @@ -3340,7 +3320,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.24.4 resolution: "@babel/runtime@npm:7.24.4" dependencies: @@ -3349,62 +3329,59 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.22.5, @babel/template@npm:^7.24.7, @babel/template@npm:^7.3.3": - version: 7.24.7 - resolution: "@babel/template@npm:7.24.7" +"@babel/template@npm:^7.22.5, @babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0, @babel/template@npm:^7.3.3": + version: 7.25.0 + resolution: "@babel/template@npm:7.25.0" dependencies: "@babel/code-frame": ^7.24.7 - "@babel/parser": ^7.24.7 - "@babel/types": ^7.24.7 - checksum: ea90792fae708ddf1632e54c25fe1a86643d8c0132311f81265d2bdbdd42f9f4fac65457056c1b6ca87f7aa0d6a795b549566774bba064bdcea2034ab3960ee9 + "@babel/parser": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 3f2db568718756d0daf2a16927b78f00c425046b654cd30b450006f2e84bdccaf0cbe6dc04994aa1f5f6a4398da2f11f3640a4d3ee31722e43539c4c919c817b languageName: node linkType: hard -"@babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.4.5": - version: 7.24.7 - resolution: "@babel/traverse@npm:7.24.7" +"@babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.25.4, @babel/traverse@npm:^7.4.5": + version: 7.25.4 + resolution: "@babel/traverse@npm:7.25.4" dependencies: "@babel/code-frame": ^7.24.7 - "@babel/generator": ^7.24.7 - "@babel/helper-environment-visitor": ^7.24.7 - "@babel/helper-function-name": ^7.24.7 - "@babel/helper-hoist-variables": ^7.24.7 - "@babel/helper-split-export-declaration": ^7.24.7 - "@babel/parser": ^7.24.7 - "@babel/types": ^7.24.7 + "@babel/generator": ^7.25.4 + "@babel/parser": ^7.25.4 + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.4 debug: ^4.3.1 globals: ^11.1.0 - checksum: 7cd366afe9e7ee77e493779fdf24f67bf5595247289364f4689e29688572505eaeb886d7a8f20ebb9c29fc2de7d0895e4ff9e203e78e39ac67239724d45aa83b + checksum: 3b6d879b9d843b119501585269b3599f047011ae21eb7820d00aef62fc3a2bcdaf6f4cdf2679795a2d7c0b6b5d218974916e422f08dea08613dc42188ef21e4b languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.10, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.24.7 - resolution: "@babel/types@npm:7.24.7" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.10, @babel/types@npm:^7.22.5, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.4, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": + version: 7.25.4 + resolution: "@babel/types@npm:7.25.4" dependencies: - "@babel/helper-string-parser": ^7.24.7 + "@babel/helper-string-parser": ^7.24.8 "@babel/helper-validator-identifier": ^7.24.7 to-fast-properties: ^2.0.0 - checksum: 3e4437fced97e02982972ce5bebd318c47d42c9be2152c0fd28c6f786cc74086cc0a8fb83b602b846e41df37f22c36254338eada1a47ef9d8a1ec92332ca3ea8 + checksum: 497f8b583c54a92a59c3ec542144695064cd5c384fcca46ba1aa301d5e5dd6c1d011f312ca024cb0f9c956da07ae82fb4c348c31a30afa31a074c027720d2aa8 languageName: node linkType: hard -"@backstage-community/plugin-explore-common@npm:^0.0.4": - version: 0.0.4 - resolution: "@backstage-community/plugin-explore-common@npm:0.0.4" - checksum: 0c27253dd79dcb56236d382f7591e20eb87f374878b091a690b3fede23ff652aefa3b074a58bd5b51462cc44faab12a97ee82443dcc6106f121212417b9c4cf9 +"@backstage-community/plugin-explore-common@npm:^0.0.5": + version: 0.0.5 + resolution: "@backstage-community/plugin-explore-common@npm:0.0.5" + checksum: b849c1b2cb4cd2221dc5a7f6e3ea2d00cea529d27f2de074159b9eef5aa5d538e28f32e57878a97bdda7f0242d82a56cbfc42f52c2bdb02f455c7a0d232ecfeb languageName: node linkType: hard "@backstage-community/plugin-puppetdb@npm:^0.1.18": - version: 0.1.19 - resolution: "@backstage-community/plugin-puppetdb@npm:0.1.19" + version: 0.1.20 + resolution: "@backstage-community/plugin-puppetdb@npm:0.1.20" dependencies: - "@backstage/catalog-model": ^1.5.0 - "@backstage/core-components": ^0.14.9 + "@backstage/catalog-model": ^1.6.0 + "@backstage/core-components": ^0.14.10 "@backstage/core-plugin-api": ^1.9.3 "@backstage/errors": ^1.2.4 - "@backstage/plugin-catalog-react": ^1.12.2 + "@backstage/plugin-catalog-react": ^1.12.3 "@material-ui/core": ^4.12.2 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 react-use: ^17.2.4 @@ -3412,15 +3389,15 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: abe5e3b5b9772b5cdc17074f58f38bdbf81516afe7b9241e06844729608ec2a56899437a7cf82d4c8f3608038c15217bd6ea971f41dbce2934e7b05986bfcc10 + checksum: 231855a135575bdc6eb92890602589adcf82c5eabaec7dfaef456c598454d8d05e2484ee80c3684824a9b52f62ce313d5e780722ae0553c3742ec7a89ec558c7 languageName: node linkType: hard "@backstage-community/plugin-stackstorm@npm:^0.1.16": - version: 0.1.17 - resolution: "@backstage-community/plugin-stackstorm@npm:0.1.17" + version: 0.1.18 + resolution: "@backstage-community/plugin-stackstorm@npm:0.1.18" dependencies: - "@backstage/core-components": ^0.14.9 + "@backstage/core-components": ^0.14.10 "@backstage/core-plugin-api": ^1.9.3 "@backstage/errors": ^1.2.4 "@material-ui/core": ^4.12.2 @@ -3431,7 +3408,7 @@ __metadata: react: ^16.13.1 || ^17.0.0 || ^18.0.0 react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 3fa2b45da036e4001a9e034a8841b58877d0b4189d244806b3b1808d3c2a34bb4ab4acbcff629edda47d03b2941c51743dd84f7352ed0d700988aaee946b65f3 + checksum: 9a11e4ee8c6e28df83658b91efa27d41808664a19b71b874b7a3eaa1a6befa1733f92ed14902f291e8050cc78a879357ab2fd0b37042cad9f0953d78953fcfd5 languageName: node linkType: hard @@ -3468,7 +3445,6 @@ __metadata: "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" - "@backstage/cli-node": "workspace:^" "@backstage/config": "workspace:^" "@backstage/config-loader": "workspace:^" "@backstage/errors": "workspace:^" @@ -3477,7 +3453,6 @@ __metadata: "@backstage/types": "workspace:^" "@manypkg/get-packages": ^1.1.3 "@types/compression": ^1.7.0 - "@types/fs-extra": ^11.0.0 "@types/http-errors": ^2.0.0 "@types/minimist": ^1.2.0 "@types/morgan": ^1.9.0 @@ -3488,7 +3463,6 @@ __metadata: cors: ^2.8.5 express: ^4.17.1 express-promise-router: ^4.1.0 - fs-extra: ^11.2.0 helmet: ^6.0.0 http-errors: ^2.0.0 jose: ^5.0.0 @@ -3590,6 +3564,7 @@ __metadata: p-limit: ^3.1.0 path-to-regexp: ^6.2.1 pg: ^8.11.3 + pg-format: ^1.0.4 raw-body: ^2.4.1 selfsigned: ^2.0.0 stoppable: ^1.1.0 @@ -3626,6 +3601,7 @@ __metadata: "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" + "@backstage/cli-node": "workspace:^" "@backstage/config": "workspace:^" "@backstage/config-loader": "workspace:^" "@backstage/errors": "workspace:^" @@ -3783,29 +3759,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/backend-tasks@workspace:packages/backend-tasks": - version: 0.0.0-use.local - resolution: "@backstage/backend-tasks@workspace:packages/backend-tasks" - dependencies: - "@backstage/backend-common": "workspace:^" - "@backstage/backend-plugin-api": "workspace:^" - "@backstage/backend-test-utils": "workspace:^" - "@backstage/cli": "workspace:^" - "@backstage/config": "workspace:^" - "@backstage/errors": "workspace:^" - "@backstage/types": "workspace:^" - "@opentelemetry/api": ^1.3.0 - "@types/luxon": ^3.0.0 - cron: ^3.0.0 - knex: ^3.0.0 - lodash: ^4.17.21 - luxon: ^3.0.0 - uuid: ^9.0.0 - wait-for-expect: ^3.0.2 - zod: ^3.22.4 - languageName: unknown - linkType: soft - "@backstage/backend-test-utils@workspace:^, @backstage/backend-test-utils@workspace:packages/backend-test-utils": version: 0.0.0-use.local resolution: "@backstage/backend-test-utils@workspace:packages/backend-test-utils" @@ -3821,7 +3774,10 @@ __metadata: "@backstage/types": "workspace:^" "@keyv/memcache": ^1.3.5 "@keyv/redis": ^2.5.3 + "@types/express": ^4.17.6 + "@types/express-serve-static-core": ^4.17.5 "@types/keyv": ^4.2.0 + "@types/qs": ^6.9.6 "@types/supertest": ^2.0.8 better-sqlite3: ^11.0.0 cookie: ^0.6.0 @@ -3843,6 +3799,18 @@ __metadata: languageName: unknown linkType: soft +"@backstage/catalog-client@npm:^1.6.6": + version: 1.6.6 + resolution: "@backstage/catalog-client@npm:1.6.6" + dependencies: + "@backstage/catalog-model": ^1.6.0 + "@backstage/errors": ^1.2.4 + cross-fetch: ^4.0.0 + uri-template: ^2.0.0 + checksum: 10a859979a6ec3d9bcca519ace01ca371517e56bd54a90e0d667b4ef90bee54b09495238974b4040d7dc75f8cacf0d212900b40fe6738d484ff57a739e3eec4b + languageName: node + linkType: hard + "@backstage/catalog-client@workspace:^, @backstage/catalog-client@workspace:packages/catalog-client": version: 0.0.0-use.local resolution: "@backstage/catalog-client@workspace:packages/catalog-client" @@ -3856,7 +3824,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.5.0, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": +"@backstage/catalog-model@^1.4.3, @backstage/catalog-model@^1.6.0, @backstage/catalog-model@workspace:^, @backstage/catalog-model@workspace:packages/catalog-model": version: 0.0.0-use.local resolution: "@backstage/catalog-model@workspace:packages/catalog-model" dependencies: @@ -3963,7 +3931,6 @@ __metadata: "@types/yarnpkg__lockfile": ^1.1.4 "@typescript-eslint/eslint-plugin": ^6.12.0 "@typescript-eslint/parser": ^6.7.2 - "@vitejs/plugin-react": ^4.0.4 "@yarnpkg/lockfile": ^1.1.0 "@yarnpkg/parsers": ^3.0.0 bfj: ^8.0.0 @@ -3977,7 +3944,7 @@ __metadata: ctrlc-windows: ^2.1.0 del: ^7.0.0 diff: ^5.0.0 - esbuild: ^0.21.0 + esbuild: ^0.23.0 esbuild-loader: ^4.0.0 eslint: ^8.6.0 eslint-config-prettier: ^9.0.0 @@ -4018,6 +3985,7 @@ __metadata: pirates: ^4.0.6 postcss: ^8.1.0 process: ^0.11.10 + raw-loader: ^4.0.2 react-dev-utils: ^12.0.0-next.60 react-refresh: ^0.14.0 recursive-readdir: ^2.2.2 @@ -4035,9 +4003,6 @@ __metadata: tar: ^6.1.12 terser-webpack-plugin: ^5.1.3 util: ^0.12.3 - vite: ^4.4.9 - vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.22.0 webpack: ^5.70.0 webpack-dev-server: ^5.0.0 webpack-node-externals: ^3.0.0 @@ -4074,7 +4039,7 @@ __metadata: "@types/node": ^18.17.8 chalk: ^4.0.0 commander: ^12.0.0 - jscodeshift: ^0.15.0 + jscodeshift: ^0.16.0 jscodeshift-add-imports: ^1.0.10 bin: backstage-codemods: bin/backstage-codemods @@ -4109,7 +4074,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/config@^1.1.1, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": +"@backstage/config@^1.1.1, @backstage/config@^1.2.0, @backstage/config@workspace:^, @backstage/config@workspace:packages/config": version: 0.0.0-use.local resolution: "@backstage/config@workspace:packages/config" dependencies: @@ -4157,6 +4122,22 @@ __metadata: languageName: unknown linkType: soft +"@backstage/core-compat-api@npm:^0.2.8": + version: 0.2.8 + resolution: "@backstage/core-compat-api@npm:0.2.8" + dependencies: + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/frontend-plugin-api": ^0.7.0 + "@backstage/version-bridge": ^1.0.8 + "@types/react": ^16.13.1 || ^17.0.0 + lodash: ^4.17.21 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 3f0cdb7f2b68f9a173128438b8d5cad460f434b3811db9bda2ae356000a736103971e13fb4d6ab893ed44fcbede9c8e464f381b025d05f468773aa2f9790eb50 + languageName: node + linkType: hard + "@backstage/core-compat-api@workspace:^, @backstage/core-compat-api@workspace:packages/core-compat-api": version: 0.0.0-use.local resolution: "@backstage/core-compat-api@workspace:packages/core-compat-api" @@ -4183,7 +4164,107 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@^0.14.9, @backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": +"@backstage/core-components@npm:^0.13.10": + version: 0.13.10 + resolution: "@backstage/core-components@npm:0.13.10" + dependencies: + "@backstage/config": ^1.1.1 + "@backstage/core-plugin-api": ^1.8.2 + "@backstage/errors": ^1.2.3 + "@backstage/theme": ^0.5.0 + "@backstage/version-bridge": ^1.0.7 + "@date-io/core": ^1.3.13 + "@material-table/core": ^3.1.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@react-hookz/web": ^23.0.0 + "@types/react": ^16.13.1 || ^17.0.0 + "@types/react-sparklines": ^1.7.0 + "@types/react-text-truncate": ^0.14.0 + ansi-regex: ^6.0.1 + classnames: ^2.2.6 + d3-selection: ^3.0.0 + d3-shape: ^3.0.0 + d3-zoom: ^3.0.0 + dagre: ^0.8.5 + linkify-react: 4.1.3 + linkifyjs: 4.1.3 + lodash: ^4.17.21 + pluralize: ^8.0.0 + qs: ^6.9.4 + rc-progress: 3.5.1 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-idle-timer: 5.6.2 + react-markdown: ^8.0.0 + react-sparklines: ^1.7.0 + react-syntax-highlighter: ^15.4.5 + react-text-truncate: ^0.19.0 + react-use: ^17.3.2 + react-virtualized-auto-sizer: ^1.0.11 + react-window: ^1.8.6 + remark-gfm: ^3.0.1 + zen-observable: ^0.10.0 + zod: ^3.22.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: ec2a0d0a27bc4d6b9d4da97f0b4df600148529ee51bf2c8e7d3adc45c3950adac662535d3beabc451db346f2c7e3c412ceaa756fc774012b43dff5e2695f2271 + languageName: node + linkType: hard + +"@backstage/core-components@npm:^0.14.10": + version: 0.14.10 + resolution: "@backstage/core-components@npm:0.14.10" + dependencies: + "@backstage/config": ^1.2.0 + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/errors": ^1.2.4 + "@backstage/theme": ^0.5.6 + "@backstage/version-bridge": ^1.0.8 + "@date-io/core": ^1.3.13 + "@material-table/core": ^3.1.0 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@react-hookz/web": ^24.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + "@types/react-sparklines": ^1.7.0 + ansi-regex: ^6.0.1 + classnames: ^2.2.6 + d3-selection: ^3.0.0 + d3-shape: ^3.0.0 + d3-zoom: ^3.0.0 + dagre: ^0.8.5 + linkify-react: 4.1.3 + linkifyjs: 4.1.3 + lodash: ^4.17.21 + pluralize: ^8.0.0 + qs: ^6.9.4 + rc-progress: 3.5.1 + react-helmet: 6.1.0 + react-hook-form: ^7.12.2 + react-idle-timer: 5.7.2 + react-markdown: ^8.0.0 + react-sparklines: ^1.7.0 + react-syntax-highlighter: ^15.4.5 + react-use: ^17.3.2 + react-virtualized-auto-sizer: ^1.0.11 + react-window: ^1.8.6 + remark-gfm: ^3.0.1 + zen-observable: ^0.10.0 + zod: ^3.22.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 303682d411b846a4892b27c1064d499dbd4eccb5a3cdc5acbb1d3247e1141f4704efc7bd286744c19818487e52a61891943156817f59e3bd6555926f7331f575 + languageName: node + linkType: hard + +"@backstage/core-components@workspace:^, @backstage/core-components@workspace:packages/core-components": version: 0.0.0-use.local resolution: "@backstage/core-components@workspace:packages/core-components" dependencies: @@ -4254,57 +4335,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@npm:^0.13.10": - version: 0.13.10 - resolution: "@backstage/core-components@npm:0.13.10" - dependencies: - "@backstage/config": ^1.1.1 - "@backstage/core-plugin-api": ^1.8.2 - "@backstage/errors": ^1.2.3 - "@backstage/theme": ^0.5.0 - "@backstage/version-bridge": ^1.0.7 - "@date-io/core": ^1.3.13 - "@material-table/core": ^3.1.0 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.61 - "@react-hookz/web": ^23.0.0 - "@types/react": ^16.13.1 || ^17.0.0 - "@types/react-sparklines": ^1.7.0 - "@types/react-text-truncate": ^0.14.0 - ansi-regex: ^6.0.1 - classnames: ^2.2.6 - d3-selection: ^3.0.0 - d3-shape: ^3.0.0 - d3-zoom: ^3.0.0 - dagre: ^0.8.5 - linkify-react: 4.1.3 - linkifyjs: 4.1.3 - lodash: ^4.17.21 - pluralize: ^8.0.0 - qs: ^6.9.4 - rc-progress: 3.5.1 - react-helmet: 6.1.0 - react-hook-form: ^7.12.2 - react-idle-timer: 5.6.2 - react-markdown: ^8.0.0 - react-sparklines: ^1.7.0 - react-syntax-highlighter: ^15.4.5 - react-text-truncate: ^0.19.0 - react-use: ^17.3.2 - react-virtualized-auto-sizer: ^1.0.11 - react-window: ^1.8.6 - remark-gfm: ^3.0.1 - zen-observable: ^0.10.0 - zod: ^3.22.4 - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: ec2a0d0a27bc4d6b9d4da97f0b4df600148529ee51bf2c8e7d3adc45c3950adac662535d3beabc451db346f2c7e3c412ceaa756fc774012b43dff5e2695f2271 - languageName: node - linkType: hard - "@backstage/core-plugin-api@^1.8.2, @backstage/core-plugin-api@^1.9.3, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" @@ -4432,16 +4462,14 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/core-app-api": "workspace:^" - "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/frontend-defaults": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" + "@backstage/plugin-app": "workspace:^" "@backstage/test-utils": "workspace:^" - "@backstage/theme": "workspace:^" "@backstage/types": "workspace:^" "@backstage/version-bridge": "workspace:^" - "@material-ui/core": ^4.12.4 - "@material-ui/icons": ^4.11.3 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -4452,6 +4480,47 @@ __metadata: languageName: unknown linkType: soft +"@backstage/frontend-defaults@workspace:^, @backstage/frontend-defaults@workspace:packages/frontend-defaults": + version: 0.0.0-use.local + resolution: "@backstage/frontend-defaults@workspace:packages/frontend-defaults" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/frontend-app-api": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" + "@backstage/plugin-app": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@react-hookz/web": ^24.0.0 + "@testing-library/jest-dom": ^6.0.0 + "@testing-library/react": ^15.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + languageName: unknown + linkType: soft + +"@backstage/frontend-plugin-api@npm:^0.7.0": + version: 0.7.0 + resolution: "@backstage/frontend-plugin-api@npm:0.7.0" + dependencies: + "@backstage/core-components": ^0.14.10 + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/types": ^1.1.1 + "@backstage/version-bridge": ^1.0.8 + "@material-ui/core": ^4.12.4 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + lodash: ^4.17.21 + zod: ^3.22.4 + zod-to-json-schema: ^3.21.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 11d11db0af0d57014f9c16de37a1871d951ec70cdda70b8f25d4a52d46cdbccaf8c94656c6d2c939689c9b3e4fb668d96becfd58d1c00f1e33c39cf9bad97d4a + languageName: node + linkType: hard + "@backstage/frontend-plugin-api@workspace:^, @backstage/frontend-plugin-api@workspace:packages/frontend-plugin-api": version: 0.0.0-use.local resolution: "@backstage/frontend-plugin-api@workspace:packages/frontend-plugin-api" @@ -4486,6 +4555,7 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/frontend-app-api": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" + "@backstage/plugin-app": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" "@testing-library/jest-dom": ^6.0.0 @@ -4516,7 +4586,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": +"@backstage/integration-react@^1.1.30, @backstage/integration-react@workspace:^, @backstage/integration-react@workspace:packages/integration-react": version: 0.0.0-use.local resolution: "@backstage/integration-react@workspace:packages/integration-react" dependencies: @@ -4680,6 +4750,34 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-app@workspace:^, @backstage/plugin-app@workspace:plugins/app": + version: 0.0.0-use.local + resolution: "@backstage/plugin-app@workspace:plugins/app" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/frontend-plugin-api": "workspace:^" + "@backstage/frontend-test-utils": "workspace:^" + "@backstage/plugin-permission-react": "workspace:^" + "@backstage/theme": "workspace:^" + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.61 + "@testing-library/jest-dom": ^6.0.0 + "@testing-library/react": ^15.0.0 + "@testing-library/user-event": ^14.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + msw: ^1.0.0 + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + languageName: unknown + linkType: soft + "@backstage/plugin-auth-backend-module-atlassian-provider@workspace:^, @backstage/plugin-auth-backend-module-atlassian-provider@workspace:plugins/auth-backend-module-atlassian-provider": version: 0.0.0-use.local resolution: "@backstage/plugin-auth-backend-module-atlassian-provider@workspace:plugins/auth-backend-module-atlassian-provider" @@ -5600,7 +5698,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": +"@backstage/plugin-catalog-common@^1.0.20, @backstage/plugin-catalog-common@^1.0.26, @backstage/plugin-catalog-common@workspace:^, @backstage/plugin-catalog-common@workspace:plugins/catalog-common": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-common@workspace:plugins/catalog-common" dependencies: @@ -5709,7 +5807,44 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@^1.12.2, @backstage/plugin-catalog-react@^1.9.3, @backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": +"@backstage/plugin-catalog-react@npm:^1.12.3, @backstage/plugin-catalog-react@npm:^1.9.3": + version: 1.12.3 + resolution: "@backstage/plugin-catalog-react@npm:1.12.3" + dependencies: + "@backstage/catalog-client": ^1.6.6 + "@backstage/catalog-model": ^1.6.0 + "@backstage/core-compat-api": ^0.2.8 + "@backstage/core-components": ^0.14.10 + "@backstage/core-plugin-api": ^1.9.3 + "@backstage/errors": ^1.2.4 + "@backstage/frontend-plugin-api": ^0.7.0 + "@backstage/integration-react": ^1.1.30 + "@backstage/plugin-catalog-common": ^1.0.26 + "@backstage/plugin-permission-common": ^0.8.1 + "@backstage/plugin-permission-react": ^0.4.25 + "@backstage/types": ^1.1.1 + "@backstage/version-bridge": ^1.0.8 + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.61 + "@react-hookz/web": ^24.0.0 + "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + classnames: ^2.2.6 + lodash: ^4.17.21 + material-ui-popup-state: ^1.9.3 + qs: ^6.9.4 + react-use: ^17.2.4 + yaml: ^2.0.0 + zen-observable: ^0.10.0 + peerDependencies: + react: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: c91126c51f8496fdc1fbf74de7334c38d691f062d2c62a623cc5bc4e8e12e8287362c41af0cf0003519f337fb78ba78644a34867c71406badc6b01d861f9c87d + languageName: node + linkType: hard + +"@backstage/plugin-catalog-react@workspace:^, @backstage/plugin-catalog-react@workspace:plugins/catalog-react": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-react@workspace:plugins/catalog-react" dependencies: @@ -5781,6 +5916,7 @@ __metadata: "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 "@types/react": ^16.13.1 || ^17.0.0 || ^18.0.0 + luxon: ^3.5.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 || ^18.0.0 @@ -6069,7 +6205,7 @@ __metadata: "@backstage/core-plugin-api": "workspace:^" "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 - "@rjsf/utils": 5.18.5 + "@rjsf/utils": 5.20.1 "@types/react": ^16.13.1 || ^17.0.0 "@types/react-grid-layout": ^1.3.2 peerDependencies: @@ -6100,10 +6236,10 @@ __metadata: "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 - "@rjsf/core": 5.18.5 - "@rjsf/material-ui": 5.18.5 - "@rjsf/utils": 5.18.5 - "@rjsf/validator-ajv8": 5.18.5 + "@rjsf/core": 5.20.1 + "@rjsf/material-ui": 5.20.1 + "@rjsf/utils": 5.20.1 + "@rjsf/validator-ajv8": 5.20.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 @@ -6339,6 +6475,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/integration-aws-node": "workspace:^" + "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-notifications-common": "workspace:^" "@backstage/plugin-notifications-node": "workspace:^" "@backstage/types": "workspace:^" @@ -6365,6 +6502,7 @@ __metadata: "@backstage/plugin-auth-backend": "workspace:^" "@backstage/plugin-auth-backend-module-guest-provider": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-events-backend": "workspace:^" "@backstage/plugin-events-node": "workspace:^" "@backstage/plugin-notifications-common": "workspace:^" @@ -6559,7 +6697,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": +"@backstage/plugin-permission-common@^0.8.1, @backstage/plugin-permission-common@workspace:^, @backstage/plugin-permission-common@workspace:plugins/permission-common": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-common@workspace:plugins/permission-common" dependencies: @@ -6598,7 +6736,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@^0.4.25, @backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": version: 0.0.0-use.local resolution: "@backstage/plugin-permission-react@workspace:plugins/permission-react" dependencies: @@ -6987,7 +7125,7 @@ __metadata: "@types/supertest": ^2.0.8 "@types/zen-observable": ^0.8.0 concat-stream: ^2.0.0 - esbuild: ^0.21.0 + esbuild: ^0.23.0 express: ^4.17.1 express-promise-router: ^4.1.0 fs-extra: ^11.2.0 @@ -7092,10 +7230,10 @@ __metadata: "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.61 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.18.5 - "@rjsf/material-ui": 5.18.5 - "@rjsf/utils": 5.18.5 - "@rjsf/validator-ajv8": 5.18.5 + "@rjsf/core": 5.20.1 + "@rjsf/material-ui": 5.20.1 + "@rjsf/utils": 5.20.1 + "@rjsf/validator-ajv8": 5.20.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 @@ -7115,7 +7253,7 @@ __metadata: qs: ^6.9.4 react-use: ^17.2.4 swr: ^2.0.0 - use-immer: ^0.9.0 + use-immer: ^0.10.0 zen-observable: ^0.10.0 zod: ^3.22.4 zod-to-json-schema: ^3.20.4 @@ -7159,10 +7297,10 @@ __metadata: "@material-ui/lab": 4.0.0-alpha.61 "@microsoft/fetch-event-source": ^2.0.1 "@react-hookz/web": ^24.0.0 - "@rjsf/core": 5.18.5 - "@rjsf/material-ui": 5.18.5 - "@rjsf/utils": 5.18.5 - "@rjsf/validator-ajv8": 5.18.5 + "@rjsf/core": 5.20.1 + "@rjsf/material-ui": 5.20.1 + "@rjsf/utils": 5.20.1 + "@rjsf/validator-ajv8": 5.20.1 "@testing-library/dom": ^10.0.0 "@testing-library/jest-dom": ^6.0.0 "@testing-library/react": ^15.0.0 @@ -7246,7 +7384,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-search-backend-module-explore@workspace:plugins/search-backend-module-explore" dependencies: - "@backstage-community/plugin-explore-common": ^0.0.4 + "@backstage-community/plugin-explore-common": ^0.0.5 "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -7584,6 +7722,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-catalog-common": "workspace:^" + "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-search-backend-module-techdocs": "workspace:^" "@backstage/plugin-techdocs-common": "workspace:^" @@ -7648,7 +7787,6 @@ __metadata: "@aws-sdk/types": ^3.347.0 "@azure/identity": ^4.0.0 "@azure/storage-blob": ^12.5.0 - "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/catalog-model": "workspace:^" @@ -7766,7 +7904,6 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-user-settings-backend@workspace:plugins/user-settings-backend" dependencies: - "@backstage/backend-common": "workspace:^" "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -7783,7 +7920,6 @@ __metadata: express-promise-router: ^4.1.0 knex: ^3.0.0 supertest: ^6.1.3 - winston: ^3.2.1 yn: ^4.0.0 languageName: unknown linkType: soft @@ -7873,7 +8009,7 @@ __metadata: "@types/is-glob": ^4.0.2 "@types/node": ^18.17.8 "@types/prettier": ^2.0.0 - "@useoptic/openapi-utilities": ^0.54.8 + "@useoptic/openapi-utilities": ^0.55.0 chalk: ^4.0.0 codeowners-utils: ^1.0.2 command-exists: ^1.2.9 @@ -7931,7 +8067,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/theme@^0.5.0, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": +"@backstage/theme@^0.5.0, @backstage/theme@^0.5.6, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": version: 0.0.0-use.local resolution: "@backstage/theme@workspace:packages/theme" dependencies: @@ -7962,7 +8098,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": +"@backstage/version-bridge@^1.0.7, @backstage/version-bridge@^1.0.8, @backstage/version-bridge@workspace:^, @backstage/version-bridge@workspace:packages/version-bridge": version: 0.0.0-use.local resolution: "@backstage/version-bridge@workspace:packages/version-bridge" dependencies: @@ -8016,15 +8152,24 @@ __metadata: languageName: node linkType: hard -"@changesets/apply-release-plan@npm:^7.0.4": - version: 7.0.4 - resolution: "@changesets/apply-release-plan@npm:7.0.4" +"@bundled-es-modules/tough-cookie@npm:^0.1.6": + version: 0.1.6 + resolution: "@bundled-es-modules/tough-cookie@npm:0.1.6" dependencies: - "@babel/runtime": ^7.20.1 - "@changesets/config": ^3.0.2 + "@types/tough-cookie": ^4.0.5 + tough-cookie: ^4.1.4 + checksum: e31c1262cbc044373e757117b1b152acc86ba5d088124153b3d1ae83e0de0a2b4d2362758cec3e1a49cf15c39a4447587cc2672e4f5a961754c91ef9ca3221e1 + languageName: node + linkType: hard + +"@changesets/apply-release-plan@npm:^7.0.5": + version: 7.0.5 + resolution: "@changesets/apply-release-plan@npm:7.0.5" + dependencies: + "@changesets/config": ^3.0.3 "@changesets/get-version-range-type": ^0.4.0 - "@changesets/git": ^3.0.0 - "@changesets/should-skip-package": ^0.1.0 + "@changesets/git": ^3.0.1 + "@changesets/should-skip-package": ^0.1.1 "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 detect-indent: ^6.0.0 @@ -8034,22 +8179,21 @@ __metadata: prettier: ^2.7.1 resolve-from: ^5.0.0 semver: ^7.5.3 - checksum: 5a61a8794fd4762e9270ffec474dc7c5d420c1d0479c5316a12e5264589882ccfb3ec08af6c0ebd07de2bf26ae880ad2f65e8f16d5886745aecf48cb11f625f5 + checksum: f6a1b90d89fd08b46c11fad05d5fee510ff8a1888c163fd6221ccfb045eab013fa57c0c32c5697d6406852a39cf4df01b44f3ecca4746f30bd610bec54aa9abf languageName: node linkType: hard -"@changesets/assemble-release-plan@npm:^6.0.3": - version: 6.0.3 - resolution: "@changesets/assemble-release-plan@npm:6.0.3" +"@changesets/assemble-release-plan@npm:^6.0.4": + version: 6.0.4 + resolution: "@changesets/assemble-release-plan@npm:6.0.4" dependencies: - "@babel/runtime": ^7.20.1 "@changesets/errors": ^0.2.0 - "@changesets/get-dependents-graph": ^2.1.1 - "@changesets/should-skip-package": ^0.1.0 + "@changesets/get-dependents-graph": ^2.1.2 + "@changesets/should-skip-package": ^0.1.1 "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 semver: ^7.5.3 - checksum: ae0ac29a44640fc6c0d3782c134adad3f0af80903ecb8bf663f0bf5f569586c9620980100737a05639f1a7252f145942ae62fa25d0757e89b5d6311abf899cd5 + checksum: 948066a8ca8e12390599f641a0439b6a4d6c1c2a9958f58596aa50cf68d7d594b28acc1eb6bd0ad17df2025f0614006e44728a2614fad2a3d54c669568bf6d65 languageName: node linkType: hard @@ -8063,59 +8207,57 @@ __metadata: linkType: hard "@changesets/cli@npm:^2.14.0": - version: 2.27.7 - resolution: "@changesets/cli@npm:2.27.7" + version: 2.27.8 + resolution: "@changesets/cli@npm:2.27.8" dependencies: - "@babel/runtime": ^7.20.1 - "@changesets/apply-release-plan": ^7.0.4 - "@changesets/assemble-release-plan": ^6.0.3 + "@changesets/apply-release-plan": ^7.0.5 + "@changesets/assemble-release-plan": ^6.0.4 "@changesets/changelog-git": ^0.2.0 - "@changesets/config": ^3.0.2 + "@changesets/config": ^3.0.3 "@changesets/errors": ^0.2.0 - "@changesets/get-dependents-graph": ^2.1.1 - "@changesets/get-release-plan": ^4.0.3 - "@changesets/git": ^3.0.0 - "@changesets/logger": ^0.1.0 - "@changesets/pre": ^2.0.0 - "@changesets/read": ^0.6.0 - "@changesets/should-skip-package": ^0.1.0 + "@changesets/get-dependents-graph": ^2.1.2 + "@changesets/get-release-plan": ^4.0.4 + "@changesets/git": ^3.0.1 + "@changesets/logger": ^0.1.1 + "@changesets/pre": ^2.0.1 + "@changesets/read": ^0.6.1 + "@changesets/should-skip-package": ^0.1.1 "@changesets/types": ^6.0.0 - "@changesets/write": ^0.3.1 + "@changesets/write": ^0.3.2 "@manypkg/get-packages": ^1.1.3 "@types/semver": ^7.5.0 ansi-colors: ^4.1.3 - chalk: ^2.1.0 ci-info: ^3.7.0 enquirer: ^2.3.0 external-editor: ^3.1.0 fs-extra: ^7.0.1 - human-id: ^1.0.2 mri: ^1.2.0 outdent: ^0.5.0 p-limit: ^2.2.0 - preferred-pm: ^3.0.0 + package-manager-detector: ^0.2.0 + picocolors: ^1.1.0 resolve-from: ^5.0.0 semver: ^7.5.3 spawndamnit: ^2.0.0 term-size: ^2.1.0 bin: changeset: bin.js - checksum: f518121a516ce8186dfc71dcca2f4be5fea28fe29a54b038aa787964bb4d4f1e866840d6d765776db33f7723d1a850ee4a38ed726f302a26e2e56a5e2b9422e8 + checksum: b58386716b337976d5797debd4a418fb257bec1e6c9932b99eac7725dd5a76fceff32691c625f897fd4baa78aa2bfba9747fbacf7d8193197f9246b36d31c013 languageName: node linkType: hard -"@changesets/config@npm:^3.0.2": - version: 3.0.2 - resolution: "@changesets/config@npm:3.0.2" +"@changesets/config@npm:^3.0.3": + version: 3.0.3 + resolution: "@changesets/config@npm:3.0.3" dependencies: "@changesets/errors": ^0.2.0 - "@changesets/get-dependents-graph": ^2.1.1 - "@changesets/logger": ^0.1.0 + "@changesets/get-dependents-graph": ^2.1.2 + "@changesets/logger": ^0.1.1 "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 fs-extra: ^7.0.1 micromatch: ^4.0.2 - checksum: 4160e59f74c1f36a2d3d011868f83c46410553f9fc164a83dde46ec7e37f13ba983526b9c299de3cd3f317e5e42808a991959931c9d34f2913f3e8d4c515cd12 + checksum: f216f497e09c0fcdd4c397fc3998d1651a171b89981d2bed2a6c23c0f55ffa4e240cadbd13902bf91c218686165689a5183674a5b4682d80d3d5b8b9c569f5f1 languageName: node linkType: hard @@ -8128,31 +8270,29 @@ __metadata: languageName: node linkType: hard -"@changesets/get-dependents-graph@npm:^2.1.1": - version: 2.1.1 - resolution: "@changesets/get-dependents-graph@npm:2.1.1" +"@changesets/get-dependents-graph@npm:^2.1.2": + version: 2.1.2 + resolution: "@changesets/get-dependents-graph@npm:2.1.2" dependencies: "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 - chalk: ^2.1.0 - fs-extra: ^7.0.1 + picocolors: ^1.1.0 semver: ^7.5.3 - checksum: e427603a3cad3690deec86a5831f15766dc32dc0819532e3ad70fbda027317bb46bb207c6a3bc947daf00e5e8229a01dd67aa3ec7248aa11f87611a7ecd74097 + checksum: 38446343e43f9b8731098e3b42d2525d5399d59cfccc09bdb62c9a48de60c7a893882050202badca3b5cab8405e6deb82e88258a56a318e42749fa60d96d874a languageName: node linkType: hard -"@changesets/get-release-plan@npm:^4.0.3": - version: 4.0.3 - resolution: "@changesets/get-release-plan@npm:4.0.3" +"@changesets/get-release-plan@npm:^4.0.4": + version: 4.0.4 + resolution: "@changesets/get-release-plan@npm:4.0.4" dependencies: - "@babel/runtime": ^7.20.1 - "@changesets/assemble-release-plan": ^6.0.3 - "@changesets/config": ^3.0.2 - "@changesets/pre": ^2.0.0 - "@changesets/read": ^0.6.0 + "@changesets/assemble-release-plan": ^6.0.4 + "@changesets/config": ^3.0.3 + "@changesets/pre": ^2.0.1 + "@changesets/read": ^0.6.1 "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 - checksum: baf01eb124f95df729e1798c23e4ac1996acd74e0d22336492e4a0fd68f3a19c97197337fdcb58d47d0b580ca38e0b0888cbacaa1c99d7c173c3cecb859ab4cc + checksum: 7217347f5bfaa56f97d3964e28e23a109d60c42b7c879c0cab6934feb30bdbdebb6dd0e81b4ecb5ec414be442d566b6af90d9224f6a48a52b6c5269c337f54a6 languageName: node linkType: hard @@ -8163,27 +8303,25 @@ __metadata: languageName: node linkType: hard -"@changesets/git@npm:^3.0.0": - version: 3.0.0 - resolution: "@changesets/git@npm:3.0.0" +"@changesets/git@npm:^3.0.1": + version: 3.0.1 + resolution: "@changesets/git@npm:3.0.1" dependencies: - "@babel/runtime": ^7.20.1 "@changesets/errors": ^0.2.0 - "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 is-subdir: ^1.1.1 micromatch: ^4.0.2 spawndamnit: ^2.0.0 - checksum: a8fa66d77302b50d5e604aca898ee813247537d23a05004637ecee4aa1579d6a2859283c099bdcf3e2b232258c93ff81dd57aa867858788e457df40118c64c2b + checksum: 46d780fecd3dbdafde7c96dde7fe35a8461bc6edbff1de92d490971a99f021d60c5b4606a1d4fb778567146810090ede6610cf89407c14bde88edaa246801539 languageName: node linkType: hard -"@changesets/logger@npm:^0.1.0": - version: 0.1.0 - resolution: "@changesets/logger@npm:0.1.0" +"@changesets/logger@npm:^0.1.1": + version: 0.1.1 + resolution: "@changesets/logger@npm:0.1.1" dependencies: - chalk: ^2.1.0 - checksum: d8ef1b7caf3d2c15a9e7743b7a9462e0c2e61c76d9a5bbed5eff805afa8226117505309c6e9095001136b4f6d9ae0aba61377e53af8aa0809f1febd1b5f787f1 + picocolors: ^1.1.0 + checksum: acca50ef6bf6e446b46eb576b32f1955bf4579dbf4bbc316768ed2c1d4ba4066c9c73b114eedefaa1b3e360b1060a020e6bd3dbdbc44b74da732df92307beab0 languageName: node linkType: hard @@ -8197,43 +8335,40 @@ __metadata: languageName: node linkType: hard -"@changesets/pre@npm:^2.0.0": - version: 2.0.0 - resolution: "@changesets/pre@npm:2.0.0" +"@changesets/pre@npm:^2.0.1": + version: 2.0.1 + resolution: "@changesets/pre@npm:2.0.1" dependencies: - "@babel/runtime": ^7.20.1 "@changesets/errors": ^0.2.0 "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 fs-extra: ^7.0.1 - checksum: 6a01086405f4e4ce63abb8f222de39b69a5762c9c8c8f19c0d3c72f7798248d7a152937028f1be24be1f8a4a5e47e4cb23c54bc36f979539b24a728c893caf4e + checksum: fbe94283dce0223ee79c12fa221105752ac89eb885b77e300ec755682cb06cc0145e10335f4bc6cb26d63473e549556c2b1c8c866242419aee5e41986379652a languageName: node linkType: hard -"@changesets/read@npm:^0.6.0": - version: 0.6.0 - resolution: "@changesets/read@npm:0.6.0" +"@changesets/read@npm:^0.6.1": + version: 0.6.1 + resolution: "@changesets/read@npm:0.6.1" dependencies: - "@babel/runtime": ^7.20.1 - "@changesets/git": ^3.0.0 - "@changesets/logger": ^0.1.0 + "@changesets/git": ^3.0.1 + "@changesets/logger": ^0.1.1 "@changesets/parse": ^0.4.0 "@changesets/types": ^6.0.0 - chalk: ^2.1.0 fs-extra: ^7.0.1 p-filter: ^2.1.0 - checksum: 3da6428124b4983f6ccbdae324c73044cd6a84269bfdbaff545331042e3d6845c647613b5d8f4ffdd48bad5b791623eca2be1b507652ea47b77e136cd2e26c70 + picocolors: ^1.1.0 + checksum: d00a18a3d04af5c76e7b763096650ebe16589864ab04eaf9e99c88aa77542f64de547b585037fc204d2055f9dd47fae94c789e2f173d3507a4e29dbe6609dd5b languageName: node linkType: hard -"@changesets/should-skip-package@npm:^0.1.0": - version: 0.1.0 - resolution: "@changesets/should-skip-package@npm:0.1.0" +"@changesets/should-skip-package@npm:^0.1.1": + version: 0.1.1 + resolution: "@changesets/should-skip-package@npm:0.1.1" dependencies: - "@babel/runtime": ^7.20.1 "@changesets/types": ^6.0.0 "@manypkg/get-packages": ^1.1.3 - checksum: 3c966feae085a41d4ce10a46a1b525f980cec59951f7cf23ea805866b370de5c75fdd45af326e1a5ef502fa4846f821d9df15550c2b606b96e99ed4b967f01c0 + checksum: d187ef22495deb63e678d0ff65e8627701e2b52c25bd59dde10ce8646be8d605c0ed0a6af020dd825b137c2fc748fdc6cef52e7774bad4c7a4f404bf182a85cf languageName: node linkType: hard @@ -8251,16 +8386,15 @@ __metadata: languageName: node linkType: hard -"@changesets/write@npm:^0.3.1": - version: 0.3.1 - resolution: "@changesets/write@npm:0.3.1" +"@changesets/write@npm:^0.3.2": + version: 0.3.2 + resolution: "@changesets/write@npm:0.3.2" dependencies: - "@babel/runtime": ^7.20.1 "@changesets/types": ^6.0.0 fs-extra: ^7.0.1 human-id: ^1.0.2 prettier: ^2.7.1 - checksum: 6df0447e05ededbab71f36e6ad23aa77cf06eb6adda7a8b8e7fb9d6bd5bc93acceb916d55b2a37cb7e93fb05d39a236a0dd7ade5243aae4772885081101d4784 + checksum: 553ed0ba6bd6397784f5e0e2921794bd7417a3c4fb810f1abb15e7072bf9d312af74308ff743161c6ea01478884cebcaf9cee02e5c70e2c7552b2774960ee07c languageName: node linkType: hard @@ -8358,13 +8492,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.23.0": - version: 6.32.0 - resolution: "@codemirror/view@npm:6.32.0" + version: 6.33.0 + resolution: "@codemirror/view@npm:6.33.0" dependencies: "@codemirror/state": ^6.4.0 style-mod: ^4.1.0 w3c-keyname: ^2.2.4 - checksum: 74a68694c1a7142f6b404de2ffe3a9af327065af8451a890e4e6bdc18e0eb1d4b34afd9aa917ca8eef280827fc361b5cbae5b6d79775b91dd68d5526553aedc5 + checksum: e28896a7fb40df8e7221fbebfc2cd92c10c6963948e20f3a4300e99c897fbddd091f4fc90cc30eeaf90d07c61dcf6170cd3c164810606fa07337ffb970ffdac2 languageName: node linkType: hard @@ -8448,35 +8582,35 @@ __metadata: languageName: node linkType: hard -"@emotion/babel-plugin@npm:^11.11.0": - version: 11.11.0 - resolution: "@emotion/babel-plugin@npm:11.11.0" +"@emotion/babel-plugin@npm:^11.12.0": + version: 11.12.0 + resolution: "@emotion/babel-plugin@npm:11.12.0" dependencies: "@babel/helper-module-imports": ^7.16.7 "@babel/runtime": ^7.18.3 - "@emotion/hash": ^0.9.1 - "@emotion/memoize": ^0.8.1 - "@emotion/serialize": ^1.1.2 + "@emotion/hash": ^0.9.2 + "@emotion/memoize": ^0.9.0 + "@emotion/serialize": ^1.2.0 babel-plugin-macros: ^3.1.0 convert-source-map: ^1.5.0 escape-string-regexp: ^4.0.0 find-root: ^1.1.0 source-map: ^0.5.7 stylis: 4.2.0 - checksum: 6b363edccc10290f7a23242c06f88e451b5feb2ab94152b18bb8883033db5934fb0e421e2d67d09907c13837c21218a3ac28c51707778a54d6cd3706c0c2f3f9 + checksum: b5d4b3dfe97e6763794a42b5c3a027a560caa1aa6dcaf05c18e5969691368dd08245c077bad7397dcc720b53d29caeaaec1888121e68cfd9ab02ff52f6fef662 languageName: node linkType: hard -"@emotion/cache@npm:^11.11.0": - version: 11.11.0 - resolution: "@emotion/cache@npm:11.11.0" +"@emotion/cache@npm:^11.11.0, @emotion/cache@npm:^11.13.0": + version: 11.13.1 + resolution: "@emotion/cache@npm:11.13.1" dependencies: - "@emotion/memoize": ^0.8.1 - "@emotion/sheet": ^1.2.2 - "@emotion/utils": ^1.2.1 - "@emotion/weak-memoize": ^0.3.1 + "@emotion/memoize": ^0.9.0 + "@emotion/sheet": ^1.4.0 + "@emotion/utils": ^1.4.0 + "@emotion/weak-memoize": ^0.4.0 stylis: 4.2.0 - checksum: 8eb1dc22beaa20c21a2e04c284d5a2630a018a9d51fb190e52de348c8d27f4e8ca4bbab003d68b4f6cd9cc1c569ca747a997797e0f76d6c734a660dc29decf08 + checksum: 94b161786a03a08a1e30257478fad9a9be1ac8585ddca0c6410d7411fd474fc8b0d6d1167d7d15bdb012d1fd8a1220ac2bbc79501ad9b292b83c17da0874d7de languageName: node linkType: hard @@ -8487,10 +8621,10 @@ __metadata: languageName: node linkType: hard -"@emotion/hash@npm:^0.9.1": - version: 0.9.1 - resolution: "@emotion/hash@npm:0.9.1" - checksum: 716e17e48bf9047bf9383982c071de49f2615310fb4e986738931776f5a823bc1f29c84501abe0d3df91a3803c80122d24e28b57351bca9e01356ebb33d89876 +"@emotion/hash@npm:^0.9.1, @emotion/hash@npm:^0.9.2": + version: 0.9.2 + resolution: "@emotion/hash@npm:0.9.2" + checksum: 379bde2830ccb0328c2617ec009642321c0e009a46aa383dfbe75b679c6aea977ca698c832d225a893901f29d7b3eef0e38cf341f560f6b2b56f1ff23c172387 languageName: node linkType: hard @@ -8503,12 +8637,12 @@ __metadata: languageName: node linkType: hard -"@emotion/is-prop-valid@npm:^1.1.0, @emotion/is-prop-valid@npm:^1.2.2": - version: 1.2.2 - resolution: "@emotion/is-prop-valid@npm:1.2.2" +"@emotion/is-prop-valid@npm:^1.1.0, @emotion/is-prop-valid@npm:^1.3.0": + version: 1.3.0 + resolution: "@emotion/is-prop-valid@npm:1.3.0" dependencies: - "@emotion/memoize": ^0.8.1 - checksum: 61f6b128ea62b9f76b47955057d5d86fcbe2a6989d2cd1e583daac592901a950475a37d049b9f7a7c6aa8758a33b408735db759fdedfd1f629df0f85ab60ea25 + "@emotion/memoize": ^0.9.0 + checksum: d3e36e493de3b4446634010c46cb8b99fa8ca271a8e7efba9cecf59a672ce1ebcfea8e8c7a0627dcafae87b4ab0d58c70fcf4589b849ca48e0d1e9f6c899e8be languageName: node linkType: hard @@ -8519,71 +8653,71 @@ __metadata: languageName: node linkType: hard -"@emotion/memoize@npm:^0.8.1": - version: 0.8.1 - resolution: "@emotion/memoize@npm:0.8.1" - checksum: a19cc01a29fcc97514948eaab4dc34d8272e934466ed87c07f157887406bc318000c69ae6f813a9001c6a225364df04249842a50e692ef7a9873335fbcc141b0 +"@emotion/memoize@npm:^0.9.0": + version: 0.9.0 + resolution: "@emotion/memoize@npm:0.9.0" + checksum: 038132359397348e378c593a773b1148cd0cf0a2285ffd067a0f63447b945f5278860d9de718f906a74c7c940ba1783ac2ca18f1c06a307b01cc0e3944e783b1 languageName: node linkType: hard "@emotion/react@npm:^11.10.5": - version: 11.11.4 - resolution: "@emotion/react@npm:11.11.4" + version: 11.13.3 + resolution: "@emotion/react@npm:11.13.3" dependencies: "@babel/runtime": ^7.18.3 - "@emotion/babel-plugin": ^11.11.0 - "@emotion/cache": ^11.11.0 - "@emotion/serialize": ^1.1.3 - "@emotion/use-insertion-effect-with-fallbacks": ^1.0.1 - "@emotion/utils": ^1.2.1 - "@emotion/weak-memoize": ^0.3.1 + "@emotion/babel-plugin": ^11.12.0 + "@emotion/cache": ^11.13.0 + "@emotion/serialize": ^1.3.1 + "@emotion/use-insertion-effect-with-fallbacks": ^1.1.0 + "@emotion/utils": ^1.4.0 + "@emotion/weak-memoize": ^0.4.0 hoist-non-react-statics: ^3.3.1 peerDependencies: react: ">=16.8.0" peerDependenciesMeta: "@types/react": optional: true - checksum: 6abaa7a05c5e1db31bffca7ac79169f5456990022cbb3794e6903221536609a60420f2b4888dd3f84e9634a304e394130cb88dc32c243a1dedc263e50da329f8 + checksum: 0b58374bf28de914b49881f0060acfb908989869ebab63a2287773fc5e91a39f15552632b03d376c3e9835c5b4f23a5ebac8b0963b29af164d46c0a77ac928f0 languageName: node linkType: hard -"@emotion/serialize@npm:^1.1.2, @emotion/serialize@npm:^1.1.3, @emotion/serialize@npm:^1.1.4": - version: 1.1.4 - resolution: "@emotion/serialize@npm:1.1.4" +"@emotion/serialize@npm:^1.2.0, @emotion/serialize@npm:^1.3.0, @emotion/serialize@npm:^1.3.1": + version: 1.3.1 + resolution: "@emotion/serialize@npm:1.3.1" dependencies: - "@emotion/hash": ^0.9.1 - "@emotion/memoize": ^0.8.1 - "@emotion/unitless": ^0.8.1 - "@emotion/utils": ^1.2.1 + "@emotion/hash": ^0.9.2 + "@emotion/memoize": ^0.9.0 + "@emotion/unitless": ^0.10.0 + "@emotion/utils": ^1.4.0 csstype: ^3.0.2 - checksum: 71b99f816a9c1d61a87c62cf4928da3894bb62213f3aff38b1ea9790b3368f084af98a3e5453b5055c2f36a7d70318d2fa9955b7b5676c2065b868062375df39 + checksum: 9a488b1ef8b1609a0a80a957c2e9387703c148bb6444e0b097957cfca5c501191e870d11bae32d73ffeb5fd653961b8dbbd1c2c7e371b062029c0ed31d34162e languageName: node linkType: hard -"@emotion/sheet@npm:^1.2.2": - version: 1.2.2 - resolution: "@emotion/sheet@npm:1.2.2" - checksum: d973273c9c15f1c291ca2269728bf044bd3e92a67bca87943fa9ec6c3cd2b034f9a6bfe95ef1b5d983351d128c75b547b43ff196a00a3875f7e1d269793cecfe +"@emotion/sheet@npm:^1.4.0": + version: 1.4.0 + resolution: "@emotion/sheet@npm:1.4.0" + checksum: eeb1212e3289db8e083e72e7e401cd6d1a84deece87e9ce184f7b96b9b5dbd6f070a89057255a6ff14d9865c3ce31f27c39248a053e4cdd875540359042586b4 languageName: node linkType: hard "@emotion/styled@npm:^11.10.5": - version: 11.11.5 - resolution: "@emotion/styled@npm:11.11.5" + version: 11.13.0 + resolution: "@emotion/styled@npm:11.13.0" dependencies: "@babel/runtime": ^7.18.3 - "@emotion/babel-plugin": ^11.11.0 - "@emotion/is-prop-valid": ^1.2.2 - "@emotion/serialize": ^1.1.4 - "@emotion/use-insertion-effect-with-fallbacks": ^1.0.1 - "@emotion/utils": ^1.2.1 + "@emotion/babel-plugin": ^11.12.0 + "@emotion/is-prop-valid": ^1.3.0 + "@emotion/serialize": ^1.3.0 + "@emotion/use-insertion-effect-with-fallbacks": ^1.1.0 + "@emotion/utils": ^1.4.0 peerDependencies: "@emotion/react": ^11.0.0-rc.0 react: ">=16.8.0" peerDependenciesMeta: "@types/react": optional: true - checksum: ad5fc42d00e8aa9597f6d9665986036d5ebe0e8f8155af6d95831c5e8fb2319fb837724e6c5cd59e5346f14c3263711b7ce7271d34688e974d1f32ffeecb37ba + checksum: f5b951059418f57bc8ea32b238afb25965ece3314f2ffd1b14ce049ba3c066a424990dfbfabbf57bb88e044eaa80bf19f620ac988adda3d2fc483177be6da05e languageName: node linkType: hard @@ -8594,6 +8728,13 @@ __metadata: languageName: node linkType: hard +"@emotion/unitless@npm:^0.10.0": + version: 0.10.0 + resolution: "@emotion/unitless@npm:0.10.0" + checksum: d79346df31a933e6d33518e92636afeb603ce043f3857d0a39a2ac78a09ef0be8bedff40130930cb25df1beeee12d96ee38613963886fa377c681a89970b787c + languageName: node + linkType: hard + "@emotion/unitless@npm:^0.7.4": version: 0.7.5 resolution: "@emotion/unitless@npm:0.7.5" @@ -8601,65 +8742,26 @@ __metadata: languageName: node linkType: hard -"@emotion/unitless@npm:^0.8.1": - version: 0.8.1 - resolution: "@emotion/unitless@npm:0.8.1" - checksum: 385e21d184d27853bb350999471f00e1429fa4e83182f46cd2c164985999d9b46d558dc8b9cc89975cb337831ce50c31ac2f33b15502e85c299892e67e7b4a88 - languageName: node - linkType: hard - -"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.1": - version: 1.0.1 - resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.1" +"@emotion/use-insertion-effect-with-fallbacks@npm:^1.1.0": + version: 1.1.0 + resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.1.0" peerDependencies: react: ">=16.8.0" - checksum: 700b6e5bbb37a9231f203bb3af11295eed01d73b2293abece0bc2a2237015e944d7b5114d4887ad9a79776504aa51ed2a8b0ddbc117c54495dd01a6b22f93786 + checksum: 63665191773b27de66807c53b90091ef0d10d5161381f62726cfceecfe1d8c944f18594b8021805fc81575b64246fd5ab9c75d60efabec92f940c1c410530949 languageName: node linkType: hard -"@emotion/utils@npm:^1.2.1": - version: 1.2.1 - resolution: "@emotion/utils@npm:1.2.1" - checksum: e0b44be0705b56b079c55faff93952150be69e79b660ae70ddd5b6e09fc40eb1319654315a9f34bb479d7f4ec94be6068c061abbb9e18b9778ae180ad5d97c73 +"@emotion/utils@npm:^1.4.0": + version: 1.4.0 + resolution: "@emotion/utils@npm:1.4.0" + checksum: 212af0b0d6bcaa63c76e1a36e35bee4d3579359316c03bf970faabb5427a4c0aab3e2346a721bac54f0c8e027958e759c5682be78f308755a1d9753e83963621 languageName: node linkType: hard -"@emotion/weak-memoize@npm:^0.3.1": - version: 0.3.1 - resolution: "@emotion/weak-memoize@npm:0.3.1" - checksum: b2be47caa24a8122622ea18cd2d650dbb4f8ad37b636dc41ed420c2e082f7f1e564ecdea68122b546df7f305b159bf5ab9ffee872abd0f052e687428459af594 - languageName: node - linkType: hard - -"@ericcornelissen/bash-parser@npm:0.5.3": - version: 0.5.3 - resolution: "@ericcornelissen/bash-parser@npm:0.5.3" - dependencies: - array-last: ^1.1.1 - babylon: ^6.9.1 - compose-function: ^3.0.3 - filter-obj: ^1.1.0 - has-own-property: ^0.1.0 - identity-function: ^1.0.0 - is-iterable: ^1.1.0 - iterable-lookahead: ^1.0.0 - lodash.curry: ^4.1.1 - magic-string: ^0.16.0 - map-obj: ^2.0.0 - object-pairs: ^0.1.0 - object-values: ^1.0.0 - reverse-arguments: ^1.0.0 - shell-quote-word: ^1.0.1 - to-pascal-case: ^1.0.0 - unescape-js: ^1.0.5 - checksum: b3f6c899ea3240000b83674d37c744e2ae06e776b2f76129db9fcd397d77f2cb84c1c560ce318395fffc6a2b5edb1ec513a8c67514f4ea0229d9d87095955ac5 - languageName: node - linkType: hard - -"@esbuild/aix-ppc64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/aix-ppc64@npm:0.20.2" - conditions: os=aix & cpu=ppc64 +"@emotion/weak-memoize@npm:^0.4.0": + version: 0.4.0 + resolution: "@emotion/weak-memoize@npm:0.4.0" + checksum: db5da0e89bd752c78b6bd65a1e56231f0abebe2f71c0bd8fc47dff96408f7065b02e214080f99924f6a3bfe7ee15afc48dad999d76df86b39b16e513f7a94f52 languageName: node linkType: hard @@ -8670,17 +8772,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm64@npm:0.18.20" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/android-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-arm64@npm:0.20.2" - conditions: os=android & cpu=arm64 +"@esbuild/aix-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/aix-ppc64@npm:0.23.1" + conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -8691,17 +8786,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-arm@npm:0.18.20" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@esbuild/android-arm@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-arm@npm:0.20.2" - conditions: os=android & cpu=arm +"@esbuild/android-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm64@npm:0.23.1" + conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -8712,17 +8800,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/android-x64@npm:0.18.20" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/android-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-x64@npm:0.20.2" - conditions: os=android & cpu=x64 +"@esbuild/android-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm@npm:0.23.1" + conditions: os=android & cpu=arm languageName: node linkType: hard @@ -8733,17 +8814,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-arm64@npm:0.18.20" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/darwin-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/darwin-arm64@npm:0.20.2" - conditions: os=darwin & cpu=arm64 +"@esbuild/android-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-x64@npm:0.23.1" + conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -8754,17 +8828,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/darwin-x64@npm:0.18.20" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/darwin-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/darwin-x64@npm:0.20.2" - conditions: os=darwin & cpu=x64 +"@esbuild/darwin-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-arm64@npm:0.23.1" + conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -8775,17 +8842,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-arm64@npm:0.18.20" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/freebsd-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/freebsd-arm64@npm:0.20.2" - conditions: os=freebsd & cpu=arm64 +"@esbuild/darwin-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-x64@npm:0.23.1" + conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -8796,17 +8856,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/freebsd-x64@npm:0.18.20" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/freebsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/freebsd-x64@npm:0.20.2" - conditions: os=freebsd & cpu=x64 +"@esbuild/freebsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-arm64@npm:0.23.1" + conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -8817,17 +8870,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm64@npm:0.18.20" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/linux-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-arm64@npm:0.20.2" - conditions: os=linux & cpu=arm64 +"@esbuild/freebsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-x64@npm:0.23.1" + conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -8838,17 +8884,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-arm@npm:0.18.20" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@esbuild/linux-arm@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-arm@npm:0.20.2" - conditions: os=linux & cpu=arm +"@esbuild/linux-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm64@npm:0.23.1" + conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -8859,17 +8898,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ia32@npm:0.18.20" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/linux-ia32@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-ia32@npm:0.20.2" - conditions: os=linux & cpu=ia32 +"@esbuild/linux-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm@npm:0.23.1" + conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -8880,17 +8912,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-loong64@npm:0.18.20" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - -"@esbuild/linux-loong64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-loong64@npm:0.20.2" - conditions: os=linux & cpu=loong64 +"@esbuild/linux-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ia32@npm:0.23.1" + conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -8901,17 +8926,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-mips64el@npm:0.18.20" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - -"@esbuild/linux-mips64el@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-mips64el@npm:0.20.2" - conditions: os=linux & cpu=mips64el +"@esbuild/linux-loong64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-loong64@npm:0.23.1" + conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -8922,17 +8940,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-ppc64@npm:0.18.20" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - -"@esbuild/linux-ppc64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-ppc64@npm:0.20.2" - conditions: os=linux & cpu=ppc64 +"@esbuild/linux-mips64el@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-mips64el@npm:0.23.1" + conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -8943,17 +8954,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-riscv64@npm:0.18.20" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - -"@esbuild/linux-riscv64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-riscv64@npm:0.20.2" - conditions: os=linux & cpu=riscv64 +"@esbuild/linux-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ppc64@npm:0.23.1" + conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -8964,17 +8968,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-s390x@npm:0.18.20" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - -"@esbuild/linux-s390x@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-s390x@npm:0.20.2" - conditions: os=linux & cpu=s390x +"@esbuild/linux-riscv64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-riscv64@npm:0.23.1" + conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -8985,17 +8982,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/linux-x64@npm:0.18.20" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/linux-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-x64@npm:0.20.2" - conditions: os=linux & cpu=x64 +"@esbuild/linux-s390x@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-s390x@npm:0.23.1" + conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -9006,17 +8996,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/netbsd-x64@npm:0.18.20" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/netbsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/netbsd-x64@npm:0.20.2" - conditions: os=netbsd & cpu=x64 +"@esbuild/linux-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-x64@npm:0.23.1" + conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -9027,17 +9010,17 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/openbsd-x64@npm:0.18.20" - conditions: os=openbsd & cpu=x64 +"@esbuild/netbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/netbsd-x64@npm:0.23.1" + conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/openbsd-x64@npm:0.20.2" - conditions: os=openbsd & cpu=x64 +"@esbuild/openbsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-arm64@npm:0.23.1" + conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard @@ -9048,17 +9031,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/sunos-x64@npm:0.18.20" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/sunos-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/sunos-x64@npm:0.20.2" - conditions: os=sunos & cpu=x64 +"@esbuild/openbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-x64@npm:0.23.1" + conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -9069,17 +9045,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-arm64@npm:0.18.20" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@esbuild/win32-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-arm64@npm:0.20.2" - conditions: os=win32 & cpu=arm64 +"@esbuild/sunos-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/sunos-x64@npm:0.23.1" + conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -9090,17 +9059,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-ia32@npm:0.18.20" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@esbuild/win32-ia32@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-ia32@npm:0.20.2" - conditions: os=win32 & cpu=ia32 +"@esbuild/win32-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-arm64@npm:0.23.1" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -9111,17 +9073,10 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.18.20": - version: 0.18.20 - resolution: "@esbuild/win32-x64@npm:0.18.20" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@esbuild/win32-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-x64@npm:0.20.2" - conditions: os=win32 & cpu=x64 +"@esbuild/win32-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-ia32@npm:0.23.1" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -9132,6 +9087,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-x64@npm:0.23.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.4.0 resolution: "@eslint-community/eslint-utils@npm:4.4.0" @@ -9181,6 +9143,13 @@ __metadata: languageName: node linkType: hard +"@fastify/busboy@npm:^2.0.0": + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 42c32ef75e906c9a4809c1e1930a5ca6d4ddc8d138e1a8c8ba5ea07f997db32210617d23b2e4a85fe376316a41a1a0439fc6ff2dedf5126d96f45a9d80754fb2 + languageName: node + linkType: hard + "@floating-ui/core@npm:^1.0.0": version: 1.6.0 resolution: "@floating-ui/core@npm:1.6.0" @@ -9200,7 +9169,7 @@ __metadata: languageName: node linkType: hard -"@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.0.8": +"@floating-ui/react-dom@npm:^2.0.0": version: 2.0.8 resolution: "@floating-ui/react-dom@npm:2.0.8" dependencies: @@ -9251,14 +9220,14 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/core@npm:^40.0.3": - version: 40.0.3 - resolution: "@gitbeaker/core@npm:40.0.3" +"@gitbeaker/core@npm:^40.1.4": + version: 40.1.4 + resolution: "@gitbeaker/core@npm:40.1.4" dependencies: - "@gitbeaker/requester-utils": ^40.0.3 - qs: ^6.11.2 + "@gitbeaker/requester-utils": ^40.1.4 + qs: ^6.12.2 xcase: ^2.0.1 - checksum: 999cea3f1523eabfae473e8a21849fdd4f6b4d30f0de681e735b238713b198ff9381c35d2ba5949d27ddc7ed5a953b14fc5a6ed38a5d98b05b6a5670a0c69162 + checksum: 21a3dde1013e78ee2f03cfcdb5a5e4ee270a186b491bf76890799b0687b7afda56213c4e8fe97dfe104e51128a09f4b4c72f1ba3d10ab323413a5398c59dcbe7 languageName: node linkType: hard @@ -9298,15 +9267,15 @@ __metadata: languageName: node linkType: hard -"@gitbeaker/requester-utils@npm:^40.0.3": - version: 40.0.3 - resolution: "@gitbeaker/requester-utils@npm:40.0.3" +"@gitbeaker/requester-utils@npm:^40.1.4": + version: 40.1.4 + resolution: "@gitbeaker/requester-utils@npm:40.1.4" dependencies: picomatch-browser: ^2.2.6 - qs: ^6.11.2 - rate-limiter-flexible: ^4.0.0 + qs: ^6.12.2 + rate-limiter-flexible: ^4.0.1 xcase: ^2.0.1 - checksum: 1a46dc9c730c29e2229b04ed9bbe6cd87b7e5f16c1d0a5e78106f0287ab3d981ce2b099eb41cdb0f9180bb6b11d25f5f1fa92a91b69682bcd4ac986e58b55d31 + checksum: 4edcb0011b3b305f58c856cbb3a8e09f9f1c32c34179cc222a82192a3e3c9d8c50fae39b7bfe47a16564ba8f2f5138d0a143011d59979b1bf8202db9cb202611 languageName: node linkType: hard @@ -9321,21 +9290,21 @@ __metadata: linkType: hard "@gitbeaker/rest@npm:^40.0.3": - version: 40.0.3 - resolution: "@gitbeaker/rest@npm:40.0.3" + version: 40.1.4 + resolution: "@gitbeaker/rest@npm:40.1.4" dependencies: - "@gitbeaker/core": ^40.0.3 - "@gitbeaker/requester-utils": ^40.0.3 - checksum: 6a6427b82ee3357fbe07e1235de7a3c98d50155898180fbe4dd641c8575faa93853f1a39185e18876f84469e1a385ccd9beb26fd95b61c260b81eb0ed342355b + "@gitbeaker/core": ^40.1.4 + "@gitbeaker/requester-utils": ^40.1.4 + checksum: 8182546ab331af01afe253fb429e5f7fe19a93e889fc5859a72ce4d1a4925d3c083d2461740ed2a9454580f8fef7bdbcf4a375803c1e725b61bafcc879084672 languageName: node linkType: hard "@google-cloud/container@npm:^5.0.0": - version: 5.15.0 - resolution: "@google-cloud/container@npm:5.15.0" + version: 5.17.0 + resolution: "@google-cloud/container@npm:5.17.0" dependencies: google-gax: ^4.0.3 - checksum: e31332b17816688f0cf831c66ef1ccc24c7600e4ec798fdeed33b66ed934372b1a962e92c665903bae661db5aaf872d79becc7d67b3f9c6a55b403acdfd534ec + checksum: 8e583f9cd1f12cf860dd9d483f4e0e8c1e4edf7191d0152c8b821c2debbe80b77eb663b45fa3526faf1d3182e5000df532628360bbae53420e090b92043c3880 languageName: node linkType: hard @@ -9376,8 +9345,8 @@ __metadata: linkType: hard "@google-cloud/storage@npm:^7.0.0": - version: 7.11.2 - resolution: "@google-cloud/storage@npm:7.11.2" + version: 7.12.1 + resolution: "@google-cloud/storage@npm:7.12.1" dependencies: "@google-cloud/paginator": ^5.0.0 "@google-cloud/projectify": ^4.0.0 @@ -9385,7 +9354,7 @@ __metadata: abort-controller: ^3.0.0 async-retry: ^1.3.3 duplexify: ^4.1.3 - fast-xml-parser: ^4.3.0 + fast-xml-parser: ^4.4.1 gaxios: ^6.0.2 google-auth-library: ^9.6.3 html-entities: ^2.5.2 @@ -9394,7 +9363,7 @@ __metadata: retry-request: ^7.0.0 teeny-request: ^9.0.0 uuid: ^8.0.0 - checksum: 763cd560245006e11a060fdbd5edff5d6bfe22b0c0b06dfe88af43b7b14458598c00a71c4e1b079e9ab09096d7d262bdc27fa77d76a8969af0765f23c93f8405 + checksum: dec26558f9476304e857447527225accd5c4a6bf17484e4484f58c8eaf99a77366e8be4f0679962b5a36603e873cf8a29237519b729b20cca645088512ecb043 languageName: node linkType: hard @@ -9776,97 +9745,6 @@ __metadata: languageName: node linkType: hard -"@hapi/b64@npm:5.x.x": - version: 5.0.0 - resolution: "@hapi/b64@npm:5.0.0" - dependencies: - "@hapi/hoek": 9.x.x - checksum: 1e166bc9a6ca2952190ede40089d552efa21554c3325d5174e5616b940f79cd8327520b239ef6725f823f95b9e4684579bc8e99a222b28639b793ae0ef788409 - languageName: node - linkType: hard - -"@hapi/boom@npm:9.x.x, @hapi/boom@npm:^9.0.0": - version: 9.1.4 - resolution: "@hapi/boom@npm:9.1.4" - dependencies: - "@hapi/hoek": 9.x.x - checksum: b1cdde1e82fae8222d893ac74e13e9a784f0398ffcb7ece32f6eb69bad990ca62f3c40cca19673e74cc676628ff121ee5576d6b0f1add92dcfa182ff9b90b937 - languageName: node - linkType: hard - -"@hapi/bourne@npm:2.x.x": - version: 2.1.0 - resolution: "@hapi/bourne@npm:2.1.0" - checksum: 0ce5a38bc46b1b649fc04c00763def978c99b2eba5013e512f492f4d0d806a6fc1d09f36524c2f8b45cc778d481a06c1f808392e08bc6ebd14abab4bfde07ca5 - languageName: node - linkType: hard - -"@hapi/cryptiles@npm:5.x.x": - version: 5.1.0 - resolution: "@hapi/cryptiles@npm:5.1.0" - dependencies: - "@hapi/boom": 9.x.x - checksum: 3109ad8435d6333b22092e8264e0cc32baafaa10c8c813685ca379c033b5d4123cd503aecdb535fb0c2d39d8e26c494f4c4998d5d040865907b64bf4cb72c705 - languageName: node - linkType: hard - -"@hapi/hoek@npm:9.x.x, @hapi/hoek@npm:^9.0.0, @hapi/hoek@npm:^9.3.0": - version: 9.3.0 - resolution: "@hapi/hoek@npm:9.3.0" - checksum: 4771c7a776242c3c022b168046af4e324d116a9d2e1d60631ee64f474c6e38d1bb07092d898bf95c7bc5d334c5582798a1456321b2e53ca817d4e7c88bc25b43 - languageName: node - linkType: hard - -"@hapi/iron@npm:^6.0.0": - version: 6.0.0 - resolution: "@hapi/iron@npm:6.0.0" - dependencies: - "@hapi/b64": 5.x.x - "@hapi/boom": 9.x.x - "@hapi/bourne": 2.x.x - "@hapi/cryptiles": 5.x.x - "@hapi/hoek": 9.x.x - checksum: ef07abc8a55eb8b60ab0c09d797bb13b39d283260ecdabedc1568c64c47d8c15fe517beed4f76a2b69dac57e6c26cd30ac7612169c41adb8f4c77ea3f58d973d - languageName: node - linkType: hard - -"@hapi/podium@npm:^4.1.3": - version: 4.1.3 - resolution: "@hapi/podium@npm:4.1.3" - dependencies: - "@hapi/hoek": 9.x.x - "@hapi/teamwork": 5.x.x - "@hapi/validate": 1.x.x - checksum: da7d02af93a2797fc522cca0ec6cf12691a75047857db80162405d7f83bbf437d49f95c20714bd8e19f2ff41b8e5139e88fb7a896f5d967e0d9bcbf632a9feae - languageName: node - linkType: hard - -"@hapi/teamwork@npm:5.x.x": - version: 5.1.1 - resolution: "@hapi/teamwork@npm:5.1.1" - checksum: f679aff66b432f5fe3daa72a0659c4280de8f6e109e0c547ed24e7ea60149b182c406c4c02426a8bcfd87a79889b180f6d5f5a95690489e5607cc044c3c2defb - languageName: node - linkType: hard - -"@hapi/topo@npm:^5.0.0, @hapi/topo@npm:^5.1.0": - version: 5.1.0 - resolution: "@hapi/topo@npm:5.1.0" - dependencies: - "@hapi/hoek": ^9.0.0 - checksum: 604dfd5dde76d5c334bd03f9001fce69c7ce529883acf92da96f4fe7e51221bf5e5110e964caca287a6a616ba027c071748ab636ff178ad750547fba611d6014 - languageName: node - linkType: hard - -"@hapi/validate@npm:1.x.x": - version: 1.1.3 - resolution: "@hapi/validate@npm:1.1.3" - dependencies: - "@hapi/hoek": ^9.0.0 - "@hapi/topo": ^5.0.0 - checksum: dd6f8d6e33ac55d430448bc83c33572a593702ae856186610161a9488a611110ac4f793339043ea44a6f79bebe689bc7f86122df2f817725255159a0c1cb62ec - languageName: node - linkType: hard - "@headlessui/react@npm:^1.7.15": version: 1.7.17 resolution: "@headlessui/react@npm:1.7.17" @@ -10472,7 +10350,7 @@ __metadata: languageName: node linkType: hard -"@kubernetes-models/apimachinery@npm:^1.1.0, @kubernetes-models/apimachinery@npm:^1.2.1": +"@kubernetes-models/apimachinery@npm:^1.1.0": version: 1.2.2 resolution: "@kubernetes-models/apimachinery@npm:1.2.2" dependencies: @@ -10483,7 +10361,18 @@ __metadata: languageName: node linkType: hard -"@kubernetes-models/base@npm:^4.0.1, @kubernetes-models/base@npm:^4.0.3, @kubernetes-models/base@npm:^4.0.4": +"@kubernetes-models/apimachinery@npm:^2.0.0": + version: 2.0.0 + resolution: "@kubernetes-models/apimachinery@npm:2.0.0" + dependencies: + "@kubernetes-models/base": ^5.0.0 + "@kubernetes-models/validate": ^4.0.0 + "@swc/helpers": ^0.5.8 + checksum: 0e9ed8f05166221e2ccfe21a45a3aa480ab31c8e8b97b2dbb22d1d3c60477fb0b093def5d78727ba1037df4f14a9c7f38a7da0432c769fdc606097b4b6018dd6 + languageName: node + linkType: hard + +"@kubernetes-models/base@npm:^4.0.1, @kubernetes-models/base@npm:^4.0.4": version: 4.0.4 resolution: "@kubernetes-models/base@npm:4.0.4" dependencies: @@ -10494,7 +10383,18 @@ __metadata: languageName: node linkType: hard -"@kubernetes-models/validate@npm:^3.1.1, @kubernetes-models/validate@npm:^3.1.2": +"@kubernetes-models/base@npm:^5.0.0": + version: 5.0.0 + resolution: "@kubernetes-models/base@npm:5.0.0" + dependencies: + "@kubernetes-models/validate": ^4.0.0 + is-plain-object: ^5.0.0 + tslib: ^2.4.0 + checksum: 3ac064e6c18d88f356b8e91d320e08ee31a12a3ecd47d6d86e23566203125640b88223bc9003d02d420b6a9a86f2990f65e4a26c32ed075ef0753d8599549c0b + languageName: node + linkType: hard + +"@kubernetes-models/validate@npm:^3.1.2": version: 3.1.2 resolution: "@kubernetes-models/validate@npm:3.1.2" dependencies: @@ -10506,6 +10406,24 @@ __metadata: languageName: node linkType: hard +"@kubernetes-models/validate@npm:^4.0.0": + version: 4.0.0 + resolution: "@kubernetes-models/validate@npm:4.0.0" + dependencies: + ajv: ^8.12.0 + ajv-formats: ^2.1.1 + ajv-formats-draft2019: ^1.6.1 + ajv-i18n: ^4.2.0 + is-cidr: ^4.0.0 + re2-wasm: ^1.0.2 + tslib: ^2.4.0 + dependenciesMeta: + re2-wasm: + optional: true + checksum: 983c873a674b16714b88c444fcfeba555a3349036b263e1e41441e80d58be8b783fee8ce8217b2e5a8fda6c9893ea377f9635d6a37d85c412b327c1bbad4fdef + languageName: node + linkType: hard + "@kubernetes/client-node@npm:0.20.0, @kubernetes/client-node@npm:^0.20.0": version: 0.20.0 resolution: "@kubernetes/client-node@npm:0.20.0" @@ -11151,13 +11069,6 @@ __metadata: languageName: node linkType: hard -"@mswjs/cookies@npm:^1.1.0": - version: 1.1.0 - resolution: "@mswjs/cookies@npm:1.1.0" - checksum: 1d9be44548907b92ff6acd46795292968661be19f1c04c43fdb2beb98bc7e58b8ffcef3be19d0f2cb58df07a36a6b53b4bbc0ea34e023b7366dbc28ffee90338 - languageName: node - linkType: hard - "@mswjs/interceptors@npm:^0.17.10": version: 0.17.10 resolution: "@mswjs/interceptors@npm:0.17.10" @@ -11188,50 +11099,28 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.40": - version: 5.0.0-beta.40 - resolution: "@mui/base@npm:5.0.0-beta.40" - dependencies: - "@babel/runtime": ^7.23.9 - "@floating-ui/react-dom": ^2.0.8 - "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.14 - "@popperjs/core": ^2.11.8 - clsx: ^2.1.0 - prop-types: ^15.8.1 - peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - checksum: 9c084ee67de372411a71af5eca9a5367db9f5bce57bb43973629c522760fe64fa2a43d2934dccd24d6dcbcd0ed399c5fc5c461226c86104f5767de1c9b8deba2 - languageName: node - linkType: hard - -"@mui/core-downloads-tracker@npm:^5.15.20": - version: 5.15.20 - resolution: "@mui/core-downloads-tracker@npm:5.15.20" - checksum: 8cc71169ce1201c5a37fad6c5c58739850694e90c7bda636c692d47a79fd4c7884eab2c24b0084d6732a3d28c9a4a6d222dd5747f9d91f5075614700a3a3282a +"@mui/core-downloads-tracker@npm:^5.16.7": + version: 5.16.7 + resolution: "@mui/core-downloads-tracker@npm:5.16.7" + checksum: b65c48ba2bf6bba6435ba9f2d6c33db0c8a85b3ff7599136a9682b72205bec76470ab5ed5e6e625d5bd012ed9bcbc641ed677548be80d217c9fb5d0435567062 languageName: node linkType: hard "@mui/material@npm:^5.12.2": - version: 5.15.20 - resolution: "@mui/material@npm:5.15.20" + version: 5.16.7 + resolution: "@mui/material@npm:5.16.7" dependencies: "@babel/runtime": ^7.23.9 - "@mui/base": 5.0.0-beta.40 - "@mui/core-downloads-tracker": ^5.15.20 - "@mui/system": ^5.15.20 - "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.20 + "@mui/core-downloads-tracker": ^5.16.7 + "@mui/system": ^5.16.7 + "@mui/types": ^7.2.15 + "@mui/utils": ^5.16.6 + "@popperjs/core": ^2.11.8 "@types/react-transition-group": ^4.4.10 clsx: ^2.1.0 csstype: ^3.1.3 prop-types: ^15.8.1 - react-is: ^18.2.0 + react-is: ^18.3.1 react-transition-group: ^4.4.5 peerDependencies: "@emotion/react": ^11.5.0 @@ -11246,16 +11135,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 0d0e29682fa8f4ff03746efabb4b480da9dfe004e68982a36662ff0d40d76f5840ebf8ef3b0f9629056afb3030145dd5eb3bd2b0ab96d201fac7a300fef155b0 + checksum: 5057b48c3ce554247de9a8f675bda9bbda079bc83a696c500525f3ebbd63315a44f1c2a7c83c2025dbd02d2722892e397a0af10c1219d45f6534e41d91a43cc0 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.20": - version: 5.15.20 - resolution: "@mui/private-theming@npm:5.15.20" +"@mui/private-theming@npm:^5.16.6": + version: 5.16.6 + resolution: "@mui/private-theming@npm:5.16.6" dependencies: "@babel/runtime": ^7.23.9 - "@mui/utils": ^5.15.20 + "@mui/utils": ^5.16.6 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -11263,13 +11152,13 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 5c70a9ebca3827cea11d67b3f8ed24d18a10c44f30f14d8d1c37b3f1e74d7a5e91cec5ffb7f24e8b2d974b38e4d046a93473c20a0cd7c7a880580e5df3d1afb7 + checksum: 314ba598ab17cd425a36e4cab677ed26fe0939b23e53120da77cfbc3be6dada5428fa8e2a55cb697417599a4e3abfee6d4711de0a7318b9fb2c3a822b2d5b5a8 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.14": - version: 5.15.14 - resolution: "@mui/styled-engine@npm:5.15.14" +"@mui/styled-engine@npm:^5.16.6": + version: 5.16.6 + resolution: "@mui/styled-engine@npm:5.16.6" dependencies: "@babel/runtime": ^7.23.9 "@emotion/cache": ^11.11.0 @@ -11284,19 +11173,19 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 23b45c859a4f0d2b10933d06a6082c0ff093f7b6d8d32a2bfe3a6e515fe46d7a38ca9e7150d45c025a2e98d963bae9a5991d131cf4748b62670075ef0fa321ed + checksum: 604f83b91801945336db211a8273061132668d01e9f456c30bb811a3b49cc5786b8b7dd8e0b5b89de15f6209abc900d9e679d3ae7a4651a6df45e323b6ed95c5 languageName: node linkType: hard "@mui/styles@npm:^5.14.18": - version: 5.15.20 - resolution: "@mui/styles@npm:5.15.20" + version: 5.16.7 + resolution: "@mui/styles@npm:5.16.7" dependencies: "@babel/runtime": ^7.23.9 "@emotion/hash": ^0.9.1 - "@mui/private-theming": ^5.15.20 - "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.20 + "@mui/private-theming": ^5.16.6 + "@mui/types": ^7.2.15 + "@mui/utils": ^5.16.6 clsx: ^2.1.0 csstype: ^3.1.3 hoist-non-react-statics: ^3.3.2 @@ -11315,19 +11204,19 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: bdc19d66caf3fb3272dd1c67d6a40b0e77bca2c3c7a5b9112ebed2cf3d6795932401bcb9ddfb9daba9c3e293455cf9cb2c24975eff15c75a2ce3d40ed30d59d7 + checksum: 1109eb150cf40782a6f24bebf6d22d55ea8c36bbf43893664c303e679b7d235a6578b2f2e1d9ee64132aa24496a15fd32f80278cb641208c3a372bd53679e1c0 languageName: node linkType: hard -"@mui/system@npm:^5.15.20": - version: 5.15.20 - resolution: "@mui/system@npm:5.15.20" +"@mui/system@npm:^5.16.7": + version: 5.16.7 + resolution: "@mui/system@npm:5.16.7" dependencies: "@babel/runtime": ^7.23.9 - "@mui/private-theming": ^5.15.20 - "@mui/styled-engine": ^5.15.14 - "@mui/types": ^7.2.14 - "@mui/utils": ^5.15.20 + "@mui/private-theming": ^5.16.6 + "@mui/styled-engine": ^5.16.6 + "@mui/types": ^7.2.15 + "@mui/utils": ^5.16.6 clsx: ^2.1.0 csstype: ^3.1.3 prop-types: ^15.8.1 @@ -11343,37 +11232,39 @@ __metadata: optional: true "@types/react": optional: true - checksum: e9e79b6a905845aef87939de8ac7990d73a2f92bba02e41905dcb9f44e53727bdfa52a978cf59a2a2cfa73d2512df78c4351eb130d7c25af1880bb8b7ebfc686 + checksum: 86cc11d062645b6742328178ca3a9e2aa2c6d064a559e4fb8c6c6bb8251794959b9dad385f9508fdcab2ae2764503c80f7c3d4f6eb1e0e8aa649f28d4f59133b languageName: node linkType: hard -"@mui/types@npm:^7.2.14": - version: 7.2.14 - resolution: "@mui/types@npm:7.2.14" +"@mui/types@npm:^7.2.15": + version: 7.2.16 + resolution: "@mui/types@npm:7.2.16" peerDependencies: - "@types/react": ^17.0.0 || ^18.0.0 + "@types/react": ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 615c9f9110933157f5d3c4fee69d6e70b98fc0d9ebc3b63079b6a1e23e6b389748687a25ab4ac15b56166fc228885da87c3929503b41fa322cfdee0f6d411206 + checksum: 7bb86487be8e55a4e138a6a5878ab272caee71546a7a2368223274afae65229f673334e59b8e3f7717ea7ea8d44af5f068b2eb4c212cddb98fefecfa873b868a languageName: node linkType: hard -"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.15.14, @mui/utils@npm:^5.15.20": - version: 5.15.20 - resolution: "@mui/utils@npm:5.15.20" +"@mui/utils@npm:^5.14.15, @mui/utils@npm:^5.16.6": + version: 5.16.6 + resolution: "@mui/utils@npm:5.16.6" dependencies: "@babel/runtime": ^7.23.9 - "@types/prop-types": ^15.7.11 + "@mui/types": ^7.2.15 + "@types/prop-types": ^15.7.12 + clsx: ^2.1.1 prop-types: ^15.8.1 - react-is: ^18.2.0 + react-is: ^18.3.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 react: ^17.0.0 || ^18.0.0 peerDependenciesMeta: "@types/react": optional: true - checksum: 8f8c7f9129e0eb1bf55c1d675c647da1fa4acf1c7f50e0ce2ce750cc0603e62fdc21b76e8ef8ff9bf06bce054e9cf97210ed737f55887b0ef939bd6605b4e537 + checksum: 6f8068f07f60a842fcb2e2540eecbd9c5f04df695bcc427184720e8ae138ae689fefd3c20147ab7c76e809ede6e10f5e08d1c34cd3a8b09bd22d2020a666a96f languageName: node linkType: hard @@ -11487,16 +11378,6 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.scandir@npm:3.0.0": - version: 3.0.0 - resolution: "@nodelib/fs.scandir@npm:3.0.0" - dependencies: - "@nodelib/fs.stat": 3.0.0 - run-parallel: ^1.2.0 - checksum: f4e9d07b310f248503d3cd632310b25cd01d97a74701bc59e1458bad32c84f78615d9853820adba8af73d970868aab46de68e540ca7efd90dacd4ea34d05553d - languageName: node - linkType: hard - "@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": version: 2.0.5 resolution: "@nodelib/fs.stat@npm:2.0.5" @@ -11504,24 +11385,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.stat@npm:3.0.0": - version: 3.0.0 - resolution: "@nodelib/fs.stat@npm:3.0.0" - checksum: 93a93e19b64d0275b5120bed2cf85da4c5804014de1bdac6e9933b835b1cb9f88252dc990b148076bec034fc757bdd97d74cf5d99bc9f895e0f925aeabe7dbcf - languageName: node - linkType: hard - -"@nodelib/fs.walk@npm:2.0.0": - version: 2.0.0 - resolution: "@nodelib/fs.walk@npm:2.0.0" - dependencies: - "@nodelib/fs.scandir": 3.0.0 - fastq: ^1.15.0 - checksum: f900965bc3953a67cb74916ec0950cd5d58006a9218aef99928cc22dd77d117376aaf710e46c740d18638a99337a4e81cbf70c892a2124269bf177c459d89837 - languageName: node - linkType: hard - -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": +"@nodelib/fs.walk@npm:1.2.8, @nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -12491,14 +12355,14 @@ __metadata: linkType: hard "@openapitools/openapi-generator-cli@npm:^2.4.26, @openapitools/openapi-generator-cli@npm:^2.7.0": - version: 2.13.4 - resolution: "@openapitools/openapi-generator-cli@npm:2.13.4" + version: 2.13.5 + resolution: "@openapitools/openapi-generator-cli@npm:2.13.5" dependencies: "@nestjs/axios": 3.0.2 "@nestjs/common": 10.3.0 "@nestjs/core": 10.3.0 "@nuxtjs/opencollective": 0.3.2 - axios: 1.6.8 + axios: 1.7.4 chalk: 4.1.2 commander: 8.3.0 compare-versions: 4.1.4 @@ -12514,143 +12378,107 @@ __metadata: tslib: 2.6.2 bin: openapi-generator-cli: main.js - checksum: 825a49ff86632767d318fa860d9d251984b9b3e8f386cf8298430005f20611d7b535c6e87e370edd19ff824a5c68cf65efc93cbb64d7a2f1649e46a8887cf5d2 + checksum: 923fcdfe29c2d349aaae28a86dd5f63a4f441233549a4575bce6760177c6c48508180c57569bcc4deb63a40d8d36049c4a9060e2884248b1b5fbab2d28954a4e languageName: node linkType: hard "@opensearch-project/opensearch@npm:^2.2.1": - version: 2.7.0 - resolution: "@opensearch-project/opensearch@npm:2.7.0" + version: 2.12.0 + resolution: "@opensearch-project/opensearch@npm:2.12.0" dependencies: aws4: ^1.11.0 debug: ^4.3.1 hpagent: ^1.2.0 + json11: ^1.1.2 ms: ^2.1.3 secure-json-parse: ^2.4.0 - checksum: 6905373048d3896e158de8a229b1110828cf0cbffee3180fcd98b114a025f11e8938124863106544df09d7aa587b41843e2818fe03f34e33a27abcd1601740fe + checksum: 5bf64305a401a1fe2e3a9d06c2582ba5173f809cbe04ccec7e70247070ccd973c9e6a9f09a00507d0a937cc830354642e1b6e5adcac383a53bbec05b240f857b languageName: node linkType: hard -"@opentelemetry/api-logs@npm:0.49.1, @opentelemetry/api-logs@npm:^0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/api-logs@npm:0.49.1" +"@opentelemetry/api-logs@npm:0.53.0, @opentelemetry/api-logs@npm:^0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/api-logs@npm:0.53.0" dependencies: "@opentelemetry/api": ^1.0.0 - checksum: 83f559164fb62ed4343e650afccae766bb7ec730540a14f391d6ab4516a96a11cb1f9db9fc77495d07cb95541b4e8ccd184a6f36a0e38ddaad4fdd6359b3a3d9 - languageName: node - linkType: hard - -"@opentelemetry/api-logs@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/api-logs@npm:0.50.0" - dependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 5d4d9d448d1dc3a74879a19d5d24b9aecfd180e05acc622e25e5ca1bd0ad2c27b5541e101e474f2870e6470e148a7bad3c1b041d5a41181ebcde1f38a1ee6feb + checksum: 3383ff75f94a77402370a655f8edf049f9864ad60140f70821a1b775ce43bdb9ca6fade533a1faf46dbca19f3189bcbf1f8805062f5a68bfe2a00281b1712d1f languageName: node linkType: hard "@opentelemetry/api@npm:^1.0.0, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.0": - version: 1.8.0 - resolution: "@opentelemetry/api@npm:1.8.0" - checksum: 0e32079975f05bee6de2ad8ade097f0afdc63f462c76550150fce2444c73ab92aaf851ac85e638b6e3b269da6640ac7e63f33913a0fd7df9f9beec2e100759df + version: 1.9.0 + resolution: "@opentelemetry/api@npm:1.9.0" + checksum: 9e88e59d53ced668f3daaecfd721071c5b85a67dd386f1c6f051d1be54375d850016c881f656ffbe9a03bedae85f7e89c2f2b635313f9c9b195ad033cdc31020 languageName: node linkType: hard -"@opentelemetry/auto-instrumentations-node@npm:^0.43.0": - version: 0.43.0 - resolution: "@opentelemetry/auto-instrumentations-node@npm:0.43.0" +"@opentelemetry/auto-instrumentations-node@npm:^0.50.0": + version: 0.50.0 + resolution: "@opentelemetry/auto-instrumentations-node@npm:0.50.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/instrumentation-amqplib": ^0.35.0 - "@opentelemetry/instrumentation-aws-lambda": ^0.39.0 - "@opentelemetry/instrumentation-aws-sdk": ^0.39.1 - "@opentelemetry/instrumentation-bunyan": ^0.36.0 - "@opentelemetry/instrumentation-cassandra-driver": ^0.36.0 - "@opentelemetry/instrumentation-connect": ^0.34.0 - "@opentelemetry/instrumentation-cucumber": ^0.4.0 - "@opentelemetry/instrumentation-dataloader": ^0.7.0 - "@opentelemetry/instrumentation-dns": ^0.34.0 - "@opentelemetry/instrumentation-express": ^0.36.1 - "@opentelemetry/instrumentation-fastify": ^0.34.0 - "@opentelemetry/instrumentation-fs": ^0.10.0 - "@opentelemetry/instrumentation-generic-pool": ^0.34.0 - "@opentelemetry/instrumentation-graphql": ^0.38.1 - "@opentelemetry/instrumentation-grpc": ^0.49.1 - "@opentelemetry/instrumentation-hapi": ^0.35.0 - "@opentelemetry/instrumentation-http": ^0.49.1 - "@opentelemetry/instrumentation-ioredis": ^0.38.0 - "@opentelemetry/instrumentation-knex": ^0.34.0 - "@opentelemetry/instrumentation-koa": ^0.38.0 - "@opentelemetry/instrumentation-lru-memoizer": ^0.35.0 - "@opentelemetry/instrumentation-memcached": ^0.34.0 - "@opentelemetry/instrumentation-mongodb": ^0.41.0 - "@opentelemetry/instrumentation-mongoose": ^0.36.0 - "@opentelemetry/instrumentation-mysql": ^0.36.0 - "@opentelemetry/instrumentation-mysql2": ^0.36.0 - "@opentelemetry/instrumentation-nestjs-core": ^0.35.0 - "@opentelemetry/instrumentation-net": ^0.34.0 - "@opentelemetry/instrumentation-pg": ^0.39.1 - "@opentelemetry/instrumentation-pino": ^0.36.0 - "@opentelemetry/instrumentation-redis": ^0.37.0 - "@opentelemetry/instrumentation-redis-4": ^0.37.0 - "@opentelemetry/instrumentation-restify": ^0.36.0 - "@opentelemetry/instrumentation-router": ^0.35.0 - "@opentelemetry/instrumentation-socket.io": ^0.37.0 - "@opentelemetry/instrumentation-tedious": ^0.8.0 - "@opentelemetry/instrumentation-winston": ^0.35.0 - "@opentelemetry/resource-detector-alibaba-cloud": ^0.28.7 - "@opentelemetry/resource-detector-aws": ^1.4.0 - "@opentelemetry/resource-detector-container": ^0.3.7 - "@opentelemetry/resource-detector-gcp": ^0.29.7 - "@opentelemetry/resources": ^1.12.0 - "@opentelemetry/sdk-node": ^0.49.1 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/instrumentation-amqplib": ^0.42.0 + "@opentelemetry/instrumentation-aws-lambda": ^0.44.0 + "@opentelemetry/instrumentation-aws-sdk": ^0.44.0 + "@opentelemetry/instrumentation-bunyan": ^0.41.0 + "@opentelemetry/instrumentation-cassandra-driver": ^0.41.0 + "@opentelemetry/instrumentation-connect": ^0.39.0 + "@opentelemetry/instrumentation-cucumber": ^0.9.0 + "@opentelemetry/instrumentation-dataloader": ^0.12.0 + "@opentelemetry/instrumentation-dns": ^0.39.0 + "@opentelemetry/instrumentation-express": ^0.42.0 + "@opentelemetry/instrumentation-fastify": ^0.39.0 + "@opentelemetry/instrumentation-fs": ^0.15.0 + "@opentelemetry/instrumentation-generic-pool": ^0.39.0 + "@opentelemetry/instrumentation-graphql": ^0.43.0 + "@opentelemetry/instrumentation-grpc": ^0.53.0 + "@opentelemetry/instrumentation-hapi": ^0.41.0 + "@opentelemetry/instrumentation-http": ^0.53.0 + "@opentelemetry/instrumentation-ioredis": ^0.43.0 + "@opentelemetry/instrumentation-kafkajs": ^0.3.0 + "@opentelemetry/instrumentation-knex": ^0.40.0 + "@opentelemetry/instrumentation-koa": ^0.43.0 + "@opentelemetry/instrumentation-lru-memoizer": ^0.40.0 + "@opentelemetry/instrumentation-memcached": ^0.39.0 + "@opentelemetry/instrumentation-mongodb": ^0.47.0 + "@opentelemetry/instrumentation-mongoose": ^0.42.0 + "@opentelemetry/instrumentation-mysql": ^0.41.0 + "@opentelemetry/instrumentation-mysql2": ^0.41.0 + "@opentelemetry/instrumentation-nestjs-core": ^0.40.0 + "@opentelemetry/instrumentation-net": ^0.39.0 + "@opentelemetry/instrumentation-pg": ^0.44.0 + "@opentelemetry/instrumentation-pino": ^0.42.0 + "@opentelemetry/instrumentation-redis": ^0.42.0 + "@opentelemetry/instrumentation-redis-4": ^0.42.0 + "@opentelemetry/instrumentation-restify": ^0.41.0 + "@opentelemetry/instrumentation-router": ^0.40.0 + "@opentelemetry/instrumentation-socket.io": ^0.42.0 + "@opentelemetry/instrumentation-tedious": ^0.14.0 + "@opentelemetry/instrumentation-undici": ^0.6.0 + "@opentelemetry/instrumentation-winston": ^0.40.0 + "@opentelemetry/resource-detector-alibaba-cloud": ^0.29.1 + "@opentelemetry/resource-detector-aws": ^1.6.1 + "@opentelemetry/resource-detector-azure": ^0.2.11 + "@opentelemetry/resource-detector-container": ^0.4.1 + "@opentelemetry/resource-detector-gcp": ^0.29.11 + "@opentelemetry/resources": ^1.24.0 + "@opentelemetry/sdk-node": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.4.1 - checksum: e1bb1119a58f70186cffc8de192f1b3884ba10aa31976b513a7df0995a737383fd043c570142f6feb660db087e160c24356aa55d8fe22010394efca3ca9ceb0b + checksum: 0d78211226f86a33f2fc55dc53e902726f89b70eece49db55f3c79aa37a643269989c672733739d9ad83f32d26c009207b302174f64b673567c80f5c8f68ac19 languageName: node linkType: hard -"@opentelemetry/context-async-hooks@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/context-async-hooks@npm:1.22.0" +"@opentelemetry/context-async-hooks@npm:1.26.0": + version: 1.26.0 + resolution: "@opentelemetry/context-async-hooks@npm:1.26.0" peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 03b3b8c3eb34b35495abd9869303e67a61fafb8a004a9bc6ab1234a35909ee89d0f515cfeb5b710c9f3e8f4d185b776ada3fa2975a62d607c80986a7c46f4d83 + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: f0fe5bfa3aeed99fbe7d6f6157e3bcc2e4450850a62ef60e551812f3e5aa72cb81e38de8c4e1b6934c93e18579a503664597f78e7e7d9904e271f59c939a3e02 languageName: node linkType: hard -"@opentelemetry/context-async-hooks@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/context-async-hooks@npm:1.23.0" - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 4dc6c4f816402fe3deb5d43aebd4ceadd8afa8feab2047eed7cc906379fd341686cac8d16bce1c436d15e03b29883bcf73f04d4da005abe318e0b9ec69bdbd23 - languageName: node - linkType: hard - -"@opentelemetry/core@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/core@npm:1.22.0" - dependencies: - "@opentelemetry/semantic-conventions": 1.22.0 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 0056bbaceb922816ec87e7e21aa8a7687377a41ba36a598bb6c49738d1eb5767f823e5758b5bf844d2b10aa075c553e98904dd6fd4f02c24cf335e3951fe78a6 - languageName: node - linkType: hard - -"@opentelemetry/core@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/core@npm:1.23.0" - dependencies: - "@opentelemetry/semantic-conventions": 1.23.0 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 88aa733364c42f90a61a6efc8b5138dcfed4763f3a0692d957d506a6fe49db943169a0631ad762ac7569723faf5eaca092d6590eca1ad8ff77583fb10512a06b - languageName: node - linkType: hard - -"@opentelemetry/core@npm:1.24.0, @opentelemetry/core@npm:^1.0.0, @opentelemetry/core@npm:^1.1.0, @opentelemetry/core@npm:^1.8.0": +"@opentelemetry/core@npm:1.24.0": version: 1.24.0 resolution: "@opentelemetry/core@npm:1.24.0" dependencies: @@ -12661,760 +12489,695 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/exporter-prometheus@npm:^0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/exporter-prometheus@npm:0.50.0" +"@opentelemetry/core@npm:1.26.0, @opentelemetry/core@npm:^1.0.0, @opentelemetry/core@npm:^1.1.0, @opentelemetry/core@npm:^1.25.0, @opentelemetry/core@npm:^1.25.1, @opentelemetry/core@npm:^1.8.0": + version: 1.26.0 + resolution: "@opentelemetry/core@npm:1.26.0" dependencies: - "@opentelemetry/core": 1.23.0 - "@opentelemetry/resources": 1.23.0 - "@opentelemetry/sdk-metrics": 1.23.0 + "@opentelemetry/semantic-conventions": 1.27.0 + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: e5b06b4d69605927b850109c6b898f00a6a921171b3bf62335a4e00b9a170c1b93ddef6d7f8cc480a551faeaf81074b594f4462a91d4fbc4b313e64ff9ebd717 + languageName: node + linkType: hard + +"@opentelemetry/exporter-logs-otlp-grpc@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/exporter-logs-otlp-grpc@npm:0.53.0" + dependencies: + "@grpc/grpc-js": ^1.7.1 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/otlp-grpc-exporter-base": 0.53.0 + "@opentelemetry/otlp-transformer": 0.53.0 + "@opentelemetry/sdk-logs": 0.53.0 + peerDependencies: + "@opentelemetry/api": ^1.0.0 + checksum: ff2d26958f5553e33f5be91bc2758449afb55eb30977a00262aec1c9044134d0e6cc4da4634dababe0a22e6ac67243181da7f95b7129ffe65901bb70cddca2c1 + languageName: node + linkType: hard + +"@opentelemetry/exporter-logs-otlp-http@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/exporter-logs-otlp-http@npm:0.53.0" + dependencies: + "@opentelemetry/api-logs": 0.53.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/otlp-exporter-base": 0.53.0 + "@opentelemetry/otlp-transformer": 0.53.0 + "@opentelemetry/sdk-logs": 0.53.0 + peerDependencies: + "@opentelemetry/api": ^1.0.0 + checksum: cebff4b11872e5fcdeb345758759b0e69fc292100060edc7207ad0b594f66d990e86ee687ba9407d5eb44e020d384cd5517ee438a9d4cd5ff512ce468ffa72a1 + languageName: node + linkType: hard + +"@opentelemetry/exporter-logs-otlp-proto@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/exporter-logs-otlp-proto@npm:0.53.0" + dependencies: + "@opentelemetry/api-logs": 0.53.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/otlp-exporter-base": 0.53.0 + "@opentelemetry/otlp-transformer": 0.53.0 + "@opentelemetry/resources": 1.26.0 + "@opentelemetry/sdk-logs": 0.53.0 + "@opentelemetry/sdk-trace-base": 1.26.0 + peerDependencies: + "@opentelemetry/api": ^1.0.0 + checksum: 86acdbb58723236aca2bc3e7822443038fe7009324176e190d700585cb1d0089a31a9270340af14c961b958ff3c42071f9b408aab569843a6555af55f923613c + languageName: node + linkType: hard + +"@opentelemetry/exporter-prometheus@npm:^0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/exporter-prometheus@npm:0.53.0" + dependencies: + "@opentelemetry/core": 1.26.0 + "@opentelemetry/resources": 1.26.0 + "@opentelemetry/sdk-metrics": 1.26.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 0bb3e6c36f2a6ef4822d31eb23254e6f6380b3bf50b29767349881ce606bd685bb4e728adb93187c9df190291e3d64f7f98593f96ec7bb5eff76be9e338f1d05 + checksum: a5f5997063728f9c421c4a16c928bfaa8bdf287c2c229ef1a523dc14d8e9ef2240842a68c59b008c506b547dea51993c21f3ac841b341cbcfe9c70a5fb6e9458 languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-grpc@npm:0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/exporter-trace-otlp-grpc@npm:0.49.1" +"@opentelemetry/exporter-trace-otlp-grpc@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/exporter-trace-otlp-grpc@npm:0.53.0" dependencies: "@grpc/grpc-js": ^1.7.1 - "@opentelemetry/core": 1.22.0 - "@opentelemetry/otlp-grpc-exporter-base": 0.49.1 - "@opentelemetry/otlp-transformer": 0.49.1 - "@opentelemetry/resources": 1.22.0 - "@opentelemetry/sdk-trace-base": 1.22.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/otlp-grpc-exporter-base": 0.53.0 + "@opentelemetry/otlp-transformer": 0.53.0 + "@opentelemetry/resources": 1.26.0 + "@opentelemetry/sdk-trace-base": 1.26.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 2418f68c8027d5baf5609f7e32b524826ecdc16b3382f6113a6f1f00835e59275a51f2fdefcd5b6f73f455aab444892097866ce8e894d0415d70acd25a6a3049 + checksum: 8f851d05abc49a93779682f7194ec1f9ff116b407633dffe12ebdbb2f69d9bb475af431b2fded58557d4866ea18c534b0510889741f1650b8cd5300acfc9e630 languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-grpc@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/exporter-trace-otlp-grpc@npm:0.50.0" +"@opentelemetry/exporter-trace-otlp-http@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.53.0" dependencies: - "@grpc/grpc-js": ^1.7.1 - "@opentelemetry/core": 1.23.0 - "@opentelemetry/otlp-grpc-exporter-base": 0.50.0 - "@opentelemetry/otlp-transformer": 0.50.0 - "@opentelemetry/resources": 1.23.0 - "@opentelemetry/sdk-trace-base": 1.23.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/otlp-exporter-base": 0.53.0 + "@opentelemetry/otlp-transformer": 0.53.0 + "@opentelemetry/resources": 1.26.0 + "@opentelemetry/sdk-trace-base": 1.26.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: f27189ebf0ae4f417d7e3697a5679805da3544cc60082b89d2d66344a3a4e1941f2f9ab130954ea2718ed32f14201d5679b675d1eb026b7ed5f7b9f817243e57 + checksum: 647cd28b39cdc8de6958d14d70ee5b58b57fa8441b25e82c15b47be424186eabcf6b772e7fbd4dd86ee4617ddb0166d622fb68f950e0db242ab6e7ae4d07837b languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-http@npm:0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.49.1" +"@opentelemetry/exporter-trace-otlp-proto@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/exporter-trace-otlp-proto@npm:0.53.0" dependencies: - "@opentelemetry/core": 1.22.0 - "@opentelemetry/otlp-exporter-base": 0.49.1 - "@opentelemetry/otlp-transformer": 0.49.1 - "@opentelemetry/resources": 1.22.0 - "@opentelemetry/sdk-trace-base": 1.22.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/otlp-exporter-base": 0.53.0 + "@opentelemetry/otlp-transformer": 0.53.0 + "@opentelemetry/resources": 1.26.0 + "@opentelemetry/sdk-trace-base": 1.26.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 35084da407169f7871c016f92df787446f7e133b8cf6a062b9e76e4779373dae7f054b98ace7709bd52b236f13a073b58fa599bf8fc09d5a9df09945bac0fa49 + checksum: 52811ac5d4eb4f9a4bc31441429ad5df378834483b370ca438e7a49e22fdcef1c88d4cd6e4f3b23a9e43f08f09ec9e0cdef79b0edf70ba3922ac42567b3646ae languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-http@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.50.0" +"@opentelemetry/exporter-zipkin@npm:1.26.0": + version: 1.26.0 + resolution: "@opentelemetry/exporter-zipkin@npm:1.26.0" dependencies: - "@opentelemetry/core": 1.23.0 - "@opentelemetry/otlp-exporter-base": 0.50.0 - "@opentelemetry/otlp-transformer": 0.50.0 - "@opentelemetry/resources": 1.23.0 - "@opentelemetry/sdk-trace-base": 1.23.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/resources": 1.26.0 + "@opentelemetry/sdk-trace-base": 1.26.0 + "@opentelemetry/semantic-conventions": 1.27.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: e0725be8f19f2c37c9b16989ff234183213878dad44f0698fc2b6a815c5979498c3766b0377932197ef051a0914d337c81a486612eac2285a4c9cb8313eefa6b + checksum: 30fe42eed605c6a40b50bd72d93d0ae668bee63120e43f4c5adb9e2b7868b19df8e21d80a366d63adbe31dbd4b1b08e2705a8f7d02e18f067306052744d0acde languageName: node linkType: hard -"@opentelemetry/exporter-trace-otlp-proto@npm:0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/exporter-trace-otlp-proto@npm:0.49.1" - dependencies: - "@opentelemetry/core": 1.22.0 - "@opentelemetry/otlp-exporter-base": 0.49.1 - "@opentelemetry/otlp-proto-exporter-base": 0.49.1 - "@opentelemetry/otlp-transformer": 0.49.1 - "@opentelemetry/resources": 1.22.0 - "@opentelemetry/sdk-trace-base": 1.22.0 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 0afa21d176f087d52b68b84f5645076241e5b842461add7de4429f8860861d5141d5f84be144b74d7656d3928bc580f8ee12bb231b4d80861f73128f3b09b4fc - languageName: node - linkType: hard - -"@opentelemetry/exporter-trace-otlp-proto@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/exporter-trace-otlp-proto@npm:0.50.0" - dependencies: - "@opentelemetry/core": 1.23.0 - "@opentelemetry/otlp-exporter-base": 0.50.0 - "@opentelemetry/otlp-proto-exporter-base": 0.50.0 - "@opentelemetry/otlp-transformer": 0.50.0 - "@opentelemetry/resources": 1.23.0 - "@opentelemetry/sdk-trace-base": 1.23.0 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 9666686d85a0966373e5b01e55f6ae9bbe397a27efce4f2bd1eb861e993f5894724b5b5131c4a74061f6bb60b18ba946f27e38850fcd33204ca99f631317139e - languageName: node - linkType: hard - -"@opentelemetry/exporter-zipkin@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/exporter-zipkin@npm:1.22.0" - dependencies: - "@opentelemetry/core": 1.22.0 - "@opentelemetry/resources": 1.22.0 - "@opentelemetry/sdk-trace-base": 1.22.0 - "@opentelemetry/semantic-conventions": 1.22.0 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 8d3d396d3cf69d5b507abb980a1d548c6a93243d5413c371a8ed7a025990e02c04498f7232c2562279d74a1c4ec862292d6a3498a4513eebe9882d615226c5fd - languageName: node - linkType: hard - -"@opentelemetry/exporter-zipkin@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/exporter-zipkin@npm:1.23.0" - dependencies: - "@opentelemetry/core": 1.23.0 - "@opentelemetry/resources": 1.23.0 - "@opentelemetry/sdk-trace-base": 1.23.0 - "@opentelemetry/semantic-conventions": 1.23.0 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 08d5f7a9e2af1ad749be8cb6e65d1b312d1e86dd9ec484156ddcd2c0ad3ff27dded459c599ec406d9bccb937e1fd5b58e9af6ff2e5efc3d2e4e83ca2af12920e - languageName: node - linkType: hard - -"@opentelemetry/instrumentation-amqplib@npm:^0.35.0": - version: 0.35.0 - resolution: "@opentelemetry/instrumentation-amqplib@npm:0.35.0" +"@opentelemetry/instrumentation-amqplib@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-amqplib@npm:0.42.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 7f99738f85d56ee0b706330558936c92e2f2b6f91ae86896b3ac0891f40a42c5b8cee8b457a8efc12d4875ed73b29f36d9aa3590b779a1214d13a655b83268ce + checksum: 64c5a07cca54f2673aa9708638ba8a3dce864d69686924acb926a08f981941b080d68dcfc465b3139dc6824f239f1be9fc49257557c9bfcb460cb2c1f3b4dc80 languageName: node linkType: hard -"@opentelemetry/instrumentation-aws-lambda@npm:^0.39.0": - version: 0.39.0 - resolution: "@opentelemetry/instrumentation-aws-lambda@npm:0.39.0" +"@opentelemetry/instrumentation-aws-lambda@npm:^0.44.0": + version: 0.44.0 + resolution: "@opentelemetry/instrumentation-aws-lambda@npm:0.44.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 + "@opentelemetry/instrumentation": ^0.53.0 "@opentelemetry/propagator-aws-xray": ^1.3.1 "@opentelemetry/resources": ^1.8.0 - "@opentelemetry/semantic-conventions": ^1.0.0 - "@types/aws-lambda": 8.10.122 + "@opentelemetry/semantic-conventions": ^1.27.0 + "@types/aws-lambda": 8.10.143 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: e2840a79680e70157f82341f7796e3d53e79c65c63bfc77995760a647e797fee4afb5dcf6220a672cf8dd3d2caa74ac15f1850a295b483d50d19dd0aeb7512d1 + checksum: 675e002c5d77cb5720d4eb53fd1a2b738bfe72de9d25140c4b6fd4a8353d03ddf29ff1bbdb72b23d26f79e92c9212731f883071dcc66b66666f29dc83f0b5954 languageName: node linkType: hard -"@opentelemetry/instrumentation-aws-sdk@npm:^0.39.1": - version: 0.39.1 - resolution: "@opentelemetry/instrumentation-aws-sdk@npm:0.39.1" +"@opentelemetry/instrumentation-aws-sdk@npm:^0.44.0": + version: 0.44.0 + resolution: "@opentelemetry/instrumentation-aws-sdk@npm:0.44.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/propagation-utils": ^0.30.7 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/propagation-utils": ^0.30.11 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 7d18489b2f161b9bbc2e2d25c23f7358dc5b4e623b76edfdac9f999c083b3b5dd49326b79f6dc1b19c74b9024683e12e1addf03d0817946b2f11481808bbf530 + checksum: 7ab0fe1c9a93866a2bc01027d794cf5f1c59973490890982d9db82b50d555b4f896537e768df62374e365d4322e4afd4d27941910d124c6f48ac63a5212484f1 languageName: node linkType: hard -"@opentelemetry/instrumentation-bunyan@npm:^0.36.0": - version: 0.36.0 - resolution: "@opentelemetry/instrumentation-bunyan@npm:0.36.0" +"@opentelemetry/instrumentation-bunyan@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-bunyan@npm:0.41.0" dependencies: - "@opentelemetry/api-logs": ^0.49.1 - "@opentelemetry/instrumentation": ^0.49.1 + "@opentelemetry/api-logs": ^0.53.0 + "@opentelemetry/instrumentation": ^0.53.0 "@types/bunyan": 1.8.9 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 4848164223c152381d435127a39d296da6445591a99c7d872c220e9605e1ff769537d3840f8d3b17bb4db8d8ccfec54c505e75a82f19117addef793ba990d74d + checksum: f53f0fd1f285e6f7bd7d5a1ccb5747ea0c928c83f855dd4853b8d37b8b1e163d060a592957a89d1891e740b5dab800d0cda7d5b9db29206adb7938679e6f05e1 languageName: node linkType: hard -"@opentelemetry/instrumentation-cassandra-driver@npm:^0.36.0": - version: 0.36.0 - resolution: "@opentelemetry/instrumentation-cassandra-driver@npm:0.36.0" +"@opentelemetry/instrumentation-cassandra-driver@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-cassandra-driver@npm:0.41.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: f978269c922b1a1880ad792accfe359073c0e2ba6060ea75060c9785115aab0b6ce39cfe861a4f358e3da90ad2a7d9f53d52cbf54ac94fd65602bfd732709a32 + checksum: e9c620e241938f16e667746c741480c809b959b44e8affe1b27e90c412ab898da2631307eae3fdee1f8fb928f50b88bc7c74275592beefc3fffc6c5eef83a184 languageName: node linkType: hard -"@opentelemetry/instrumentation-connect@npm:^0.34.0": - version: 0.34.0 - resolution: "@opentelemetry/instrumentation-connect@npm:0.34.0" +"@opentelemetry/instrumentation-connect@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-connect@npm:0.39.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 "@types/connect": 3.4.36 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: dde9880cd00490bfc52dca8b3b1be6a4951e859fa98617e6db78ec95ce84e8d3df3bbbbe5711796a13bd672aa2d89ba4439621a70614f8b1400943cc439540ad + checksum: 946c3d7ea0ca569942fd1e45a1f149f94fed4ee86609b4f2aedb23d67feeafe29a563beffa75d97f9b10c6b18b01c42d5eabf92d4f9f160bc938317c88ebc0de languageName: node linkType: hard -"@opentelemetry/instrumentation-cucumber@npm:^0.4.0": - version: 0.4.0 - resolution: "@opentelemetry/instrumentation-cucumber@npm:0.4.0" +"@opentelemetry/instrumentation-cucumber@npm:^0.9.0": + version: 0.9.0 + resolution: "@opentelemetry/instrumentation-cucumber@npm:0.9.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 4126c5eaf5d48daca410b0ce76bd4d97f6e868fe0b0c151f88f379a93a1d95a1b7e934cb876d0060182f1b9dd20012aac13fc9c7baa6dd4f0c7f903fdfdce54e + checksum: 31d702a2e3404298a8410362c7834efb840ec10de56144811803207ba9e0a12af9bcac483da96a5df32143597dc0b74c32ba697b6525b3db3601edb97d192e84 languageName: node linkType: hard -"@opentelemetry/instrumentation-dataloader@npm:^0.7.0": - version: 0.7.0 - resolution: "@opentelemetry/instrumentation-dataloader@npm:0.7.0" +"@opentelemetry/instrumentation-dataloader@npm:^0.12.0": + version: 0.12.0 + resolution: "@opentelemetry/instrumentation-dataloader@npm:0.12.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: bbd5f27ff770ccb7d79bf16c81c5de9ad84e0c27df8991f8fd36560f190bbb7b7b7d9c8c62d438577f18033447795519a16f66e650f8e009031ffc52a96be825 + checksum: 7d502bd4ca6eac448bebc971d7b7b85b1e1e959bfcbf4b7927ea3fe90784aec8132d147fef2e773e468a8d20241df825edec6e0753be824b155a15d89e6f57a1 languageName: node linkType: hard -"@opentelemetry/instrumentation-dns@npm:^0.34.0": - version: 0.34.0 - resolution: "@opentelemetry/instrumentation-dns@npm:0.34.0" +"@opentelemetry/instrumentation-dns@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-dns@npm:0.39.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 semver: ^7.5.4 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 9c2b4aae823255d88590c39802a76df888b745f744442930e322e9f48558090a9e08f91c7cd7433d48fac97dc7747ed636446277f3f163dcaecc0c70c53d0604 + checksum: 691358e32532c8a830a4dc4133ae90f80bd659b4acc2db308353d3027663a4223de9e0ae7ef8c24be895b20be5995cb78f1bb86e57b32b8397b43339f58b5555 languageName: node linkType: hard -"@opentelemetry/instrumentation-express@npm:^0.36.1": - version: 0.36.1 - resolution: "@opentelemetry/instrumentation-express@npm:0.36.1" +"@opentelemetry/instrumentation-express@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-express@npm:0.42.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: c4f4ed644a194160dd816e20cd914ab59b7927c11b2c1639fb17bb160a59148a027b23c3259d3ec3ac3384b90c769b15bedd7aac4649ac3ae01ee2cdb746f61d + checksum: c4606bd593ee841eb891927f404609b05e1375b28f9e5cd179381b744d826e3a6d07d069835d02b06e2cd8de6861c0ecebaa2d3a180181733e9fdc6b80444837 languageName: node linkType: hard -"@opentelemetry/instrumentation-fastify@npm:^0.34.0": - version: 0.34.0 - resolution: "@opentelemetry/instrumentation-fastify@npm:0.34.0" +"@opentelemetry/instrumentation-fastify@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-fastify@npm:0.39.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: c37d8f889b1b1db87fa066d41d595220505b6b708183daae06a0b8db94140a5f6d294bcc5650f024385626e114e5d926b1679c8246008be40a540a2f5710b1c5 + checksum: a64ffd35f01e6ae08a7de7092ef34ec186c284ebada7f8e4d87420440bbc5a00b568624e7c1dd35b00550d68ccb24ae905ad8488adb7eaf14344f334d436244e languageName: node linkType: hard -"@opentelemetry/instrumentation-fs@npm:^0.10.0": - version: 0.10.0 - resolution: "@opentelemetry/instrumentation-fs@npm:0.10.0" +"@opentelemetry/instrumentation-fs@npm:^0.15.0": + version: 0.15.0 + resolution: "@opentelemetry/instrumentation-fs@npm:0.15.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 4382ddeb28b663d218f47b2db533c2f4a350d9c38ca71b1a4b688b54f8f0333ce9f54ed411e294f0ce05cbf339897b2379ee8dfd7aaf6b3109077c86cc629a94 + checksum: d1f50b541629e9155dcbfbdd26d5fa43d6569f835abf88ea35261e0c03c6afb89b26cd2056dda6e9c4de72a49d7e2ca0336e1dc75604256db09e0e09d2182466 languageName: node linkType: hard -"@opentelemetry/instrumentation-generic-pool@npm:^0.34.0": - version: 0.34.0 - resolution: "@opentelemetry/instrumentation-generic-pool@npm:0.34.0" +"@opentelemetry/instrumentation-generic-pool@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-generic-pool@npm:0.39.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 0d55b59e65b6cf2af9942d303bc550da66455b718be5778330a0538f5c6ca27c18a2f82cb88dbeab98d4d8fb37ce761de1cd448e338701e57fd61bdb3b60b12a + checksum: 2d094b217afe9c1d388f06cdaca07f9801b70f0d01ee3db374f1b4f07cd18efba55e90679f0237c1f2a7db22f9ee0e564e8583161bb7d578ecea779b874e967e languageName: node linkType: hard -"@opentelemetry/instrumentation-graphql@npm:^0.38.1": - version: 0.38.1 - resolution: "@opentelemetry/instrumentation-graphql@npm:0.38.1" +"@opentelemetry/instrumentation-graphql@npm:^0.43.0": + version: 0.43.0 + resolution: "@opentelemetry/instrumentation-graphql@npm:0.43.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: d148d1aa5ab661ab375bce5a0539e80836e0dc695936661a93e64a4f58b7b7c9617cca6d9989b15f6d7fa2a5ffbdd8c26ba43316416cdf527ce03cb9fc9165ac + checksum: 4164f3dad9c44f3d9684750d879ba79a51949fe69179d8437f5736762cdd0156c63a8914c7accd767b090a18db45f011a9cff5e238d3240077f1c095d3c5dd28 languageName: node linkType: hard -"@opentelemetry/instrumentation-grpc@npm:^0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/instrumentation-grpc@npm:0.49.1" +"@opentelemetry/instrumentation-grpc@npm:^0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/instrumentation-grpc@npm:0.53.0" dependencies: - "@opentelemetry/instrumentation": 0.49.1 - "@opentelemetry/semantic-conventions": 1.22.0 + "@opentelemetry/instrumentation": 0.53.0 + "@opentelemetry/semantic-conventions": 1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 55b22e2dffb6be63d57c97773b63fed9576307676d7919b16b005f47bce13a103437160966f2c01c2ed5aa71f135b36248d3db69c3030685a1e8ea9d4c42d4f9 + checksum: 937e96ec7fe655d3599ba71ffe48d79ff068e3ce820600249ed2807d2e7b2769e0771b723e5961bcd11ae8585df26f596a39e320497a9d3299d816510bb61eca languageName: node linkType: hard -"@opentelemetry/instrumentation-hapi@npm:^0.35.0": - version: 0.35.0 - resolution: "@opentelemetry/instrumentation-hapi@npm:0.35.0" +"@opentelemetry/instrumentation-hapi@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-hapi@npm:0.41.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 - "@types/hapi__hapi": 20.0.13 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 23545b19597e3f7f65fb0ff06adb6d5ed9ce4675ebbc5153c243668b0476f99d298e097b7f2349b3eaa565bcab0c26e7985332b749624afd5b77172669b70217 + checksum: 2195c8366d9b81a40dd6d8db041c13687932ab7ec761c9dfea13162c4000638c699dfebf384e22f985aea2d7692c742ed8090cb5bad056e5137d2db79a615380 languageName: node linkType: hard -"@opentelemetry/instrumentation-http@npm:^0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/instrumentation-http@npm:0.49.1" +"@opentelemetry/instrumentation-http@npm:^0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/instrumentation-http@npm:0.53.0" dependencies: - "@opentelemetry/core": 1.22.0 - "@opentelemetry/instrumentation": 0.49.1 - "@opentelemetry/semantic-conventions": 1.22.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/instrumentation": 0.53.0 + "@opentelemetry/semantic-conventions": 1.27.0 semver: ^7.5.2 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: b3dc388f94a69202749cca70d71b5bcd3b713d67c40e0421b84d11a323080a76d645ea05fc551092022451cbbef6da303d806890e90f1784edde65adefd20e4d + checksum: 4ee569f7fc8c7ce50fabaff016d33577f36e63272b0634ac45806d70bffdf38fcf09db3cd9dd27c3150f6c4547fec673c356c419a6ed2399ff2849b9487a6e89 languageName: node linkType: hard -"@opentelemetry/instrumentation-ioredis@npm:^0.38.0": - version: 0.38.0 - resolution: "@opentelemetry/instrumentation-ioredis@npm:0.38.0" +"@opentelemetry/instrumentation-ioredis@npm:^0.43.0": + version: 0.43.0 + resolution: "@opentelemetry/instrumentation-ioredis@npm:0.43.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/redis-common": ^0.36.1 - "@opentelemetry/semantic-conventions": ^1.0.0 - "@types/ioredis4": "npm:@types/ioredis@^4.28.10" + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/redis-common": ^0.36.2 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 0b61f92db80ff89d00e93f3ef8b532c9439973ac0fd7d6b492a5faf46dc61d3c0b65b6b4359d69d23413db59b85e86a3857d82b00f810dd22be41014b3ff392d + checksum: 16ae17687db3b4bbe78d92667ce86f3afb212adb5eda8f17b549a06ff9e1ba3e0f146ded9e943cb781780b64853a6b7fa3b85d2c2f5e4f42fd76d651c90aa71f languageName: node linkType: hard -"@opentelemetry/instrumentation-knex@npm:^0.34.0": - version: 0.34.0 - resolution: "@opentelemetry/instrumentation-knex@npm:0.34.0" +"@opentelemetry/instrumentation-kafkajs@npm:^0.3.0": + version: 0.3.0 + resolution: "@opentelemetry/instrumentation-kafkajs@npm:0.3.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 544b280c7a508bf4930f3d99dbce844358d066a1b7455c389916a6c13cab9d43ac5ff6eb1dd7e147988bc2636ca0e979f62883ee9c5941abcda29ba168af6165 + checksum: 9ea20f4f70edd7d47b551f56f56b6b0462e5f9dff3981462d9d061084a3bb345f1989ddc46a2d8fabebf2a9650c52ab6c6fb906a03e9176191cc71073c2bf22c languageName: node linkType: hard -"@opentelemetry/instrumentation-koa@npm:^0.38.0": - version: 0.38.0 - resolution: "@opentelemetry/instrumentation-koa@npm:0.38.0" +"@opentelemetry/instrumentation-knex@npm:^0.40.0": + version: 0.40.0 + resolution: "@opentelemetry/instrumentation-knex@npm:0.40.0" + dependencies: + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: ca7f08b4a783ebb470663fa53a5418074cc04a42ad7b6f19939be04aff1c0db2070ca8b7ada17e363a412b1013149bde38bf1930f05c09cd6207a90711db0372 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation-koa@npm:^0.43.0": + version: 0.43.0 + resolution: "@opentelemetry/instrumentation-koa@npm:0.43.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 - "@types/koa": 2.14.0 - "@types/koa__router": 12.0.3 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 7b76f6d03cbaeeda3a8a1e40790b76b52587365bd1ee2d2b04b65d62a527b9085c13827398e0422be4432f1b0dde3621246e7cbd85fa489aced58e085702e201 + checksum: 7b30d11f8cbabc1570eeca771f421c65f014d87b850cf17a8f2aec98dc84a8a43ce6fe15634f5d16944466f8da1011508367498e215b3f6378e8f8d618a12ec9 languageName: node linkType: hard -"@opentelemetry/instrumentation-lru-memoizer@npm:^0.35.0": - version: 0.35.0 - resolution: "@opentelemetry/instrumentation-lru-memoizer@npm:0.35.0" +"@opentelemetry/instrumentation-lru-memoizer@npm:^0.40.0": + version: 0.40.0 + resolution: "@opentelemetry/instrumentation-lru-memoizer@npm:0.40.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 9ef0231cf21c747fac86134402f36ea8561e8df694bc1e536b0f54af536e0a675e38c8d34c22628afbe6bc65ab5b5edebfe4de7b45d42e6e9d616afb60db62bf + checksum: 1a65e7c397707f9d09fe11f9fbd127d5094406ec98f84e74309c1d9869da23173c3895c851bccf9c5c1b8aeef6fc516340311f87d154832c74a344a0ed4ac9ef languageName: node linkType: hard -"@opentelemetry/instrumentation-memcached@npm:^0.34.0": - version: 0.34.0 - resolution: "@opentelemetry/instrumentation-memcached@npm:0.34.0" +"@opentelemetry/instrumentation-memcached@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-memcached@npm:0.39.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 "@types/memcached": ^2.2.6 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: b2a9d97f78641074054e9a67458702785fb15ceb7c1e4868ab8f5ddde85826676e29094154fac19b0722a58a62e1311afc5fda69e883b2bd7e4780bb8dd3f2cb + checksum: bbf976f90463fe1b8a64d6e20057fc1926342a1f644e4cfd160ce1b0a032269b48b754e6cd86eff41faf92bd2e3617f1572a1ef272cb5059ed21aaf7c6591ccb languageName: node linkType: hard -"@opentelemetry/instrumentation-mongodb@npm:^0.41.0": - version: 0.41.0 - resolution: "@opentelemetry/instrumentation-mongodb@npm:0.41.0" +"@opentelemetry/instrumentation-mongodb@npm:^0.47.0": + version: 0.47.0 + resolution: "@opentelemetry/instrumentation-mongodb@npm:0.47.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 + "@opentelemetry/instrumentation": ^0.53.0 "@opentelemetry/sdk-metrics": ^1.9.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 8fb991a1ea05a559d369e0274825b1f7e2a27f2aa4ddb8ecbf4e329efa35e115a19bd75864597918b74773319ad9dcbaf846e621dd286543d4f732399ab942b1 + checksum: 1d7c87532b5857e8d6d72272ce874f02a4b2adc8a135d07c48e432cc990a4493c110b15c842c72dfc79e33ddc63f518185b69e242e2c55521a06fe6503cb1980 languageName: node linkType: hard -"@opentelemetry/instrumentation-mongoose@npm:^0.36.0": - version: 0.36.0 - resolution: "@opentelemetry/instrumentation-mongoose@npm:0.36.0" +"@opentelemetry/instrumentation-mongoose@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-mongoose@npm:0.42.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 7bc18b731f321090550e02930f2a2ffa4a99d7becd58b3cfba16c89f8c5e91a97e59abac4976864c98c13b5ce171f9b4131c723b13ec62657d9a0d8e3f74e79f + checksum: 77d36437073ee589ccd73f4a10a4602afd0f4a3a89a9c572be18b2df75941f5a6885d4823094d8ffe8859801d827d0b46f93dee03f39286d89eead373edf76bb languageName: node linkType: hard -"@opentelemetry/instrumentation-mysql2@npm:^0.36.0": - version: 0.36.0 - resolution: "@opentelemetry/instrumentation-mysql2@npm:0.36.0" +"@opentelemetry/instrumentation-mysql2@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-mysql2@npm:0.41.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 - "@opentelemetry/sql-common": ^0.40.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + "@opentelemetry/sql-common": ^0.40.1 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 3395f0d69c23d3a98e9e4d7085a36868b938eb5337c5f5bd540d6b4d025d90a6af89f28e01635e2558d963d2c28be1ba6bf63364767575dd39383fd6dfc82c89 + checksum: 37c8a57fb6591ae1db353e149ad5f38ac68c5f727e313ba6d1cc403d910ae8e3b743c3234500272012ea6eecb5b838803ee493ce5096ad40bb285b09090f4a65 languageName: node linkType: hard -"@opentelemetry/instrumentation-mysql@npm:^0.36.0": - version: 0.36.0 - resolution: "@opentelemetry/instrumentation-mysql@npm:0.36.0" +"@opentelemetry/instrumentation-mysql@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-mysql@npm:0.41.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 - "@types/mysql": 2.15.22 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + "@types/mysql": 2.15.26 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 705ab9e38e79a6db3be59eac718814c1cc71dea7d45e4da5257094625940f1e84002d9c5c8afa33f5bbc25ff012a66988d02b5be8fac521e2fc0fae353d9e013 + checksum: c8c23a1273e900902867ca4da8c026581d3f584e420a5f26ec738ace20c1a85695a411721541e63e0639d9ddbb8c3713a2bc25621886f81912014882395d3531 languageName: node linkType: hard -"@opentelemetry/instrumentation-nestjs-core@npm:^0.35.0": - version: 0.35.0 - resolution: "@opentelemetry/instrumentation-nestjs-core@npm:0.35.0" +"@opentelemetry/instrumentation-nestjs-core@npm:^0.40.0": + version: 0.40.0 + resolution: "@opentelemetry/instrumentation-nestjs-core@npm:0.40.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: f878dc88d65e4ac876ca36a2e1f9c109aba14dd97f7aa8863b2231d90b57cb2526c74124690661a4d5fad8936d8c9b44c63c46563a5b89a1a57c86eb0ba01efd + checksum: ce6b2d9186d95e5fa5c65efd902254c724e296172787d1fa9382a6204ae9d089e861ce8831ba6e6865d449a96a8aada7b1049568217f1bda21af3f36e01b9512 languageName: node linkType: hard -"@opentelemetry/instrumentation-net@npm:^0.34.0": - version: 0.34.0 - resolution: "@opentelemetry/instrumentation-net@npm:0.34.0" +"@opentelemetry/instrumentation-net@npm:^0.39.0": + version: 0.39.0 + resolution: "@opentelemetry/instrumentation-net@npm:0.39.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: ed4dd2a9ea69314d519358733fcaee8a55d120cb8a5e85088b20626b753e5ddeea7a61e58b76d1e86b27c36828e9777a504ba405556046e9a30ef1bf12eeaa08 + checksum: ae3c7cdb4894a9aae7ea7a4d6a00cbef4afc2194539226f01f68ee78d25fb2d5debfb738b8a79a9842c4987bc4c673c7e6386d328c1e6bfc09e2613bf4677ed3 languageName: node linkType: hard -"@opentelemetry/instrumentation-pg@npm:^0.39.1": - version: 0.39.1 - resolution: "@opentelemetry/instrumentation-pg@npm:0.39.1" +"@opentelemetry/instrumentation-pg@npm:^0.44.0": + version: 0.44.0 + resolution: "@opentelemetry/instrumentation-pg@npm:0.44.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 - "@opentelemetry/sql-common": ^0.40.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + "@opentelemetry/sql-common": ^0.40.1 "@types/pg": 8.6.1 - "@types/pg-pool": 2.0.4 + "@types/pg-pool": 2.0.6 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 5e6276aaed45e88ccf019ce533a905570340160752e08e7e85c1bdfbe646ca6779046afd46c759cba18b2acec3dcb5bf80591807cf335bc2583d577725fdede8 + checksum: 13cf8bacee1139b551622cb76670c627e87b37ee5ad2b6c63417d985812c7db53ce7aae23bd04156cb5c0d1a214bb8c65890fde43fbd99aac540c625216703b7 languageName: node linkType: hard -"@opentelemetry/instrumentation-pino@npm:^0.36.0": - version: 0.36.0 - resolution: "@opentelemetry/instrumentation-pino@npm:0.36.0" +"@opentelemetry/instrumentation-pino@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-pino@npm:0.42.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 + "@opentelemetry/api-logs": ^0.53.0 + "@opentelemetry/core": ^1.25.0 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: bf46db42c88930f64430a68c227b5b08deeb40518ad082a610524ad8efc5768d038117951032e89a86131eb0f95106368cba8d3fde091f906aa3e42e167c2c95 + checksum: 005146e233c53ffbf703c97d855a523fe91d9d2632b77fd0b094caec6f3646908fd03c22bea77575d4a75eac0a2aa2065c7a2d9caac45c370e9592abe9b231c1 languageName: node linkType: hard -"@opentelemetry/instrumentation-redis-4@npm:^0.37.0": - version: 0.37.0 - resolution: "@opentelemetry/instrumentation-redis-4@npm:0.37.0" +"@opentelemetry/instrumentation-redis-4@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-redis-4@npm:0.42.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/redis-common": ^0.36.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/redis-common": ^0.36.2 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 98208f8fe83bcf5e4fc9efeadff8724bc9eba4cfddc9c76630a30a582583e4d49842a47730429705c1d5931acbcc7223a4538194c43373c30ea6b0e326721db8 + checksum: b6d92ad302c31add32b1cdfe6f6ea836367a777737beb187b178bfb65047f84263b38855cda56746b793582eb6012942c03ed91f6e8e6710058bf3eb427fba2d languageName: node linkType: hard -"@opentelemetry/instrumentation-redis@npm:^0.37.0": - version: 0.37.0 - resolution: "@opentelemetry/instrumentation-redis@npm:0.37.0" +"@opentelemetry/instrumentation-redis@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-redis@npm:0.42.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/redis-common": ^0.36.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/redis-common": ^0.36.2 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 06ceaf8df2cfc7f197f981b6785af3160379eb94c4a7b3e0a0e60ca78c47b3f22599d3e9f030c52ff016da396418a0c31eb38282b207d0477aa42e8c9180ac2c + checksum: 1a84b516599a290de78eaf1a1db897bf2e866baaf4a77a76880b24261786f6ffa2673fcec36f360abf73d5e52104557ff957964b7b3683962b0bde2bbfbb074e languageName: node linkType: hard -"@opentelemetry/instrumentation-restify@npm:^0.36.0": - version: 0.36.0 - resolution: "@opentelemetry/instrumentation-restify@npm:0.36.0" +"@opentelemetry/instrumentation-restify@npm:^0.41.0": + version: 0.41.0 + resolution: "@opentelemetry/instrumentation-restify@npm:0.41.0" dependencies: "@opentelemetry/core": ^1.8.0 - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: f7dbca7e2a10463575d33f27c9c7e3b9352732dfe3df646fa0772a61aaae4757d1e66ede740ebe41804a952de904447cc6823c82ece31db16b568f926e40bcaa + checksum: 28aac1e5bf2cdca2fa18c8423db3edb530bc338bb05a30537c24575bac12f4588d975598b020f58817393cf68354b913ca07e3720b3ff8497278887baee7b10b languageName: node linkType: hard -"@opentelemetry/instrumentation-router@npm:^0.35.0": - version: 0.35.0 - resolution: "@opentelemetry/instrumentation-router@npm:0.35.0" +"@opentelemetry/instrumentation-router@npm:^0.40.0": + version: 0.40.0 + resolution: "@opentelemetry/instrumentation-router@npm:0.40.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 3bdfba103b41f10c7fe7a650ad4f54cfa7a53b38afe69e05a0402b0157f2c393543b45e42febf05cc5c964ecb8667374a60ad25d00ce021180c70c02770e5f63 + checksum: 7f8fb67d755cb8fa94dbe44f698d22e1ce80971071f574aa9a8b177410cf6a8ab37abd449777670705b73aa6a4272212e80d6dc3c6ec0aa7f99ce161238c7f33 languageName: node linkType: hard -"@opentelemetry/instrumentation-socket.io@npm:^0.37.0": - version: 0.37.0 - resolution: "@opentelemetry/instrumentation-socket.io@npm:0.37.0" +"@opentelemetry/instrumentation-socket.io@npm:^0.42.0": + version: 0.42.0 + resolution: "@opentelemetry/instrumentation-socket.io@npm:0.42.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 21b790f53b91994a1241d7d3c5a400d5232001f740c13f64a0f48461e5db7974d2563e17059a44f567fb8dc4fb9078dc57738784b1474fb40e771e5d7bca67bb + checksum: 21f92a17b26627ac03bf19f8c5eea550bac915366919a7b7f73893f0bdd8669421e02ec0379387439a46b1e1ad05dfe8dc9a6f6784b9dc8919f8c7dc05694dd8 languageName: node linkType: hard -"@opentelemetry/instrumentation-tedious@npm:^0.8.0": - version: 0.8.0 - resolution: "@opentelemetry/instrumentation-tedious@npm:0.8.0" +"@opentelemetry/instrumentation-tedious@npm:^0.14.0": + version: 0.14.0 + resolution: "@opentelemetry/instrumentation-tedious@npm:0.14.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 - "@opentelemetry/semantic-conventions": ^1.0.0 - "@types/tedious": ^4.0.10 + "@opentelemetry/instrumentation": ^0.53.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + "@types/tedious": ^4.0.14 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 920a8446fb765f6833d926680ae4e6a7e7e4013e2f9145b20546e945848e3f9a31aabb6e37c087a9a7667457c7ec710cd5d6304279e67a6c7ddeda0d41501e01 + checksum: 31d6f0d10c3c1f03c9bf3207d7b5569f23ff202f954cb5b91242d788813b5807e5fc204748d14c3b12d320fa5dc1205d4b54131847496117af54e205f025a23e languageName: node linkType: hard -"@opentelemetry/instrumentation-winston@npm:^0.35.0": - version: 0.35.0 - resolution: "@opentelemetry/instrumentation-winston@npm:0.35.0" +"@opentelemetry/instrumentation-undici@npm:^0.6.0": + version: 0.6.0 + resolution: "@opentelemetry/instrumentation-undici@npm:0.6.0" dependencies: - "@opentelemetry/instrumentation": ^0.49.1 + "@opentelemetry/core": ^1.8.0 + "@opentelemetry/instrumentation": ^0.53.0 peerDependencies: - "@opentelemetry/api": ^1.3.0 - checksum: f4f2ef0adf049de6434906fd573e2465900e1f5c0f788c842978f6a43889c12dc04d15a8c079a615e9fe09df1eeabc0c2b93a219aff6f1106b2031b01f045d96 + "@opentelemetry/api": ^1.7.0 + checksum: b16b9ff23fbca13a18889fc302ddae3db8b22ebd9d8224b0297bd45014bb914d6bea89e55aedda6879cee1760c93bcedc2eaa12e60e88f45dd8c9e5f61a0aefd languageName: node linkType: hard -"@opentelemetry/instrumentation@npm:0.49.1, @opentelemetry/instrumentation@npm:^0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/instrumentation@npm:0.49.1" +"@opentelemetry/instrumentation-winston@npm:^0.40.0": + version: 0.40.0 + resolution: "@opentelemetry/instrumentation-winston@npm:0.40.0" dependencies: - "@opentelemetry/api-logs": 0.49.1 - "@types/shimmer": ^1.0.2 - import-in-the-middle: 1.7.1 + "@opentelemetry/api-logs": ^0.53.0 + "@opentelemetry/instrumentation": ^0.53.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: be7c3f6f8a5672db940b8196e9254a4188c9c6bb717a272088fe5e8319874a80a28a56b1073ad130bb2233a29d4459a754b4ea2f36855f90a679a9c379f5cf16 + languageName: node + linkType: hard + +"@opentelemetry/instrumentation@npm:0.53.0, @opentelemetry/instrumentation@npm:^0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/instrumentation@npm:0.53.0" + dependencies: + "@opentelemetry/api-logs": 0.53.0 + "@types/shimmer": ^1.2.0 + import-in-the-middle: ^1.8.1 require-in-the-middle: ^7.1.1 semver: ^7.5.2 shimmer: ^1.2.1 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 87379f8505118c850f73947784fd57fbaa2667fbf5ca8bd0a91a0782d0a240ab92e9091cd4107a6785d37e4976a6f1fb20b89a1d9ac9bec6faf858681a7d8707 + checksum: a386fe066eab71129a6edbc883ab407b1022850e8acc4750029a12e8730588a8b81442d0b008aaddb46f7614af40d19d331e7348790ca2d08ba8eed6d23ffdae languageName: node linkType: hard -"@opentelemetry/instrumentation@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/instrumentation@npm:0.50.0" +"@opentelemetry/otlp-exporter-base@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/otlp-exporter-base@npm:0.53.0" dependencies: - "@opentelemetry/api-logs": 0.50.0 - "@types/shimmer": ^1.0.2 - import-in-the-middle: 1.7.1 - require-in-the-middle: ^7.1.1 - semver: ^7.5.2 - shimmer: ^1.2.1 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/otlp-transformer": 0.53.0 + peerDependencies: + "@opentelemetry/api": ^1.0.0 + checksum: 8c80374c476e7aacf04172d18ffba5ec7ecc33c98dd102f74d22c916f20e147a42038662bc4ec17eaa7b7ffc85f8fde0c72b81b978a7460977fe236fc757207b + languageName: node + linkType: hard + +"@opentelemetry/otlp-grpc-exporter-base@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/otlp-grpc-exporter-base@npm:0.53.0" + dependencies: + "@grpc/grpc-js": ^1.7.1 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/otlp-exporter-base": 0.53.0 + "@opentelemetry/otlp-transformer": 0.53.0 + peerDependencies: + "@opentelemetry/api": ^1.0.0 + checksum: 1e59ad97cd65e618a7d1f43590b8039e4b0aea91231719515ba80a414bd1063ecb7457466f1d73b60f9571415e1621b48af374e1cd7f70f9325d2a06c393c045 + languageName: node + linkType: hard + +"@opentelemetry/otlp-transformer@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/otlp-transformer@npm:0.53.0" + dependencies: + "@opentelemetry/api-logs": 0.53.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/resources": 1.26.0 + "@opentelemetry/sdk-logs": 0.53.0 + "@opentelemetry/sdk-metrics": 1.26.0 + "@opentelemetry/sdk-trace-base": 1.26.0 + protobufjs: ^7.3.0 peerDependencies: "@opentelemetry/api": ^1.3.0 - checksum: 371398639ca68c188d4b77a0034ea369222a2a1de421be37190900bade1210802a50b53cc48fd21206917817319a92a4cb52bd92bd534889355b54316145e634 + checksum: 0dbec27a293a70802ae68e5cd75f094477b80e15026bff185acd4c7ce45d28e9964033715a0d909f8e8bd8eda92bd31f2a8e9f4444717e40880334f1341465de languageName: node linkType: hard -"@opentelemetry/otlp-exporter-base@npm:0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/otlp-exporter-base@npm:0.49.1" - dependencies: - "@opentelemetry/core": 1.22.0 +"@opentelemetry/propagation-utils@npm:^0.30.11": + version: 0.30.11 + resolution: "@opentelemetry/propagation-utils@npm:0.30.11" peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 43b2237b83811ccb632b0e6a5a6b824627c1c05670c0ca158f0686278ec6d1dc32d8780d0fde8c496531e6b7fbe780e154aa5dc53b911b49c927f0566bcc795d - languageName: node - linkType: hard - -"@opentelemetry/otlp-exporter-base@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/otlp-exporter-base@npm:0.50.0" - dependencies: - "@opentelemetry/core": 1.23.0 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: e1e6586a64d753e542f28858c1618776deeaf639afd50e4ff325c14f7571ac91546928d0f2f89b2287e7cdbadf3211e3f9dd844139f64e6253e99f71b6cc1f07 - languageName: node - linkType: hard - -"@opentelemetry/otlp-grpc-exporter-base@npm:0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/otlp-grpc-exporter-base@npm:0.49.1" - dependencies: - "@grpc/grpc-js": ^1.7.1 - "@opentelemetry/core": 1.22.0 - "@opentelemetry/otlp-exporter-base": 0.49.1 - protobufjs: ^7.2.3 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 7d8065ea161ba105060856ec448d2fdbbb725fd397bfd47a3281929249af3995373619d8e8c6504ca22893d1e1cffe12f3af220988d06e2b1576c8ac26edb86e - languageName: node - linkType: hard - -"@opentelemetry/otlp-grpc-exporter-base@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/otlp-grpc-exporter-base@npm:0.50.0" - dependencies: - "@grpc/grpc-js": ^1.7.1 - "@opentelemetry/core": 1.23.0 - "@opentelemetry/otlp-exporter-base": 0.50.0 - protobufjs: ^7.2.3 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 97a4e69d2834c840f1f037737eb378c309e5645002490b5bc51b836303a205a65658e2b1ec512dd613207626517efbe744b46225a9b3079b782cdda0a168fcf6 - languageName: node - linkType: hard - -"@opentelemetry/otlp-proto-exporter-base@npm:0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/otlp-proto-exporter-base@npm:0.49.1" - dependencies: - "@opentelemetry/core": 1.22.0 - "@opentelemetry/otlp-exporter-base": 0.49.1 - protobufjs: ^7.2.3 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: b381e1022855867b621ad04252cad7376445c6a110073c8715f1c41b782b5dbad668f2acee2aecfca348c49a3f2adb4c16297d99fe9d3068b1746314cc6d4c13 - languageName: node - linkType: hard - -"@opentelemetry/otlp-proto-exporter-base@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/otlp-proto-exporter-base@npm:0.50.0" - dependencies: - "@opentelemetry/core": 1.23.0 - "@opentelemetry/otlp-exporter-base": 0.50.0 - protobufjs: ^7.2.3 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: d39f61a5ca31ac9cbb6ac7e77c71afebc7b40bf247361c99e34f8c00aeae88db1d4c7e6742f9dd01d2334ee50c7db8e24d7d9df67a65ee005c947358611f2050 - languageName: node - linkType: hard - -"@opentelemetry/otlp-transformer@npm:0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/otlp-transformer@npm:0.49.1" - dependencies: - "@opentelemetry/api-logs": 0.49.1 - "@opentelemetry/core": 1.22.0 - "@opentelemetry/resources": 1.22.0 - "@opentelemetry/sdk-logs": 0.49.1 - "@opentelemetry/sdk-metrics": 1.22.0 - "@opentelemetry/sdk-trace-base": 1.22.0 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.9.0" - checksum: 1f79e796a452168f353a3dfead3ae3e3206a30fa68d690721d7377e78f9e2ba0f3de32621fd8743b3c47c9b8c22034bf7f9b209327d2d09caa8a08f13288eeb0 - languageName: node - linkType: hard - -"@opentelemetry/otlp-transformer@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/otlp-transformer@npm:0.50.0" - dependencies: - "@opentelemetry/api-logs": 0.50.0 - "@opentelemetry/core": 1.23.0 - "@opentelemetry/resources": 1.23.0 - "@opentelemetry/sdk-logs": 0.50.0 - "@opentelemetry/sdk-metrics": 1.23.0 - "@opentelemetry/sdk-trace-base": 1.23.0 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.9.0" - checksum: d2637146cdb1a3c7c311f03c8d8a11c1c4b57c63ac3532865096055d603a334bb4b5a63cecaba96f27dd0f3b8b4c7ffcebd248d85c47b7e60a5b5e7ae821219c - languageName: node - linkType: hard - -"@opentelemetry/propagation-utils@npm:^0.30.7": - version: 0.30.9 - resolution: "@opentelemetry/propagation-utils@npm:0.30.9" - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 4cc6e645ed7334fc1773396854c95aaabd5c5a307ede85ee8533e362fff4fa290a6efa36b35ced7a7d73894f575d07bd4daae4331ddd62536a4847efdd9354b0 + checksum: 4cce9958ca40b042adda8601b651799f1a140a513dd8c085094cb88265470bf40a04ed5f84301d891fef90f59698802e20828311b6189e4ab6c741101d8ac248 languageName: node linkType: hard @@ -13429,335 +13192,206 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/propagator-b3@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/propagator-b3@npm:1.22.0" +"@opentelemetry/propagator-b3@npm:1.26.0": + version: 1.26.0 + resolution: "@opentelemetry/propagator-b3@npm:1.26.0" dependencies: - "@opentelemetry/core": 1.22.0 + "@opentelemetry/core": 1.26.0 peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: f072fcfaa2c126b84f7f9b060fa66fff36fbe3f425123f6aec9a99094d20296dc781d3c61e765b2727e957fcad311fd4f58da70ed51bf152fbc21202d78d70a5 + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: c2e99a8ed2814cf5b8e6e2a79411f2f6d668b7d5fc8351e5302ea4149601a96ec655422cf59470c66d8a408850f8a6b5156bf7deac7afb07d3f7a935c51fff04 languageName: node linkType: hard -"@opentelemetry/propagator-b3@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/propagator-b3@npm:1.23.0" +"@opentelemetry/propagator-jaeger@npm:1.26.0": + version: 1.26.0 + resolution: "@opentelemetry/propagator-jaeger@npm:1.26.0" dependencies: - "@opentelemetry/core": 1.23.0 + "@opentelemetry/core": 1.26.0 peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 8478a4ac3fcad3ea53ed7af70c7da22dee48a262aef2bb2c64a039a3aff1368476b23ce385b95b3c34334a29d7964c98ca3c08bc05dd2999a891faf3ab858799 + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: a0ac3888c86f1b4671c7ca520396b89b4c47fa9e9d976bd014472d2b7786e7c5bdf4823a6e2a900fed5ea5dfe23eda0bdf6740e77c1352f2c0f82b13a71c03df languageName: node linkType: hard -"@opentelemetry/propagator-jaeger@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/propagator-jaeger@npm:1.22.0" - dependencies: - "@opentelemetry/core": 1.22.0 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 0d998bd160b6d812ebc61b8ba75009688cf2d0feaeb4389c8f6bb32d2a02c16f7cf6a77d1bc5f773bf5663f31ca3fa7ec2dc79cf6d9909ffb5098297f6357a86 - languageName: node - linkType: hard - -"@opentelemetry/propagator-jaeger@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/propagator-jaeger@npm:1.23.0" - dependencies: - "@opentelemetry/core": 1.23.0 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 240f27f15473704a5cf8549ea22b1640d865ef40c3da65b023e7f44cc89422b9f983061e4508a3f4576339907625c8f725c42e7f5e77c243c833e03d9490880d - languageName: node - linkType: hard - -"@opentelemetry/redis-common@npm:^0.36.1": +"@opentelemetry/redis-common@npm:^0.36.2": version: 0.36.2 resolution: "@opentelemetry/redis-common@npm:0.36.2" checksum: b0a6f2c2dc64ba3b655ed944a5a33715d00365865e6f498005527a4ad6c40ca0e7b8ac531791b6d5abfbab9b22d9c6aa1cd8bcc851a7634dfb381ad2d5061b0d languageName: node linkType: hard -"@opentelemetry/resource-detector-alibaba-cloud@npm:^0.28.7": - version: 0.28.9 - resolution: "@opentelemetry/resource-detector-alibaba-cloud@npm:0.28.9" +"@opentelemetry/resource-detector-alibaba-cloud@npm:^0.29.1": + version: 0.29.1 + resolution: "@opentelemetry/resource-detector-alibaba-cloud@npm:0.29.1" dependencies: "@opentelemetry/resources": ^1.0.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/semantic-conventions": ^1.27.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 8ac05377da60c7c1a958509849989d2151a29c341819def6033f65e5302066dec77ad0358a117d40eef22cbb3537956bb492a15e524a86131f92e0e5d9a91c16 + checksum: 8b32490aaa18996aaed79d2b512d947ea0509c326002b98ec63fcba8ad3793e63365f338f5792bf0dd6c4141126ca491dff3bbf079fa37fdf78a772bb6c8d487 languageName: node linkType: hard -"@opentelemetry/resource-detector-aws@npm:^1.4.0": - version: 1.4.2 - resolution: "@opentelemetry/resource-detector-aws@npm:1.4.2" +"@opentelemetry/resource-detector-aws@npm:^1.6.1": + version: 1.6.1 + resolution: "@opentelemetry/resource-detector-aws@npm:1.6.1" + dependencies: + "@opentelemetry/core": ^1.0.0 + "@opentelemetry/resources": ^1.10.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + peerDependencies: + "@opentelemetry/api": ^1.0.0 + checksum: ff466f439c2dc061e5c587226ebace5f6d88ddda923889842d6c7fc4076dd88bf27096e4f80f23e8c37bde4e309b3666c7e0fd90637f2dffa6581e9e9cf75a33 + languageName: node + linkType: hard + +"@opentelemetry/resource-detector-azure@npm:^0.2.11": + version: 0.2.11 + resolution: "@opentelemetry/resource-detector-azure@npm:0.2.11" + dependencies: + "@opentelemetry/core": ^1.25.1 + "@opentelemetry/resources": ^1.10.1 + "@opentelemetry/semantic-conventions": ^1.27.0 + peerDependencies: + "@opentelemetry/api": ^1.0.0 + checksum: 13515be1d57f9a9611064224e55766a7a66176d85bcbc62e7313e261c0a40e8c02e6ec024ed51f1e20ce16f3e969a601a756d2130f01b24a1e088743886903b3 + languageName: node + linkType: hard + +"@opentelemetry/resource-detector-container@npm:^0.4.1": + version: 0.4.1 + resolution: "@opentelemetry/resource-detector-container@npm:0.4.1" + dependencies: + "@opentelemetry/resources": ^1.10.0 + "@opentelemetry/semantic-conventions": ^1.27.0 + peerDependencies: + "@opentelemetry/api": ^1.0.0 + checksum: 7a8e5715469209881f63fe21745d807e821fa3cdf4bd4751b2da43078607b9498a18773a7bd47ba22e872397766d2c3bbf55d168ad0d9ad31c159979a32d62bf + languageName: node + linkType: hard + +"@opentelemetry/resource-detector-gcp@npm:^0.29.11": + version: 0.29.11 + resolution: "@opentelemetry/resource-detector-gcp@npm:0.29.11" dependencies: "@opentelemetry/core": ^1.0.0 "@opentelemetry/resources": ^1.0.0 - "@opentelemetry/semantic-conventions": ^1.22.0 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: 66a7c90f037bccb0a754701182b6ec89982f8ba1d46bc07c0b4db6debe69dc504482fe65bdb3867c8ddf8f18e899a657cbb0c6bf5e677becb2ec08be8c3538f1 - languageName: node - linkType: hard - -"@opentelemetry/resource-detector-container@npm:^0.3.7": - version: 0.3.9 - resolution: "@opentelemetry/resource-detector-container@npm:0.3.9" - dependencies: - "@opentelemetry/resources": ^1.0.0 - "@opentelemetry/semantic-conventions": ^1.22.0 - peerDependencies: - "@opentelemetry/api": ^1.0.0 - checksum: c2157f4d9b602c6fd32ad27c2b0ee8dd944542b18c025363d47fd9b38458ee2107f442dab957e8d4107c8ac7cc049cdc09779965cb309ab3fedb5b52fafbcb30 - languageName: node - linkType: hard - -"@opentelemetry/resource-detector-gcp@npm:^0.29.7": - version: 0.29.9 - resolution: "@opentelemetry/resource-detector-gcp@npm:0.29.9" - dependencies: - "@opentelemetry/core": ^1.0.0 - "@opentelemetry/resources": ^1.0.0 - "@opentelemetry/semantic-conventions": ^1.22.0 + "@opentelemetry/semantic-conventions": ^1.27.0 gcp-metadata: ^6.0.0 peerDependencies: "@opentelemetry/api": ^1.0.0 - checksum: 4829cef6e5d849cae34320751c172ac9583ae12a9336db48ffa8ae47c288ca8d86d5b2ec19f20881fdd9505b6f3f12eeadd59f9dd341187dc8702f0a68d7e4d0 + checksum: 4e47558b767c97e9dae67f648449987cd7dd372a8d29e1ee7eefa3da6cf15d944f7f8f9a8a8f07026e7843b95958faf26739c24cabbb106e923f898abeae5132 languageName: node linkType: hard -"@opentelemetry/resources@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/resources@npm:1.22.0" +"@opentelemetry/resources@npm:1.26.0, @opentelemetry/resources@npm:^1.0.0, @opentelemetry/resources@npm:^1.10.0, @opentelemetry/resources@npm:^1.10.1, @opentelemetry/resources@npm:^1.24.0, @opentelemetry/resources@npm:^1.8.0": + version: 1.26.0 + resolution: "@opentelemetry/resources@npm:1.26.0" dependencies: - "@opentelemetry/core": 1.22.0 - "@opentelemetry/semantic-conventions": 1.22.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/semantic-conventions": 1.27.0 peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: f1da492d9fa7dbe3e5f08a511654b45265fcd16c4695bb1ae92488baa45ae9910d5a962166aaa4ae63be4c75393680c6f064450a5f10b86501b9df427ac49f27 + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: f70b0fdf4fb00c950bc30084818c92a5339f1be5d709bd681ab14453e877d6bb9f700324b8e65a0eabfeea618d01ed071abf9088e00fa0bf7f3305b1abad22cb languageName: node linkType: hard -"@opentelemetry/resources@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/resources@npm:1.23.0" +"@opentelemetry/sdk-logs@npm:0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/sdk-logs@npm:0.53.0" dependencies: - "@opentelemetry/core": 1.23.0 - "@opentelemetry/semantic-conventions": 1.23.0 + "@opentelemetry/api-logs": 0.53.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/resources": 1.26.0 peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: e780d34f8107cdd2853aab3c0c680a817da54d9c6020bba9b8a6b8e7b637487592d87440e5c4f09a10dfad7aededde34532e0e337a5c2d441bf26dd921836cfc + "@opentelemetry/api": ">=1.4.0 <1.10.0" + checksum: f36c051f6264786688e3b20b4b1a876e6f7a40166b425efaa6aab12dfe32f2ebbcc5bea1662631b2b17016ec5cf9205798219c896234828503477b144b02342e languageName: node linkType: hard -"@opentelemetry/resources@npm:1.24.0, @opentelemetry/resources@npm:^1.0.0, @opentelemetry/resources@npm:^1.12.0, @opentelemetry/resources@npm:^1.8.0": - version: 1.24.0 - resolution: "@opentelemetry/resources@npm:1.24.0" +"@opentelemetry/sdk-metrics@npm:1.26.0, @opentelemetry/sdk-metrics@npm:^1.9.1": + version: 1.26.0 + resolution: "@opentelemetry/sdk-metrics@npm:1.26.0" dependencies: - "@opentelemetry/core": 1.24.0 - "@opentelemetry/semantic-conventions": 1.24.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/resources": 1.26.0 peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: b9a59d4267388aaec8d4adc1d708220209bdba1f60ef80fdf1436a23a4e1e04d0c05c33bf1cd08bec7ab75d1b7d2311d25bbe62253bd1d6efbb64102a7018958 + "@opentelemetry/api": ">=1.3.0 <1.10.0" + checksum: c7fd09991bc28c4cfa0eef2e75a9fcfd1465638327e50ce55fb7631c9e333ae27c7c4bfbb4875c8fbb60f94bb60a307af157a898ea21f13fef967ab5e1146ed5 languageName: node linkType: hard -"@opentelemetry/sdk-logs@npm:0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/sdk-logs@npm:0.49.1" +"@opentelemetry/sdk-node@npm:^0.53.0": + version: 0.53.0 + resolution: "@opentelemetry/sdk-node@npm:0.53.0" dependencies: - "@opentelemetry/core": 1.22.0 - "@opentelemetry/resources": 1.22.0 + "@opentelemetry/api-logs": 0.53.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/exporter-logs-otlp-grpc": 0.53.0 + "@opentelemetry/exporter-logs-otlp-http": 0.53.0 + "@opentelemetry/exporter-logs-otlp-proto": 0.53.0 + "@opentelemetry/exporter-trace-otlp-grpc": 0.53.0 + "@opentelemetry/exporter-trace-otlp-http": 0.53.0 + "@opentelemetry/exporter-trace-otlp-proto": 0.53.0 + "@opentelemetry/exporter-zipkin": 1.26.0 + "@opentelemetry/instrumentation": 0.53.0 + "@opentelemetry/resources": 1.26.0 + "@opentelemetry/sdk-logs": 0.53.0 + "@opentelemetry/sdk-metrics": 1.26.0 + "@opentelemetry/sdk-trace-base": 1.26.0 + "@opentelemetry/sdk-trace-node": 1.26.0 + "@opentelemetry/semantic-conventions": 1.27.0 peerDependencies: - "@opentelemetry/api": ">=1.4.0 <1.9.0" - "@opentelemetry/api-logs": ">=0.39.1" - checksum: 9c2a60a15fd5a40316b96805a23d96dffb62258d78d20edcc0a9dedcb89aa410ab592d67c315fa63138657cb717d7e9e406337b16bee89a7115bdfe8a190190b + "@opentelemetry/api": ">=1.3.0 <1.10.0" + checksum: b58dd621961f4d020527a7b0551ebd190330c83f4c19b552cd899079c7047064206b7d71735833506b52796831c22e72e73b635309a7d2e6ba78355ec93cd305 languageName: node linkType: hard -"@opentelemetry/sdk-logs@npm:0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/sdk-logs@npm:0.50.0" +"@opentelemetry/sdk-trace-base@npm:1.26.0": + version: 1.26.0 + resolution: "@opentelemetry/sdk-trace-base@npm:1.26.0" dependencies: - "@opentelemetry/core": 1.23.0 - "@opentelemetry/resources": 1.23.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/resources": 1.26.0 + "@opentelemetry/semantic-conventions": 1.27.0 peerDependencies: - "@opentelemetry/api": ">=1.4.0 <1.9.0" - "@opentelemetry/api-logs": ">=0.39.1" - checksum: e93be98f4ea2b64dd0fc0aebc5dfa7276f995a0822cae727455988397cb0c10f7696dbabc4d01a7b09d515faceffa2858c3329a85841ae79c44072e8c0911df8 + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: a4f4ddf644fd0d79b2bd49e4377143688d2aa657643a470d8bed6696f26817598fb4e9f16ba2d8c237292af56f06eec56594a7b4cc417d4ea7e490a45a22113b languageName: node linkType: hard -"@opentelemetry/sdk-metrics@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/sdk-metrics@npm:1.22.0" +"@opentelemetry/sdk-trace-node@npm:1.26.0": + version: 1.26.0 + resolution: "@opentelemetry/sdk-trace-node@npm:1.26.0" dependencies: - "@opentelemetry/core": 1.22.0 - "@opentelemetry/resources": 1.22.0 - lodash.merge: ^4.6.2 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.9.0" - checksum: 43b6599432bece2e41a48d40653f4f928ad7ba0b74c50a17bdb38f13bcb47cec1e08ce9af7f8cc643dc2c28cb127ef5ef4ce3e53cd1bf386d54fdaca361f29f2 - languageName: node - linkType: hard - -"@opentelemetry/sdk-metrics@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/sdk-metrics@npm:1.23.0" - dependencies: - "@opentelemetry/core": 1.23.0 - "@opentelemetry/resources": 1.23.0 - lodash.merge: ^4.6.2 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.9.0" - checksum: ca24338ceb537fa9c4d9a87b4e81164db1275d96ecf97347a2e48f07cfaab0fb25013091898fb435751eb488efcd6d01232150cce3c034263fe293ce6bd83abd - languageName: node - linkType: hard - -"@opentelemetry/sdk-metrics@npm:^1.9.1": - version: 1.24.0 - resolution: "@opentelemetry/sdk-metrics@npm:1.24.0" - dependencies: - "@opentelemetry/core": 1.24.0 - "@opentelemetry/resources": 1.24.0 - lodash.merge: ^4.6.2 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.9.0" - checksum: 4468302b048685fa06c03c434754a37a671c4b1ae9a0409ad53132742eac7c982a65712bee4614f2d46e1fd361ec012afc55f693f00316808573f5c427cb68b9 - languageName: node - linkType: hard - -"@opentelemetry/sdk-node@npm:^0.49.1": - version: 0.49.1 - resolution: "@opentelemetry/sdk-node@npm:0.49.1" - dependencies: - "@opentelemetry/api-logs": 0.49.1 - "@opentelemetry/core": 1.22.0 - "@opentelemetry/exporter-trace-otlp-grpc": 0.49.1 - "@opentelemetry/exporter-trace-otlp-http": 0.49.1 - "@opentelemetry/exporter-trace-otlp-proto": 0.49.1 - "@opentelemetry/exporter-zipkin": 1.22.0 - "@opentelemetry/instrumentation": 0.49.1 - "@opentelemetry/resources": 1.22.0 - "@opentelemetry/sdk-logs": 0.49.1 - "@opentelemetry/sdk-metrics": 1.22.0 - "@opentelemetry/sdk-trace-base": 1.22.0 - "@opentelemetry/sdk-trace-node": 1.22.0 - "@opentelemetry/semantic-conventions": 1.22.0 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.9.0" - checksum: eb1ef8ddb33de7a4e8be697ed0eca100a4d728f41f7c8fca5a06f3facf5a1c2a4fce3d9585a29f47d958904a920024dd6637907e810cc9fb4b702cc8970136eb - languageName: node - linkType: hard - -"@opentelemetry/sdk-node@npm:^0.50.0": - version: 0.50.0 - resolution: "@opentelemetry/sdk-node@npm:0.50.0" - dependencies: - "@opentelemetry/api-logs": 0.50.0 - "@opentelemetry/core": 1.23.0 - "@opentelemetry/exporter-trace-otlp-grpc": 0.50.0 - "@opentelemetry/exporter-trace-otlp-http": 0.50.0 - "@opentelemetry/exporter-trace-otlp-proto": 0.50.0 - "@opentelemetry/exporter-zipkin": 1.23.0 - "@opentelemetry/instrumentation": 0.50.0 - "@opentelemetry/resources": 1.23.0 - "@opentelemetry/sdk-logs": 0.50.0 - "@opentelemetry/sdk-metrics": 1.23.0 - "@opentelemetry/sdk-trace-base": 1.23.0 - "@opentelemetry/sdk-trace-node": 1.23.0 - "@opentelemetry/semantic-conventions": 1.23.0 - peerDependencies: - "@opentelemetry/api": ">=1.3.0 <1.9.0" - checksum: 1ca47e0cec7832a291e20fc838bfb2a7307b6d041a29b0ace1a5f3eb9f77fa8bad6e40d55eb19e5ab7c153afb866890bfc415e843d6b950691527566a592ad35 - languageName: node - linkType: hard - -"@opentelemetry/sdk-trace-base@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/sdk-trace-base@npm:1.22.0" - dependencies: - "@opentelemetry/core": 1.22.0 - "@opentelemetry/resources": 1.22.0 - "@opentelemetry/semantic-conventions": 1.22.0 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 9a15bca01532b9bd279fcf7c083af7e39c24187c6793aa6ce0e6f780394abc12458fc5ae67bff279afd9392ccd67f5d1823c326d4f4511d789667ba2a878d56c - languageName: node - linkType: hard - -"@opentelemetry/sdk-trace-base@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/sdk-trace-base@npm:1.23.0" - dependencies: - "@opentelemetry/core": 1.23.0 - "@opentelemetry/resources": 1.23.0 - "@opentelemetry/semantic-conventions": 1.23.0 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 564a14a38b151d793949da95949a5eb4e0034ff95356162a7fcf7fe6a81b312cd8d601d6e46b303e6d9f785152ff28621cb7bd114f61e064bfdfa77ed28ca8cc - languageName: node - linkType: hard - -"@opentelemetry/sdk-trace-node@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/sdk-trace-node@npm:1.22.0" - dependencies: - "@opentelemetry/context-async-hooks": 1.22.0 - "@opentelemetry/core": 1.22.0 - "@opentelemetry/propagator-b3": 1.22.0 - "@opentelemetry/propagator-jaeger": 1.22.0 - "@opentelemetry/sdk-trace-base": 1.22.0 + "@opentelemetry/context-async-hooks": 1.26.0 + "@opentelemetry/core": 1.26.0 + "@opentelemetry/propagator-b3": 1.26.0 + "@opentelemetry/propagator-jaeger": 1.26.0 + "@opentelemetry/sdk-trace-base": 1.26.0 semver: ^7.5.2 peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: fcd755be1355b211551e54d6a36d46f196fd9bec30b2eff0dc935082a59a86df3f9e9460a6d0b1f540063627f0baf1780f504ec13653a08a2954985d06888ac0 + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: 1d63bed8fc36496698919ccd25be3b7b0e0d0bf9478f413a26bdbfe0bf0d4166bf58bbbee2415fb2fe42d3008b5c32ec7e4e42f2cb6d18b665b349eb025c15eb languageName: node linkType: hard -"@opentelemetry/sdk-trace-node@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/sdk-trace-node@npm:1.23.0" - dependencies: - "@opentelemetry/context-async-hooks": 1.23.0 - "@opentelemetry/core": 1.23.0 - "@opentelemetry/propagator-b3": 1.23.0 - "@opentelemetry/propagator-jaeger": 1.23.0 - "@opentelemetry/sdk-trace-base": 1.23.0 - semver: ^7.5.2 - peerDependencies: - "@opentelemetry/api": ">=1.0.0 <1.9.0" - checksum: 165f26d77672d6745e9b1d3af78e3b1afcd4fe1b48e0eaef1aa67e9c86e822f9d0947cb0066c6a1080bdcf03c9da268870cace839254d1fee03446b25dbf6d30 - languageName: node - linkType: hard - -"@opentelemetry/semantic-conventions@npm:1.22.0": - version: 1.22.0 - resolution: "@opentelemetry/semantic-conventions@npm:1.22.0" - checksum: cb3bdca1a29d3c32c44599bdf5ee5143b84e81aaa61edcd3f750133bfaffd7c1b36755c877921e4993e2468284a0564388844a7dda388122bee486d3f67fa4c8 - languageName: node - linkType: hard - -"@opentelemetry/semantic-conventions@npm:1.23.0": - version: 1.23.0 - resolution: "@opentelemetry/semantic-conventions@npm:1.23.0" - checksum: a4bd6e67e0fe5821be7dc14baff77574e9881d208a63740a3ab416b367c132bc77cf3c0b398daea1344c9af2f32383cf6c7da3141ba6d1e87e30756e4f2234b8 - languageName: node - linkType: hard - -"@opentelemetry/semantic-conventions@npm:1.24.0, @opentelemetry/semantic-conventions@npm:^1.0.0, @opentelemetry/semantic-conventions@npm:^1.22.0": +"@opentelemetry/semantic-conventions@npm:1.24.0": version: 1.24.0 resolution: "@opentelemetry/semantic-conventions@npm:1.24.0" checksum: ba7c71602f3eddc3f015457cf1183bd24f0300b2636b57cafe2e5196ae233daf05e573e3a7b954818e8f2d9543a44282a0406f327b9c066ae948eea5f4a91d27 languageName: node linkType: hard -"@opentelemetry/sql-common@npm:^0.40.0": +"@opentelemetry/semantic-conventions@npm:1.27.0, @opentelemetry/semantic-conventions@npm:^1.27.0": + version: 1.27.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.27.0" + checksum: 26d85f8d13c8c64024f7a84528cff41d56afc9829e7ff8a654576404f8b2c1a9c264adcc6fa5a9551bacdd938a4a464041fa9493e0a722e5605f2c2ae6752398 + languageName: node + linkType: hard + +"@opentelemetry/sql-common@npm:^0.40.1": version: 0.40.1 resolution: "@opentelemetry/sql-common@npm:0.40.1" dependencies: @@ -13802,13 +13436,13 @@ __metadata: linkType: hard "@playwright/test@npm:^1.32.3": - version: 1.45.3 - resolution: "@playwright/test@npm:1.45.3" + version: 1.46.1 + resolution: "@playwright/test@npm:1.46.1" dependencies: - playwright: 1.45.3 + playwright: 1.46.1 bin: playwright: cli.js - checksum: 3e2c88d40f98cf94ab7947263804d1ee78c4bb21a35c8dbb64855eed5565ffc688509c5f07bda5438cba6c354374981448dcba3dbe326d1699b4fef75c9ce43d + checksum: 180d90c6421ee6a8c00a1ae65d91d5f69767e2de95c3f5582ac2bdf3a388e621fdd3ee00ecb7836db427bb0d4cee58111c14f133cb62150357d8e4f43e3e2295 languageName: node linkType: hard @@ -14526,10 +14160,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.18.0": - version: 1.18.0 - resolution: "@remix-run/router@npm:1.18.0" - checksum: dad8e8cbd3b44503c89de0fc5d8f92954d04c00bf36b42a18ae8b03fe0783742a99d0cae36f2962db38e2bdba3d40259105202c69620943e88f81711ceeb8fe4 +"@remix-run/router@npm:1.19.1": + version: 1.19.1 + resolution: "@remix-run/router@npm:1.19.1" + checksum: ebe4474ba0c1046093976b48a4eb4e39bd2f47368aacea21400126d72e133d2cfbfb50254cf1bde0b66dacdf0344452f743049d1595a22e86130668f60112376 languageName: node linkType: hard @@ -14547,9 +14181,9 @@ __metadata: languageName: node linkType: hard -"@rjsf/core@npm:5.18.5": - version: 5.18.5 - resolution: "@rjsf/core@npm:5.18.5" +"@rjsf/core@npm:5.20.1": + version: 5.20.1 + resolution: "@rjsf/core@npm:5.20.1" dependencies: lodash: ^4.17.21 lodash-es: ^4.17.21 @@ -14557,28 +14191,28 @@ __metadata: nanoid: ^3.3.7 prop-types: ^15.8.1 peerDependencies: - "@rjsf/utils": ^5.18.x + "@rjsf/utils": ^5.20.x react: ^16.14.0 || >=17 - checksum: 7b986ec075d5b2de503d01172abdb3e3d33d04e5298fbf80842400e682f0aecdabfe4bb8482dde8a6aed90a35f4f5574cb7b24a11d689566c0cc0599485b334a + checksum: a75a5261090bc1dd46594060981a130721060c38805031d1554b077e46673f84ffb40c489c2b579cf50e4fbb709210585a139e1c5d9eaccd603d957e95c2ead2 languageName: node linkType: hard -"@rjsf/material-ui@npm:5.18.5": - version: 5.18.5 - resolution: "@rjsf/material-ui@npm:5.18.5" +"@rjsf/material-ui@npm:5.20.1": + version: 5.20.1 + resolution: "@rjsf/material-ui@npm:5.20.1" peerDependencies: "@material-ui/core": ^4.12.3 "@material-ui/icons": ^4.11.2 - "@rjsf/core": ^5.18.x - "@rjsf/utils": ^5.18.x + "@rjsf/core": ^5.20.x + "@rjsf/utils": ^5.20.x react: ^16.14.0 || >=17 - checksum: 61337141bcd7bcb46013d81ae6b618919eff3f55319800511443e524876bf5c84089970e14148716de203d5def341aa15c4d102243f0b694f120f05189a3adb7 + checksum: d7f5d4107ccf31d3320ef2f42e50c79004aaff44cac76dba60382f8f7e051fbb3b0470675bdccc25aa15c18ac84c77301509546eb0f0cfac897fd06a0f95facd languageName: node linkType: hard -"@rjsf/utils@npm:5.18.5": - version: 5.18.5 - resolution: "@rjsf/utils@npm:5.18.5" +"@rjsf/utils@npm:5.20.1": + version: 5.20.1 + resolution: "@rjsf/utils@npm:5.20.1" dependencies: json-schema-merge-allof: ^0.8.1 jsonpointer: ^5.0.1 @@ -14587,21 +14221,21 @@ __metadata: react-is: ^18.2.0 peerDependencies: react: ^16.14.0 || >=17 - checksum: 8da3ce82a0ec83e78806461db7226fd20489f6e8c41906ccde9d55c554aec3f50b8b8bac8c35e3cdf12d788c18fdad71c992f0d8b44f6161a1bf9e13598ded99 + checksum: 8bf59caeb9d32d40ec492df7fc702f0573ad2054042a3a0676fb7e10afa56d0d85740be28a752782fc16273952553ab76b40eb17e4e5b1178f473628003109f4 languageName: node linkType: hard -"@rjsf/validator-ajv8@npm:5.18.5": - version: 5.18.5 - resolution: "@rjsf/validator-ajv8@npm:5.18.5" +"@rjsf/validator-ajv8@npm:5.20.1": + version: 5.20.1 + resolution: "@rjsf/validator-ajv8@npm:5.20.1" dependencies: ajv: ^8.12.0 ajv-formats: ^2.1.1 lodash: ^4.17.21 lodash-es: ^4.17.21 peerDependencies: - "@rjsf/utils": ^5.18.x - checksum: 350d1f8043b7bbd88cf5d7fa28560062f4141e1ef9ef004c2997b63d0281d4a1af04be4b951c2c9c4d1c56d10f0e2fbab665c7176b38e87dd6da6d5303e1c84e + "@rjsf/utils": ^5.20.x + checksum: b6d9833335903465fa79cc808e4ad564d6f09adb23e728d3a3d0d309202b45846494ea1bed2bbc32b07d8583d37c9ce8fe9772ba48aa77c0660829162517c4d2 languageName: node linkType: hard @@ -14624,22 +14258,6 @@ __metadata: languageName: node linkType: hard -"@rollup/plugin-inject@npm:^5.0.5": - version: 5.0.5 - resolution: "@rollup/plugin-inject@npm:5.0.5" - dependencies: - "@rollup/pluginutils": ^5.0.1 - estree-walker: ^2.0.2 - magic-string: ^0.30.3 - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - checksum: 22cb772fd6f7178308b2ece95cdde5f8615f6257197832166294552a7e4c0d3976dc996cbfa6470af3151d8b86c00091aa93da5f4db6ec563f11b6db29fd1b63 - languageName: node - linkType: hard - "@rollup/plugin-json@npm:^6.0.0": version: 6.1.0 resolution: "@rollup/plugin-json@npm:6.1.0" @@ -14689,7 +14307,7 @@ __metadata: languageName: node linkType: hard -"@rollup/pluginutils@npm:^4.2.0, @rollup/pluginutils@npm:^4.2.1": +"@rollup/pluginutils@npm:^4.2.1": version: 4.2.1 resolution: "@rollup/pluginutils@npm:4.2.1" dependencies: @@ -14715,118 +14333,125 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.16.2" +"@rollup/rollup-android-arm-eabi@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.21.2" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-android-arm64@npm:4.16.2" +"@rollup/rollup-android-arm64@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-android-arm64@npm:4.21.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-darwin-arm64@npm:4.16.2" +"@rollup/rollup-darwin-arm64@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.21.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-darwin-x64@npm:4.16.2" +"@rollup/rollup-darwin-x64@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-darwin-x64@npm:4.21.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.16.2" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.21.2" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.16.2" +"@rollup/rollup-linux-arm-musleabihf@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.21.2" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.16.2" +"@rollup/rollup-linux-arm64-gnu@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.21.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.16.2" +"@rollup/rollup-linux-arm64-musl@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.21.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-powerpc64le-gnu@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.16.2" +"@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.2" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.16.2" +"@rollup/rollup-linux-riscv64-gnu@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.21.2" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.16.2" +"@rollup/rollup-linux-s390x-gnu@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.21.2" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.16.2" +"@rollup/rollup-linux-x64-gnu@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.21.2" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.16.2" +"@rollup/rollup-linux-x64-musl@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.21.2" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.16.2" +"@rollup/rollup-win32-arm64-msvc@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.21.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.16.2" +"@rollup/rollup-win32-ia32-msvc@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.21.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.16.2": - version: 4.16.2 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.16.2" +"@rollup/rollup-win32-x64-msvc@npm:4.21.2": + version: 4.21.2 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.21.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard +"@rtsao/scc@npm:^1.1.0": + version: 1.1.0 + resolution: "@rtsao/scc@npm:1.1.0" + checksum: 17d04adf404e04c1e61391ed97bca5117d4c2767a76ae3e879390d6dec7b317fcae68afbf9e98badee075d0b64fa60f287729c4942021b4d19cd01db77385c01 + languageName: node + linkType: hard + "@rushstack/node-core-library@npm:3.59.7": version: 3.59.7 resolution: "@rushstack/node-core-library@npm:3.59.7" @@ -14963,29 +14588,6 @@ __metadata: languageName: node linkType: hard -"@sideway/address@npm:^4.1.5": - version: 4.1.5 - resolution: "@sideway/address@npm:4.1.5" - dependencies: - "@hapi/hoek": ^9.0.0 - checksum: 3e3ea0f00b4765d86509282290368a4a5fd39a7995fdc6de42116ca19a96120858e56c2c995081def06e1c53e1f8bccc7d013f6326602bec9d56b72ee2772b9d - languageName: node - linkType: hard - -"@sideway/formula@npm:^3.0.1": - version: 3.0.1 - resolution: "@sideway/formula@npm:3.0.1" - checksum: e4beeebc9dbe2ff4ef0def15cec0165e00d1612e3d7cea0bc9ce5175c3263fc2c818b679bd558957f49400ee7be9d4e5ac90487e1625b4932e15c4aa7919c57a - languageName: node - linkType: hard - -"@sideway/pinpoint@npm:^2.0.0": - version: 2.0.0 - resolution: "@sideway/pinpoint@npm:2.0.0" - checksum: 0f4491e5897fcf5bf02c46f5c359c56a314e90ba243f42f0c100437935daa2488f20482f0f77186bd6bf43345095a95d8143ecf8b1f4d876a7bc0806aba9c3d2 - languageName: node - linkType: hard - "@sinclair/typebox@npm:^0.27.8": version: 0.27.8 resolution: "@sinclair/typebox@npm:0.27.8" @@ -15111,19 +14713,21 @@ __metadata: languageName: node linkType: hard -"@smithy/core@npm:^2.3.1": - version: 2.3.1 - resolution: "@smithy/core@npm:2.3.1" +"@smithy/core@npm:^2.4.0": + version: 2.4.0 + resolution: "@smithy/core@npm:2.4.0" dependencies: "@smithy/middleware-endpoint": ^3.1.0 - "@smithy/middleware-retry": ^3.0.13 + "@smithy/middleware-retry": ^3.0.15 "@smithy/middleware-serde": ^3.0.3 "@smithy/protocol-http": ^4.1.0 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 + "@smithy/util-body-length-browser": ^3.0.0 "@smithy/util-middleware": ^3.0.3 + "@smithy/util-utf8": ^3.0.0 tslib: ^2.6.2 - checksum: f191a36742a08c6898f4aaa43335bfb96cdca9a9099c0608fb0ef151917816b03ee1b27ef3720d89fba90d2d24fedfb47478f837d47c1c2e5ff8ceeb844ec7d6 + checksum: 7ec00d742630feced4bb185a20f5fcb8b6706c9c22c0b86545e9c62e4dda10c8327847d55350f190c3e95d59df2b8f911893e35d5af87cf09fd6bc91e45379cf languageName: node linkType: hard @@ -15152,14 +14756,14 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^3.0.5": - version: 3.0.5 - resolution: "@smithy/eventstream-serde-browser@npm:3.0.5" +"@smithy/eventstream-serde-browser@npm:^3.0.6": + version: 3.0.6 + resolution: "@smithy/eventstream-serde-browser@npm:3.0.6" dependencies: - "@smithy/eventstream-serde-universal": ^3.0.4 + "@smithy/eventstream-serde-universal": ^3.0.5 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 14e8a2027745e7a1ad261068e792e4a660043ce53fefc5f564b38b841ba02d40992b38fbd2357e762f0a1ecb658df3bbf23cf5ef33c3ec2488d316be95b61b9e + checksum: 0d0f77fc7d277f1e8d29cfd7d745adac6ed627af8b8812dc5d821064f6d98a40e4e8c4ea0f1b67efe1070454fe19879b5edb8a892451a4b12cfa23d3bb9bcd50 languageName: node linkType: hard @@ -15173,25 +14777,25 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^3.0.4": - version: 3.0.4 - resolution: "@smithy/eventstream-serde-node@npm:3.0.4" +"@smithy/eventstream-serde-node@npm:^3.0.5": + version: 3.0.5 + resolution: "@smithy/eventstream-serde-node@npm:3.0.5" dependencies: - "@smithy/eventstream-serde-universal": ^3.0.4 + "@smithy/eventstream-serde-universal": ^3.0.5 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 0a75b184d95ab8c08efd93bf32c5fd9d735b5879df556599bd2ab78f23e3f77452e597bbdd42586c9bbedcc2b0b7683de4c816db739c19a2ebd62a34096ca86d + checksum: ba0117495e2b9fc6b116620b1e15ade6c0aff72561d6db70c18ff4d6671a579fc6616f762918ba28b8146786aef1ba758969ac75dde80ee0099903408b2788ff languageName: node linkType: hard -"@smithy/eventstream-serde-universal@npm:^3.0.4": - version: 3.0.4 - resolution: "@smithy/eventstream-serde-universal@npm:3.0.4" +"@smithy/eventstream-serde-universal@npm:^3.0.5": + version: 3.0.5 + resolution: "@smithy/eventstream-serde-universal@npm:3.0.5" dependencies: "@smithy/eventstream-codec": ^3.1.2 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: 8463403ca4caf4ad48dba89b126f394439a289c9095ce6361c1f186c6021c1cd8ea402d1ce06b7284069c3415091ae4d802f66ded1b89e9da9d4c255b8402668 + checksum: 8394e27de4caf49076ec664f6e1c934ce4e9cb25ab4936f47fb1cb4da8ba5b027d46da363c77210c73845cd6841e3286115789d179bb2c45c567e3d4227dac73 languageName: node linkType: hard @@ -15308,20 +14912,20 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^3.0.13": - version: 3.0.13 - resolution: "@smithy/middleware-retry@npm:3.0.13" +"@smithy/middleware-retry@npm:^3.0.15": + version: 3.0.15 + resolution: "@smithy/middleware-retry@npm:3.0.15" dependencies: "@smithy/node-config-provider": ^3.1.4 "@smithy/protocol-http": ^4.1.0 "@smithy/service-error-classification": ^3.0.3 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 "@smithy/util-middleware": ^3.0.3 "@smithy/util-retry": ^3.0.3 tslib: ^2.6.2 uuid: ^9.0.1 - checksum: 3aa98ae08633022dedc19a60b173289d4c8e04c94fe45a626499269f596de517a94b587272a578d554d1e91dc8cb19297e3d3c45da01829d520a6c730e77df36 + checksum: 035dd1e2a3e9c58b3328f2035095cf09b545b6af764dd5070e5495167f74b56c73e48f13b9f9a17378a73486bdd7dcfcfcc62214f9e34df90180834ec7fbf727 languageName: node linkType: hard @@ -15480,9 +15084,9 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^3.1.11": - version: 3.1.11 - resolution: "@smithy/smithy-client@npm:3.1.11" +"@smithy/smithy-client@npm:^3.2.0": + version: 3.2.0 + resolution: "@smithy/smithy-client@npm:3.2.0" dependencies: "@smithy/middleware-endpoint": ^3.1.0 "@smithy/middleware-stack": ^3.0.3 @@ -15490,7 +15094,7 @@ __metadata: "@smithy/types": ^3.3.0 "@smithy/util-stream": ^3.1.3 tslib: ^2.6.2 - checksum: acbbd29f45d342845eebf9086fd37cbf5abc563c60f37f787be92e4922bf09594cd882a6f9dcec85073120580c030ad14a035fd10c120733ca402938d87c143b + checksum: 446203aae20e9d3ff9d09ed8bde1bc25be009d658ae2ba7e71678d3727cb75d2bf398b9231e41687234eac3802e795742865b0b0e1f00d30f3669a5389e6fbaa languageName: node linkType: hard @@ -15590,31 +15194,31 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^3.0.13": - version: 3.0.13 - resolution: "@smithy/util-defaults-mode-browser@npm:3.0.13" +"@smithy/util-defaults-mode-browser@npm:^3.0.15": + version: 3.0.15 + resolution: "@smithy/util-defaults-mode-browser@npm:3.0.15" dependencies: "@smithy/property-provider": ^3.1.3 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 bowser: ^2.11.0 tslib: ^2.6.2 - checksum: 087c583d0b276df7369053b068217821c4474bf3d9de3111110ef81e8d895539f80b53a11ecaaae105ce2d24a78a52d958840b8a6c6d3e18696c45f27015a3f3 + checksum: 77a081a66110f35b1457a655556712b03b9368528dae0e2b68c1422a0c05fd9fe84b811d12bcd15bdfc7ee2a72f395d6661e1045fa907a7a177137a97feb3ce9 languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^3.0.13": - version: 3.0.13 - resolution: "@smithy/util-defaults-mode-node@npm:3.0.13" +"@smithy/util-defaults-mode-node@npm:^3.0.15": + version: 3.0.15 + resolution: "@smithy/util-defaults-mode-node@npm:3.0.15" dependencies: "@smithy/config-resolver": ^3.0.5 "@smithy/credential-provider-imds": ^3.2.0 "@smithy/node-config-provider": ^3.1.4 "@smithy/property-provider": ^3.1.3 - "@smithy/smithy-client": ^3.1.11 + "@smithy/smithy-client": ^3.2.0 "@smithy/types": ^3.3.0 tslib: ^2.6.2 - checksum: a56c9f06472bb42e4180fd424ec237a6ca170eef5d487d1a3806a8845cd9c0bef37b431b22a9340afee5ae26b6bca6c11647112ef73433ba949f8c671e2b2067 + checksum: 1a58ba9d0b8e269c5689aafff54df56e10297a5937f8feea0fdf16e56559b4d48f19e4927d7ec5fbe58adcdeb820692f3dc61d61a886f0206ba0c490e2322035 languageName: node linkType: hard @@ -15917,8 +15521,8 @@ __metadata: linkType: hard "@stoplight/spectral-functions@npm:^1.5.1, @stoplight/spectral-functions@npm:^1.6.1, @stoplight/spectral-functions@npm:^1.7.2": - version: 1.7.2 - resolution: "@stoplight/spectral-functions@npm:1.7.2" + version: 1.8.0 + resolution: "@stoplight/spectral-functions@npm:1.8.0" dependencies: "@stoplight/better-ajv-errors": 1.0.3 "@stoplight/json": ^3.17.1 @@ -15931,7 +15535,7 @@ __metadata: ajv-formats: ~2.1.0 lodash: ~4.17.21 tslib: ^2.3.0 - checksum: f89d966d33dd484e5ea63a7971478d176c94215b4ffd2ef24eb8e507a2b60ed3bcfa391b9137793e939f3a10443914db6da62d081055fb8ba49d2d397f0d5907 + checksum: d3ca142ae79b0855992b5e1c2a4facb57f3a851afcd9f6893c5010079934ac97550a7aedff4866ba027b1f2e208572ee6791c228be7d1f472e3fc3cdb01bfa20 languageName: node linkType: hard @@ -15961,8 +15565,8 @@ __metadata: linkType: hard "@stoplight/spectral-rulesets@npm:^1.14.1, @stoplight/spectral-rulesets@npm:^1.18.0": - version: 1.18.1 - resolution: "@stoplight/spectral-rulesets@npm:1.18.1" + version: 1.19.1 + resolution: "@stoplight/spectral-rulesets@npm:1.19.1" dependencies: "@asyncapi/specs": ^4.1.0 "@stoplight/better-ajv-errors": 1.0.3 @@ -15973,12 +15577,13 @@ __metadata: "@stoplight/spectral-runtime": ^1.1.1 "@stoplight/types": ^13.6.0 "@types/json-schema": ^7.0.7 - ajv: ^8.8.2 + ajv: ^8.12.0 ajv-formats: ~2.1.0 json-schema-traverse: ^1.0.0 + leven: 3.1.0 lodash: ~4.17.21 tslib: ^2.3.0 - checksum: 2eeff0fb3ffb7a2f3fca8c92c4d766925f62fabdc92b1899d3bc620a29e4ff8e68aacc63b8a77ede4030ee9127a12022e94117773ba5fd278acd7ba15c0fe5a0 + checksum: eaecc5062701bd1317ab828dd3b6ad69544e5f0e9d9aecdfdf1da0c476557cb355d6a077731751d6c177c57fa6234f0fd28639733f196768c46e404a4376c763 languageName: node linkType: hard @@ -16734,92 +16339,92 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-arm64@npm:1.5.29" +"@swc/core-darwin-arm64@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-darwin-arm64@npm:1.7.23" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-darwin-x64@npm:1.5.29" +"@swc/core-darwin-x64@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-darwin-x64@npm:1.7.23" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.5.29" +"@swc/core-linux-arm-gnueabihf@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.23" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-gnu@npm:1.5.29" +"@swc/core-linux-arm64-gnu@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-arm64-gnu@npm:1.7.23" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-arm64-musl@npm:1.5.29" +"@swc/core-linux-arm64-musl@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-arm64-musl@npm:1.7.23" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-gnu@npm:1.5.29" +"@swc/core-linux-x64-gnu@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-x64-gnu@npm:1.7.23" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-linux-x64-musl@npm:1.5.29" +"@swc/core-linux-x64-musl@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-linux-x64-musl@npm:1.7.23" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-arm64-msvc@npm:1.5.29" +"@swc/core-win32-arm64-msvc@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-win32-arm64-msvc@npm:1.7.23" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-ia32-msvc@npm:1.5.29" +"@swc/core-win32-ia32-msvc@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-win32-ia32-msvc@npm:1.7.23" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.5.29": - version: 1.5.29 - resolution: "@swc/core-win32-x64-msvc@npm:1.5.29" +"@swc/core-win32-x64-msvc@npm:1.7.23": + version: 1.7.23 + resolution: "@swc/core-win32-x64-msvc@npm:1.7.23" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.46": - version: 1.5.29 - resolution: "@swc/core@npm:1.5.29" + version: 1.7.23 + resolution: "@swc/core@npm:1.7.23" dependencies: - "@swc/core-darwin-arm64": 1.5.29 - "@swc/core-darwin-x64": 1.5.29 - "@swc/core-linux-arm-gnueabihf": 1.5.29 - "@swc/core-linux-arm64-gnu": 1.5.29 - "@swc/core-linux-arm64-musl": 1.5.29 - "@swc/core-linux-x64-gnu": 1.5.29 - "@swc/core-linux-x64-musl": 1.5.29 - "@swc/core-win32-arm64-msvc": 1.5.29 - "@swc/core-win32-ia32-msvc": 1.5.29 - "@swc/core-win32-x64-msvc": 1.5.29 + "@swc/core-darwin-arm64": 1.7.23 + "@swc/core-darwin-x64": 1.7.23 + "@swc/core-linux-arm-gnueabihf": 1.7.23 + "@swc/core-linux-arm64-gnu": 1.7.23 + "@swc/core-linux-arm64-musl": 1.7.23 + "@swc/core-linux-x64-gnu": 1.7.23 + "@swc/core-linux-x64-musl": 1.7.23 + "@swc/core-win32-arm64-msvc": 1.7.23 + "@swc/core-win32-ia32-msvc": 1.7.23 + "@swc/core-win32-x64-msvc": 1.7.23 "@swc/counter": ^0.1.3 - "@swc/types": ^0.1.8 + "@swc/types": ^0.1.12 peerDependencies: "@swc/helpers": "*" dependenciesMeta: @@ -16846,7 +16451,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 19e3f8525ce4f4d9f6f3f62825b1f13e1e76146390930b6d5e663c0bb2c5e95ef3bf30268110d1444ea92b99dd95bfe5a3c6e2a3c0dd79291505dc7da1ed3dab + checksum: a21e9a67d305ad9b49b6def9f9698b374db6c15b2ded5e5cf29390221181fc6b91bfa317b53fd41d9cca989d85b79bbbca5ab27635df1e0232cad4681f618fa5 languageName: node linkType: hard @@ -16857,12 +16462,12 @@ __metadata: languageName: node linkType: hard -"@swc/helpers@npm:^0.5.0": - version: 0.5.11 - resolution: "@swc/helpers@npm:0.5.11" +"@swc/helpers@npm:^0.5.0, @swc/helpers@npm:^0.5.8": + version: 0.5.13 + resolution: "@swc/helpers@npm:0.5.13" dependencies: tslib: ^2.4.0 - checksum: 5d85e641d993264f38871bf53e7509da959cdff7646a40d876153291146b9d0aa701518546e5bfef18fa17c5944333bbeb66c2f0d7a570e8c5535d0937d76bd9 + checksum: d50c2c10da6ef940af423c6b03ad9c3c94cf9de59314b1e921a7d1bcc081a6074481c9d67b655fc8fe66a73288f98b25950743792a63882bfb5793b362494fc0 languageName: node linkType: hard @@ -16879,12 +16484,12 @@ __metadata: languageName: node linkType: hard -"@swc/types@npm:^0.1.8": - version: 0.1.8 - resolution: "@swc/types@npm:0.1.8" +"@swc/types@npm:^0.1.12": + version: 0.1.12 + resolution: "@swc/types@npm:0.1.12" dependencies: "@swc/counter": ^0.1.3 - checksum: e564d0e37b0e28546973c6d50c7a179395912a97168d695cfe9cf1051199c8b828680cdafcb8d43948f76d3703873bafb88dfb5bc2dfe0596b4ad18fcaf90c80 + checksum: cf7f89e46f859864075d7965582baea9c5f98830f45b1046251568c9bdf1ca484b1bf37f6d3c32b7c82ecf8cd5df89d22f05268c391819c44e49911bb1a8e71a languageName: node linkType: hard @@ -16938,8 +16543,8 @@ __metadata: linkType: soft "@testing-library/dom@npm:^10.0.0": - version: 10.0.0 - resolution: "@testing-library/dom@npm:10.0.0" + version: 10.4.0 + resolution: "@testing-library/dom@npm:10.4.0" dependencies: "@babel/code-frame": ^7.10.4 "@babel/runtime": ^7.12.5 @@ -16949,40 +16554,22 @@ __metadata: dom-accessibility-api: ^0.5.9 lz-string: ^1.5.0 pretty-format: ^27.0.2 - checksum: 682cc22cb3414ffbcf5d9bac777907167c5523f2dcbe5d96cd2e99386009acd879640c7fe5b1c66b199c2d2679f97057410557b3848b871f59c547b1dc8fc28a + checksum: bb128b90be0c8cd78c5f5e67aa45f53de614cc048a2b50b230e736ec710805ac6c73375af354b83c74d710b3928d52b83a273a4cb89de4eb3efe49e91e706837 languageName: node linkType: hard "@testing-library/jest-dom@npm:^6.0.0": - version: 6.4.2 - resolution: "@testing-library/jest-dom@npm:6.4.2" + version: 6.5.0 + resolution: "@testing-library/jest-dom@npm:6.5.0" dependencies: - "@adobe/css-tools": ^4.3.2 - "@babel/runtime": ^7.9.2 + "@adobe/css-tools": ^4.4.0 aria-query: ^5.0.0 chalk: ^3.0.0 css.escape: ^1.5.1 dom-accessibility-api: ^0.6.3 - lodash: ^4.17.15 + lodash: ^4.17.21 redent: ^3.0.0 - peerDependencies: - "@jest/globals": ">= 28" - "@types/bun": "*" - "@types/jest": ">= 28" - jest: ">= 28" - vitest: ">= 0.32" - peerDependenciesMeta: - "@jest/globals": - optional: true - "@types/bun": - optional: true - "@types/jest": - optional: true - jest: - optional: true - vitest: - optional: true - checksum: 631aeadbf4e738080ae095242cf1a29a0b4ee2f09c8bdd0d3f00a923707da64c1617e088ba9a961d098481afabdc1d19149fb7ef98edf15132348eb222f345ae + checksum: c2d14103ebe3358852ec527ff7512f64207a39932b2f7b6dff7e73ba91296b01a71bad9a9584b6ee010681380a906c1740af50470adc6db660e1c7585d012ebf languageName: node linkType: hard @@ -17009,16 +16596,20 @@ __metadata: linkType: hard "@testing-library/react@npm:^15.0.0": - version: 15.0.2 - resolution: "@testing-library/react@npm:15.0.2" + version: 15.0.7 + resolution: "@testing-library/react@npm:15.0.7" dependencies: "@babel/runtime": ^7.12.5 "@testing-library/dom": ^10.0.0 "@types/react-dom": ^18.0.0 peerDependencies: + "@types/react": ^18.0.0 react: ^18.0.0 react-dom: ^18.0.0 - checksum: 32be030a5540164403f3cd8d6f46ad907119b2bc0a0df43ce6b925cdd520d5003298d06af1ee94d7bd764f294d74e802b6509caf2cf10afc77e67407baa9c1fb + peerDependenciesMeta: + "@types/react": + optional: true + checksum: eb33fd82eb811bb8612aa154e430a2c1c251d5ed45a477ef57fe20095db494ea7dcfa6b1e1e2bffb0c7ee10c86e408745d95a879be8ca8fbe301bb91e5f2e5db languageName: node linkType: hard @@ -17130,15 +16721,6 @@ __metadata: languageName: node linkType: hard -"@types/accepts@npm:*": - version: 1.3.7 - resolution: "@types/accepts@npm:1.3.7" - dependencies: - "@types/node": "*" - checksum: 7678cf74976e16093aff6e6f9755826faf069ac1e30179276158ce46ea246348ff22ca6bdd46cef08428881337d9ceefbf00bab08a7731646eb9fc9449d6a1e7 - languageName: node - linkType: hard - "@types/ansi-regex@npm:^5.0.0": version: 5.0.0 resolution: "@types/ansi-regex@npm:5.0.0" @@ -17171,10 +16753,10 @@ __metadata: languageName: node linkType: hard -"@types/aws-lambda@npm:8.10.122, @types/aws-lambda@npm:^8.10.83": - version: 8.10.122 - resolution: "@types/aws-lambda@npm:8.10.122" - checksum: 5c2e02ae8fc0eea90fa3b1014f401a8567695e65910fb53452e813b9b58761c956fba50ac7da606b97e07d881d264ff513573d279e7116f3c6b9590fdb093f31 +"@types/aws-lambda@npm:8.10.143, @types/aws-lambda@npm:^8.10.83": + version: 8.10.143 + resolution: "@types/aws-lambda@npm:8.10.143" + checksum: b2ec1db79c57916651a47c173f14ef90564273542a455d79cc07d3eeabef11a39a3d63c3d26061335fbc557210ec4c8d4daf90bc8b51a38ef43a3299223dc3bf languageName: node linkType: hard @@ -17187,7 +16769,7 @@ __metadata: languageName: node linkType: hard -"@types/babel__core@npm:^7.1.14, @types/babel__core@npm:^7.20.5": +"@types/babel__core@npm:^7.1.14": version: 7.20.5 resolution: "@types/babel__core@npm:7.20.5" dependencies: @@ -17371,13 +16953,6 @@ __metadata: languageName: node linkType: hard -"@types/content-disposition@npm:*": - version: 0.5.8 - resolution: "@types/content-disposition@npm:0.5.8" - checksum: eeea868fb510ae7a32aa2d7de680fba79d59001f3e758a334621e10bc0a6496d3a42bb79243a5e53b9c63cb524522853ccc144fe1ab160c4247d37cdb81146c4 - languageName: node - linkType: hard - "@types/cookie-parser@npm:^1.4.2": version: 1.4.7 resolution: "@types/cookie-parser@npm:1.4.7" @@ -17408,18 +16983,6 @@ __metadata: languageName: node linkType: hard -"@types/cookies@npm:*": - version: 0.9.0 - resolution: "@types/cookies@npm:0.9.0" - dependencies: - "@types/connect": "*" - "@types/express": "*" - "@types/keygrip": "*" - "@types/node": "*" - checksum: ce59bfdf3a5d750400ac32aa93157ec7be997dc632660cf0bbfd76df23d71a70bb5f0820558cd26b9a5576f86b6664a2fd23ae211b51202a5b2f9a15995d7331 - languageName: node - linkType: hard - "@types/core-js@npm:^2.5.4": version: 2.5.8 resolution: "@types/core-js@npm:2.5.8" @@ -17511,9 +17074,9 @@ __metadata: linkType: hard "@types/diff@npm:^5.0.0": - version: 5.2.1 - resolution: "@types/diff@npm:5.2.1" - checksum: 5983a323177bd691cb2194f5d55b960cd20a9c8fec653b4b038760c5809627cc9ea3578fdf10119ccbefefef193ea925f2817136eb97b17388f66b16c8480a8a + version: 5.2.2 + resolution: "@types/diff@npm:5.2.2" + checksum: f64504a8528fa2b1d6a966363e304ef0626d2e5e71bdcf4666a02b586f045cf7e47151cb80be00dbc310f19fa81fb45d3c37a0647441abd6942a54883dc4c6dc languageName: node linkType: hard @@ -17527,14 +17090,14 @@ __metadata: languageName: node linkType: hard -"@types/dockerode@npm:^3.3.0, @types/dockerode@npm:^3.3.24": - version: 3.3.28 - resolution: "@types/dockerode@npm:3.3.28" +"@types/dockerode@npm:^3.3.0, @types/dockerode@npm:^3.3.29": + version: 3.3.31 + resolution: "@types/dockerode@npm:3.3.31" dependencies: "@types/docker-modem": "*" "@types/node": "*" "@types/ssh2": "*" - checksum: d354d790a970b20f7e6b65554eaf851a931adb6fdce831408797b660ff58bf46e87c625ae56c8f7eb902437515cc2286a7cb171ca4e54fbc1262f2d08ab93b78 + checksum: f634f18dc0633f8324faefcde53bcd3d8f3c4bd74d31078cbeb65d2e1597f9abcf12c2158abfaea13dc816bae0f5fa08d0bb570d4214ab0df1ded90db5ebabfe languageName: node linkType: hard @@ -17579,23 +17142,13 @@ __metadata: languageName: node linkType: hard -"@types/eslint-scope@npm:^3.7.3": - version: 3.7.3 - resolution: "@types/eslint-scope@npm:3.7.3" - dependencies: - "@types/eslint": "*" - "@types/estree": "*" - checksum: 6772b05e1b92003d1f295e81bc847a61f4fbe8ddab77ffa49e84ed3f9552513bdde677eb53ef167753901282857dd1d604d9f82eddb34a233495932b2dc3dc17 - languageName: node - linkType: hard - -"@types/eslint@npm:*, @types/eslint@npm:^8.56.5": - version: 8.56.5 - resolution: "@types/eslint@npm:8.56.5" +"@types/eslint@npm:^8.56.10": + version: 8.56.12 + resolution: "@types/eslint@npm:8.56.12" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: 95a7a23ca38c78e5c27a2ed36ef60f094d5e6589e3473c320b6ff69eb3ca6333d5b7f0d5053416369f5ab2fb86874df19562d4d67a98237c17def6e30abff540 + checksum: 0f7710ee02a256c499514251f527f84de964bb29487db840408e4cde79283124a38935597636d2265756c34dd1d902e1b00ae78930d4a0b55111909cb7b80d84 languageName: node linkType: hard @@ -17703,47 +17256,6 @@ __metadata: languageName: node linkType: hard -"@types/hapi__catbox@npm:*": - version: 10.2.6 - resolution: "@types/hapi__catbox@npm:10.2.6" - checksum: 06cd8f4bced5ee912ec89daa53c10a416ab8d7c25ebf981dc3525a9fcc744afcfafd7353146ab8612a71b8905851e44613579ef89ab0c0cef2def0f27aeac480 - languageName: node - linkType: hard - -"@types/hapi__hapi@npm:20.0.13": - version: 20.0.13 - resolution: "@types/hapi__hapi@npm:20.0.13" - dependencies: - "@hapi/boom": ^9.0.0 - "@hapi/iron": ^6.0.0 - "@hapi/podium": ^4.1.3 - "@types/hapi__catbox": "*" - "@types/hapi__mimos": "*" - "@types/hapi__shot": "*" - "@types/node": "*" - joi: ^17.3.0 - checksum: 02d0f91b3b0900e05b6e8d31ae664e20d9c41238155c56fe8c4ca3e8f3d6bc99a8be117eb9aced2141435c855ce8be9bade575ce97af0d5ba8939268ba40d798 - languageName: node - linkType: hard - -"@types/hapi__mimos@npm:*": - version: 4.1.4 - resolution: "@types/hapi__mimos@npm:4.1.4" - dependencies: - "@types/mime-db": "*" - checksum: 8cae226b3d38427d3a380840506be0f226b0494d3e00826c2ff093e38e4f0ec2254d790531110f874b2ed6ac482eceaf5ac628a5e71898c49aea5d29a4875568 - languageName: node - linkType: hard - -"@types/hapi__shot@npm:*": - version: 4.1.6 - resolution: "@types/hapi__shot@npm:4.1.6" - dependencies: - "@types/node": "*" - checksum: 12fdb024a69890c0f552e5953c8afb76bf023c5315b8d70aeb9609c382efb63907a60ae5b048675c82fea5df9c3bad52befdef78df5758f6cf3d00b8cfee628d - languageName: node - linkType: hard - "@types/hast@npm:^2.0.0": version: 2.3.4 resolution: "@types/hast@npm:2.3.4" @@ -17779,13 +17291,6 @@ __metadata: languageName: node linkType: hard -"@types/http-assert@npm:*": - version: 1.5.5 - resolution: "@types/http-assert@npm:1.5.5" - checksum: cd6bb7fd42cc6e2a702cb55370b8b25231954ad74c04bcd185b943a74ded3d4c28099c30f77b26951df2426441baff41718816c60b5af80efe2b8888d900bf93 - languageName: node - linkType: hard - "@types/http-cache-semantics@npm:*": version: 4.0.0 resolution: "@types/http-cache-semantics@npm:4.0.0" @@ -17835,15 +17340,6 @@ __metadata: languageName: node linkType: hard -"@types/ioredis4@npm:@types/ioredis@^4.28.10": - version: 4.28.10 - resolution: "@types/ioredis@npm:4.28.10" - dependencies: - "@types/node": "*" - checksum: 0f2788cf25f490d3b345db8c5f8b8ce3f6c92cc99abcf744c8f974f02b9b3875233b3d22098614c462a0d6c41c523bd655509418ea88eb6249db6652290ce7cf - languageName: node - linkType: hard - "@types/is-glob@npm:^4.0.2": version: 4.0.4 resolution: "@types/is-glob@npm:4.0.4" @@ -17946,7 +17442,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.11, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.11, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 @@ -17978,13 +17474,6 @@ __metadata: languageName: node linkType: hard -"@types/keygrip@npm:*": - version: 1.0.6 - resolution: "@types/keygrip@npm:1.0.6" - checksum: d157f60bf920492347791d2b26d530d5069ce05796549fbacd4c24d66ffbebbcb0ab67b21e7a1b80a593b9fd4b67dc4843dec04c12bbc2e0fddfb8577a826c41 - languageName: node - linkType: hard - "@types/keyv@npm:*, @types/keyv@npm:^4.2.0": version: 4.2.0 resolution: "@types/keyv@npm:4.2.0" @@ -18003,56 +17492,6 @@ __metadata: languageName: node linkType: hard -"@types/koa-compose@npm:*": - version: 3.2.8 - resolution: "@types/koa-compose@npm:3.2.8" - dependencies: - "@types/koa": "*" - checksum: 95c32bdee738ac7c10439bbf6342ca3b9f0aafd7e8118739eac7fb0fa703a23cfe4c88f63e13a69a16fbde702e0bcdc62b272aa734325fc8efa7e5625479752e - languageName: node - linkType: hard - -"@types/koa@npm:*": - version: 2.15.0 - resolution: "@types/koa@npm:2.15.0" - dependencies: - "@types/accepts": "*" - "@types/content-disposition": "*" - "@types/cookies": "*" - "@types/http-assert": "*" - "@types/http-errors": "*" - "@types/keygrip": "*" - "@types/koa-compose": "*" - "@types/node": "*" - checksum: f429b92f36f96c8f5ceb5333f982400d0db20e177b7d89a7a576ac6f63aff8c964f7ab313e2e281a07bbb93931c66327fb42614cd4984b2ef33dfe7cbd76d741 - languageName: node - linkType: hard - -"@types/koa@npm:2.14.0": - version: 2.14.0 - resolution: "@types/koa@npm:2.14.0" - dependencies: - "@types/accepts": "*" - "@types/content-disposition": "*" - "@types/cookies": "*" - "@types/http-assert": "*" - "@types/http-errors": "*" - "@types/keygrip": "*" - "@types/koa-compose": "*" - "@types/node": "*" - checksum: 57d809e42350c9ddefa2150306355e40757877468bb027e0bd99f5aeb43cfaf8ba8b14761ea65e419d6fb4c2403a1f3ed0762872a9cf040dbd14357caca56548 - languageName: node - linkType: hard - -"@types/koa__router@npm:12.0.3": - version: 12.0.3 - resolution: "@types/koa__router@npm:12.0.3" - dependencies: - "@types/koa": "*" - checksum: e9cdc53e01a6b2340583e94982cec2720c2d4c582240438eca57db7db4596f707578ac3e32cd32ace787331de304b6292cca8c98b0233c77f8749493c4991c96 - languageName: node - linkType: hard - "@types/ldapjs@npm:^2.2.5": version: 2.2.5 resolution: "@types/ldapjs@npm:2.2.5" @@ -18070,9 +17509,9 @@ __metadata: linkType: hard "@types/lodash@npm:^4.14.151": - version: 4.17.5 - resolution: "@types/lodash@npm:4.17.5" - checksum: 3c9bb15772509f0ecb40428531863dbc3f064f2bf34bbccc2ce2b2923c69fb0868aec7e357b1d97fd0d7f7e435a014ea5c1adef8a64715529887179c97a5a823 + version: 4.17.7 + resolution: "@types/lodash@npm:4.17.7" + checksum: 09e58a119cd8a70acfb33f8623dc2fc54f74cdce3b3429b879fc2daac4807fe376190a04b9e024dd300f9a3ee1876d6623979cefe619f70654ca0fe0c47679a7 languageName: node linkType: hard @@ -18122,13 +17561,6 @@ __metadata: languageName: node linkType: hard -"@types/mime-db@npm:*": - version: 1.43.5 - resolution: "@types/mime-db@npm:1.43.5" - checksum: 83a994ba20d5e1f5ad7bf9d408dd01631ce80d0bfdedabac5af046810f5d6e94b6d9f34bcbad85c2e02516851c946e034ba4122d4f5168b30a008fc19c2292fe - languageName: node - linkType: hard - "@types/mime-types@npm:^2.1.0": version: 2.1.4 resolution: "@types/mime-types@npm:2.1.4" @@ -18187,12 +17619,12 @@ __metadata: languageName: node linkType: hard -"@types/multer@npm:^1.4.7": - version: 1.4.7 - resolution: "@types/multer@npm:1.4.7" +"@types/multer@npm:^1.4.11": + version: 1.4.12 + resolution: "@types/multer@npm:1.4.12" dependencies: "@types/express": "*" - checksum: 680cb0710aa25264d20cdcdaf34c212b636b55ea141310f06c25354ab1401193c7aa6839f9d22abf64a223fab1f2b8287f2512b0bef7e1628c4e9ffe54b4aeb2 + checksum: 719cacf88ec83ed77e250e45bee830fd7a505323825efa2a2c1144f5f3d7d36e67408ec988e571bcbaa571e0c214b5ede42d57ebb0f9b453a5eb8faba8ff12d0 languageName: node linkType: hard @@ -18205,12 +17637,12 @@ __metadata: languageName: node linkType: hard -"@types/mysql@npm:2.15.22": - version: 2.15.22 - resolution: "@types/mysql@npm:2.15.22" +"@types/mysql@npm:2.15.26": + version: 2.15.26 + resolution: "@types/mysql@npm:2.15.26" dependencies: "@types/node": "*" - checksum: 325120f027b04052b3ed056fef096d186ecc0988d9efe110a52bd3f2233d02e17fb802ea42da7fa1ae1d150b0194cddf56ff71bfb28411bc05361f947b0635af + checksum: c43395643aca3565492a12f7bb7168cea7f5fa1b6539caabc99e657bbbea3ef330d65e8d8fc873fedfbbbed48a01ac8c1ce0d31c7989cd44a4845b32253daf6c languageName: node linkType: hard @@ -18243,12 +17675,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:>=13.7.0, @types/node@npm:^20.1.1, @types/node@npm:^20.10.6, @types/node@npm:^20.11.16": - version: 20.12.7 - resolution: "@types/node@npm:20.12.7" +"@types/node@npm:*, @types/node@npm:>=13.7.0": + version: 22.5.4 + resolution: "@types/node@npm:22.5.4" dependencies: - undici-types: ~5.26.4 - checksum: 7cc979f7e2ca9a339ec71318c3901b9978555257929ef3666987f3e447123bc6dc92afcc89f6347e09e07d602fde7d51bcddea626c23aa2bb74aeaacfd1e1686 + undici-types: ~6.19.2 + checksum: 77ac225c38c428200036780036da0bc6764e2721cfa8f528c7e7da7cfefe01a32a5791e28a54efbeedbc977949058d7db902b2e00139298225d4686cee4ae6db languageName: node linkType: hard @@ -18267,9 +17699,9 @@ __metadata: linkType: hard "@types/node@npm:^16.11.26, @types/node@npm:^16.7.10, @types/node@npm:^16.9.2": - version: 16.18.74 - resolution: "@types/node@npm:16.18.74" - checksum: 33d8f157b51cb2f6907a7019e0bef0733f6ebd025f208863e6e6ea4721348902f2c7ac9eeaadff9f1e138927921e620c7f0a655475a298569d7551f2d28e35f3 + version: 16.18.108 + resolution: "@types/node@npm:16.18.108" + checksum: 5029ce7b0d247690360f2698da4fe765ef5cd5e2409b63b3a45e90bbf7bbaaf3497e769336fb7725be04a221d6e934e3a4616ec7fc205812943def3ea9d70862 languageName: node linkType: hard @@ -18281,11 +17713,20 @@ __metadata: linkType: hard "@types/node@npm:^18.17.15, @types/node@npm:^18.17.8": - version: 18.19.8 - resolution: "@types/node@npm:18.19.8" + version: 18.19.50 + resolution: "@types/node@npm:18.19.50" dependencies: undici-types: ~5.26.4 - checksum: fa291495d6157a9d9393b4c3bdbf1ce12a8f661dc9da6a4fa19bcdb19af1c62bb8dbf7fb66ae135f29cd788b618e9845b83e9c47edcf39f0953a8561fdacd9a3 + checksum: 73bdd2b46fb96816a1f7309e1b609f0832a29739c87df7daa729ff497160be143e02cf18486a0112e1981b092358aed3ca0716b532aff93c7e05f7dbb4f7586a + languageName: node + linkType: hard + +"@types/node@npm:^20.1.1, @types/node@npm:^20.11.16": + version: 20.16.5 + resolution: "@types/node@npm:20.16.5" + dependencies: + undici-types: ~6.19.2 + checksum: f38b7bd8c4993dcf38943afa2ffdd7dfd18fc94f8f3f28d0c1045a10d39871a6cc1b8f8d3bf0c7ed848457d0e1d283482f6ca125579c13fed1b7575d23e8e8f5 languageName: node linkType: hard @@ -18416,23 +17857,23 @@ __metadata: languageName: node linkType: hard -"@types/pg-pool@npm:2.0.4": - version: 2.0.4 - resolution: "@types/pg-pool@npm:2.0.4" +"@types/pg-pool@npm:2.0.6": + version: 2.0.6 + resolution: "@types/pg-pool@npm:2.0.6" dependencies: "@types/pg": "*" - checksum: 5ae1c49fe1820ec011f8e2a877198a62f4c9795d2cc340dff4527c26f24ee22dffe99a8ca5cdec6edb54613bded820cc51256fb668e0eb4d22794181b94fad82 + checksum: cc54ce97115effc982bd052f79901a78215e76554aca0ecc92e78eb907e4fb2962924039369cd9aaf48075f1637593ce14647c62d3a2eb03789ce5d1c6df750b languageName: node linkType: hard "@types/pg@npm:*, @types/pg@npm:^8.6.6": - version: 8.11.6 - resolution: "@types/pg@npm:8.11.6" + version: 8.11.8 + resolution: "@types/pg@npm:8.11.8" dependencies: "@types/node": "*" pg-protocol: "*" pg-types: ^4.0.1 - checksum: 231f7e5bfe8b4d14cca398d24cd55f4f14f582f815b62059e6f3ee74108cf92089fbd946568ebc35fa402f238ed9c8a8c1e10e7084e83e4ca3aff75957243014 + checksum: da101e985abd93ced25d9bd4bbbeb86eac37773310b910afd83971009525cfd1fff3e2ec4f072b2cea184475b6387211c38df8bfbac916d3c73b5a62b6bfb692 languageName: node linkType: hard @@ -18468,7 +17909,7 @@ __metadata: languageName: node linkType: hard -"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.11, @types/prop-types@npm:^15.7.3": +"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.12, @types/prop-types@npm:^15.7.3": version: 15.7.12 resolution: "@types/prop-types@npm:15.7.12" checksum: ac16cc3d0a84431ffa5cfdf89579ad1e2269549f32ce0c769321fdd078f84db4fbe1b461ed5a1a496caf09e637c0e367d600c541435716a55b1d9713f5035dfe @@ -18484,10 +17925,10 @@ __metadata: languageName: node linkType: hard -"@types/qs@npm:*": - version: 6.9.6 - resolution: "@types/qs@npm:6.9.6" - checksum: 01871b1cf7062717ec76fcb9b29ddae1e04fcfadc1c76d86ec2571e72f27bf09ff31b094b295be8d4ca664aeec9b8965563680b31fcab7aba1ed93afac5181cd +"@types/qs@npm:*, @types/qs@npm:^6.9.6": + version: 6.9.15 + resolution: "@types/qs@npm:6.9.15" + checksum: 97d8208c2b82013b618e7a9fc14df6bd40a73e1385ac479b6896bafc7949a46201c15f42afd06e86a05e914f146f495f606b6fb65610cc60cf2e0ff743ec38a2 languageName: node linkType: hard @@ -18752,10 +18193,10 @@ __metadata: languageName: node linkType: hard -"@types/shimmer@npm:^1.0.2": - version: 1.0.5 - resolution: "@types/shimmer@npm:1.0.5" - checksum: f6b0c950dc9187464c5393faf4f4e2b7b44b16665bb49196da28affecceb4fdcd9749af15cbe50f1a2de39f3a84b7523e73445f117f6b48bdbd61b892568364a +"@types/shimmer@npm:^1.2.0": + version: 1.2.0 + resolution: "@types/shimmer@npm:1.2.0" + checksum: f081a31d826ce7bfe8cc7ba8129d2b1dffae44fd580eba4fcf741237646c4c2494ae6de2cada4b7713d138f35f4bc512dbf01311d813dee82020f97d7d8c491c languageName: node linkType: hard @@ -18889,7 +18330,7 @@ __metadata: languageName: node linkType: hard -"@types/tedious@npm:^4.0.10": +"@types/tedious@npm:^4.0.14": version: 4.0.14 resolution: "@types/tedious@npm:4.0.14" dependencies: @@ -18925,10 +18366,10 @@ __metadata: languageName: node linkType: hard -"@types/tough-cookie@npm:*": - version: 4.0.0 - resolution: "@types/tough-cookie@npm:4.0.0" - checksum: 454fa8d4d64532992274ebf2ff5ea0061b0dd32a2282255a3e793f04a8b64a9c4c1f9e0f4ed83c514c852b7b604d69336c66c80de4a857cb41a81e9572981e7f +"@types/tough-cookie@npm:*, @types/tough-cookie@npm:^4.0.5": + version: 4.0.5 + resolution: "@types/tough-cookie@npm:4.0.5" + checksum: f19409d0190b179331586365912920d192733112a195e870c7f18d20ac8adb7ad0b0ff69dad430dba8bc2be09593453a719cfea92dc3bda19748fd158fe1498d languageName: node linkType: hard @@ -19017,11 +18458,11 @@ __metadata: linkType: hard "@types/ws@npm:*, @types/ws@npm:^8.0.0, @types/ws@npm:^8.5.10, @types/ws@npm:^8.5.3": - version: 8.5.10 - resolution: "@types/ws@npm:8.5.10" + version: 8.5.12 + resolution: "@types/ws@npm:8.5.12" dependencies: "@types/node": "*" - checksum: 3ec416ea2be24042ebd677932a462cf16d2080393d8d7d0b1b3f5d6eaa4a7387aaf0eefb99193c0bfd29444857cf2e0c3ac89899e130550dc6c14ada8a46d25e + checksum: ddefb6ad1671f70ce73b38a5f47f471d4d493864fca7c51f002a86e5993d031294201c5dced6d5018fb8905ad46888d65c7f20dd54fc165910b69f42fba9a6d0 languageName: node linkType: hard @@ -19294,9 +18735,9 @@ __metadata: languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.21.25": - version: 4.21.25 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.21.25" +"@uiw/codemirror-extensions-basic-setup@npm:4.23.0": + version: 4.23.0 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.23.0" dependencies: "@codemirror/autocomplete": ^6.0.0 "@codemirror/commands": ^6.0.0 @@ -19313,19 +18754,19 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: 1714fcb9ff1a80c14cef5b6b78f41d18f3991877fc088e5c5edf4ce4ee203f468a6401aab7d042ceae527f6475e2e11d4f30dbab6e127bd157c6aaf4c68049d2 + checksum: bc48d3aa82dc0b7cf9724c2806fe013423448135b38ab7d2472eb1df80d3297d75f4a45e3dbd817cb32423ebc57169a46505598e185d351ad819b59f8887c539 languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.9.3": - version: 4.21.25 - resolution: "@uiw/react-codemirror@npm:4.21.25" + version: 4.23.0 + resolution: "@uiw/react-codemirror@npm:4.23.0" dependencies: "@babel/runtime": ^7.18.6 "@codemirror/commands": ^6.1.0 "@codemirror/state": ^6.1.1 "@codemirror/theme-one-dark": ^6.0.0 - "@uiw/codemirror-extensions-basic-setup": 4.21.25 + "@uiw/codemirror-extensions-basic-setup": 4.23.0 codemirror: ^6.0.0 peerDependencies: "@babel/runtime": ">=7.11.0" @@ -19335,7 +18776,7 @@ __metadata: codemirror: ">=6.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 63d7578dab73f66d0357bdd566d24c3c43431627c77b5756f0a982ac5ebff35322e3292ce33a16cb19d5e8fb750a64f59d17c35a3d84c66b38c8454d06613dff + checksum: b1341dee1f0257c1fd62bd3b356a207ff2bb72b9eb509c5c52cabf87b8aa23b4dac812ebb25ad7b84cddf58d8674b09842bce3c763bb63a9f8cc1d731d7de0be languageName: node linkType: hard @@ -19356,13 +18797,13 @@ __metadata: languageName: node linkType: hard -"@useoptic/json-pointer-helpers@npm:0.54.13": - version: 0.54.13 - resolution: "@useoptic/json-pointer-helpers@npm:0.54.13" +"@useoptic/json-pointer-helpers@npm:0.55.1": + version: 0.55.1 + resolution: "@useoptic/json-pointer-helpers@npm:0.55.1" dependencies: jsonpointer: ^5.0.1 minimatch: 9.0.3 - checksum: ad987e9bbec82606bd5995f4ffea7eb708549573e8a94a201ed266e4efc854423804671c3772be714457c417641da69d6689a1e61164bd0cfb8f83a1561facdb + checksum: 874db1e25c4abecf29faf95c51d39d127ac50ee9f1ad9654babb3a0257a7c321e54312bf66214ac188e3f92f7e9c342fd81565356c0472689c120ea40465b15d languageName: node linkType: hard @@ -19420,11 +18861,11 @@ __metadata: languageName: node linkType: hard -"@useoptic/openapi-utilities@npm:^0.54.8": - version: 0.54.13 - resolution: "@useoptic/openapi-utilities@npm:0.54.13" +"@useoptic/openapi-utilities@npm:^0.55.0": + version: 0.55.1 + resolution: "@useoptic/openapi-utilities@npm:0.55.1" dependencies: - "@useoptic/json-pointer-helpers": 0.54.13 + "@useoptic/json-pointer-helpers": 0.55.1 ajv: ^8.6.0 ajv-errors: ~3.0.0 ajv-formats: ~2.1.0 @@ -19441,7 +18882,7 @@ __metadata: ts-invariant: ^0.9.3 url-join: ^4.0.1 yaml-ast-parser: ^0.0.43 - checksum: d02eabba96af29632557cdb5532edcc4a629860471fe6cd02990c54ad8014c980d07e3dde8d04ed644a0bd3c2218a93fc50fe9904ee317ef6189b2db41bc7505 + checksum: 53f9ebc645d69cb1ede0263bb3dc2786cfb18f7e5a3da734898c3d9cc2109d581cd6238cec77e6eaae2f478da4ed134abca8255977e68fd06418966a65a9bbe6 languageName: node linkType: hard @@ -19552,21 +18993,6 @@ __metadata: languageName: node linkType: hard -"@vitejs/plugin-react@npm:^4.0.4": - version: 4.3.1 - resolution: "@vitejs/plugin-react@npm:4.3.1" - dependencies: - "@babel/core": ^7.24.5 - "@babel/plugin-transform-react-jsx-self": ^7.24.5 - "@babel/plugin-transform-react-jsx-source": ^7.24.1 - "@types/babel__core": ^7.20.5 - react-refresh: ^0.14.2 - peerDependencies: - vite: ^4.2.0 || ^5.0.0 - checksum: 57872e0193c7e545c5ef4852cbe1adf17a6b35406a2aba4b3acce06c173a9dabbf6ff4c72701abc11bb3cbe24a056f5054f39018f7034c9aa57133a3a7770237 - languageName: node - linkType: hard - "@webassemblyjs/ast@npm:1.12.1, @webassemblyjs/ast@npm:^1.12.1": version: 1.12.1 resolution: "@webassemblyjs/ast@npm:1.12.1" @@ -20431,12 +19857,12 @@ __metadata: languageName: node linkType: hard -"acorn-import-assertions@npm:^1.9.0": - version: 1.9.0 - resolution: "acorn-import-assertions@npm:1.9.0" +"acorn-import-attributes@npm:^1.9.5": + version: 1.9.5 + resolution: "acorn-import-attributes@npm:1.9.5" peerDependencies: acorn: ^8 - checksum: 944fb2659d0845c467066bdcda2e20c05abe3aaf11972116df457ce2627628a81764d800dd55031ba19de513ee0d43bb771bc679cc0eda66dc8b4fade143bc0c + checksum: 1c0c49b6a244503964ae46ae850baccf306e84caf99bc2010ed6103c69a423987b07b520a6c619f075d215388bd4923eccac995886a54309eda049ab78a4be95 languageName: node linkType: hard @@ -20593,6 +20019,15 @@ __metadata: languageName: node linkType: hard +"ajv-i18n@npm:^4.2.0": + version: 4.2.0 + resolution: "ajv-i18n@npm:4.2.0" + peerDependencies: + ajv: ^8.0.0-beta.0 + checksum: 6fa53eeafb13dc11dd99119039cd1e4394c949ca3ec407b2b421b8aae20ad2acd2f615f134ab9de64a636d66c6e0df1e15dcfca50b45683ebb9044e6667735e9 + languageName: node + linkType: hard + "ajv-keywords@npm:^3.4.1, ajv-keywords@npm:^3.5.2": version: 3.5.2 resolution: "ajv-keywords@npm:3.5.2" @@ -20625,15 +20060,15 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.11.2, ajv@npm:^8.12.0, ajv@npm:^8.6.0, ajv@npm:^8.6.3, ajv@npm:^8.8.2, ajv@npm:^8.9.0": - version: 8.12.0 - resolution: "ajv@npm:8.12.0" +"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0, ajv@npm:^8.12.0, ajv@npm:^8.17.1, ajv@npm:^8.6.0, ajv@npm:^8.6.3, ajv@npm:^8.9.0": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" dependencies: - fast-deep-equal: ^3.1.1 + fast-deep-equal: ^3.1.3 + fast-uri: ^3.0.1 json-schema-traverse: ^1.0.0 require-from-string: ^2.0.2 - uri-js: ^4.2.2 - checksum: 4dc13714e316e67537c8b31bc063f99a1d9d9a497eb4bbd55191ac0dcd5e4985bbb71570352ad6f1e76684fb6d790928f96ba3b2d4fd6e10024be9612fe3f001 + checksum: 1797bf242cfffbaf3b870d13565bd1716b73f214bb7ada9a497063aada210200da36e3ed40237285f3255acc4feeae91b1fb183625331bad27da95973f7253d9 languageName: node linkType: hard @@ -20708,12 +20143,12 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^6.2.0": - version: 6.2.0 - resolution: "ansi-escapes@npm:6.2.0" +"ansi-escapes@npm:^7.0.0": + version: 7.0.0 + resolution: "ansi-escapes@npm:7.0.0" dependencies: - type-fest: ^3.0.0 - checksum: f0bc667d5f1ededc3ea89b73c34f0cba95473525b07e1290ddfd3fc868c94614e95f3549f5c4fd0c05424af7d3fd298101fb3d9a52a597d3782508b340783bd7 + environment: ^1.0.0 + checksum: 19baa61e68d1998c03b3b8bd023653a6c2667f0ed6caa9a00780ffd6f0a14f4a6563c57a38b3c0aba71bd704cd49c4c8df41be60bd81c957409f91e9dd49051f languageName: node linkType: hard @@ -20843,24 +20278,6 @@ __metadata: languageName: node linkType: hard -"archiver-utils@npm:^2.1.0": - version: 2.1.0 - resolution: "archiver-utils@npm:2.1.0" - dependencies: - glob: ^7.1.4 - graceful-fs: ^4.2.0 - lazystream: ^1.0.0 - lodash.defaults: ^4.2.0 - lodash.difference: ^4.5.0 - lodash.flatten: ^4.4.0 - lodash.isplainobject: ^4.0.6 - lodash.union: ^4.6.0 - normalize-path: ^3.0.0 - readable-stream: ^2.0.0 - checksum: 5665f40bde87ee82cb638177bdccca8cc6e55edea1b94338f7e6b56a1d9367b0d9a39e42b47866eaf84b8c67669a7d250900a226207ecc30fa163b52aae859a5 - languageName: node - linkType: hard - "archiver-utils@npm:^4.0.1": version: 4.0.1 resolution: "archiver-utils@npm:4.0.1" @@ -20875,18 +20292,18 @@ __metadata: languageName: node linkType: hard -"archiver@npm:^5.3.2": - version: 5.3.2 - resolution: "archiver@npm:5.3.2" +"archiver-utils@npm:^5.0.0, archiver-utils@npm:^5.0.2": + version: 5.0.2 + resolution: "archiver-utils@npm:5.0.2" dependencies: - archiver-utils: ^2.1.0 - async: ^3.2.4 - buffer-crc32: ^0.2.1 - readable-stream: ^3.6.0 - readdir-glob: ^1.1.2 - tar-stream: ^2.2.0 - zip-stream: ^4.1.0 - checksum: 7d3b9b9b51cf54d88c89fbca9b0847c120bfcf9776c7025c52dd0b62f6603dc63dc0f3f1a09582f936f67e3906b46d58954cc762a255be45e8d3e14e3cb0b0b1 + glob: ^10.0.0 + graceful-fs: ^4.2.0 + is-stream: ^2.0.1 + lazystream: ^1.0.0 + lodash: ^4.17.15 + normalize-path: ^3.0.0 + readable-stream: ^4.0.0 + checksum: 7dc4f3001dc373bd0fa7671ebf08edf6f815cbc539c78b5478a2eaa67e52e3fc0e92f562cdef2ba016c4dcb5468d3d069eb89535c6844da4a5bb0baf08ad5720 languageName: node linkType: hard @@ -20905,6 +20322,21 @@ __metadata: languageName: node linkType: hard +"archiver@npm:^7.0.1": + version: 7.0.1 + resolution: "archiver@npm:7.0.1" + dependencies: + archiver-utils: ^5.0.2 + async: ^3.2.4 + buffer-crc32: ^1.0.0 + readable-stream: ^4.0.0 + readdir-glob: ^1.1.2 + tar-stream: ^3.0.0 + zip-stream: ^6.0.1 + checksum: f93bcc00f919e0bbb6bf38fddf111d6e4d1ed34721b73cc073edd37278303a7a9f67aa4abd6fd2beb80f6c88af77f2eb4f60276343f67605e3aea404e5ad93ea + languageName: node + linkType: hard + "are-we-there-yet@npm:^2.0.0": version: 2.0.0 resolution: "are-we-there-yet@npm:2.0.0" @@ -20969,7 +20401,7 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:5.3.0, aria-query@npm:^5.0.0, aria-query@npm:^5.3.0": +"aria-query@npm:5.3.0, aria-query@npm:^5.0.0": version: 5.3.0 resolution: "aria-query@npm:5.3.0" dependencies: @@ -20978,14 +20410,16 @@ __metadata: languageName: node linkType: hard -"arity-n@npm:^1.0.4": - version: 1.0.4 - resolution: "arity-n@npm:1.0.4" - checksum: 3d76e16907f7b8a9452690c1efc301d0fbecea457365797eccfbade9b8d1653175b2c38343201bf26fdcbf0bcbb31eab6d912e7c008c6d19042301dc0be80a73 +"aria-query@npm:~5.1.3": + version: 5.1.3 + resolution: "aria-query@npm:5.1.3" + dependencies: + deep-equal: ^2.0.5 + checksum: 929ff95f02857b650fb4cbcd2f41072eee2f46159a6605ea03bf63aa572e35ffdff43d69e815ddc462e16e07de8faba3978afc2813650b4448ee18c9895d982b languageName: node linkType: hard -"array-buffer-byte-length@npm:^1.0.1": +"array-buffer-byte-length@npm:^1.0.0, array-buffer-byte-length@npm:^1.0.1": version: 1.0.1 resolution: "array-buffer-byte-length@npm:1.0.1" dependencies: @@ -21009,7 +20443,7 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.6, array-includes@npm:^3.1.7, array-includes@npm:^3.1.8": +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8": version: 3.1.8 resolution: "array-includes@npm:3.1.8" dependencies: @@ -21023,15 +20457,6 @@ __metadata: languageName: node linkType: hard -"array-last@npm:^1.1.1": - version: 1.3.0 - resolution: "array-last@npm:1.3.0" - dependencies: - is-number: ^4.0.0 - checksum: 7631c7df9b44ea26f49e2f6eeb7a7d4d95b3798586b917e1efae4a321b6362e449e00b011e88eb0260959fbfc940fbdfce1d2a35765ea080de6d71e3fc3cf1dd - languageName: node - linkType: hard - "array-to-table@npm:^1.0.1": version: 1.0.1 resolution: "array-to-table@npm:1.0.1" @@ -21060,16 +20485,17 @@ __metadata: languageName: node linkType: hard -"array.prototype.findlastindex@npm:^1.2.3": - version: 1.2.3 - resolution: "array.prototype.findlastindex@npm:1.2.3" +"array.prototype.findlastindex@npm:^1.2.5": + version: 1.2.5 + resolution: "array.prototype.findlastindex@npm:1.2.5" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-shim-unscopables: ^1.0.0 - get-intrinsic: ^1.2.1 - checksum: 31f35d7b370c84db56484618132041a9af401b338f51899c2e78ef7690fbba5909ee7ca3c59a7192085b328cc0c68c6fd1f6d1553db01a689a589ae510f3966e + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + es-shim-unscopables: ^1.0.2 + checksum: 2c81cff2a75deb95bf1ed89b6f5f2bfbfb882211e3b7cc59c3d6b87df774cd9d6b36949a8ae39ac476e092c1d4a4905f5ee11a86a456abb10f35f8211ae4e710 languageName: node linkType: hard @@ -21097,18 +20523,6 @@ __metadata: languageName: node linkType: hard -"array.prototype.toreversed@npm:^1.1.2": - version: 1.1.2 - resolution: "array.prototype.toreversed@npm:1.1.2" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-shim-unscopables: ^1.0.0 - checksum: 58598193426282155297bedf950dc8d464624a0d81659822fb73124286688644cb7e0e4927a07f3ab2daaeb6617b647736cc3a5e6ca7ade5bb8e573b284e6240 - languageName: node - linkType: hard - "array.prototype.tosorted@npm:^1.1.4": version: 1.1.4 resolution: "array.prototype.tosorted@npm:1.1.4" @@ -21190,18 +20604,6 @@ __metadata: languageName: node linkType: hard -"assert@npm:^2.0.0": - version: 2.0.0 - resolution: "assert@npm:2.0.0" - dependencies: - es6-object-assign: ^1.1.0 - is-nan: ^1.2.1 - object-is: ^1.0.1 - util: ^0.12.0 - checksum: bb91f181a86d10588ee16c5e09c280f9811373974c29974cbe401987ea34e966699d7989a812b0e19377b511ea0bc627f5905647ce569311824848ede382cae8 - languageName: node - linkType: hard - "ast-types-flow@npm:^0.0.8": version: 0.0.8 resolution: "ast-types-flow@npm:0.0.8" @@ -21391,10 +20793,17 @@ __metadata: languageName: node linkType: hard +"aws-ssl-profiles@npm:^1.1.1": + version: 1.1.1 + resolution: "aws-ssl-profiles@npm:1.1.1" + checksum: c428ee04614bca4a22e5b4d0fd31181f9ba901206c4f614c08ae3b05333c06f1a99964082dcf2f1b119b3a7b07de9c35d2876c7b96eaa41d680c6eac9bc9443e + languageName: node + linkType: hard + "aws4@npm:^1.11.0, aws4@npm:^1.12.0, aws4@npm:^1.8.0": - version: 1.12.0 - resolution: "aws4@npm:1.12.0" - checksum: 68f79708ac7c335992730bf638286a3ee0a645cf12575d557860100767c500c08b30e24726b9f03265d74116417f628af78509e1333575e9f8d52a80edfe8cbc + version: 1.13.2 + resolution: "aws4@npm:1.13.2" + checksum: 9ac924e4a91c088b4928ea86b68d8c4558b0e6289ccabaae0e3e96a611bd75277c2eab6e3965821028768700516f612b929a5ce822f33a8771f74ba2a8cedb9c languageName: node linkType: hard @@ -21405,10 +20814,10 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:=4.7.0": - version: 4.7.0 - resolution: "axe-core@npm:4.7.0" - checksum: f086bcab42be1761ba2b0b127dec350087f4c3a853bba8dd58f69d898cefaac31a1561da23146f6f3c07954c76171d1f2ce460e555e052d2b02cd79af628fa4a +"axe-core@npm:^4.10.0": + version: 4.10.0 + resolution: "axe-core@npm:4.10.0" + checksum: 7eca827fd8d98d7e4b561df65437be608155c613d8f262ae9e4a6ade02c156c7362dcbc3f71b4b526edce686f7c686280236bcff1d6725e2ef8327def72a8c41 languageName: node linkType: hard @@ -21435,14 +20844,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:1.6.8": - version: 1.6.8 - resolution: "axios@npm:1.6.8" +"axios@npm:1.7.4, axios@npm:^1.0.0, axios@npm:^1.4.0, axios@npm:^1.6.0, axios@npm:^1.6.7": + version: 1.7.4 + resolution: "axios@npm:1.7.4" dependencies: follow-redirects: ^1.15.6 form-data: ^4.0.0 proxy-from-env: ^1.1.0 - checksum: bf007fa4b207d102459300698620b3b0873503c6d47bf5a8f6e43c0c64c90035a4f698b55027ca1958f61ab43723df2781c38a99711848d232cad7accbcdfcdd + checksum: 0c17039a9acfe6a566fca8431ba5c1b455c83d30ea6157fec68a6722878fcd30f3bd32d172f6bee0c51fe75ca98e6414ddcd968a87b5606b573731629440bfaf languageName: node linkType: hard @@ -21456,23 +20865,10 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.0.0, axios@npm:^1.4.0, axios@npm:^1.6.0, axios@npm:^1.6.7": - version: 1.7.2 - resolution: "axios@npm:1.7.2" - dependencies: - follow-redirects: ^1.15.6 - form-data: ^4.0.0 - proxy-from-env: ^1.1.0 - checksum: e457e2b0ab748504621f6fa6609074ac08c824bf0881592209dfa15098ece7e88495300e02cd22ba50b3468fd712fe687e629dcb03d6a3f6a51989727405aedf - languageName: node - linkType: hard - -"axobject-query@npm:^3.2.1": - version: 3.2.1 - resolution: "axobject-query@npm:3.2.1" - dependencies: - dequal: ^2.0.3 - checksum: a94047e702b57c91680e6a952ec4a1aaa2cfd0d80ead76bc8c954202980d8c51968a6ea18b4d8010e8e2cf95676533d8022a8ebba9abc1dfe25686721df26fd2 +"axobject-query@npm:^4.1.0": + version: 4.1.0 + resolution: "axobject-query@npm:4.1.0" + checksum: 7d1e87bf0aa7ae7a76cd39ab627b7c48fda3dc40181303d9adce4ba1d5b5ce73b5e5403ee6626ec8e91090448c887294d6144e24b6741a976f5be9347e3ae1df languageName: node linkType: hard @@ -21493,15 +20889,6 @@ __metadata: languageName: node linkType: hard -"babel-core@npm:^7.0.0-bridge.0": - version: 7.0.0-bridge.0 - resolution: "babel-core@npm:7.0.0-bridge.0" - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 2a1cb879019dffb08d17bec36e13c3a6d74c94773f41c1fd8b14de13f149cc34b705b0a1e07b42fcf35917b49d78db6ff0c5c3b00b202a5235013d517b5c6bbb - languageName: node - linkType: hard - "babel-jest@npm:^29.7.0": version: 29.7.0 resolution: "babel-jest@npm:29.7.0" @@ -21668,15 +21055,6 @@ __metadata: languageName: node linkType: hard -"babylon@npm:^6.9.1": - version: 6.18.0 - resolution: "babylon@npm:6.18.0" - bin: - babylon: ./bin/babylon.js - checksum: 0777ae0c735ce1cbfc856d627589ed9aae212b84fb0c03c368b55e6c5d3507841780052808d0ad46e18a2ba516e93d55eeed8cd967f3b2938822dfeccfb2a16d - languageName: node - linkType: hard - "backo2@npm:^1.0.2": version: 1.0.2 resolution: "backo2@npm:1.0.2" @@ -21826,13 +21204,13 @@ __metadata: linkType: hard "better-sqlite3@npm:^11.0.0": - version: 11.0.0 - resolution: "better-sqlite3@npm:11.0.0" + version: 11.2.1 + resolution: "better-sqlite3@npm:11.2.1" dependencies: bindings: ^1.5.0 node-gyp: latest prebuild-install: ^7.1.1 - checksum: 7bf02ea6ba3253f53cb36bd872f86379ebf1a66cb103d39b91c610995c4396dde2b976bdf866f07eb7d67eb6f5433aa5490a6a4f4264244f83a53562f68832dc + checksum: 22259c298e76d4bc2bd993dfc9392bb80ecef948f48342804a7bd38a43ff7693089a9ea0ac0c14ebc195453aa94fce588755f6eea234d7550383b9f6ac7150a9 languageName: node linkType: hard @@ -22076,15 +21454,6 @@ __metadata: languageName: node linkType: hard -"browser-resolve@npm:^2.0.0": - version: 2.0.0 - resolution: "browser-resolve@npm:2.0.0" - dependencies: - resolve: ^1.17.0 - checksum: 69225e73b555bd6d2a08fb93c7342cfcf3b5058b975099c52649cd5c3cec84c2066c5385084d190faedfb849684d9dabe10129f0cd401d1883572f2e6650f440 - languageName: node - linkType: hard - "browserify-aes@npm:^1.0.0, browserify-aes@npm:^1.0.4": version: 1.2.0 resolution: "browserify-aes@npm:1.2.0" @@ -22158,17 +21527,17 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.16.0, browserslist@npm:^4.16.6, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.22.2": - version: 4.23.1 - resolution: "browserslist@npm:4.23.1" +"browserslist@npm:^4.0.0, browserslist@npm:^4.16.0, browserslist@npm:^4.16.6, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.23.1": + version: 4.23.3 + resolution: "browserslist@npm:4.23.3" dependencies: - caniuse-lite: ^1.0.30001629 - electron-to-chromium: ^1.4.796 - node-releases: ^2.0.14 - update-browserslist-db: ^1.0.16 + caniuse-lite: ^1.0.30001646 + electron-to-chromium: ^1.5.4 + node-releases: ^2.0.18 + update-browserslist-db: ^1.1.0 bin: browserslist: cli.js - checksum: 06189e2d6666a203ce097cc0e713a40477d08420927b79af139211e5712f3cf676fdc4dd6af3aa493d47c09206a344b3420a8315577dbe88c58903132de9b0f5 + checksum: 7906064f9970aeb941310b2fcb8b4ace4a1b50aa657c986677c6f1553a8cabcc94ee9c5922f715baffbedaa0e6cf0831b6fed7b059dde6873a4bfadcbe069c7e languageName: node linkType: hard @@ -22197,13 +21566,20 @@ __metadata: languageName: node linkType: hard -"buffer-crc32@npm:^0.2.1, buffer-crc32@npm:^0.2.13, buffer-crc32@npm:~0.2.3": +"buffer-crc32@npm:^0.2.1, buffer-crc32@npm:~0.2.3": version: 0.2.13 resolution: "buffer-crc32@npm:0.2.13" checksum: 06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c languageName: node linkType: hard +"buffer-crc32@npm:^1.0.0": + version: 1.0.0 + resolution: "buffer-crc32@npm:1.0.0" + checksum: bc114c0e02fe621249e0b5093c70e6f12d4c2b1d8ddaf3b1b7bbe3333466700100e6b1ebdc12c050d0db845bc582c4fce8c293da487cc483f97eea027c480b23 + languageName: node + linkType: hard + "buffer-equal-constant-time@npm:1.0.1": version: 1.0.1 resolution: "buffer-equal-constant-time@npm:1.0.1" @@ -22246,7 +21622,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.5.0, buffer@npm:^5.7.1": +"buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -22459,7 +21835,7 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": +"call-bind@npm:^1.0.2, call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": version: 1.0.7 resolution: "call-bind@npm:1.0.7" dependencies: @@ -22536,10 +21912,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001629": - version: 1.0.30001632 - resolution: "caniuse-lite@npm:1.0.30001632" - checksum: 95be155501650ac36a8c3bdf60886bc8f7c419e7715cdaf1c04941f8676c0bd75355aeda62563092585fbe6f9d50d2eb6dea6bd063d7f6a58004ec62d8f8fe49 +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001646": + version: 1.0.30001653 + resolution: "caniuse-lite@npm:1.0.30001653" + checksum: 289cf06c26a46f3e6460ccd5feffa788ab0ab35d306898c48120c65cfb11959bfa560e9f739393769b4fd01150c69b0747ad3ad5ec3abf3dfafd66df3c59254e languageName: node linkType: hard @@ -22569,7 +21945,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:2.4.2, chalk@npm:^2.1.0, chalk@npm:^2.3.2, chalk@npm:^2.4.2": +"chalk@npm:2.4.2, chalk@npm:^2.3.2, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" dependencies: @@ -22740,6 +22116,15 @@ __metadata: languageName: node linkType: hard +"cidr-regex@npm:^3.1.1": + version: 3.1.1 + resolution: "cidr-regex@npm:3.1.1" + dependencies: + ip-regex: ^4.1.0 + checksum: ef9306d086928ee82b3f841b3bdab6e072230f3623a57cf19e06174946f2cbfeb70ca52bc106b127db27a628b9e84fb39284f5851003898ffdb957fe330478ee + languageName: node + linkType: hard + "cipher-base@npm:^1.0.0, cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": version: 1.0.4 resolution: "cipher-base@npm:1.0.4" @@ -22825,12 +22210,12 @@ __metadata: languageName: node linkType: hard -"cli-cursor@npm:^4.0.0": - version: 4.0.0 - resolution: "cli-cursor@npm:4.0.0" +"cli-cursor@npm:^5.0.0": + version: 5.0.0 + resolution: "cli-cursor@npm:5.0.0" dependencies: - restore-cursor: ^4.0.0 - checksum: ab3f3ea2076e2176a1da29f9d64f72ec3efad51c0960898b56c8a17671365c26e67b735920530eaf7328d61f8bd41c27f46b9cf6e4e10fe2fa44b5e8c0e392cc + restore-cursor: ^5.0.0 + checksum: 1eb9a3f878b31addfe8d82c6d915ec2330cec8447ab1f117f4aa34f0137fbb3137ec3466e1c9a65bcb7557f6e486d343f2da57f253a2f668d691372dfa15c090 languageName: node linkType: hard @@ -23002,10 +22387,10 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^2.1.0": - version: 2.1.0 - resolution: "clsx@npm:2.1.0" - checksum: 43fefc29b6b49c9476fbce4f8b1cc75c27b67747738e598e6651dd40d63692135dc60b18fa1c5b78a2a9ba8ae6fd2055a068924b94e20b42039bd53b78b98e1d +"clsx@npm:^2.1.0, clsx@npm:^2.1.1": + version: 2.1.1 + resolution: "clsx@npm:2.1.1" + checksum: acd3e1ab9d8a433ecb3cc2f6a05ab95fe50b4a3cfc5ba47abb6cbf3754585fcb87b84e90c822a1f256c4198e3b41c7f6c391577ffc8678ad587fc0976b24fd57 languageName: node linkType: hard @@ -23185,7 +22570,7 @@ __metadata: languageName: node linkType: hard -"colorette@npm:^2.0.10, colorette@npm:^2.0.16, colorette@npm:^2.0.20": +"colorette@npm:^2.0.10, colorette@npm:^2.0.20": version: 2.0.20 resolution: "colorette@npm:2.0.20" checksum: 0c016fea2b91b733eb9f4bcdb580018f52c0bc0979443dad930e5037a968237ac53d9beb98e218d2e9235834f8eebce7f8e080422d6194e957454255bde71d3d @@ -23351,27 +22736,6 @@ __metadata: languageName: node linkType: hard -"compose-function@npm:^3.0.3": - version: 3.0.3 - resolution: "compose-function@npm:3.0.3" - dependencies: - arity-n: ^1.0.4 - checksum: 9f17d431e3ee4797c844f2870e13494079882ac3dbc54c143b7d99967b371908e0ce7ceb71c6aed61e2ecddbcd7bb437d91428a3d0e6569aee17a87fcbc7918f - languageName: node - linkType: hard - -"compress-commons@npm:^4.1.0": - version: 4.1.0 - resolution: "compress-commons@npm:4.1.0" - dependencies: - buffer-crc32: ^0.2.13 - crc32-stream: ^4.0.1 - normalize-path: ^3.0.0 - readable-stream: ^3.6.0 - checksum: 3348bea7a1cce04b430f6ec3125eebbc0e23bd8dd14d30ec2fb113d3733f95ae6b12d5b33ad794e7ceab70f57e38a6c2642d96a64bc83e490a3ddae8db469949 - languageName: node - linkType: hard - "compress-commons@npm:^5.0.1": version: 5.0.1 resolution: "compress-commons@npm:5.0.1" @@ -23384,6 +22748,19 @@ __metadata: languageName: node linkType: hard +"compress-commons@npm:^6.0.2": + version: 6.0.2 + resolution: "compress-commons@npm:6.0.2" + dependencies: + crc-32: ^1.2.0 + crc32-stream: ^6.0.0 + is-stream: ^2.0.1 + normalize-path: ^3.0.0 + readable-stream: ^4.0.0 + checksum: 37d79a54f91344ecde352588e0a128f28ce619b085acd4f887defd76978a0640e3454a42c7dcadb0191bb3f971724ae4b1f9d6ef9620034aa0427382099ac946 + languageName: node + linkType: hard + "compressible@npm:~2.0.16": version: 2.0.18 resolution: "compressible@npm:2.0.18" @@ -23521,13 +22898,6 @@ __metadata: languageName: node linkType: hard -"connect-history-api-fallback@npm:^1.6.0": - version: 1.6.0 - resolution: "connect-history-api-fallback@npm:1.6.0" - checksum: 804ca2be28c999032ecd37a9f71405e5d7b7a4b3defcebbe41077bb8c5a0a150d7b59f51dcc33b2de30bc7e217a31d10f8cfad27e8e74c2fc7655eeba82d6e7e - languageName: node - linkType: hard - "connect-history-api-fallback@npm:^2.0.0": version: 2.0.0 resolution: "connect-history-api-fallback@npm:2.0.0" @@ -23557,7 +22927,7 @@ __metadata: languageName: node linkType: hard -"consola@npm:^2.15.0, consola@npm:^2.15.3": +"consola@npm:^2.15.0": version: 2.15.3 resolution: "consola@npm:2.15.3" checksum: 8ef7a09b703ec67ac5c389a372a33b6dc97eda6c9876443a60d76a3076eea0259e7f67a4e54fd5a52f97df73690822d090cf8b7e102b5761348afef7c6d03e28 @@ -23740,9 +23110,9 @@ __metadata: linkType: hard "core-js@npm:^3.6.5": - version: 3.37.1 - resolution: "core-js@npm:3.37.1" - checksum: 2d58a5c599f05c3e04abc8bc5e64b88eb17d914c0f552f670fb800afa74ec54b4fcc7f231ad6bd45badaf62c0fb0ce30e6fe89cedb6bb6d54e6f19115c3c17ff + version: 3.38.1 + resolution: "core-js@npm:3.38.1" + checksum: 55703c2f6fcd537e47a5cc83e9dc9884efef61861bbefb4a96a8c95e87956db980ce314628465dd49f14e626c5e633b9e3433f3e4a1f628404a14da420eb2556 languageName: node linkType: hard @@ -23796,7 +23166,7 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^8.1.0, cosmiconfig@npm:^8.2.0": +"cosmiconfig@npm:^8.2.0": version: 8.3.6 resolution: "cosmiconfig@npm:8.3.6" dependencies: @@ -23813,6 +23183,23 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:^9.0.0": + version: 9.0.0 + resolution: "cosmiconfig@npm:9.0.0" + dependencies: + env-paths: ^2.2.1 + import-fresh: ^3.3.0 + js-yaml: ^4.1.0 + parse-json: ^5.2.0 + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: a30c424b53d442ea0bdd24cb1b3d0d8687c8dda4a17ab6afcdc439f8964438801619cdb66e8e79f63b9caa3e6586b60d8bab9ce203e72df6c5e80179b971fe8f + languageName: node + linkType: hard + "cpu-features@npm:~0.0.9": version: 0.0.9 resolution: "cpu-features@npm:0.0.9" @@ -23836,16 +23223,6 @@ __metadata: languageName: node linkType: hard -"crc32-stream@npm:^4.0.1": - version: 4.0.1 - resolution: "crc32-stream@npm:4.0.1" - dependencies: - crc-32: ^1.2.0 - readable-stream: ^3.4.0 - checksum: 39c2e0d5d7a3388e85ccf27ef0b30475f98902d34e7a048decc1665ff67f98f17f850059b28942fdf5582cb836eaa5184453ec35a6ea2442ce3bc10c8f1ee8a4 - languageName: node - linkType: hard - "crc32-stream@npm:^5.0.0": version: 5.0.0 resolution: "crc32-stream@npm:5.0.0" @@ -23856,6 +23233,16 @@ __metadata: languageName: node linkType: hard +"crc32-stream@npm:^6.0.0": + version: 6.0.0 + resolution: "crc32-stream@npm:6.0.0" + dependencies: + crc-32: ^1.2.0 + readable-stream: ^4.0.0 + checksum: e6edc2f81bc387daef6d18b2ac18c2ffcb01b554d3b5c7d8d29b177505aafffba574658fdd23922767e8dab1183d1962026c98c17e17fb272794c33293ef607c + languageName: node + linkType: hard + "create-ecdh@npm:^4.0.0": version: 4.0.3 resolution: "create-ecdh@npm:4.0.3" @@ -23910,7 +23297,7 @@ __metadata: languageName: node linkType: hard -"create-require@npm:^1.1.0, create-require@npm:^1.1.1": +"create-require@npm:^1.1.0": version: 1.1.1 resolution: "create-require@npm:1.1.1" checksum: a9a1503d4390d8b59ad86f4607de7870b39cad43d929813599a23714831e81c520bddf61bcdd1f8e30f05fd3a2b71ae8538e946eb2786dc65c2bbc520f692eff @@ -23944,11 +23331,11 @@ __metadata: linkType: hard "cronstrue@npm:^2.2.0, cronstrue@npm:^2.32.0": - version: 2.49.0 - resolution: "cronstrue@npm:2.49.0" + version: 2.50.0 + resolution: "cronstrue@npm:2.50.0" bin: cronstrue: bin/cli.js - checksum: 8f45275b95d7f03c0762efe7318c373ceef1d45a34ac73ab1523bfc32359f383380268ab35e4592224284d3844df4002ffcb289d42057e91dfd8567284c73995 + checksum: bf6e51c4b9ab28d7ba928a392a76b7d97bd3c3dc8da5618db8424480dc6213cafed658ea835925675767fe5497931d1325e51634eeb8e2556f0630a62eb29cc3 languageName: node linkType: hard @@ -24128,7 +23515,7 @@ __metadata: languageName: node linkType: hard -"css-select@npm:^4.1.3, css-select@npm:^4.2.1": +"css-select@npm:^4.1.3": version: 4.3.0 resolution: "css-select@npm:4.3.0" dependencies: @@ -24595,7 +23982,19 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:4.3.4, debug@npm:^4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:~4.3.4": +"debug@npm:4, debug@npm:^4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:~4.3.6": + version: 4.3.6 + resolution: "debug@npm:4.3.6" + dependencies: + ms: 2.1.2 + peerDependenciesMeta: + supports-color: + optional: true + checksum: 1630b748dea3c581295e02137a9f5cbe2c1d85fea35c1e6597a65ca2b16a6fce68cec61b299d480787ef310ba927dc8c92d3061faba0ad06c6a724672f66be7f + languageName: node + linkType: hard + +"debug@npm:4.3.4": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -24694,6 +24093,32 @@ __metadata: languageName: node linkType: hard +"deep-equal@npm:^2.0.5": + version: 2.2.3 + resolution: "deep-equal@npm:2.2.3" + dependencies: + array-buffer-byte-length: ^1.0.0 + call-bind: ^1.0.5 + es-get-iterator: ^1.1.3 + get-intrinsic: ^1.2.2 + is-arguments: ^1.1.1 + is-array-buffer: ^3.0.2 + is-date-object: ^1.0.5 + is-regex: ^1.1.4 + is-shared-array-buffer: ^1.0.2 + isarray: ^2.0.5 + object-is: ^1.1.5 + object-keys: ^1.1.1 + object.assign: ^4.1.4 + regexp.prototype.flags: ^1.5.1 + side-channel: ^1.0.4 + which-boxed-primitive: ^1.0.2 + which-collection: ^1.0.1 + which-typed-array: ^1.1.13 + checksum: ee8852f23e4d20a5626c13b02f415ba443a1b30b4b3d39eaf366d59c4a85e6545d7ec917db44d476a85ae5a86064f7e5f7af7479f38f113995ba869f3a1ddc53 + languageName: node + linkType: hard + "deep-equal@npm:~1.0.1": version: 1.0.1 resolution: "deep-equal@npm:1.0.1" @@ -24739,15 +24164,6 @@ __metadata: languageName: node linkType: hard -"default-gateway@npm:^6.0.3": - version: 6.0.3 - resolution: "default-gateway@npm:6.0.3" - dependencies: - execa: ^5.0.0 - checksum: 126f8273ecac8ee9ff91ea778e8784f6cd732d77c3157e8c5bdd6ed03651b5291f71446d05bc02d04073b1e67583604db5394ea3cf992ede0088c70ea15b7378 - languageName: node - linkType: hard - "defaults@npm:^1.0.3": version: 1.0.3 resolution: "defaults@npm:1.0.3" @@ -25059,12 +24475,12 @@ __metadata: languageName: node linkType: hard -"docker-compose@npm:^0.24.6": - version: 0.24.7 - resolution: "docker-compose@npm:0.24.7" +"docker-compose@npm:^0.24.8": + version: 0.24.8 + resolution: "docker-compose@npm:0.24.8" dependencies: yaml: ^2.2.2 - checksum: 54daa1985fd7a57a1881dfdb7d294a189b9ba4e097de81127bfb4ff2f7727d249cc1514ee6a5a06c0085f9f6b5bcafe55b3e463f30b87c4d682bd8b0dac0450e + checksum: 48f3564c46490f1f51899a144deb546b61450a76bffddb378379ac7702aa34b055e0237e0dc77507df94d7ad6f1f7daeeac27730230bce9aafe2e35efeda6b45 languageName: node linkType: hard @@ -25194,13 +24610,6 @@ __metadata: languageName: node linkType: hard -"domain-browser@npm:^4.22.0": - version: 4.22.0 - resolution: "domain-browser@npm:4.22.0" - checksum: e7ce1c19073e17dec35cfde050a3ddaac437d3ba8b870adabf9d5682e665eab3084df05de432dedf25b34303f0a2c71ac30f1cdba61b1aea018047b10de3d988 - languageName: node - linkType: hard - "domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0, domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" @@ -25315,14 +24724,7 @@ __metadata: languageName: node linkType: hard -"dotenv-expand@npm:^8.0.2": - version: 8.0.3 - resolution: "dotenv-expand@npm:8.0.3" - checksum: 128ce90ac825b543de3ece0154a51b056ab0dc36bb26d97a68cd0b8707327ecd3c182fb6ac63b26a0fcdfa85064419906a1065cb634f1f9dc08ad311375f1fc0 - languageName: node - linkType: hard - -"dotenv@npm:^16.0.0, dotenv@npm:^16.0.3, dotenv@npm:^16.3.1": +"dotenv@npm:^16.0.3, dotenv@npm:^16.3.1": version: 16.4.5 resolution: "dotenv@npm:16.4.5" checksum: 301a12c3d44fd49888b74eb9ccf9f07a1f5df43f489e7fcb89647a2edcd84c42d6bc349dc8df099cd18f07c35c7b04685c1a4f3e6a6a9e6b30f8d48c15b7f49c @@ -25494,8 +24896,8 @@ __metadata: linkType: hard "elastic-builder@npm:^2.16.0": - version: 2.28.1 - resolution: "elastic-builder@npm:2.28.1" + version: 2.29.0 + resolution: "elastic-builder@npm:2.29.0" dependencies: lodash.has: ^4.5.2 lodash.hasin: ^4.5.2 @@ -25505,14 +24907,14 @@ __metadata: lodash.isobject: ^3.0.2 lodash.isstring: ^4.0.1 lodash.omit: ^4.5.0 - checksum: 5a3fb79441942825005e2bfa798c113809c3198b3cc711d3500894677eb212bb2bf100c5110bedafe354e154e035de1bbeebb7c593fb1aaacc58f98f0d8cd2bc + checksum: 9fe71c5e5f24d09f08d9bfd66afd8e0e3f212e8e54ca5906607a109ace293adaa2c820f626608532dff28fc211a2ee414faf29f397b87b86b6af33c57428de2e languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.796": - version: 1.4.801 - resolution: "electron-to-chromium@npm:1.4.801" - checksum: fe2a75afefc08a03b7f077782ef7ab0a755d5f10dfdac981a13910e9257ed149d8a81477c16a4b2e4396ec698f3ad98c339155772f69d2f8f7907b5ee4d57b07 +"electron-to-chromium@npm:^1.5.4": + version: 1.5.13 + resolution: "electron-to-chromium@npm:1.5.13" + checksum: f18ac84dd3bf9a200654a6a9292b9ec4bced0cf9bd26cec9941b775f4470c581c9d043e70b37a124d9752dcc0f47fc96613d52b2defd8e59632852730cb418b9 languageName: node linkType: hard @@ -25598,13 +25000,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.16.0": - version: 5.16.0 - resolution: "enhanced-resolve@npm:5.16.0" +"enhanced-resolve@npm:^5.17.1": + version: 5.17.1 + resolution: "enhanced-resolve@npm:5.17.1" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: ccfd01850ecf2aa51e8554d539973319ff7d8a539ef1e0ba3460a0ccad6223c4ef6e19165ee64161b459cd8a48df10f52af4434c60023c65fde6afa32d475f7e + checksum: 4bc38cf1cea96456f97503db7280394177d1bc46f8f87c267297d04f795ac5efa81e48115a2f5b6273c781027b5b6bfc5f62b54df629e4d25fa7001a86624f59 languageName: node linkType: hard @@ -25646,6 +25048,13 @@ __metadata: languageName: node linkType: hard +"environment@npm:^1.0.0": + version: 1.1.0 + resolution: "environment@npm:1.1.0" + checksum: dd3c1b9825e7f71f1e72b03c2344799ac73f2e9ef81b78ea8b373e55db021786c6b9f3858ea43a436a2c4611052670ec0afe85bc029c384cc71165feee2f4ba6 + languageName: node + linkType: hard + "err-code@npm:^2.0.2": version: 2.0.3 resolution: "err-code@npm:2.0.3" @@ -25685,7 +25094,7 @@ __metadata: languageName: node linkType: hard -"es-abstract@npm:^1.20.4, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3": +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.20.4, es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3": version: 1.23.3 resolution: "es-abstract@npm:1.23.3" dependencies: @@ -25770,7 +25179,24 @@ __metadata: languageName: node linkType: hard -"es-iterator-helpers@npm:^1.0.15, es-iterator-helpers@npm:^1.0.19": +"es-get-iterator@npm:^1.1.3": + version: 1.1.3 + resolution: "es-get-iterator@npm:1.1.3" + dependencies: + call-bind: ^1.0.2 + get-intrinsic: ^1.1.3 + has-symbols: ^1.0.3 + is-arguments: ^1.1.1 + is-map: ^2.0.2 + is-set: ^2.0.2 + is-string: ^1.0.7 + isarray: ^2.0.5 + stop-iteration-iterator: ^1.0.0 + checksum: 8fa118da42667a01a7c7529f8a8cca514feeff243feec1ce0bb73baaa3514560bd09d2b3438873cf8a5aaec5d52da248131de153b28e2638a061b6e4df13267d + languageName: node + linkType: hard + +"es-iterator-helpers@npm:^1.0.19": version: 1.0.19 resolution: "es-iterator-helpers@npm:1.0.19" dependencies: @@ -25869,13 +25295,6 @@ __metadata: languageName: node linkType: hard -"es6-object-assign@npm:^1.1.0": - version: 1.1.0 - resolution: "es6-object-assign@npm:1.1.0" - checksum: 8d4fdf63484d78b5c64cacc2c2e1165bc7b6a64b739d2a9db6a4dc8641d99cc9efb433cdd4dc3d3d6b00bfa6ce959694e4665e3255190339945c5f33b692b5d8 - languageName: node - linkType: hard - "es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": version: 3.1.3 resolution: "es6-symbol@npm:3.1.3" @@ -25899,173 +25318,16 @@ __metadata: linkType: hard "esbuild-loader@npm:^4.0.0": - version: 4.1.0 - resolution: "esbuild-loader@npm:4.1.0" + version: 4.2.2 + resolution: "esbuild-loader@npm:4.2.2" dependencies: - esbuild: ^0.20.0 + esbuild: ^0.21.0 get-tsconfig: ^4.7.0 loader-utils: ^2.0.4 webpack-sources: ^1.4.3 peerDependencies: webpack: ^4.40.0 || ^5.0.0 - checksum: 51e76c36dd1fb70545889b07e3c4b4a437aaf1a2acc836e83141f06bcb8fbf96af778cf21b37355ea724c30504ad288ba76b0554ff94af260bb12ece647de861 - languageName: node - linkType: hard - -"esbuild@npm:^0.18.10": - version: 0.18.20 - resolution: "esbuild@npm:0.18.20" - dependencies: - "@esbuild/android-arm": 0.18.20 - "@esbuild/android-arm64": 0.18.20 - "@esbuild/android-x64": 0.18.20 - "@esbuild/darwin-arm64": 0.18.20 - "@esbuild/darwin-x64": 0.18.20 - "@esbuild/freebsd-arm64": 0.18.20 - "@esbuild/freebsd-x64": 0.18.20 - "@esbuild/linux-arm": 0.18.20 - "@esbuild/linux-arm64": 0.18.20 - "@esbuild/linux-ia32": 0.18.20 - "@esbuild/linux-loong64": 0.18.20 - "@esbuild/linux-mips64el": 0.18.20 - "@esbuild/linux-ppc64": 0.18.20 - "@esbuild/linux-riscv64": 0.18.20 - "@esbuild/linux-s390x": 0.18.20 - "@esbuild/linux-x64": 0.18.20 - "@esbuild/netbsd-x64": 0.18.20 - "@esbuild/openbsd-x64": 0.18.20 - "@esbuild/sunos-x64": 0.18.20 - "@esbuild/win32-arm64": 0.18.20 - "@esbuild/win32-ia32": 0.18.20 - "@esbuild/win32-x64": 0.18.20 - dependenciesMeta: - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 5d253614e50cdb6ec22095afd0c414f15688e7278a7eb4f3720a6dd1306b0909cf431e7b9437a90d065a31b1c57be60130f63fe3e8d0083b588571f31ee6ec7b - languageName: node - linkType: hard - -"esbuild@npm:^0.20.0": - version: 0.20.2 - resolution: "esbuild@npm:0.20.2" - dependencies: - "@esbuild/aix-ppc64": 0.20.2 - "@esbuild/android-arm": 0.20.2 - "@esbuild/android-arm64": 0.20.2 - "@esbuild/android-x64": 0.20.2 - "@esbuild/darwin-arm64": 0.20.2 - "@esbuild/darwin-x64": 0.20.2 - "@esbuild/freebsd-arm64": 0.20.2 - "@esbuild/freebsd-x64": 0.20.2 - "@esbuild/linux-arm": 0.20.2 - "@esbuild/linux-arm64": 0.20.2 - "@esbuild/linux-ia32": 0.20.2 - "@esbuild/linux-loong64": 0.20.2 - "@esbuild/linux-mips64el": 0.20.2 - "@esbuild/linux-ppc64": 0.20.2 - "@esbuild/linux-riscv64": 0.20.2 - "@esbuild/linux-s390x": 0.20.2 - "@esbuild/linux-x64": 0.20.2 - "@esbuild/netbsd-x64": 0.20.2 - "@esbuild/openbsd-x64": 0.20.2 - "@esbuild/sunos-x64": 0.20.2 - "@esbuild/win32-arm64": 0.20.2 - "@esbuild/win32-ia32": 0.20.2 - "@esbuild/win32-x64": 0.20.2 - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: bc88050fc1ca5c1bd03648f9979e514bdefb956a63aa3974373bb7b9cbac0b3aac9b9da1b5bdca0b3490e39d6b451c72815dbd6b7d7f978c91fbe9c9e9aa4e4c + checksum: 793d2482693c1c66298f63d7fdb62f2f3e314b006ade1dc3c46b46ade39777c5fba5930c2fa2752636c511997faa08d4a0f5d5b8a734b9046b3626aa6d5ab8e3 languageName: node linkType: hard @@ -26149,6 +25411,89 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.23.0": + version: 0.23.1 + resolution: "esbuild@npm:0.23.1" + dependencies: + "@esbuild/aix-ppc64": 0.23.1 + "@esbuild/android-arm": 0.23.1 + "@esbuild/android-arm64": 0.23.1 + "@esbuild/android-x64": 0.23.1 + "@esbuild/darwin-arm64": 0.23.1 + "@esbuild/darwin-x64": 0.23.1 + "@esbuild/freebsd-arm64": 0.23.1 + "@esbuild/freebsd-x64": 0.23.1 + "@esbuild/linux-arm": 0.23.1 + "@esbuild/linux-arm64": 0.23.1 + "@esbuild/linux-ia32": 0.23.1 + "@esbuild/linux-loong64": 0.23.1 + "@esbuild/linux-mips64el": 0.23.1 + "@esbuild/linux-ppc64": 0.23.1 + "@esbuild/linux-riscv64": 0.23.1 + "@esbuild/linux-s390x": 0.23.1 + "@esbuild/linux-x64": 0.23.1 + "@esbuild/netbsd-x64": 0.23.1 + "@esbuild/openbsd-arm64": 0.23.1 + "@esbuild/openbsd-x64": 0.23.1 + "@esbuild/sunos-x64": 0.23.1 + "@esbuild/win32-arm64": 0.23.1 + "@esbuild/win32-ia32": 0.23.1 + "@esbuild/win32-x64": 0.23.1 + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 0413c3b9257327fb598427688b7186ea335bf1693746fe5713cc93c95854d6388b8ed4ad643fddf5b5ace093f7dcd9038dd58e087bf2da1f04dfb4c5571660af + languageName: node + linkType: hard + "esbuild@npm:esbuild-wasm@^0.15.15": version: 0.15.18 resolution: "esbuild-wasm@npm:0.15.18" @@ -26279,15 +25624,15 @@ __metadata: languageName: node linkType: hard -"eslint-module-utils@npm:^2.8.0": - version: 2.8.0 - resolution: "eslint-module-utils@npm:2.8.0" +"eslint-module-utils@npm:^2.9.0": + version: 2.9.0 + resolution: "eslint-module-utils@npm:2.9.0" dependencies: debug: ^3.2.7 peerDependenciesMeta: eslint: optional: true - checksum: 74c6dfea7641ebcfe174be61168541a11a14aa8d72e515f5f09af55cd0d0862686104b0524aa4b8e0ce66418a44aa38a94d2588743db5fd07a6b49ffd16921d2 + checksum: 304ec1279cac62b242d9347859625235c07be8b8870306d85502375b2b4beeccda2da2f03884ec00a1820e643d87718e5a2eea149730c61aeb42ea8f4cb9f4a6 languageName: node linkType: hard @@ -26306,29 +25651,30 @@ __metadata: linkType: hard "eslint-plugin-import@npm:^2.25.4": - version: 2.29.1 - resolution: "eslint-plugin-import@npm:2.29.1" + version: 2.30.0 + resolution: "eslint-plugin-import@npm:2.30.0" dependencies: - array-includes: ^3.1.7 - array.prototype.findlastindex: ^1.2.3 + "@rtsao/scc": ^1.1.0 + array-includes: ^3.1.8 + array.prototype.findlastindex: ^1.2.5 array.prototype.flat: ^1.3.2 array.prototype.flatmap: ^1.3.2 debug: ^3.2.7 doctrine: ^2.1.0 eslint-import-resolver-node: ^0.3.9 - eslint-module-utils: ^2.8.0 - hasown: ^2.0.0 - is-core-module: ^2.13.1 + eslint-module-utils: ^2.9.0 + hasown: ^2.0.2 + is-core-module: ^2.15.1 is-glob: ^4.0.3 minimatch: ^3.1.2 - object.fromentries: ^2.0.7 - object.groupby: ^1.0.1 - object.values: ^1.1.7 + object.fromentries: ^2.0.8 + object.groupby: ^1.0.3 + object.values: ^1.2.0 semver: ^6.3.1 tsconfig-paths: ^3.15.0 peerDependencies: eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - checksum: e65159aef808136d26d029b71c8c6e4cb5c628e65e5de77f1eb4c13a379315ae55c9c3afa847f43f4ff9df7e54515c77ffc6489c6a6f81f7dd7359267577468c + checksum: 0ec1ad69c0d22f15bc4a49ee97ae757e4adfc3181996f2c4a1ed4d5028bd99bab38e7623e58ef4477ba1db8425f441e4e986367125273efa4c5f7ad2c4467a9a languageName: node linkType: hard @@ -26351,28 +25697,28 @@ __metadata: linkType: hard "eslint-plugin-jsx-a11y@npm:^6.5.1": - version: 6.8.0 - resolution: "eslint-plugin-jsx-a11y@npm:6.8.0" + version: 6.10.0 + resolution: "eslint-plugin-jsx-a11y@npm:6.10.0" dependencies: - "@babel/runtime": ^7.23.2 - aria-query: ^5.3.0 - array-includes: ^3.1.7 + aria-query: ~5.1.3 + array-includes: ^3.1.8 array.prototype.flatmap: ^1.3.2 ast-types-flow: ^0.0.8 - axe-core: =4.7.0 - axobject-query: ^3.2.1 + axe-core: ^4.10.0 + axobject-query: ^4.1.0 damerau-levenshtein: ^1.0.8 emoji-regex: ^9.2.2 - es-iterator-helpers: ^1.0.15 - hasown: ^2.0.0 + es-iterator-helpers: ^1.0.19 + hasown: ^2.0.2 jsx-ast-utils: ^3.3.5 language-tags: ^1.0.9 minimatch: ^3.1.2 - object.entries: ^1.1.7 - object.fromentries: ^2.0.7 + object.fromentries: ^2.0.8 + safe-regex-test: ^1.0.3 + string.prototype.includes: ^2.0.0 peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 3dec00e2a3089c4c61ac062e4196a70985fb7eda1fd67fe035363d92578debde92fdb8ed2e472321fc0d71e75f4a1e8888c6a3218c14dd93c8e8d19eb6f51554 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + checksum: 1009deca12ddbe3624586bc5fc3534ca98d00a5841a2563cb6abd9339b984f0a99075dc2a703a517f4087eb84d659c87e60beda17645883de2ba1d86f2b20c96 languageName: node linkType: hard @@ -26399,47 +25745,47 @@ __metadata: linkType: hard "eslint-plugin-react@npm:^7.28.0": - version: 7.34.3 - resolution: "eslint-plugin-react@npm:7.34.3" + version: 7.35.2 + resolution: "eslint-plugin-react@npm:7.35.2" dependencies: array-includes: ^3.1.8 array.prototype.findlast: ^1.2.5 array.prototype.flatmap: ^1.3.2 - array.prototype.toreversed: ^1.1.2 array.prototype.tosorted: ^1.1.4 doctrine: ^2.1.0 es-iterator-helpers: ^1.0.19 estraverse: ^5.3.0 + hasown: ^2.0.2 jsx-ast-utils: ^2.4.1 || ^3.0.0 minimatch: ^3.1.2 object.entries: ^1.1.8 object.fromentries: ^2.0.8 - object.hasown: ^1.1.4 object.values: ^1.2.0 prop-types: ^15.8.1 resolve: ^2.0.0-next.5 semver: ^6.3.1 string.prototype.matchall: ^4.0.11 + string.prototype.repeat: ^1.0.0 peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: 1a519b9792ab9392a5157f2543ce98ab1218c62f4a31c4c3ceb5dd3e7997def4aa07ab39f7276af0fe116ef002db29d97216a15b7aa3b200e55b641cf77d6292 + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + checksum: 88dfb91d52a10fa0333199fa4abaa8d1112066d8fdc5df88c136d1cc24145b8d92bb7292f82a3781aef9c3ec91990b4461dbd1fa5eee471df5517014c6e843f9 languageName: node linkType: hard "eslint-plugin-testing-library@npm:^6.0.0": - version: 6.2.2 - resolution: "eslint-plugin-testing-library@npm:6.2.2" + version: 6.3.0 + resolution: "eslint-plugin-testing-library@npm:6.3.0" dependencies: "@typescript-eslint/utils": ^5.58.0 peerDependencies: eslint: ^7.5.0 || ^8.0.0 - checksum: df55ca98415bad3e7d6b21adcd0f817d7c6df59cb32099528e45b39e8d7edf95e040334106fc7574fd402ed624ca65215ccf37745e1da1a9c90cfe00b99c5be4 + checksum: 4813b3d90d449ebbce8c53389ca356aa63a122c897eea6580fd3e87ee4bcea7e3b56b9822c0e65d78c2cc6490cb0eb3d3b27ca5445e5de60181469718a70f645 languageName: node linkType: hard "eslint-plugin-unused-imports@npm:^3.0.0": - version: 3.1.0 - resolution: "eslint-plugin-unused-imports@npm:3.1.0" + version: 3.2.0 + resolution: "eslint-plugin-unused-imports@npm:3.2.0" dependencies: eslint-rule-composer: ^0.3.0 peerDependencies: @@ -26448,7 +25794,7 @@ __metadata: peerDependenciesMeta: "@typescript-eslint/eslint-plugin": optional: true - checksum: c41da339ea8faf40b8b4081f0d52a4c75d24f121c5b95b19b777d12abfbc23505e4aab2422918b2517dd239a749a38912fb3405b42a9aa6b50c32cf5f3d6ecf0 + checksum: e85ae4f3af489294ef5e0969ab904fa87f9fa7c959ca0804f30845438db4aeb0428ddad7ab06a70608e93121626799977241b442fdf126a4d0667be57390c3d6 languageName: node linkType: hard @@ -26487,18 +25833,18 @@ __metadata: linkType: hard "eslint-webpack-plugin@npm:^4.0.0": - version: 4.1.0 - resolution: "eslint-webpack-plugin@npm:4.1.0" + version: 4.2.0 + resolution: "eslint-webpack-plugin@npm:4.2.0" dependencies: - "@types/eslint": ^8.56.5 + "@types/eslint": ^8.56.10 jest-worker: ^29.7.0 micromatch: ^4.0.5 normalize-path: ^3.0.0 schema-utils: ^4.2.0 peerDependencies: - eslint: ^8.0.0 + eslint: ^8.0.0 || ^9.0.0 webpack: ^5.0.0 - checksum: 1676ff08b0424e4656aa638a0c2a7b2f3f6a504651689a2d86b237c9a52ad65e17aeb5abbe13663e25353d8a706dcf45f49dbe4795dad27b6b0650db8aa21b16 + checksum: 51538d60d0d0f3dd5774a4291af4620884a45a40270e2878c2f7c8dbff3584ef8588ffded8de696a4bbcee45bee219eba442eb503f5eddcc79aefeb4845985ae languageName: node linkType: hard @@ -26729,9 +26075,11 @@ __metadata: "@backstage/core-components": "workspace:^" "@backstage/core-plugin-api": "workspace:^" "@backstage/frontend-app-api": "workspace:^" + "@backstage/frontend-defaults": "workspace:^" "@backstage/frontend-plugin-api": "workspace:^" "@backstage/integration-react": "workspace:^" "@backstage/plugin-api-docs": "workspace:^" + "@backstage/plugin-app": "workspace:^" "@backstage/plugin-app-visualizer": "workspace:^" "@backstage/plugin-auth-react": "workspace:^" "@backstage/plugin-catalog": "workspace:^" @@ -26770,7 +26118,6 @@ __metadata: "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 - "@vitejs/plugin-react": ^4.0.4 cross-env: ^7.0.0 history: ^5.0.0 react: ^18.0.2 @@ -26778,13 +26125,16 @@ __metadata: react-router: ^6.3.0 react-router-dom: ^6.3.0 react-use: ^17.2.4 - vite: ^4.4.9 - vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.22.0 zen-observable: ^0.10.0 languageName: unknown linkType: soft +"example-app@link:../app::locator=example-backend%40workspace%3Apackages%2Fbackend": + version: 0.0.0-use.local + resolution: "example-app@link:../app::locator=example-backend%40workspace%3Apackages%2Fbackend" + languageName: node + linkType: soft + "example-app@link:../app::locator=example-backend-legacy%40workspace%3Apackages%2Fbackend-legacy": version: 0.0.0-use.local resolution: "example-app@link:../app::locator=example-backend-legacy%40workspace%3Apackages%2Fbackend-legacy" @@ -26844,7 +26194,6 @@ __metadata: "@types/react": "*" "@types/react-dom": "*" "@types/zen-observable": ^0.8.0 - "@vitejs/plugin-react": ^4.0.4 cross-env: ^7.0.0 history: ^5.0.0 react: ^18.0.2 @@ -26852,9 +26201,6 @@ __metadata: react-router: ^6.3.0 react-router-dom: ^6.3.0 react-use: ^17.2.4 - vite: ^4.4.9 - vite-plugin-html: ^3.2.0 - vite-plugin-node-polyfills: ^0.22.0 zen-observable: ^0.10.0 languageName: unknown linkType: soft @@ -26957,9 +26303,10 @@ __metadata: "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-signals-backend": "workspace:^" "@backstage/plugin-techdocs-backend": "workspace:^" - "@opentelemetry/auto-instrumentations-node": ^0.43.0 - "@opentelemetry/exporter-prometheus": ^0.50.0 - "@opentelemetry/sdk-node": ^0.50.0 + "@opentelemetry/auto-instrumentations-node": ^0.50.0 + "@opentelemetry/exporter-prometheus": ^0.53.0 + "@opentelemetry/sdk-node": ^0.53.0 + example-app: "link:../app" languageName: unknown linkType: soft @@ -27079,12 +26426,12 @@ __metadata: linkType: hard "express-openapi-validator@npm:^5.0.4": - version: 5.1.6 - resolution: "express-openapi-validator@npm:5.1.6" + version: 5.3.4 + resolution: "express-openapi-validator@npm:5.3.4" dependencies: - "@apidevtools/json-schema-ref-parser": ^9.1.2 - "@types/multer": ^1.4.7 - ajv: ^8.11.2 + "@apidevtools/json-schema-ref-parser": ^11.7.0 + "@types/multer": ^1.4.11 + ajv: ^8.17.1 ajv-draft-04: ^1.0.0 ajv-formats: ^2.1.1 content-type: ^1.0.5 @@ -27094,8 +26441,10 @@ __metadata: media-typer: ^1.1.0 multer: ^1.4.5-lts.1 ono: ^7.1.3 - path-to-regexp: ^6.2.0 - checksum: 46be5236101e51593d1365505879d380a40d0307be8173cdaa3b643def518fcca25944f2e0eb5b2c48a7a09eacb192e5287b3a995b1903275dbca0e59fa669e3 + path-to-regexp: ^6.2.2 + peerDependencies: + express: "*" + checksum: 0c699e8f12d499d759e11c08009cc479d8748bb1adf9e31b72e7f1c0d56d6c6c2333e72124517724cb1d6c7bd428a1a6dfe241b15fbe16f513f373222baf2d77 languageName: node linkType: hard @@ -27146,7 +26495,7 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.14.0, express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1, express@npm:^4.18.2, express@npm:^4.19.2": +"express@npm:^4.14.0, express@npm:^4.17.1, express@npm:^4.18.1, express@npm:^4.18.2, express@npm:^4.19.2": version: 4.19.2 resolution: "express@npm:4.19.2" dependencies: @@ -27309,13 +26658,6 @@ __metadata: languageName: node linkType: hard -"fast-loops@npm:^1.1.3": - version: 1.1.4 - resolution: "fast-loops@npm:1.1.4" - checksum: 8031a20f465ef35ac4ad98258470250636112d34f7e4efcb4ef21f3ced99df95a1ef1f0d6943df729a1e3e12a9df9319f3019df8cc1a0e0ed5a118bd72e505f9 - languageName: node - linkType: hard - "fast-memoize@npm:^2.5.2": version: 2.5.2 resolution: "fast-memoize@npm:2.5.2" @@ -27353,6 +26695,13 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.0.1 + resolution: "fast-uri@npm:3.0.1" + checksum: 106143ff83705995225dcc559411288f3337e732bb2e264e79788f1914b6bd8f8bc3683102de60b15ba00e6ebb443633cabac77d4ebc5cb228c47cf955e199ff + languageName: node + linkType: hard + "fast-url-parser@npm:1.1.3, fast-url-parser@npm:^1.1.3": version: 1.1.3 resolution: "fast-url-parser@npm:1.1.3" @@ -27362,7 +26711,7 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:4.4.1, fast-xml-parser@npm:^4.3.0, fast-xml-parser@npm:^4.3.2": +"fast-xml-parser@npm:4.4.1, fast-xml-parser@npm:^4.3.2, fast-xml-parser@npm:^4.4.1": version: 4.4.1 resolution: "fast-xml-parser@npm:4.4.1" dependencies: @@ -27380,7 +26729,7 @@ __metadata: languageName: node linkType: hard -"fastq@npm:^1.15.0, fastq@npm:^1.6.0": +"fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" dependencies: @@ -27953,7 +27302,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:10.1.0, fs-extra@npm:^10.0.0, fs-extra@npm:^10.0.1": +"fs-extra@npm:10.1.0, fs-extra@npm:^10.0.0": version: 10.1.0 resolution: "fs-extra@npm:10.1.0" dependencies: @@ -28207,7 +27556,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": +"get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": version: 1.2.4 resolution: "get-intrinsic@npm:1.2.4" dependencies: @@ -28409,18 +27758,19 @@ __metadata: languageName: node linkType: hard -"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7": - version: 10.3.10 - resolution: "glob@npm:10.3.10" +"glob@npm:^10.0.0, glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.4.5 + resolution: "glob@npm:10.4.5" dependencies: foreground-child: ^3.1.0 - jackspeak: ^2.3.5 - minimatch: ^9.0.1 - minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 - path-scurry: ^1.10.1 + jackspeak: ^3.1.2 + minimatch: ^9.0.4 + minipass: ^7.1.2 + package-json-from-dist: ^1.0.0 + path-scurry: ^1.11.1 bin: glob: dist/esm/bin.mjs - checksum: 4f2fe2511e157b5a3f525a54092169a5f92405f24d2aed3142f4411df328baca13059f4182f1db1bf933e2c69c0bd89e57ae87edd8950cba8c7ccbe84f721cf3 + checksum: 0bc725de5e4862f9f387fd0f2b274baf16850dcd2714502ccf471ee401803997983e2c05590cb65f9675a3c6f2a58e7a53f9e365704108c6ad3cbf1d60934c4a languageName: node linkType: hard @@ -28580,8 +27930,8 @@ __metadata: linkType: hard "google-auth-library@npm:^9.0.0, google-auth-library@npm:^9.3.0, google-auth-library@npm:^9.6.3": - version: 9.11.0 - resolution: "google-auth-library@npm:9.11.0" + version: 9.14.1 + resolution: "google-auth-library@npm:9.14.1" dependencies: base64-js: ^1.3.0 ecdsa-sig-formatter: ^1.0.11 @@ -28589,7 +27939,7 @@ __metadata: gcp-metadata: ^6.1.0 gtoken: ^7.0.0 jws: ^4.0.0 - checksum: 984d344b5e0a21ea1e097d06e27173035619c0e8f89a363e538b445adb1414b79e938b56b4432aa36fda074c5922fa6a34f9b64734765c01dff73c45c8568554 + checksum: 98c7ffb6ef8d811a54d728a94c31aa60c777f035306f0ded70654ce0aa1f4dcf393bb505b262aa48438f5ead8941248f3759f24f0e22b4465b8537b1d90415ac languageName: node linkType: hard @@ -28667,7 +28017,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 @@ -28714,8 +28064,8 @@ __metadata: linkType: hard "graphql-config@npm:^5.0.2": - version: 5.0.3 - resolution: "graphql-config@npm:5.0.3" + version: 5.1.2 + resolution: "graphql-config@npm:5.1.2" dependencies: "@graphql-tools/graphql-file-loader": ^8.0.0 "@graphql-tools/json-file-loader": ^8.0.0 @@ -28723,9 +28073,9 @@ __metadata: "@graphql-tools/merge": ^9.0.0 "@graphql-tools/url-loader": ^8.0.0 "@graphql-tools/utils": ^10.0.0 - cosmiconfig: ^8.1.0 + cosmiconfig: ^9.0.0 jiti: ^1.18.2 - minimatch: ^4.2.3 + minimatch: ^9.0.5 string-env-interpolation: ^1.0.1 tslib: ^2.4.0 peerDependencies: @@ -28734,7 +28084,7 @@ __metadata: peerDependenciesMeta: cosmiconfig-toml-loader: optional: true - checksum: 3d079d48ccc624d16bee58d15802267d65e856f4d1ba278ededb3ac66a565d4f205cd60ac1f19ed8159bfa2d944c453ae58512c6513a8004754bea9964924485 + checksum: 48e17fff9e31a5037a42e9edb79251fe91e49338125ac3141ec80886832e0669112f547b2b67db9412d31fcc4cdac4548180f45550dc2ed2bc94c54bcb01053a languageName: node linkType: hard @@ -28794,16 +28144,16 @@ __metadata: linkType: hard "graphql@npm:^14.0.2 || ^15.5": - version: 15.8.0 - resolution: "graphql@npm:15.8.0" - checksum: 423325271db8858428641b9aca01699283d1fe5b40ef6d4ac622569ecca927019fce8196208b91dd1d8eb8114f00263fe661d241d0eb40c10e5bfd650f86ec5e + version: 15.9.0 + resolution: "graphql@npm:15.9.0" + checksum: fecf48b878baf8bd1d943b79860554f9e0bdf8d23a8f014356209fedcc1f1353729388538842d8a4a79078ea75b3f24d504d074223c815acf9b6059837c5c934 languageName: node linkType: hard "graphql@npm:^16.0.0, graphql@npm:^16.8.1": - version: 16.8.1 - resolution: "graphql@npm:16.8.1" - checksum: 8d304b7b6f708c8c5cc164b06e92467dfe36aff6d4f2cf31dd19c4c2905a0e7b89edac4b7e225871131fd24e21460836b369de0c06532644d15b461d55b1ccc0 + version: 16.9.0 + resolution: "graphql@npm:16.9.0" + checksum: 8cb3d54100e9227310383ce7f791ca48d12f15ed9f2021f23f8735f1121aafe4e5e611a853081dd935ce221724ea1ae4638faef5d2921fb1ad7c26b5f46611e9 languageName: node linkType: hard @@ -28927,13 +28277,6 @@ __metadata: languageName: node linkType: hard -"has-own-property@npm:^0.1.0": - version: 0.1.0 - resolution: "has-own-property@npm:0.1.0" - checksum: 4754f42e8a54860ea1a397c231843937ba890f3aa556698c9a2160df5f9b1a02ddb321ef0528294aec3aaa3139d17744da048027aa7129a631cb6554b6faed6f - languageName: node - linkType: hard - "has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": version: 1.0.2 resolution: "has-property-descriptors@npm:1.0.2" @@ -29199,7 +28542,7 @@ __metadata: languageName: node linkType: hard -"html-minifier-terser@npm:^6.0.2, html-minifier-terser@npm:^6.1.0": +"html-minifier-terser@npm:^6.0.2": version: 6.1.0 resolution: "html-minifier-terser@npm:6.1.0" dependencies: @@ -29507,11 +28850,11 @@ __metadata: linkType: hard "husky@npm:^9.0.0": - version: 9.0.11 - resolution: "husky@npm:9.0.11" + version: 9.1.5 + resolution: "husky@npm:9.1.5" bin: - husky: bin.mjs - checksum: 1aebc3334dc7ac6288ff5e1fb72cfb447cfa474e72cf7ba692e8c5698c573ab725c28c6a5088c9f8e6aca5f47d40fa7261beffbc07a4d307ca21656dc4571f07 + husky: bin.js + checksum: c240018e852666dc12a93ca84751f1440bdf436468ba872c7b7b3cee54f5f1d7b4222a117988b27ca437093efdeb128778897ab0e409361336676a2c3012c8a7 languageName: node linkType: hard @@ -29565,13 +28908,6 @@ __metadata: languageName: node linkType: hard -"identity-function@npm:^1.0.0": - version: 1.0.0 - resolution: "identity-function@npm:1.0.0" - checksum: 0ec311050c69679334b12479f53226f67ca41bc3ba7283ede3dacfb80802ec07643868d16b274ab823ceb2e81291697f01b07e32c7796f92255bd81452b7ea15 - languageName: node - linkType: hard - "identity-obj-proxy@npm:3.0.0": version: 3.0.0 resolution: "identity-obj-proxy@npm:3.0.0" @@ -29669,15 +29005,15 @@ __metadata: languageName: node linkType: hard -"import-in-the-middle@npm:1.7.1": - version: 1.7.1 - resolution: "import-in-the-middle@npm:1.7.1" +"import-in-the-middle@npm:^1.8.1": + version: 1.11.0 + resolution: "import-in-the-middle@npm:1.11.0" dependencies: acorn: ^8.8.2 - acorn-import-assertions: ^1.9.0 + acorn-import-attributes: ^1.9.5 cjs-module-lexer: ^1.2.2 module-details-from-path: ^1.0.3 - checksum: 37cc8c75fb7eac60611bafafea7fc60f794d0931fdabcec516c8a26effe69e914b1f7e8116e98549c6fdd1fe88dcaebfdebf35d7f52c761b48b312e40f3bf323 + checksum: 7e7c47e363be9579a4269e1df803be29cd3feb1df2c490b7cdef7c3a7c20f1f5cfa62d7f8de934b73e5c0e98ff07e1f0147b9fc11789a0f160d2893ddcc035ab languageName: node linkType: hard @@ -29837,13 +29173,12 @@ __metadata: languageName: node linkType: hard -"inline-style-prefixer@npm:^7.0.0": - version: 7.0.0 - resolution: "inline-style-prefixer@npm:7.0.0" +"inline-style-prefixer@npm:^7.0.1": + version: 7.0.1 + resolution: "inline-style-prefixer@npm:7.0.1" dependencies: css-in-js-utils: ^3.1.0 - fast-loops: ^1.1.3 - checksum: 89fd73eb06e7392e24032ea33b8b33ae7f9a24298f2d9ebbf7b31a3a3934247270047f4f49a454a363aace14e25c3a20fd97465405b0399cc888e5a2bc04ec05 + checksum: 07a72573dfdac5e08fa18f5ce71d922861716955e230175ac415db227d9ed49443c764356cb407a92f4c85b30ebf39604165260b4dfbf3196b7736d7332c5c06 languageName: node linkType: hard @@ -29870,7 +29205,7 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.7": +"internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.7": version: 1.0.7 resolution: "internal-slot@npm:1.0.7" dependencies: @@ -29931,6 +29266,13 @@ __metadata: languageName: node linkType: hard +"ip-regex@npm:^4.1.0": + version: 4.3.0 + resolution: "ip-regex@npm:4.3.0" + checksum: 7ff904b891221b1847f3fdf3dbb3e6a8660dc39bc283f79eb7ed88f5338e1a3d1104b779bc83759159be266249c59c2160e779ee39446d79d4ed0890dfd06f08 + languageName: node + linkType: hard + "ip@npm:^1.1.8": version: 1.1.9 resolution: "ip@npm:1.1.9" @@ -30009,7 +29351,7 @@ __metadata: languageName: node linkType: hard -"is-arguments@npm:^1.0.4": +"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1": version: 1.1.1 resolution: "is-arguments@npm:1.1.1" dependencies: @@ -30019,7 +29361,7 @@ __metadata: languageName: node linkType: hard -"is-array-buffer@npm:^3.0.4": +"is-array-buffer@npm:^3.0.2, is-array-buffer@npm:^3.0.4": version: 3.0.4 resolution: "is-array-buffer@npm:3.0.4" dependencies: @@ -30121,12 +29463,21 @@ __metadata: languageName: node linkType: hard -"is-core-module@npm:^2.1.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1": - version: 2.13.1 - resolution: "is-core-module@npm:2.13.1" +"is-cidr@npm:^4.0.0": + version: 4.0.2 + resolution: "is-cidr@npm:4.0.2" dependencies: - hasown: ^2.0.0 - checksum: 256559ee8a9488af90e4bad16f5583c6d59e92f0742e9e8bb4331e758521ee86b810b93bae44f390766ffbc518a0488b18d9dab7da9a5ff997d499efc9403f7c + cidr-regex: ^3.1.1 + checksum: ee6e670e655a835710a7fa15268b428adbf80267114a494ce1c2ca2b09e1ca0b629fe1375aae621d4c093b32930d5ff7c4ee6da97eae14e3836bc7b3a07b171f + languageName: node + linkType: hard + +"is-core-module@npm:^2.1.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.15.1": + version: 2.15.1 + resolution: "is-core-module@npm:2.15.1" + dependencies: + hasown: ^2.0.2 + checksum: df134c168115690724b62018c37b2f5bba0d5745fa16960b329c5a00883a8bea6a5632fdb1e3efcce237c201826ba09f93197b7cd95577ea56b0df335be23633 languageName: node linkType: hard @@ -30303,13 +29654,6 @@ __metadata: languageName: node linkType: hard -"is-iterable@npm:^1.1.0": - version: 1.1.1 - resolution: "is-iterable@npm:1.1.1" - checksum: d059aaf00899cf351cdf4d71ea6b4e8912107c47b31b554d28205199b306420f3b5d30a419efa6b807f466f675fd945822f1651fd6d1fd45469a578573da671e - languageName: node - linkType: hard - "is-lambda@npm:^1.0.1": version: 1.0.1 resolution: "is-lambda@npm:1.0.1" @@ -30317,10 +29661,10 @@ __metadata: languageName: node linkType: hard -"is-map@npm:^2.0.1": - version: 2.0.2 - resolution: "is-map@npm:2.0.2" - checksum: ace3d0ecd667bbdefdb1852de601268f67f2db725624b1958f279316e13fecb8fa7df91fd60f690d7417b4ec180712f5a7ee967008e27c65cfd475cc84337728 +"is-map@npm:^2.0.1, is-map@npm:^2.0.2": + version: 2.0.3 + resolution: "is-map@npm:2.0.3" + checksum: e6ce5f6380f32b141b3153e6ba9074892bbbbd655e92e7ba5ff195239777e767a976dcd4e22f864accaf30e53ebf961ab1995424aef91af68788f0591b7396cc languageName: node linkType: hard @@ -30331,16 +29675,6 @@ __metadata: languageName: node linkType: hard -"is-nan@npm:^1.2.1": - version: 1.3.2 - resolution: "is-nan@npm:1.3.2" - dependencies: - call-bind: ^1.0.0 - define-properties: ^1.1.3 - checksum: 5dfadcef6ad12d3029d43643d9800adbba21cf3ce2ec849f734b0e14ee8da4070d82b15fdb35138716d02587c6578225b9a22779cab34888a139cc43e4e3610a - languageName: node - linkType: hard - "is-negative-zero@npm:^2.0.3": version: 2.0.3 resolution: "is-negative-zero@npm:2.0.3" @@ -30378,13 +29712,6 @@ __metadata: languageName: node linkType: hard -"is-number@npm:^4.0.0": - version: 4.0.0 - resolution: "is-number@npm:4.0.0" - checksum: e71962a5ae97400211e6be5946eff2b81d3fa85154dad498bfe2704999e63ac6b3f8591fdb7971a121122cc6e25915c2cfe882ff7b77e243d51b92ca6961267e - languageName: node - linkType: hard - "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" @@ -30534,10 +29861,10 @@ __metadata: languageName: node linkType: hard -"is-set@npm:^2.0.1": - version: 2.0.2 - resolution: "is-set@npm:2.0.2" - checksum: b64343faf45e9387b97a6fd32be632ee7b269bd8183701f3b3f5b71a7cf00d04450ed8669d0bd08753e08b968beda96fca73a10fd0ff56a32603f64deba55a57 +"is-set@npm:^2.0.1, is-set@npm:^2.0.2": + version: 2.0.3 + resolution: "is-set@npm:2.0.3" + checksum: 36e3f8c44bdbe9496c9689762cc4110f6a6a12b767c5d74c0398176aa2678d4467e3bf07595556f2dba897751bde1422480212b97d973c7b08a343100b0c0dfe languageName: node linkType: hard @@ -30566,7 +29893,7 @@ __metadata: languageName: node linkType: hard -"is-stream@npm:^2.0.0": +"is-stream@npm:^2.0.0, is-stream@npm:^2.0.1": version: 2.0.1 resolution: "is-stream@npm:2.0.1" checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 @@ -30789,8 +30116,8 @@ __metadata: linkType: hard "isomorphic-git@npm:^1.23.0": - version: 1.25.10 - resolution: "isomorphic-git@npm:1.25.10" + version: 1.27.1 + resolution: "isomorphic-git@npm:1.27.1" dependencies: async-lock: ^1.4.1 clean-git-ref: ^2.0.1 @@ -30805,14 +30132,7 @@ __metadata: simple-get: ^4.0.1 bin: isogit: cli.cjs - checksum: 69e358e47a3677e1251ae3becf56ec7b2dd63e191516800647c341b101f4d40f42d185cb80acc1f8c71b4d6bf417b44b75233d2581a63c3eda69dd2c1a33886f - languageName: node - linkType: hard - -"isomorphic-timers-promises@npm:^1.0.1": - version: 1.0.1 - resolution: "isomorphic-timers-promises@npm:1.0.1" - checksum: 16ef59f0fbcceba1a037c74b5f7195d252ae058724ccd3e53b37ad034e8498f5532084e8ab18e7940ba3fa8fca2f21403d00eed15802ab1f7cab7c099cba62a8 + checksum: ba6f3c10b3160dac74185881f1da1c5a9b6cbd32d5f273ebce7291055566e5c58f466f89be9039e9c83ededd86a69e367bc4050262bbfbc6b785eea211a7f923 languageName: node linkType: hard @@ -30906,13 +30226,6 @@ __metadata: languageName: node linkType: hard -"iterable-lookahead@npm:^1.0.0": - version: 1.0.0 - resolution: "iterable-lookahead@npm:1.0.0" - checksum: 9d849bfbfafcaf83c6eec2835192088b1f7d1aadf9f33ec4e1d117664af2d47acb742e130179c35a6eec01d0e3ec2750ea8347ba6796e47e329b015455076e67 - languageName: node - linkType: hard - "iterall@npm:^1.2.1, iterall@npm:^1.3.0": version: 1.3.0 resolution: "iterall@npm:1.3.0" @@ -30940,16 +30253,16 @@ __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": ^8.0.2 "@pkgjs/parseargs": ^0.11.0 dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: 57d43ad11eadc98cdfe7496612f6bbb5255ea69fe51ea431162db302c2a11011642f50cfad57288bd0aea78384a0612b16e131944ad8ecd09d619041c8531b54 + checksum: be31027fc72e7cc726206b9f560395604b82e0fddb46c4cbf9f97d049bcef607491a5afc0699612eaa4213ca5be8fd3e1e7cd187b3040988b65c9489838a7c00 languageName: node linkType: hard @@ -31489,7 +30802,7 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^1.18.2, jiti@npm:^1.21.0": +"jiti@npm:^1.18.2, jiti@npm:^1.21.6": version: 1.21.6 resolution: "jiti@npm:1.21.6" bin: @@ -31512,19 +30825,6 @@ __metadata: languageName: node linkType: hard -"joi@npm:^17.3.0": - version: 17.13.1 - resolution: "joi@npm:17.13.1" - dependencies: - "@hapi/hoek": ^9.3.0 - "@hapi/topo": ^5.1.0 - "@sideway/address": ^4.1.5 - "@sideway/formula": ^3.0.1 - "@sideway/pinpoint": ^2.0.0 - checksum: e755140446a0e0fb679c0f512d20dfe1625691de368abe8069507c9bccae5216b5bb56b5a83100a600808b1753ab44fdfdc9933026268417f84b6e0832a9604e - languageName: node - linkType: hard - "join-component@npm:^1.1.0": version: 1.1.0 resolution: "join-component@npm:1.1.0" @@ -31533,16 +30833,16 @@ __metadata: linkType: hard "jose@npm:^4.15.5": - version: 4.15.5 - resolution: "jose@npm:4.15.5" - checksum: 7dde76447c7707bd4b448f914b216f3858e701aa83f00447434252461af5b9e159dcbffb88badea3f9616739526763581267c9560622f0a058df8d68c86d7f79 + version: 4.15.9 + resolution: "jose@npm:4.15.9" + checksum: 41abe1c99baa3cf8a78ebbf93da8f8e50e417b7a26754c4afa21865d87527b8ac2baf66de2c5f6accc3f7d7158658dae7364043677236ea1d07895b040097f15 languageName: node linkType: hard "jose@npm:^5.0.0": - version: 5.2.4 - resolution: "jose@npm:5.2.4" - checksum: 81e1f4494f406debd14392975327f0daa8b88ff09c83f2fe94754dcd7cfdefdb1adf785b2ec7481751927e609d342581cd41cb444628ef62fca423facebcd280 + version: 5.8.0 + resolution: "jose@npm:5.8.0" + checksum: bb9cd97ac6ccb8148a8e23d6a7f61e5756a3373a7d65dd783051d8af409c3534bdc2a2c30ecd1820988ea943aba5755b2a45b86955c5765d71691bb0ddd45d61 languageName: node linkType: hard @@ -31644,30 +30944,29 @@ __metadata: languageName: node linkType: hard -"jscodeshift@npm:^0.15.0": - version: 0.15.2 - resolution: "jscodeshift@npm:0.15.2" +"jscodeshift@npm:^0.16.0": + version: 0.16.1 + resolution: "jscodeshift@npm:0.16.1" dependencies: - "@babel/core": ^7.23.0 - "@babel/parser": ^7.23.0 - "@babel/plugin-transform-class-properties": ^7.22.5 - "@babel/plugin-transform-modules-commonjs": ^7.23.0 - "@babel/plugin-transform-nullish-coalescing-operator": ^7.22.11 - "@babel/plugin-transform-optional-chaining": ^7.23.0 - "@babel/plugin-transform-private-methods": ^7.22.5 - "@babel/preset-flow": ^7.22.15 - "@babel/preset-typescript": ^7.23.0 - "@babel/register": ^7.22.15 - babel-core: ^7.0.0-bridge.0 + "@babel/core": ^7.24.7 + "@babel/parser": ^7.24.7 + "@babel/plugin-transform-class-properties": ^7.24.7 + "@babel/plugin-transform-modules-commonjs": ^7.24.7 + "@babel/plugin-transform-nullish-coalescing-operator": ^7.24.7 + "@babel/plugin-transform-optional-chaining": ^7.24.7 + "@babel/plugin-transform-private-methods": ^7.24.7 + "@babel/preset-flow": ^7.24.7 + "@babel/preset-typescript": ^7.24.7 + "@babel/register": ^7.24.6 chalk: ^4.1.2 flow-parser: 0.* graceful-fs: ^4.2.4 - micromatch: ^4.0.4 + micromatch: ^4.0.7 neo-async: ^2.5.0 node-dir: ^0.1.17 - recast: ^0.23.3 - temp: ^0.8.4 - write-file-atomic: ^2.3.0 + recast: ^0.23.9 + temp: ^0.9.4 + write-file-atomic: ^5.0.1 peerDependencies: "@babel/preset-env": ^7.1.6 peerDependenciesMeta: @@ -31675,7 +30974,7 @@ __metadata: optional: true bin: jscodeshift: bin/jscodeshift.js - checksum: e3fa018bfd0ee5b65da1b98797a2536ae8ff0185f0c0d11f9be11e27e1f25ab33a4e17cecc8b73ef520e5d9d8dade98abc49bc0835c024a0f1ff14b48288528b + checksum: d9dbe7d8e434c41205a7f968a1c10907d4a16b0fd755838e0f991cf70fe4ee3fc13485a9a689390087010c12c9953542ecb518aea908e3faf15da200f3a9df63 languageName: node linkType: hard @@ -31859,12 +31158,12 @@ __metadata: linkType: hard "json-schema-to-ts@npm:^3.0.0": - version: 3.0.1 - resolution: "json-schema-to-ts@npm:3.0.1" + version: 3.1.1 + resolution: "json-schema-to-ts@npm:3.1.1" dependencies: "@babel/runtime": ^7.18.3 - ts-algebra: ^1.2.2 - checksum: 32013ac5cc28b55d056d3241e50360f69fe86d7a6efeeed097e3b6c30c17d30e655b2565ff27d2e7cc232dcbcf9180f77556c154482b30a8d32bc428a0692c62 + ts-algebra: ^2.0.0 + checksum: b616f1c2d7492502e11eec4f8e4539ee1e897543a679d929494afdc164d9557275cead8372747b73f239b1e68056ffbf551b03ae82d0047bba0dfe2bbd6b64f4 languageName: node linkType: hard @@ -31926,6 +31225,15 @@ __metadata: languageName: node linkType: hard +"json11@npm:^1.1.2": + version: 1.1.2 + resolution: "json11@npm:1.1.2" + bin: + json11: dist/cli.mjs + checksum: 5f447f6d5cba0c4ae739c3da46c86921e2dc862db0106b3960e1c79f178e53c94ac54e61f401518fa55cdcff4b264a03f2234a33a591b8b4eb281aba44afd056 + languageName: node + linkType: hard + "json5@npm:^1.0.1, json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" @@ -31937,7 +31245,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.1.2, json5@npm:^2.1.3, json5@npm:^2.2.2, json5@npm:^2.2.3": +"json5@npm:^2.1.2, json5@npm:^2.1.3, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" bin: @@ -32330,25 +31638,23 @@ __metadata: linkType: hard "knip@npm:^5.0.0": - version: 5.23.2 - resolution: "knip@npm:5.23.2" + version: 5.29.2 + resolution: "knip@npm:5.29.2" dependencies: - "@ericcornelissen/bash-parser": 0.5.3 - "@nodelib/fs.walk": 2.0.0 + "@nodelib/fs.walk": 1.2.8 "@snyk/github-codeowners": 1.1.0 easy-table: 1.2.0 + enhanced-resolve: ^5.17.1 fast-glob: ^3.3.2 - jiti: ^1.21.0 + jiti: ^1.21.6 js-yaml: ^4.1.0 minimist: ^1.2.8 picocolors: ^1.0.0 picomatch: ^4.0.1 pretty-ms: ^9.0.0 - resolve: ^1.22.8 smol-toml: ^1.1.4 strip-json-comments: 5.0.1 summary: 2.1.0 - tsconfig-paths: ^4.2.0 zod: ^3.22.4 zod-validation-error: ^3.0.3 peerDependencies: @@ -32357,7 +31663,7 @@ __metadata: bin: knip: bin/knip.js knip-bun: bin/knip-bun.js - checksum: efcfa5bea3848bb6e054cb80a840dbcc718a1c91d8f6c508a686239de5e1fe7775afc05d03fd624f07fb545767b4a08a5c59b7a29a009cbad001cb68a1e92859 + checksum: c1c9abf9f6438c17f854c52adc7f294d07991632a7a45675c0213815546556b74fc7ac9cd3b7fd3eca2bd6c816fa973e212a4b38c0dc87e0826ea63635d5e2b6 languageName: node linkType: hard @@ -32420,14 +31726,14 @@ __metadata: linkType: hard "kubernetes-models@npm:^4.1.0, kubernetes-models@npm:^4.3.1": - version: 4.3.1 - resolution: "kubernetes-models@npm:4.3.1" + version: 4.4.0 + resolution: "kubernetes-models@npm:4.4.0" dependencies: - "@kubernetes-models/apimachinery": ^1.2.1 - "@kubernetes-models/base": ^4.0.3 - "@kubernetes-models/validate": ^3.1.1 - tslib: ^2.4.0 - checksum: cf0b8ac25b1583f237b08e5554893b38e9f67d25e5acb095cb1d9001dd3c1102e746fb69165b04627499af125ca2e2376e8ae14a69d1de0ab8ac32ab8f9f83e2 + "@kubernetes-models/apimachinery": ^2.0.0 + "@kubernetes-models/base": ^5.0.0 + "@kubernetes-models/validate": ^4.0.0 + "@swc/helpers": ^0.5.8 + checksum: 9884c56c35415fe4b44a676a8b628e91fab17eb9a5ef5de08b7b9652d74afeb843d4a139d52bb19e1aaaeba44545542e92cef737b845a2cff5139aa62f820ced languageName: node linkType: hard @@ -32514,7 +31820,7 @@ __metadata: languageName: node linkType: hard -"leven@npm:^3.1.0": +"leven@npm:3.1.0, leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" checksum: 638401d534585261b6003db9d99afd244dfe82d75ddb6db5c0df412842d5ab30b2ef18de471aaec70fe69a46f17b4ae3c7f01d8a4e6580ef7adb9f4273ad1e55 @@ -32580,10 +31886,10 @@ __metadata: languageName: node linkType: hard -"lilconfig@npm:~3.1.1": - version: 3.1.1 - resolution: "lilconfig@npm:3.1.1" - checksum: dc8a4f4afde3f0fac6bd36163cc4777a577a90759b8ef1d0d766b19ccf121f723aa79924f32af5b954f3965268215e046d0f237c41c76e5ef01d4e6d1208a15e +"lilconfig@npm:~3.1.2": + version: 3.1.2 + resolution: "lilconfig@npm:3.1.2" + checksum: 4e8b83ddd1d0ad722600994e6ba5d858ddca14f0587aa6b9c8185e17548149b5e13d4d583d811e9e9323157fa8c6a527e827739794c7502b59243c58e210b8c3 languageName: node linkType: hard @@ -32630,22 +31936,22 @@ __metadata: linkType: hard "lint-staged@npm:^15.0.0": - version: 15.2.7 - resolution: "lint-staged@npm:15.2.7" + version: 15.2.10 + resolution: "lint-staged@npm:15.2.10" dependencies: chalk: ~5.3.0 commander: ~12.1.0 - debug: ~4.3.4 + debug: ~4.3.6 execa: ~8.0.1 - lilconfig: ~3.1.1 - listr2: ~8.2.1 - micromatch: ~4.0.7 + lilconfig: ~3.1.2 + listr2: ~8.2.4 + micromatch: ~4.0.8 pidtree: ~0.6.0 string-argv: ~0.3.2 - yaml: ~2.4.2 + yaml: ~2.5.0 bin: lint-staged: bin/lint-staged.js - checksum: 0f21d1b44c046fcfc0388dab66d45d244818afdb24bdf57e7593640c7ca82cc55be7d75e086708e453fac0c0d9ab8760b2cde053944f7b2121c2dd65f6367ffe + checksum: 7ab255b848478ca47c6b94aad0e7a3cfe5ba48ae1fb353cfa86635741333b83b1fd793d7cac6d44bf0388ad087d7e0250c7ec0a8ebece63fbcf7a8d175279809 languageName: node linkType: hard @@ -32656,17 +31962,17 @@ __metadata: languageName: node linkType: hard -"listr2@npm:~8.2.1": - version: 8.2.1 - resolution: "listr2@npm:8.2.1" +"listr2@npm:~8.2.4": + version: 8.2.4 + resolution: "listr2@npm:8.2.4" dependencies: cli-truncate: ^4.0.0 colorette: ^2.0.20 eventemitter3: ^5.0.1 - log-update: ^6.0.0 - rfdc: ^1.3.1 + log-update: ^6.1.0 + rfdc: ^1.4.1 wrap-ansi: ^9.0.0 - checksum: a37c032850fc01f45cf6144f2b66d0c56a596b708de1acbd52e7c396a2eb188d027ad132c93a0ad946d7932a581dfcfc2e4318bb301926b01877cb4903d09fbd + checksum: b1cdcae653ff967a9b28637e346df2d6614165b4ad1e9e36b1403bc972550c51f57ec0e6d307dc3921ceea0601e244e848ab79457c6d570ab1f088b577a63d90 languageName: node linkType: hard @@ -32700,7 +32006,7 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:^2.0.4": +"loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.4": version: 2.0.4 resolution: "loader-utils@npm:2.0.4" dependencies: @@ -32781,7 +32087,7 @@ __metadata: languageName: node linkType: hard -"lodash.curry@npm:^4.0.1, lodash.curry@npm:^4.1.1": +"lodash.curry@npm:^4.0.1": version: 4.1.1 resolution: "lodash.curry@npm:4.1.1" checksum: 9192b70fe7df4d1ff780c0260bee271afa9168c93fe4fa24bc861900240531b59781b5fdaadf4644fea8f4fbcd96f0700539ab294b579ffc1022c6c15dcc462a @@ -32802,20 +32108,6 @@ __metadata: languageName: node linkType: hard -"lodash.difference@npm:^4.5.0": - version: 4.5.0 - resolution: "lodash.difference@npm:4.5.0" - checksum: ecee276aa578f300e79350805a14a51be8d1f12b3c1389a19996d8ab516f814211a5f65c68331571ecdad96522b863ccc484b55504ce8c9947212a29f8857d5a - languageName: node - linkType: hard - -"lodash.flatten@npm:^4.4.0": - version: 4.4.0 - resolution: "lodash.flatten@npm:4.4.0" - checksum: 0ac34a393d4b795d4b7421153d27c13ae67e08786c9cbb60ff5b732210d46f833598eee3fb3844bb10070e8488efe390ea53bb567377e0cb47e9e630bf0811cb - languageName: node - linkType: hard - "lodash.flattendeep@npm:^4.0.0": version: 4.4.0 resolution: "lodash.flattendeep@npm:4.4.0" @@ -32900,13 +32192,6 @@ __metadata: languageName: node linkType: hard -"lodash.isplainobject@npm:^4.0.6": - version: 4.0.6 - resolution: "lodash.isplainobject@npm:4.0.6" - checksum: 29c6351f281e0d9a1d58f1a4c8f4400924b4c79f18dfc4613624d7d54784df07efaff97c1ff2659f3e085ecf4fff493300adc4837553104cef2634110b0d5337 - languageName: node - linkType: hard - "lodash.isstring@npm:^4.0.1": version: 4.0.1 resolution: "lodash.isstring@npm:4.0.1" @@ -32963,13 +32248,6 @@ __metadata: languageName: node linkType: hard -"lodash.union@npm:^4.6.0": - version: 4.6.0 - resolution: "lodash.union@npm:4.6.0" - checksum: 1514dc6508b2614ec071a6470f36eb7a70f69bf1abb6d55bdfdc21069635a4517783654b28504c0f025059a7598d37529766888e6d5902b8ab28b712228f7b2a - languageName: node - linkType: hard - "lodash.uniq@npm:^4.5.0": version: 4.5.0 resolution: "lodash.uniq@npm:4.5.0" @@ -33012,16 +32290,16 @@ __metadata: languageName: node linkType: hard -"log-update@npm:^6.0.0": - version: 6.0.0 - resolution: "log-update@npm:6.0.0" +"log-update@npm:^6.1.0": + version: 6.1.0 + resolution: "log-update@npm:6.1.0" dependencies: - ansi-escapes: ^6.2.0 - cli-cursor: ^4.0.0 - slice-ansi: ^7.0.0 + ansi-escapes: ^7.0.0 + cli-cursor: ^5.0.0 + slice-ansi: ^7.1.0 strip-ansi: ^7.1.0 wrap-ansi: ^9.0.0 - checksum: 8803ceba2fb28626951b85de598c8d5a4f5e39f1f767cc54fd925412cc7780ba89ce1dbec24dc96fa46f89d226e1ae984534aa729dc9c9b734e36bb805428ffa + checksum: 817a9ba6c5cbc19e94d6359418df8cfe8b3244a2903f6d53354e175e243a85b782dc6a98db8b5e457ee2f09542ca8916c39641b9cd3b0e6ef45e9481d50c918a languageName: node linkType: hard @@ -33053,7 +32331,7 @@ __metadata: languageName: node linkType: hard -"logform@npm:^2.3.2, logform@npm:^2.4.0": +"logform@npm:^2.3.2, logform@npm:^2.6.0, logform@npm:^2.6.1": version: 2.6.1 resolution: "logform@npm:2.6.1" dependencies: @@ -33139,10 +32417,10 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.0.0, lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": - version: 10.2.0 - resolution: "lru-cache@npm:10.2.0" - checksum: eee7ddda4a7475deac51ac81d7dd78709095c6fa46e8350dc2d22462559a1faa3b81ed931d5464b13d48cbd7e08b46100b6f768c76833912bc444b99c37e25db +"lru-cache@npm:^10.0.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: 6476138d2125387a6d20f100608c2583d415a4f64a0fecf30c9e2dda976614f09cad4baa0842447bd37dd459a7bd27f57d9d8f8ce558805abd487c583f3d774a languageName: node linkType: hard @@ -33218,7 +32496,14 @@ __metadata: languageName: node linkType: hard -"luxon@npm:^3.0.0, luxon@npm:^3.2.1, luxon@npm:^3.4.3, luxon@npm:~3.4.0": +"luxon@npm:^3.0.0, luxon@npm:^3.2.1, luxon@npm:^3.4.3, luxon@npm:^3.5.0": + version: 3.5.0 + resolution: "luxon@npm:3.5.0" + checksum: f290fe5788c8e51e748744f05092160d4be12150dca70f9fadc0d233e53d60ce86acd82e7d909a114730a136a77e56f0d3ebac6141bbb82fd310969a4704825b + languageName: node + linkType: hard + +"luxon@npm:~3.4.0": version: 3.4.4 resolution: "luxon@npm:3.4.4" checksum: 36c1f99c4796ee4bfddf7dc94fa87815add43ebc44c8934c924946260a58512f0fd2743a629302885df7f35ccbd2d13f178c15df046d0e3b6eb71db178f1c60c @@ -33234,15 +32519,6 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.16.0": - version: 0.16.0 - resolution: "magic-string@npm:0.16.0" - dependencies: - vlq: ^0.2.1 - checksum: f97e225062b600212e95fc8ed1948410bee3cb5248e03ed14fc45f12bb61a43960fdc0525f4aaaf62d6e79165526c9f8274ec225a92d421980cfcfcb8063be98 - languageName: node - linkType: hard - "magic-string@npm:^0.25.7": version: 0.25.7 resolution: "magic-string@npm:0.25.7" @@ -33372,13 +32648,6 @@ __metadata: languageName: node linkType: hard -"map-obj@npm:^2.0.0": - version: 2.0.0 - resolution: "map-obj@npm:2.0.0" - checksum: 77d2b7b03398a71c84bd7df8ab7be2139e5459fc1e18dbb5f15055fe7284bec0fc37fe410185b5f8ca2e3c3e01fd0fd1f946c579607878adb26cad1cd75314aa - languageName: node - linkType: hard - "markdown-it@npm:^12.2.0": version: 12.3.2 resolution: "markdown-it@npm:12.3.2" @@ -34133,13 +33402,13 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5, micromatch@npm:~4.0.7": - version: 4.0.7 - resolution: "micromatch@npm:4.0.7" +"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5, micromatch@npm:^4.0.7, micromatch@npm:~4.0.8": + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" dependencies: braces: ^3.0.3 picomatch: ^2.3.1 - checksum: 3cde047d70ad80cf60c787b77198d680db3b8c25b23feb01de5e2652205d9c19f43bd81882f69a0fd1f0cde6a7a122d774998aad3271ddb1b8accf8a0f480cf7 + checksum: 79920eb634e6f400b464a954fcfa589c4e7c7143209488e44baf627f9affc8b1e306f41f4f0deedde97e69cb725920879462d3e750ab3bd3c1aed675bb3a8966 languageName: node linkType: hard @@ -34244,6 +33513,13 @@ __metadata: languageName: node linkType: hard +"mimic-function@npm:^5.0.0": + version: 5.0.1 + resolution: "mimic-function@npm:5.0.1" + checksum: eb5893c99e902ccebbc267c6c6b83092966af84682957f79313311edb95e8bb5f39fb048d77132b700474d1c86d90ccc211e99bae0935447a4834eb4c882982c + languageName: node + linkType: hard + "mimic-response@npm:^1.0.0, mimic-response@npm:^1.0.1": version: 1.0.1 resolution: "mimic-response@npm:1.0.1" @@ -34325,15 +33601,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^4.2.3": - version: 4.2.3 - resolution: "minimatch@npm:4.2.3" - dependencies: - brace-expansion: ^1.1.7 - checksum: 3392388e3ef7de7ae9a3a48d48a27a323934452f4af81b925dfbe85ce2dc07da855e3dbcc69229888be4e5118f6c0b79847d30f3e7c0e0017b25e423c11c0409 - languageName: node - linkType: hard - "minimatch@npm:^5.0.1, minimatch@npm:^5.1.0": version: 5.1.6 resolution: "minimatch@npm:5.1.6" @@ -34352,7 +33619,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.0, minimatch@npm:^9.0.1, minimatch@npm:^9.0.3, minimatch@npm:^9.0.4": +"minimatch@npm:^9.0.0, minimatch@npm:^9.0.3, minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": version: 9.0.5 resolution: "minimatch@npm:9.0.5" dependencies: @@ -34493,10 +33760,10 @@ __metadata: 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": - version: 7.0.4 - resolution: "minipass@npm:7.0.4" - checksum: 87585e258b9488caf2e7acea242fd7856bbe9a2c84a7807643513a338d66f368c7d518200ad7b70a508664d408aa000517647b2930c259a8b1f9f0984f344a21 +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 2bfd325b95c555f2b4d2814d49325691c7bee937d753814861b0b49d5edcda55cbbf22b6b6a60bb91eddac8668771f03c5ff647dcd9d0f798e9548b9cdc46ee3 languageName: node linkType: hard @@ -34528,7 +33795,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^0.5.4, mkdirp@npm:^0.5.5, mkdirp@npm:^0.5.6": +"mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.4, mkdirp@npm:^0.5.5, mkdirp@npm:^0.5.6": version: 0.5.6 resolution: "mkdirp@npm:0.5.6" dependencies: @@ -34710,19 +33977,18 @@ __metadata: linkType: hard "msw@npm:^2.0.0, msw@npm:^2.0.8": - version: 2.3.1 - resolution: "msw@npm:2.3.1" + version: 2.4.2 + resolution: "msw@npm:2.4.2" dependencies: "@bundled-es-modules/cookie": ^2.0.0 "@bundled-es-modules/statuses": ^1.0.1 + "@bundled-es-modules/tough-cookie": ^0.1.6 "@inquirer/confirm": ^3.0.0 - "@mswjs/cookies": ^1.1.0 "@mswjs/interceptors": ^0.29.0 "@open-draft/until": ^2.1.0 "@types/cookie": ^0.6.0 "@types/statuses": ^2.0.4 chalk: ^4.1.2 - graphql: ^16.8.1 headers-polyfill: ^4.0.2 is-node-process: ^1.2.0 outvariant: ^1.4.2 @@ -34731,13 +33997,16 @@ __metadata: type-fest: ^4.9.0 yargs: ^17.7.2 peerDependencies: - typescript: ">= 4.7.x" + graphql: ">= 16.8.x" + typescript: ">= 4.8.x" peerDependenciesMeta: + graphql: + optional: true typescript: optional: true bin: msw: cli/index.js - checksum: bae72567488822889cc5c18318206c847b85d1df4c7bff0eac62e3fa902b95dd2e36710e3679829eaceb9c4f5066f9ed441afd919b304fba111fe2dacf82cefb + checksum: 13ea882de674ba4a4eafe261b1fa4ed0e885bc021286730a9d6454bff3688e79265d752c826b4b4536ece728eda3cae19a5ea30495bf51bdfa1caff43893bedf languageName: node linkType: hard @@ -34796,9 +34065,10 @@ __metadata: linkType: hard "mysql2@npm:^3.0.0": - version: 3.10.1 - resolution: "mysql2@npm:3.10.1" + version: 3.11.0 + resolution: "mysql2@npm:3.11.0" dependencies: + aws-ssl-profiles: ^1.1.1 denque: ^2.1.0 generate-function: ^2.3.1 iconv-lite: ^0.6.3 @@ -34807,7 +34077,7 @@ __metadata: named-placeholders: ^1.1.3 seq-queue: ^0.0.5 sqlstring: ^2.3.2 - checksum: 293e1a76bfdbde146285ee7028336da7693b5dfb507a7c264216fdb3fe2088ba0f5d5a45a0a9e7c4de4f39c3f44edbe890fb05b28299d6c731fc2e4a281836e3 + checksum: 0a3e80c95ca9e26821bc11658cbd065704d5f07f76efd952fc84115cc28f8a0100f14646fb3dd577f28831b8d6d2bfe0ef46fd4273ba5dcbfbeabb311302874d languageName: node linkType: hard @@ -34840,22 +34110,22 @@ __metadata: languageName: node linkType: hard -"nano-css@npm:^5.6.1": - version: 5.6.1 - resolution: "nano-css@npm:5.6.1" +"nano-css@npm:^5.6.2": + version: 5.6.2 + resolution: "nano-css@npm:5.6.2" dependencies: "@jridgewell/sourcemap-codec": ^1.4.15 css-tree: ^1.1.2 csstype: ^3.1.2 fastest-stable-stringify: ^2.0.2 - inline-style-prefixer: ^7.0.0 + inline-style-prefixer: ^7.0.1 rtl-css-js: ^1.16.1 stacktrace-js: ^2.0.2 stylis: ^4.3.0 peerDependencies: react: "*" react-dom: "*" - checksum: 735f02c030a9416bb6060503d24f18f2b2c9f43e4893c2d8714508d00f9d114b8a134df3623e94e376b0b1d794b0cacac6a48f8e5fb2b7fa8996071bcad590b8 + checksum: 85d5e730798387bee3090e9943801489ec4269bd376a848b75515cf0f44dc7ce53d4a9fec575081a7dff53a8a5d4b00eebdc1bbf217d75fae7195819f917aba1 languageName: node linkType: hard @@ -35085,8 +34355,8 @@ __metadata: linkType: hard "node-gyp@npm:^10.0.0, node-gyp@npm:latest": - version: 10.1.0 - resolution: "node-gyp@npm:10.1.0" + version: 10.2.0 + resolution: "node-gyp@npm:10.2.0" dependencies: env-paths: ^2.2.0 exponential-backoff: ^3.1.1 @@ -35094,13 +34364,13 @@ __metadata: graceful-fs: ^4.2.6 make-fetch-happen: ^13.0.0 nopt: ^7.0.0 - proc-log: ^3.0.0 + proc-log: ^4.1.0 semver: ^7.3.5 - tar: ^6.1.2 + tar: ^6.2.1 which: ^4.0.0 bin: node-gyp: bin/node-gyp.js - checksum: 72e2ab4b23fc32007a763da94018f58069fc0694bf36115d49a2b195c8831e12cf5dd1e7a3718fa85c06969aedf8fc126722d3b672ec1cb27e06ed33caee3c60 + checksum: 0233759d8c19765f7fdc259a35eb046ad86c3d09e22f7384613ae2b89647dd27fcf833fdf5293d9335041e91f9b1c539494225959cdb312a5c8080b7534b926f languageName: node linkType: hard @@ -35133,16 +34403,6 @@ __metadata: languageName: node linkType: hard -"node-html-parser@npm:^5.3.3": - version: 5.4.2 - resolution: "node-html-parser@npm:5.4.2" - dependencies: - css-select: ^4.2.1 - he: 1.2.0 - checksum: 2d2391147c83b402786eeab95d23ea4e24ca8608e0e70a2823bfd4f2a248be13a8cc31acfd55a0109e051131e4f0c17d7ada8d999ce70ff2e342ab0110f5da59 - languageName: node - linkType: hard - "node-html-parser@npm:^6.1.1": version: 6.1.5 resolution: "node-html-parser@npm:6.1.5" @@ -35199,11 +34459,11 @@ __metadata: linkType: hard "node-mocks-http@npm:^1.0.0": - version: 1.15.0 - resolution: "node-mocks-http@npm:1.15.0" + version: 1.15.1 + resolution: "node-mocks-http@npm:1.15.1" dependencies: "@types/express": ^4.17.21 - "@types/node": ^20.10.6 + "@types/node": "*" accepts: ^1.3.7 content-disposition: ^0.5.3 depd: ^1.1.0 @@ -35214,14 +34474,14 @@ __metadata: parseurl: ^1.3.3 range-parser: ^1.2.0 type-is: ^1.6.18 - checksum: 9be3ef4eec1b283800bbae50d7615fb633c7d28a0bedcf13e2ddfaa7ed4aa865d00c1d26e929ee8d617b3734958d8c19345f615760004f1940a8268c9bbacf07 + checksum: f6e64065abf0e1fbb6c4b954646d96fa77d4e6cd705f1c883e7147d192efed76a1e98aa2cafee77c299ba74e2563be75315cacc421527bb97917a5a48a242bbb languageName: node linkType: hard -"node-releases@npm:^2.0.14": - version: 2.0.14 - resolution: "node-releases@npm:2.0.14" - checksum: 59443a2f77acac854c42d321bf1b43dea0aef55cd544c6a686e9816a697300458d4e82239e2d794ea05f7bbbc8a94500332e2d3ac3f11f52e4b16cbe638b3c41 +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: ef55a3d853e1269a6d6279b7692cd6ff3e40bc74947945101138745bfdc9a5edabfe72cb19a31a8e45752e1910c4c65c77d931866af6357f242b172b7283f5b3 languageName: node linkType: hard @@ -35246,41 +34506,6 @@ __metadata: languageName: node linkType: hard -"node-stdlib-browser@npm:^1.2.0": - version: 1.2.0 - resolution: "node-stdlib-browser@npm:1.2.0" - dependencies: - assert: ^2.0.0 - browser-resolve: ^2.0.0 - browserify-zlib: ^0.2.0 - buffer: ^5.7.1 - console-browserify: ^1.1.0 - constants-browserify: ^1.0.0 - create-require: ^1.1.1 - crypto-browserify: ^3.11.0 - domain-browser: ^4.22.0 - events: ^3.0.0 - https-browserify: ^1.0.0 - isomorphic-timers-promises: ^1.0.1 - os-browserify: ^0.3.0 - path-browserify: ^1.0.1 - pkg-dir: ^5.0.0 - process: ^0.11.10 - punycode: ^1.4.1 - querystring-es3: ^0.2.1 - readable-stream: ^3.6.0 - stream-browserify: ^3.0.0 - stream-http: ^3.2.0 - string_decoder: ^1.0.0 - timers-browserify: ^2.0.4 - tty-browserify: 0.0.1 - url: ^0.11.0 - util: ^0.12.4 - vm-browserify: ^1.0.1 - checksum: fe491f0839319fd9bb95964c6f7da81fc7fde4c3ac9062aa367f19bc5a6060d0d9e423d3de4196cb51f8259d6aaf6cf380048c48a86eb3721c6223dd0dcc5bfd - languageName: node - linkType: hard - "node-watch@npm:0.7.3": version: 0.7.3 resolution: "node-watch@npm:0.7.3" @@ -35289,9 +34514,9 @@ __metadata: linkType: hard "nodemailer@npm:^6.9.13": - version: 6.9.14 - resolution: "nodemailer@npm:6.9.14" - checksum: 4037a45e24dbca47c0ea9a962d2c316deef7afe6ebf73c7da3a84942a8d501d85aae7f36dc1c5dac58dec7275f7cb1c92fd4f9c7c19f037225019ad2f402a9dc + version: 6.9.15 + resolution: "nodemailer@npm:6.9.15" + checksum: 2d975f5c60f84acde52d79d43287c70197fe94bde4a731682f306e9636a148c49de29a5dd92ce7dc5aac068a148cd91da3401ede80f8f52b9f2bc00439f36ced languageName: node linkType: hard @@ -35638,13 +34863,13 @@ __metadata: languageName: node linkType: hard -"object-is@npm:^1.0.1": - version: 1.1.5 - resolution: "object-is@npm:1.1.5" +"object-is@npm:^1.1.5": + version: 1.1.6 + resolution: "object-is@npm:1.1.6" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - checksum: 989b18c4cba258a6b74dc1d74a41805c1a1425bce29f6cabb50dcb1a6a651ea9104a1b07046739a49a5bb1bc49727bcb00efd5c55f932f6ea04ec8927a7901fe + call-bind: ^1.0.7 + define-properties: ^1.2.1 + checksum: 3ea22759967e6f2380a2cbbd0f737b42dc9ddb2dfefdb159a1b927fea57335e1b058b564bfa94417db8ad58cddab33621a035de6f5e5ad56d89f2dd03e66c6a1 languageName: node linkType: hard @@ -35655,20 +34880,6 @@ __metadata: languageName: node linkType: hard -"object-pairs@npm:^0.1.0": - version: 0.1.0 - resolution: "object-pairs@npm:0.1.0" - checksum: 8bde82dda701c84a27ba5bcf5e014283c6defbdab6df189af0b6582541711ed86ba2f0cce0a300a2220ba27b54ee11128c508982a191fa04f81770a7695b23d9 - languageName: node - linkType: hard - -"object-values@npm:^1.0.0": - version: 1.0.0 - resolution: "object-values@npm:1.0.0" - checksum: b86e7ef56349de1444e45b00f4aac7dcb76f2973f3e2cd5836cf86815b1ea4b2b3827bb2320cd5d1a50c78dd3068ce23cbcb5a1f024abe12296af8cf50d17a22 - languageName: node - linkType: hard - "object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": version: 4.1.5 resolution: "object.assign@npm:4.1.5" @@ -35681,7 +34892,7 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.7, object.entries@npm:^1.1.8": +"object.entries@npm:^1.1.8": version: 1.1.8 resolution: "object.entries@npm:1.1.8" dependencies: @@ -35692,7 +34903,7 @@ __metadata: languageName: node linkType: hard -"object.fromentries@npm:^2.0.7, object.fromentries@npm:^2.0.8": +"object.fromentries@npm:^2.0.8": version: 2.0.8 resolution: "object.fromentries@npm:2.0.8" dependencies: @@ -35704,30 +34915,18 @@ __metadata: languageName: node linkType: hard -"object.groupby@npm:^1.0.1": - version: 1.0.1 - resolution: "object.groupby@npm:1.0.1" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - get-intrinsic: ^1.2.1 - checksum: d7959d6eaaba358b1608066fc67ac97f23ce6f573dc8fc661f68c52be165266fcb02937076aedb0e42722fdda0bdc0bbf74778196ac04868178888e9fd3b78b5 - languageName: node - linkType: hard - -"object.hasown@npm:^1.1.4": - version: 1.1.4 - resolution: "object.hasown@npm:1.1.4" +"object.groupby@npm:^1.0.3": + version: 1.0.3 + resolution: "object.groupby@npm:1.0.3" dependencies: + call-bind: ^1.0.7 define-properties: ^1.2.1 es-abstract: ^1.23.2 - es-object-atoms: ^1.0.0 - checksum: bc46eb5ca22106fcd07aab1411508c2c68b7565fe8fb272f166fb9bf203972e8b5c86a5a4b2c86204beead0626a7a4119d32cefbaf7c5dd57b400bf9e6363cb6 + checksum: 0d30693ca3ace29720bffd20b3130451dca7a56c612e1926c0a1a15e4306061d84410bdb1456be2656c5aca53c81b7a3661eceaa362db1bba6669c2c9b6d1982 languageName: node linkType: hard -"object.values@npm:^1.1.6, object.values@npm:^1.1.7, object.values@npm:^1.2.0": +"object.values@npm:^1.1.6, object.values@npm:^1.2.0": version: 1.2.0 resolution: "object.values@npm:1.2.0" dependencies: @@ -35840,6 +35039,15 @@ __metadata: languageName: node linkType: hard +"onetime@npm:^7.0.0": + version: 7.0.0 + resolution: "onetime@npm:7.0.0" + dependencies: + mimic-function: ^5.0.0 + checksum: eb08d2da9339819e2f9d52cab9caf2557d80e9af8c7d1ae86e1a0fef027d00a88e9f5bd67494d350df360f7c559fbb44e800b32f310fb989c860214eacbb561c + languageName: node + linkType: hard + "only@npm:~0.0.2": version: 0.0.2 resolution: "only@npm:0.0.2" @@ -36223,6 +35431,13 @@ __metadata: languageName: node linkType: hard +"package-json-from-dist@npm:^1.0.0": + version: 1.0.0 + resolution: "package-json-from-dist@npm:1.0.0" + checksum: ac706ec856a5a03f5261e4e48fa974f24feb044d51f84f8332e2af0af04fbdbdd5bbbfb9cbbe354190409bc8307c83a9e38c6672c3c8855f709afb0006a009ea + languageName: node + linkType: hard + "package-json@npm:^6.3.0": version: 6.5.0 resolution: "package-json@npm:6.5.0" @@ -36235,6 +35450,13 @@ __metadata: languageName: node linkType: hard +"package-manager-detector@npm:^0.2.0": + version: 0.2.0 + resolution: "package-manager-detector@npm:0.2.0" + checksum: 3ba12d366aef0045d8341670eea71a3c9ef4efb00a411f45bf970bd526dbfc41b6baac4fb18a2585fe2d5f93dbb7245fbce4b4fcb89baa175ecf221c05f47db1 + languageName: node + linkType: hard + "pacote@npm:^12.0.0, pacote@npm:^12.0.2": version: 12.0.3 resolution: "pacote@npm:12.0.3" @@ -36650,13 +35872,13 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.10.1": - version: 1.10.1 - resolution: "path-scurry@npm:1.10.1" +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" dependencies: - lru-cache: ^9.1.1 || ^10.0.0 + lru-cache: ^10.2.0 minipass: ^5.0.0 || ^6.0.2 || ^7.0.0 - checksum: e2557cff3a8fb8bc07afdd6ab163a92587884f9969b05bbbaf6fe7379348bfb09af9ed292af12ed32398b15fb443e81692047b786d1eeb6d898a51eb17ed7d90 + checksum: 890d5abcd593a7912dcce7cf7c6bf7a0b5648e3dee6caf0712c126ca0a65c7f3d7b9d769072a4d1baf370f61ce493ab5b038d59988688e0c5f3f646ee3c69023 languageName: node linkType: hard @@ -36690,7 +35912,7 @@ __metadata: languageName: node linkType: hard -"path-to-regexp@npm:^6.2.0, path-to-regexp@npm:^6.2.1": +"path-to-regexp@npm:^6.2.0, path-to-regexp@npm:^6.2.1, path-to-regexp@npm:^6.2.2": version: 6.2.2 resolution: "path-to-regexp@npm:6.2.2" checksum: b7b0005c36f5099f9ed1fb20a820d2e4ed1297ffe683ea1d678f5e976eb9544f01debb281369dabdc26da82e6453901bf71acf2c7ed14b9243536c2a45286c33 @@ -36704,13 +35926,6 @@ __metadata: languageName: node linkType: hard -"pathe@npm:^0.2.0": - version: 0.2.0 - resolution: "pathe@npm:0.2.0" - checksum: 9a8149ce152088f30d15b0b03a7c128ba21f16b4dc1f3f90fe38eee9f6d0f1d6da8e4e47bd2a4f9e14aaac7c30ed01cfc86216479011de2bdc598b65e6f19f41 - languageName: node - linkType: hard - "pause@npm:0.0.1": version: 0.0.1 resolution: "pause@npm:0.0.1" @@ -36846,8 +36061,8 @@ __metadata: linkType: hard "pg@npm:^8.11.3, pg@npm:^8.9.0": - version: 8.11.5 - resolution: "pg@npm:8.11.5" + version: 8.12.0 + resolution: "pg@npm:8.12.0" dependencies: pg-cloudflare: ^1.1.1 pg-connection-string: ^2.6.4 @@ -36863,7 +36078,7 @@ __metadata: peerDependenciesMeta: pg-native: optional: true - checksum: 2317bcc7080f116ced761620b8cbc98175080cacf1e8a894e14f468bcd9c996a7bd5ef36c9db91d380a772667508eb72c42b10206a90cd82b0b4a7669a19f9e4 + checksum: 8450b61c787f360e22182aa853548f834f13622714868d0789a60f63743d66ae28930cdca0ef0251bfc89b04679e9074c1398f172c2937bf59b5a360337f4149 languageName: node linkType: hard @@ -36897,10 +36112,10 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1": - version: 1.0.1 - resolution: "picocolors@npm:1.0.1" - checksum: fa68166d1f56009fc02a34cdfd112b0dd3cf1ef57667ac57281f714065558c01828cdf4f18600ad6851cbe0093952ed0660b1e0156bddf2184b6aaf5817553a5 +"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.0": + version: 1.1.0 + resolution: "picocolors@npm:1.1.0" + checksum: a64d653d3a188119ff45781dfcdaeedd7625583f45280aea33fcb032c7a0d3959f2368f9b192ad5e8aade75b74dbd954ffe3106c158509a45e4c18ab379a2acd languageName: node linkType: hard @@ -37004,7 +36219,7 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.1, pirates@npm:^4.0.4, pirates@npm:^4.0.5, pirates@npm:^4.0.6": +"pirates@npm:^4.0.1, pirates@npm:^4.0.4, pirates@npm:^4.0.6": version: 4.0.6 resolution: "pirates@npm:4.0.6" checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6 @@ -37029,15 +36244,6 @@ __metadata: languageName: node linkType: hard -"pkg-dir@npm:^5.0.0": - version: 5.0.0 - resolution: "pkg-dir@npm:5.0.0" - dependencies: - find-up: ^5.0.0 - checksum: b167bb8dac7bbf22b1d5e30ec223e6b064b84b63010c9d49384619a36734caf95ed23ad23d4f9bd975e8e8082b60a83395f43a89bb192df53a7c25a38ecb57d9 - languageName: node - linkType: hard - "pkg-up@npm:^3.1.0": version: 3.1.0 resolution: "pkg-up@npm:3.1.0" @@ -37061,27 +36267,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.45.3": - version: 1.45.3 - resolution: "playwright-core@npm:1.45.3" +"playwright-core@npm:1.46.1": + version: 1.46.1 + resolution: "playwright-core@npm:1.46.1" bin: playwright-core: cli.js - checksum: cecb58877b2c643403d7a72c24a7aa0fdd087a3c7f9a5ea5403851336ea831d8e304b1f159aacbbabd12e5c47eaac054333746c9e5431ec07b13d64dbf3b50ec + checksum: 99a03f97d76af02b0565aa09758eb03427e13497ef7e9e9044fd1184a5f050e7545a517dd7ad8988a68b3ea76e2ba0d411f81e410b1cb29f5ac9161c49689822 languageName: node linkType: hard -"playwright@npm:1.45.3": - version: 1.45.3 - resolution: "playwright@npm:1.45.3" +"playwright@npm:1.46.1": + version: 1.46.1 + resolution: "playwright@npm:1.46.1" dependencies: fsevents: 2.3.2 - playwright-core: 1.45.3 + playwright-core: 1.46.1 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: d9d23b155ccd001553214f710561b01e48eb409676102f8ab94c0b4aa5ac5f398becc1a96528b0554944e07e34189503d891913e0e0a4aa58ad36b9c08747983 + checksum: 9e721cb27f919cd92ea8c7461f4a8e97e32eade9da036baa4747f483549e33a8d77585f51e228d6639a1e28a76b0c1d59ca0a05dbd07aa3cfe427be7aaeb9ec8 languageName: node linkType: hard @@ -37548,14 +36754,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.1.0, postcss@npm:^8.4.27, postcss@npm:^8.4.33": - version: 8.4.38 - resolution: "postcss@npm:8.4.38" +"postcss@npm:^8.1.0, postcss@npm:^8.4.33": + version: 8.4.45 + resolution: "postcss@npm:8.4.45" dependencies: nanoid: ^3.3.7 - picocolors: ^1.0.0 + picocolors: ^1.0.1 source-map-js: ^1.2.0 - checksum: 649f9e60a763ca4b5a7bbec446a069edf07f057f6d780a5a0070576b841538d1ecf7dd888f2fbfd1f76200e26c969e405aeeae66332e6927dbdc8bdcb90b9451 + checksum: 3223cdad4a9392c0b334ee3ee7e4e8041c631cb6160609cef83c18d2b2580e931dd8068ab13cc6000c1a254d57492ac6c38717efc397c5dcc9756d06bc9c44f3 languageName: node linkType: hard @@ -37683,7 +36889,7 @@ __metadata: languageName: node linkType: hard -"preferred-pm@npm:^3.0.0, preferred-pm@npm:^3.0.3": +"preferred-pm@npm:^3.0.3": version: 3.0.3 resolution: "preferred-pm@npm:3.0.3" dependencies: @@ -37796,10 +37002,10 @@ __metadata: languageName: node linkType: hard -"proc-log@npm:^3.0.0": - version: 3.0.0 - resolution: "proc-log@npm:3.0.0" - checksum: 02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 +"proc-log@npm:^4.1.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 98f6cd012d54b5334144c5255ecb941ee171744f45fca8b43b58ae5a0c1af07352475f481cadd9848e7f0250376ee584f6aa0951a856ff8f021bdfbff4eb33fc languageName: node linkType: hard @@ -37947,9 +37153,9 @@ __metadata: languageName: node linkType: hard -"protobufjs@npm:^7.2.3, protobufjs@npm:^7.2.5, protobufjs@npm:^7.2.6, protobufjs@npm:^7.3.2": - version: 7.3.2 - resolution: "protobufjs@npm:7.3.2" +"protobufjs@npm:^7.2.5, protobufjs@npm:^7.2.6, protobufjs@npm:^7.3.0, protobufjs@npm:^7.3.2": + version: 7.4.0 + resolution: "protobufjs@npm:7.4.0" dependencies: "@protobufjs/aspromise": ^1.1.2 "@protobufjs/base64": ^1.1.2 @@ -37963,7 +37169,7 @@ __metadata: "@protobufjs/utf8": ^1.1.0 "@types/node": ">=13.7.0" long: ^5.0.0 - checksum: cfb2a744787f26ee7c82f3e7c4b72cfc000e9bb4c07828ed78eb414db0ea97a340c0cc3264d0e88606592f847b12c0351411f10e9af255b7ba864eec44d7705f + checksum: ba0e6b60541bbf818bb148e90f5eb68bd99004e29a6034ad9895a381cbd352be8dce5376e47ae21b2e05559f2505b4a5f4a3c8fa62402822c6ab4dcdfb89ffb3 languageName: node linkType: hard @@ -38050,7 +37256,7 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^1.2.4, punycode@npm:^1.3.2, punycode@npm:^1.4.1": +"punycode@npm:^1.2.4, punycode@npm:^1.3.2": version: 1.4.1 resolution: "punycode@npm:1.4.1" checksum: fa6e698cb53db45e4628559e557ddaf554103d2a96a1d62892c8f4032cd3bc8871796cae9eabc1bc700e2b6677611521ce5bb1d9a27700086039965d0cf34518 @@ -38096,12 +37302,12 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.9.1, qs@npm:^6.9.4": - version: 6.12.1 - resolution: "qs@npm:6.12.1" +"qs@npm:^6.10.1, qs@npm:^6.10.2, qs@npm:^6.11.0, qs@npm:^6.11.2, qs@npm:^6.12.2, qs@npm:^6.9.1, qs@npm:^6.9.4": + version: 6.13.0 + resolution: "qs@npm:6.13.0" dependencies: side-channel: ^1.0.6 - checksum: aa761d99e65b6936ba2dd2187f2d9976afbcda38deb3ff1b3fe331d09b0c578ed79ca2abdde1271164b5be619c521ec7db9b34c23f49a074e5921372d16242d5 + checksum: e9404dc0fc2849245107108ce9ec2766cde3be1b271de0bf1021d049dc5b98d1a2901e67b431ac5509f865420a7ed80b7acb3980099fe1c118a1c5d2e1432ad8 languageName: node linkType: hard @@ -38124,7 +37330,7 @@ __metadata: languageName: node linkType: hard -"querystring-es3@npm:^0.2.0, querystring-es3@npm:^0.2.1": +"querystring-es3@npm:^0.2.0": version: 0.2.1 resolution: "querystring-es3@npm:0.2.1" checksum: 691e8d6b8b157e7cd49ae8e83fcf86de39ab3ba948c25abaa94fba84c0986c641aa2f597770848c64abce290ed17a39c9df6df737dfa7e87c3b63acc7d225d61 @@ -38283,10 +37489,10 @@ __metadata: languageName: node linkType: hard -"rate-limiter-flexible@npm:^4.0.0": - version: 4.0.0 - resolution: "rate-limiter-flexible@npm:4.0.0" - checksum: defaa10e35d77399c4bbdeaa0e3f0028bcc5f6d678118d54496d5c01a4c9d5d56e16885e2ea339e7dd1ea056a3594bba24a18b5da236965f1d186fd52bdbe9fe +"rate-limiter-flexible@npm:^4.0.0, rate-limiter-flexible@npm:^4.0.1": + version: 4.0.1 + resolution: "rate-limiter-flexible@npm:4.0.1" + checksum: 88cb4ae4c6a94646eb4987f08ae203896fc340d84038e145958607ab711d9c703e47e55f177a4bf9bab4c637c73ee2254fffe2ec4e289d41389c8502194ca868 languageName: node linkType: hard @@ -38302,6 +37508,18 @@ __metadata: languageName: node linkType: hard +"raw-loader@npm:^4.0.2": + version: 4.0.2 + resolution: "raw-loader@npm:4.0.2" + dependencies: + loader-utils: ^2.0.0 + schema-utils: ^3.0.0 + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + checksum: 51cc1b0d0e8c37c4336b5318f3b2c9c51d6998ad6f56ea09612afcfefc9c1f596341309e934a744ae907177f28efc9f1654eacd62151e82853fcc6d37450e795 + languageName: node + linkType: hard + "rc-progress@npm:3.5.1": version: 3.5.1 resolution: "rc-progress@npm:3.5.1" @@ -38344,6 +37562,13 @@ __metadata: languageName: node linkType: hard +"re2-wasm@npm:^1.0.2": + version: 1.0.2 + resolution: "re2-wasm@npm:1.0.2" + checksum: cd47ad62db1e2f01dec40129f0c994f86bebbade1bd85920fa32229bec0a64b0ebbf550fefbba68a1f8268b73d811f223f79264d5ed9a208efda3fb832e9f0a9 + languageName: node + linkType: hard + "react-base16-styling@npm:^0.6.0": version: 0.6.0 resolution: "react-base16-styling@npm:0.6.0" @@ -38544,11 +37769,11 @@ __metadata: linkType: hard "react-hook-form@npm:^7.12.2": - version: 7.51.5 - resolution: "react-hook-form@npm:7.51.5" + version: 7.53.0 + resolution: "react-hook-form@npm:7.53.0" peerDependencies: - react: ^16.8.0 || ^17 || ^18 - checksum: 6b6a56b6520ddb68d491e2f07791538aa611c13fcd76052a499ba10bdaf7f77f4a5f7191e6ca9d9ab0af739bf07171c6e8d97f6c4da06f576aa74caed71828f1 + react: ^16.8.0 || ^17 || ^18 || ^19 + checksum: 84d67fb79bad03d0aa809b5e411d97fb081fc13cd2b6d063a988f81f6fbef8545463e05360afa9d8d58fff19f08fa919930dcdc98a9e68bf74048c9f63e10ad5 languageName: node linkType: hard @@ -38617,10 +37842,10 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^18.0.0, react-is@npm:^18.2.0": - version: 18.2.0 - resolution: "react-is@npm:18.2.0" - checksum: e72d0ba81b5922759e4aff17e0252bd29988f9642ed817f56b25a3e217e13eea8a7f2322af99a06edb779da12d5d636e9fda473d620df9a3da0df2a74141d53e +"react-is@npm:^18.0.0, react-is@npm:^18.2.0, react-is@npm:^18.3.1": + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: e20fe84c86ff172fc8d898251b7cc2c43645d108bf96d0b8edf39b98f9a2cae97b40520ee7ed8ee0085ccc94736c4886294456033304151c3f94978cec03df21 languageName: node linkType: hard @@ -38725,7 +37950,7 @@ __metadata: languageName: node linkType: hard -"react-refresh@npm:^0.14.0, react-refresh@npm:^0.14.2": +"react-refresh@npm:^0.14.0": version: 0.14.2 resolution: "react-refresh@npm:0.14.2" checksum: d80db4bd40a36dab79010dc8aa317a5b931f960c0d83c4f3b81f0552cbcf7f29e115b84bb7908ec6a1eb67720fff7023084eff73ece8a7ddc694882478464382 @@ -38828,15 +38053,15 @@ __metadata: linkType: hard "react-router-dom@npm:^6.3.0": - version: 6.25.1 - resolution: "react-router-dom@npm:6.25.1" + version: 6.26.1 + resolution: "react-router-dom@npm:6.26.1" dependencies: - "@remix-run/router": 1.18.0 - react-router: 6.25.1 + "@remix-run/router": 1.19.1 + react-router: 6.26.1 peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: fac768bc02cc0f39f5c1f022c8e7323ce9ffcc9b8e80456b51a70ff765854444cb4e6cdbf7d4132064a8fcbeeabeb82b8802614fbe66d8cbe7408e23ee33d789 + checksum: e393ab62e3239585d44d598e6bc8cc138ac8353f3dc46262680c6ad83dea35773662ada2f1c353921a05c37d1f369c0a2cb097848a6210689e9b6076550c7de0 languageName: node linkType: hard @@ -38851,14 +38076,14 @@ __metadata: languageName: node linkType: hard -"react-router@npm:6.25.1, react-router@npm:^6.3.0": - version: 6.25.1 - resolution: "react-router@npm:6.25.1" +"react-router@npm:6.26.1, react-router@npm:^6.3.0": + version: 6.26.1 + resolution: "react-router@npm:6.26.1" dependencies: - "@remix-run/router": 1.18.0 + "@remix-run/router": 1.19.1 peerDependencies: react: ">=16.8" - checksum: 2abbab5ecc5d1210f70980571326fd1956da3898b78bfcce6229e346e658dd42ec75bea1caea6aa45607ef677e442f3241dc3fb839293f276fa4bd466870aadd + checksum: 810949febc1bf2a6f8dd65f4c0532a2413d0532df462b3e78891aec81dca5a088d387b32c9922cde52bd9770f32263590993cab2383c94ddc1cdb50a20fd7adc languageName: node linkType: hard @@ -38980,8 +38205,8 @@ __metadata: linkType: hard "react-use@npm:^17.2.4, react-use@npm:^17.3.2, react-use@npm:^17.4.0": - version: 17.5.0 - resolution: "react-use@npm:17.5.0" + version: 17.5.1 + resolution: "react-use@npm:17.5.1" dependencies: "@types/js-cookie": ^2.2.6 "@xobotyi/scrollbar-width": ^1.9.5 @@ -38989,7 +38214,7 @@ __metadata: fast-deep-equal: ^3.1.3 fast-shallow-equal: ^1.0.0 js-cookie: ^2.2.1 - nano-css: ^5.6.1 + nano-css: ^5.6.2 react-universal-interface: ^0.6.2 resize-observer-polyfill: ^1.5.1 screenfull: ^5.1.0 @@ -39000,7 +38225,7 @@ __metadata: peerDependencies: react: "*" react-dom: "*" - checksum: d3164db313f27aa701dcf87177861db6e19624ea7dd8bc81805352af7f6bf04072010b9776da4ac458d6bd318759ee69b12763d96098d83c75b7d66ffc689e3a + checksum: 68f4333d986161038308a844d4ab99103484b69a0599a03c345eeb7cb5a0eabd0c55994fefc471ef11d4d2799a8e063d7f11fe0c48d56b54516333025fc7d726 languageName: node linkType: hard @@ -39038,7 +38263,7 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.0.2": +"react@npm:^16.13.1 || ^17.0.0 || ^18.0.0, react@npm:^18.0.2": version: 18.3.1 resolution: "react@npm:18.3.1" dependencies: @@ -39111,16 +38336,16 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^4.3.0": - version: 4.4.2 - resolution: "readable-stream@npm:4.4.2" +"readable-stream@npm:^4.0.0, readable-stream@npm:^4.3.0": + version: 4.5.2 + resolution: "readable-stream@npm:4.5.2" dependencies: abort-controller: ^3.0.0 buffer: ^6.0.3 events: ^3.3.0 process: ^0.11.10 string_decoder: ^1.3.0 - checksum: 6f4063763dbdb52658d22d3f49ca976420e1fbe16bbd241f744383715845350b196a2f08b8d6330f8e219153dff34b140aeefd6296da828e1041a7eab1f20d5e + checksum: c4030ccff010b83e4f33289c535f7830190773e274b3fcb6e2541475070bdfd69c98001c3b0cb78763fc00c8b62f514d96c2b10a8bd35d5ce45203a25fa1d33a languageName: node linkType: hard @@ -39182,16 +38407,16 @@ __metadata: languageName: node linkType: hard -"recast@npm:^0.23.3": - version: 0.23.4 - resolution: "recast@npm:0.23.4" +"recast@npm:^0.23.9": + version: 0.23.9 + resolution: "recast@npm:0.23.9" dependencies: - assert: ^2.0.0 ast-types: ^0.16.1 esprima: ~4.0.0 source-map: ~0.6.1 + tiny-invariant: ^1.3.3 tslib: ^2.0.1 - checksum: edb63bbe0457e68c0f4892f55413000e92aa7c5c53f9e109ab975d1c801cd299a62511ea72734435791f4aea6f0edf560f6a275761f66b2b6069ff6d72686029 + checksum: be8e896a46b24e30fbeafcd111ff3beaf2b5532d241c199f833fe1c18e89f695b2704cf83f3006fa96a785851019031de0de50bd3e0fd7bb114be18bf2cad900 languageName: node linkType: hard @@ -39351,7 +38576,7 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.2": +"regexp.prototype.flags@npm:^1.5.1, regexp.prototype.flags@npm:^1.5.2": version: 1.5.2 resolution: "regexp.prototype.flags@npm:1.5.2" dependencies: @@ -39502,15 +38727,15 @@ __metadata: linkType: hard "replace-in-file@npm:^7.1.0": - version: 7.1.0 - resolution: "replace-in-file@npm:7.1.0" + version: 7.2.0 + resolution: "replace-in-file@npm:7.2.0" dependencies: chalk: ^4.1.2 glob: ^8.1.0 yargs: ^17.7.2 bin: replace-in-file: bin/cli.js - checksum: 2ed61bd0cf0752b18775b52342ad36f4ee6c806f7eca0b0d085c23bafe0cb4828e4ec8f59058bde6b67d2ed5ac51e1681284f586089b58b966e2489712830db0 + checksum: 773cfff187a404a293ed0f8ee433fa6c14230b96c506455bd3a880a217b3a3ec31791b8acb3e32a629286e6d8a7825b94255f443d0873c52cb7593b05cda52ba languageName: node linkType: hard @@ -39642,7 +38867,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:1.22.8, resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:^1.22.8, resolve@npm:~1.22.1": +"resolve@npm:1.22.8, resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:~1.22.1": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -39678,7 +38903,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@1.22.8#~builtin, resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.22.8#~builtin, resolve@patch:resolve@~1.22.1#~builtin": +"resolve@patch:resolve@1.22.8#~builtin, resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@~1.22.1#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -39742,13 +38967,13 @@ __metadata: languageName: node linkType: hard -"restore-cursor@npm:^4.0.0": - version: 4.0.0 - resolution: "restore-cursor@npm:4.0.0" +"restore-cursor@npm:^5.0.0": + version: 5.1.0 + resolution: "restore-cursor@npm:5.1.0" dependencies: - onetime: ^5.1.0 - signal-exit: ^3.0.2 - checksum: 5b675c5a59763bf26e604289eab35711525f11388d77f409453904e1e69c0d37ae5889295706b2c81d23bd780165084d040f9b68fffc32cc921519031c4fa4af + onetime: ^7.0.0 + signal-exit: ^4.1.0 + checksum: 838dd54e458d89cfbc1a923b343c1b0f170a04100b4ce1733e97531842d7b440463967e521216e8ab6c6f8e89df877acc7b7f4c18ec76e99fb9bf5a60d358d2c languageName: node linkType: hard @@ -39799,13 +39024,6 @@ __metadata: languageName: node linkType: hard -"reverse-arguments@npm:^1.0.0": - version: 1.0.0 - resolution: "reverse-arguments@npm:1.0.0" - checksum: 4dc725066adb35bccdee90545bab7e3ddd07e61c3622afa22a6a17cc84cf22166f9355f8f206c89d344f0afc78a53ae6a8d43a710ca9774a676e3632a5a3d9a1 - languageName: node - linkType: hard - "rfc4648@npm:^1.3.0": version: 1.4.0 resolution: "rfc4648@npm:1.4.0" @@ -39813,7 +39031,7 @@ __metadata: languageName: node linkType: hard -"rfdc@npm:^1.3.0, rfdc@npm:^1.3.1": +"rfdc@npm:^1.3.0, rfdc@npm:^1.4.1": version: 1.4.1 resolution: "rfdc@npm:1.4.1" checksum: 3b05bd55062c1d78aaabfcea43840cdf7e12099968f368e9a4c3936beb744adb41cbdb315eac6d4d8c6623005d6f87fdf16d8a10e1ff3722e84afea7281c8d13 @@ -39842,17 +39060,6 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^5.0.5": - version: 5.0.5 - resolution: "rimraf@npm:5.0.5" - dependencies: - glob: ^10.3.7 - bin: - rimraf: dist/esm/bin.mjs - checksum: d66eef829b2e23b16445f34e73d75c7b7cf4cbc8834b04720def1c8f298eb0753c3d76df77325fad79d0a2c60470525d95f89c2475283ad985fd7441c32732d1 - languageName: node - linkType: hard - "rimraf@npm:~2.6.2": version: 2.6.3 resolution: "rimraf@npm:2.6.3" @@ -39990,40 +39197,26 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^3.27.1": - version: 3.29.4 - resolution: "rollup@npm:3.29.4" - dependencies: - fsevents: ~2.3.2 - dependenciesMeta: - fsevents: - optional: true - bin: - rollup: dist/bin/rollup - checksum: 8bb20a39c8d91130825159c3823eccf4dc2295c9a0a5c4ed851a5bf2167dbf24d9a29f23461a54c955e5506395e6cc188eafc8ab0e20399d7489fb33793b184e - languageName: node - linkType: hard - "rollup@npm:^4.0.0": - version: 4.16.2 - resolution: "rollup@npm:4.16.2" + version: 4.21.2 + resolution: "rollup@npm:4.21.2" dependencies: - "@rollup/rollup-android-arm-eabi": 4.16.2 - "@rollup/rollup-android-arm64": 4.16.2 - "@rollup/rollup-darwin-arm64": 4.16.2 - "@rollup/rollup-darwin-x64": 4.16.2 - "@rollup/rollup-linux-arm-gnueabihf": 4.16.2 - "@rollup/rollup-linux-arm-musleabihf": 4.16.2 - "@rollup/rollup-linux-arm64-gnu": 4.16.2 - "@rollup/rollup-linux-arm64-musl": 4.16.2 - "@rollup/rollup-linux-powerpc64le-gnu": 4.16.2 - "@rollup/rollup-linux-riscv64-gnu": 4.16.2 - "@rollup/rollup-linux-s390x-gnu": 4.16.2 - "@rollup/rollup-linux-x64-gnu": 4.16.2 - "@rollup/rollup-linux-x64-musl": 4.16.2 - "@rollup/rollup-win32-arm64-msvc": 4.16.2 - "@rollup/rollup-win32-ia32-msvc": 4.16.2 - "@rollup/rollup-win32-x64-msvc": 4.16.2 + "@rollup/rollup-android-arm-eabi": 4.21.2 + "@rollup/rollup-android-arm64": 4.21.2 + "@rollup/rollup-darwin-arm64": 4.21.2 + "@rollup/rollup-darwin-x64": 4.21.2 + "@rollup/rollup-linux-arm-gnueabihf": 4.21.2 + "@rollup/rollup-linux-arm-musleabihf": 4.21.2 + "@rollup/rollup-linux-arm64-gnu": 4.21.2 + "@rollup/rollup-linux-arm64-musl": 4.21.2 + "@rollup/rollup-linux-powerpc64le-gnu": 4.21.2 + "@rollup/rollup-linux-riscv64-gnu": 4.21.2 + "@rollup/rollup-linux-s390x-gnu": 4.21.2 + "@rollup/rollup-linux-x64-gnu": 4.21.2 + "@rollup/rollup-linux-x64-musl": 4.21.2 + "@rollup/rollup-win32-arm64-msvc": 4.21.2 + "@rollup/rollup-win32-ia32-msvc": 4.21.2 + "@rollup/rollup-win32-x64-msvc": 4.21.2 "@types/estree": 1.0.5 fsevents: ~2.3.2 dependenciesMeta: @@ -40063,7 +39256,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: ae20184e8c53cb2167873f6423524143c012b8df36f7b7c2fe40a440206453b8043fec48d8eb9ed184710b94e92a7195b2d4074854906763602267cba5bb72f9 + checksum: ac83ca15495dd00d6b910e87e7f5f2c480d36977471ec11e3d207089e0aa207d34fc9bd0270f7804b268a7f7473d3bc6b65bccf474fbd1d1826a70bde2741894 languageName: node linkType: hard @@ -40143,7 +39336,7 @@ __metadata: languageName: node linkType: hard -"run-parallel@npm:^1.1.9, run-parallel@npm:^1.2.0": +"run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" dependencies: @@ -40325,7 +39518,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0": +"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0": version: 3.3.0 resolution: "schema-utils@npm:3.3.0" dependencies: @@ -40448,11 +39641,11 @@ __metadata: linkType: hard "semver@npm:^7.1.1, semver@npm:^7.1.2, semver@npm:^7.1.3, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0": - version: 7.6.2 - resolution: "semver@npm:7.6.2" + version: 7.6.3 + resolution: "semver@npm:7.6.3" bin: semver: bin/semver.js - checksum: 40f6a95101e8d854357a644da1b8dd9d93ce786d5c6a77227bc69dbb17bea83d0d1d1d7c4cd5920a6df909f48e8bd8a5909869535007f90278289f2451d0292d + checksum: 4110ec5d015c9438f322257b1c51fe30276e5f766a3f64c09edd1d7ea7118ecbc3f379f3b69032bacf13116dc7abc4ad8ce0d7e2bd642e26b0d271b56b61a7d8 languageName: node linkType: hard @@ -40692,13 +39885,6 @@ __metadata: languageName: node linkType: hard -"shell-quote-word@npm:^1.0.1": - version: 1.0.1 - resolution: "shell-quote-word@npm:1.0.1" - checksum: 05c5df92acba3e7920dbd987b235276871d38cf360d339074cbfabea49bbca8406a6f06a822cd1e84912c3150277d73de5194ca21c37ef95e108dfe45372526f - languageName: node - linkType: hard - "shell-quote@npm:^1.6.1, shell-quote@npm:^1.7.3, shell-quote@npm:^1.8.1": version: 1.8.1 resolution: "shell-quote@npm:1.8.1" @@ -40897,7 +40083,7 @@ __metadata: languageName: node linkType: hard -"slice-ansi@npm:^7.0.0": +"slice-ansi@npm:^7.1.0": version: 7.1.0 resolution: "slice-ansi@npm:7.1.0" dependencies: @@ -41403,6 +40589,15 @@ __metadata: languageName: node linkType: hard +"stop-iteration-iterator@npm:^1.0.0": + version: 1.0.0 + resolution: "stop-iteration-iterator@npm:1.0.0" + dependencies: + internal-slot: ^1.0.4 + checksum: d04173690b2efa40e24ab70e5e51a3ff31d56d699550cfad084104ab3381390daccb36652b25755e420245f3b0737de66c1879eaa2a8d4fc0a78f9bf892fcb42 + languageName: node + linkType: hard + "stoppable@npm:^1.1.0": version: 1.1.0 resolution: "stoppable@npm:1.1.0" @@ -41410,7 +40605,7 @@ __metadata: languageName: node linkType: hard -"stream-browserify@npm:3.0.0, stream-browserify@npm:^3.0.0": +"stream-browserify@npm:3.0.0": version: 3.0.0 resolution: "stream-browserify@npm:3.0.0" dependencies: @@ -41466,18 +40661,6 @@ __metadata: languageName: node linkType: hard -"stream-http@npm:^3.2.0": - version: 3.2.0 - resolution: "stream-http@npm:3.2.0" - dependencies: - builtin-status-codes: ^3.0.0 - inherits: ^2.0.4 - readable-stream: ^3.6.0 - xtend: ^4.0.2 - checksum: c9b78453aeb0c84fcc59555518ac62bacab9fa98e323e7b7666e5f9f58af8f3155e34481078509b02929bd1268427f664d186604cdccee95abc446099b339f83 - languageName: node - linkType: hard - "stream-json@npm:^1.7.4": version: 1.8.0 resolution: "stream-json@npm:1.8.0" @@ -41620,10 +40803,13 @@ __metadata: languageName: node linkType: hard -"string.fromcodepoint@npm:^0.2.1": - version: 0.2.1 - resolution: "string.fromcodepoint@npm:0.2.1" - checksum: 6ba80f70c3e2a36dab87f5d68168936403295a73838564e701f5c861d397d77d9e97b0e2aa0f3c163a25a96c785dcc2145452b220753fb7b3e6c6fe431c9c411 +"string.prototype.includes@npm:^2.0.0": + version: 2.0.0 + resolution: "string.prototype.includes@npm:2.0.0" + dependencies: + define-properties: ^1.1.3 + es-abstract: ^1.17.5 + checksum: cf413e7f603b0414b65fdf1e7e3670ba85fd992b31c7eadfbdd9a484b86d265f0260431e7558cdb44a318dcadd1da8442b7bb8193b9ddd0aea3c376d2a559859 languageName: node linkType: hard @@ -41647,6 +40833,16 @@ __metadata: languageName: node linkType: hard +"string.prototype.repeat@npm:^1.0.0": + version: 1.0.0 + resolution: "string.prototype.repeat@npm:1.0.0" + dependencies: + define-properties: ^1.1.3 + es-abstract: ^1.17.5 + checksum: 95dfc514ed7f328d80a066dabbfbbb1615c3e51490351085409db2eb7cbfed7ea29fdadaf277647fbf9f4a1e10e6dd9e95e78c0fd2c4e6bb6723ea6e59401004 + languageName: node + linkType: hard + "string.prototype.trim@npm:^1.2.9": version: 1.2.9 resolution: "string.prototype.trim@npm:1.2.9" @@ -42186,9 +41382,9 @@ __metadata: languageName: node linkType: hard -"tar-fs@npm:^3.0.5": - version: 3.0.5 - resolution: "tar-fs@npm:3.0.5" +"tar-fs@npm:^3.0.6": + version: 3.0.6 + resolution: "tar-fs@npm:3.0.6" dependencies: bare-fs: ^2.1.1 bare-path: ^2.1.0 @@ -42199,7 +41395,7 @@ __metadata: optional: true bare-path: optional: true - checksum: e31c7e3e525fec0afecdec1cac58071809e396187725f2eba442f08a4c5649c8cd6b7ce25982f9a91bb0f055628df47c08177dd2ea4f5dafd3c22f42f8da8f00 + checksum: b4fa09c70f75caf05bf5cf87369cd2862f1ac5fb75c4ddf9d25d55999f7736a94b58ad679d384196cba837c5f5ff14086e060fafccef5474a16e2d3058ffa488 languageName: node linkType: hard @@ -42215,7 +41411,7 @@ __metadata: languageName: node linkType: hard -"tar-stream@npm:^2.0.0, tar-stream@npm:^2.0.1, tar-stream@npm:^2.1.4, tar-stream@npm:^2.2.0": +"tar-stream@npm:^2.0.0, tar-stream@npm:^2.0.1, tar-stream@npm:^2.1.4": version: 2.2.0 resolution: "tar-stream@npm:2.2.0" dependencies: @@ -42239,7 +41435,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:^6.0.2, tar@npm:^6.0.5, tar@npm:^6.1.0, tar@npm:^6.1.11, tar@npm:^6.1.12, tar@npm:^6.1.2": +"tar@npm:^6.0.2, tar@npm:^6.0.5, tar@npm:^6.1.0, tar@npm:^6.1.11, tar@npm:^6.1.12, tar@npm:^6.1.2, tar@npm:^6.2.1": version: 6.2.1 resolution: "tar@npm:6.2.1" dependencies: @@ -42332,12 +41528,13 @@ __metadata: languageName: node linkType: hard -"temp@npm:^0.8.4": - version: 0.8.4 - resolution: "temp@npm:0.8.4" +"temp@npm:^0.9.4": + version: 0.9.4 + resolution: "temp@npm:0.9.4" dependencies: + mkdirp: ^0.5.1 rimraf: ~2.6.2 - checksum: f35bed78565355dfdf95f730b7b489728bd6b7e35071bcc6497af7c827fb6c111fbe9063afc7b8cbc19522a072c278679f9a0ee81e684aa2c8617cc0f2e9c191 + checksum: 8709d4d63278bd309ca0e49e80a268308dea543a949e71acd427b3314cd9417da9a2cc73425dd9c21c6780334dbffd67e05e7be5aaa73e9affe8479afc6f20e3 languageName: node linkType: hard @@ -42396,25 +41593,25 @@ __metadata: linkType: hard "testcontainers@npm:^10.0.0": - version: 10.8.2 - resolution: "testcontainers@npm:10.8.2" + version: 10.13.0 + resolution: "testcontainers@npm:10.13.0" dependencies: "@balena/dockerignore": ^1.0.2 - "@types/dockerode": ^3.3.24 - archiver: ^5.3.2 + "@types/dockerode": ^3.3.29 + archiver: ^7.0.1 async-lock: ^1.4.1 byline: ^5.0.0 - debug: ^4.3.4 - docker-compose: ^0.24.6 + debug: ^4.3.5 + docker-compose: ^0.24.8 dockerode: ^3.3.5 get-port: ^5.1.1 - node-fetch: ^2.7.0 proper-lockfile: ^4.1.2 properties-reader: ^2.3.0 ssh-remote-port-forward: ^1.0.4 - tar-fs: ^3.0.5 - tmp: ^0.2.1 - checksum: 3a97ad705c98abc5066577699be5e791090ef2a5c45fee3a203196fa09d0cb66c7709f6ae8168c025ed97a07f1f5f0676a34e748680514e732e90671720d34c6 + tar-fs: ^3.0.6 + tmp: ^0.2.3 + undici: ^5.28.4 + checksum: cbc2e9503944ad51ff71e743803d14da91905590086f53acc53822f5664d606479c22129361af36e82d99027be0f6a395f7fb388a76a3b09e6692befb40cd8b5 languageName: node linkType: hard @@ -42544,10 +41741,10 @@ __metadata: languageName: node linkType: hard -"tiny-invariant@npm:^1.0.6": - version: 1.3.1 - resolution: "tiny-invariant@npm:1.3.1" - checksum: 872dbd1ff20a21303a2fd20ce3a15602cfa7fcf9b228bd694a52e2938224313b5385a1078cb667ed7375d1612194feaca81c4ecbe93121ca1baebe344de4f84c +"tiny-invariant@npm:^1.0.6, tiny-invariant@npm:^1.3.3": + version: 1.3.3 + resolution: "tiny-invariant@npm:1.3.3" + checksum: 5e185c8cc2266967984ce3b352a4e57cb89dad5a8abb0dea21468a6ecaa67cd5bb47a3b7a85d08041008644af4f667fb8b6575ba38ba5fb00b3b5068306e59fe languageName: node linkType: hard @@ -42574,12 +41771,10 @@ __metadata: languageName: node linkType: hard -"tmp@npm:^0.2.1": - version: 0.2.1 - resolution: "tmp@npm:0.2.1" - dependencies: - rimraf: ^3.0.0 - checksum: 8b1214654182575124498c87ca986ac53dc76ff36e8f0e0b67139a8d221eaecfdec108c0e6ec54d76f49f1f72ab9325500b246f562b926f85bcdfca8bf35df9e +"tmp@npm:^0.2.3": + version: 0.2.3 + resolution: "tmp@npm:0.2.3" + checksum: 73b5c96b6e52da7e104d9d44afb5d106bb1e16d9fa7d00dbeb9e6522e61b571fbdb165c756c62164be9a3bbe192b9b268c236d370a2a0955c7689cd2ae377b95 languageName: node linkType: hard @@ -42604,22 +41799,6 @@ __metadata: languageName: node linkType: hard -"to-no-case@npm:^1.0.0": - version: 1.0.2 - resolution: "to-no-case@npm:1.0.2" - checksum: 1d85326eeb89f9f3a805bf5b395bcabb8556e882350164c1faa10846076732f4cec02ac95b016e7d6bb2f55e448ce5dd227c7699ec43e387c705a5b2b1ee2963 - languageName: node - linkType: hard - -"to-pascal-case@npm:^1.0.0": - version: 1.0.0 - resolution: "to-pascal-case@npm:1.0.0" - dependencies: - to-space-case: ^1.0.0 - checksum: 3956e209defc6df9de98c5db24a16fb2a1a11f711350ea3bdd9466240a04ab889fa09f1bd005e26fc31343c1cca341981daf2d80d4ec3f2d0706a557978f8b91 - languageName: node - linkType: hard - "to-readable-stream@npm:^1.0.0": version: 1.0.0 resolution: "to-readable-stream@npm:1.0.0" @@ -42636,15 +41815,6 @@ __metadata: languageName: node linkType: hard -"to-space-case@npm:^1.0.0": - version: 1.0.0 - resolution: "to-space-case@npm:1.0.0" - dependencies: - to-no-case: ^1.0.0 - checksum: 157cebe3e98e7cb465fe1978cf26450cc8ea8e637a01039854fac7ed60ad074e5e18b32333cc5f30df81b81ca374d63df768cd4c1fa0fe672605f965376227f4 - languageName: node - linkType: hard - "toggle-selection@npm:^1.0.6": version: 1.0.6 resolution: "toggle-selection@npm:1.0.6" @@ -42694,15 +41864,15 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^4.0.0": - version: 4.1.3 - resolution: "tough-cookie@npm:4.1.3" +"tough-cookie@npm:^4.0.0, tough-cookie@npm:^4.1.4": + version: 4.1.4 + resolution: "tough-cookie@npm:4.1.4" dependencies: psl: ^1.1.33 punycode: ^2.1.1 universalify: ^0.2.0 url-parse: ^1.5.3 - checksum: c9226afff36492a52118432611af083d1d8493a53ff41ec4ea48e5b583aec744b989e4280bcf476c910ec1525a89a4a0f1cae81c08b18fb2ec3a9b3a72b91dcc + checksum: 5815059f014c31179a303c673f753f7899a6fce94ac93712c88ea5f3c26e0c042b5f0c7a599a00f8e0feeca4615dba75c3dffc54f3c1a489978aa8205e09307c languageName: node linkType: hard @@ -42823,10 +41993,10 @@ __metadata: languageName: node linkType: hard -"ts-algebra@npm:^1.2.2": - version: 1.2.2 - resolution: "ts-algebra@npm:1.2.2" - checksum: eea0c08fba10c4a758086079c575a32c4c050f50087e06fcc1ccd53b045bdf7bdb0ab9597a52a241a714f058ff047cedbddcb1539de5e66bb424aa5b33c677a1 +"ts-algebra@npm:^2.0.0": + version: 2.0.0 + resolution: "ts-algebra@npm:2.0.0" + checksum: 970b0e7db49cf8c1a8ff2a816eb047fac8add47511f5e4995e4998c56c6f7b226399284412de88f3e137ab55c857a4262c0d8f02f0765730e7d3a021de2ea7ef languageName: node linkType: hard @@ -42960,17 +42130,6 @@ __metadata: languageName: node linkType: hard -"tsconfig-paths@npm:^4.2.0": - version: 4.2.0 - resolution: "tsconfig-paths@npm:4.2.0" - dependencies: - json5: ^2.2.2 - minimist: ^1.2.6 - strip-bom: ^3.0.0 - checksum: 28c5f7bbbcabc9dabd4117e8fdc61483f6872a1c6b02a4b1c4d68c5b79d06896c3cc9547610c4c3ba64658531caa2de13ead1ea1bf321c7b53e969c4752b98c7 - languageName: node - linkType: hard - "tslib@npm:2.6.2, tslib@npm:^2.0.0, tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:^2.4.1 || ^1.9.3, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" @@ -43010,13 +42169,6 @@ __metadata: languageName: node linkType: hard -"tty-browserify@npm:0.0.1": - version: 0.0.1 - resolution: "tty-browserify@npm:0.0.1" - checksum: 93b745d43fa5a7d2b948fa23be8d313576d1d884b48acd957c07710bac1c0d8ac34c0556ad4c57c73d36e11741763ef66b3fb4fb97b06b7e4d525315a3cd45f5 - languageName: node - linkType: hard - "tunnel-agent@npm:^0.6.0": version: 0.6.0 resolution: "tunnel-agent@npm:0.6.0" @@ -43114,13 +42266,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^3.0.0": - version: 3.13.1 - resolution: "type-fest@npm:3.13.1" - checksum: c06b0901d54391dc46de3802375f5579868949d71f93b425ce564e19a428a0d411ae8d8cb0e300d330071d86152c3ea86e744c3f2860a42a79585b6ec2fdae8e - languageName: node - linkType: hard - "type-fest@npm:^4.9.0": version: 4.9.0 resolution: "type-fest@npm:4.9.0" @@ -43427,12 +42572,19 @@ __metadata: languageName: node linkType: hard -"unescape-js@npm:^1.0.5": - version: 1.1.4 - resolution: "unescape-js@npm:1.1.4" +"undici-types@npm:~6.19.2": + version: 6.19.8 + resolution: "undici-types@npm:6.19.8" + checksum: de51f1b447d22571cf155dfe14ff6d12c5bdaec237c765085b439c38ca8518fc360e88c70f99469162bf2e14188a7b0bcb06e1ed2dc031042b984b0bb9544017 + languageName: node + linkType: hard + +"undici@npm:^5.28.4": + version: 5.28.4 + resolution: "undici@npm:5.28.4" dependencies: - string.fromcodepoint: ^0.2.1 - checksum: 97acf60a8f6c170f8a66b48b71f5c56bda728c2ff6b08c3443c5f21635bf5fa38a4265bcfcf46d17cb6ac9bbb8b913a34b1abc5cfe8db5d7cc5c8eecb1817472 + "@fastify/busboy": ^2.0.0 + checksum: a8193132d84540e4dc1895ecc8dbaa176e8a49d26084d6fbe48a292e28397cd19ec5d13bc13e604484e76f94f6e334b2bdc740d5f06a6e50c44072818d0c19f9 languageName: node linkType: hard @@ -43692,9 +42844,9 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.16": - version: 1.0.16 - resolution: "update-browserslist-db@npm:1.0.16" +"update-browserslist-db@npm:^1.1.0": + version: 1.1.0 + resolution: "update-browserslist-db@npm:1.1.0" dependencies: escalade: ^3.1.2 picocolors: ^1.0.1 @@ -43702,7 +42854,7 @@ __metadata: browserslist: ">= 4.21.0" bin: update-browserslist-db: cli.js - checksum: 51b1f7189c9ea5925c80154b0a6fd3ec36106d07858d8f69826427d8edb4735d1801512c69eade38ba0814d7407d11f400d74440bbf3da0309f3d788017f35b2 + checksum: 7b74694d96f0c360f01b702e72353dc5a49df4fe6663d3ee4e5c628f061576cddf56af35a3a886238c01dd3d8f231b7a86a8ceaa31e7a9220ae31c1c1238e562 languageName: node linkType: hard @@ -43827,13 +42979,13 @@ __metadata: languageName: node linkType: hard -"use-immer@npm:^0.9.0": - version: 0.9.0 - resolution: "use-immer@npm:0.9.0" +"use-immer@npm:^0.10.0": + version: 0.10.0 + resolution: "use-immer@npm:0.10.0" peerDependencies: - immer: ">=2.0.0" + immer: ">=8.0.0" react: ^16.8.0 || ^17.0.1 || ^18.0.0 - checksum: 3f02e31d38f354125e6cffaaed0a08d9bf122b9df261aa7b38a25246813b3bd8b22bf97b192099d4e84adcfbbb07e69e14ba29520e0ac8d93f3991ef3a3652b4 + checksum: 372b0eea0a05e9435f5dc57a877ec619ea9a479fc82423f502b4a498d5697f8b06b85d089058db5a056bc8bbdb8e6f9ea8c9850b51a6b05d5c63ab0c8eeb2b7e languageName: node linkType: hard @@ -43934,7 +43086,7 @@ __metadata: languageName: node linkType: hard -"util@npm:^0.12.0, util@npm:^0.12.3, util@npm:^0.12.4": +"util@npm:^0.12.3": version: 0.12.5 resolution: "util@npm:0.12.5" dependencies: @@ -44180,87 +43332,6 @@ __metadata: languageName: node linkType: hard -"vite-plugin-html@npm:^3.2.0": - version: 3.2.2 - resolution: "vite-plugin-html@npm:3.2.2" - dependencies: - "@rollup/pluginutils": ^4.2.0 - colorette: ^2.0.16 - connect-history-api-fallback: ^1.6.0 - consola: ^2.15.3 - dotenv: ^16.0.0 - dotenv-expand: ^8.0.2 - ejs: ^3.1.6 - fast-glob: ^3.2.11 - fs-extra: ^10.0.1 - html-minifier-terser: ^6.1.0 - node-html-parser: ^5.3.3 - pathe: ^0.2.0 - peerDependencies: - vite: ">=2.0.0" - checksum: 2fd6e1f91f74a4432222ed28e68d5f27e58ccbc9ad44e71ff9d02b684b358b0c634bdb4dd32e9d93d09e88d83c3b7b74b89698e25510bc5b94173cdc067b3ac2 - languageName: node - linkType: hard - -"vite-plugin-node-polyfills@npm:^0.22.0": - version: 0.22.0 - resolution: "vite-plugin-node-polyfills@npm:0.22.0" - dependencies: - "@rollup/plugin-inject": ^5.0.5 - node-stdlib-browser: ^1.2.0 - peerDependencies: - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 - checksum: c08d3df0d5cc3102280483d3f7b216f92a18e0708fcb9f67f78f01ab865474254756bacee17caa90b3f46afe5834cb9d8de0dd0e58c1bbbdae1b949edc1e6b57 - languageName: node - linkType: hard - -"vite@npm:^4.4.9": - version: 4.5.3 - resolution: "vite@npm:4.5.3" - dependencies: - esbuild: ^0.18.10 - fsevents: ~2.3.2 - postcss: ^8.4.27 - rollup: ^3.27.1 - peerDependencies: - "@types/node": ">= 14" - less: "*" - lightningcss: ^1.21.0 - sass: "*" - stylus: "*" - sugarss: "*" - terser: ^5.4.0 - dependenciesMeta: - fsevents: - optional: true - peerDependenciesMeta: - "@types/node": - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - bin: - vite: bin/vite.js - checksum: fd3f512ce48ca2a1fe60ad0376283b832de9272725fdbc65064ae9248f792de87b0f27a89573115e23e26784800daca329f8a9234d298ba6f60e808a9c63883c - languageName: node - linkType: hard - -"vlq@npm:^0.2.1": - version: 0.2.3 - resolution: "vlq@npm:0.2.3" - checksum: 2231d8caeb5b2c1a438677ab029e9a94aa6fb61ab05819c72691b792aea0456dab29576aff5ae29309ee45bad0a309e832dc45173119bca1393f3b87709d8f8d - languageName: node - linkType: hard - "vm-browserify@npm:^1.0.1": version: 1.1.2 resolution: "vm-browserify@npm:1.1.2" @@ -44415,9 +43486,9 @@ __metadata: languageName: node linkType: hard -"webpack-dev-middleware@npm:^7.1.0": - version: 7.2.1 - resolution: "webpack-dev-middleware@npm:7.2.1" +"webpack-dev-middleware@npm:^7.4.2": + version: 7.4.2 + resolution: "webpack-dev-middleware@npm:7.4.2" dependencies: colorette: ^2.0.10 memfs: ^4.6.0 @@ -44430,13 +43501,13 @@ __metadata: peerDependenciesMeta: webpack: optional: true - checksum: bb8c75f7ceabc13ee2c3bc9648190e05a0a8c6d40b940ef72b09ea858a63d16bcb434b49995f1025125a1c3a1c8d40274beb5d26ef2fb1458b19e7f6fe3a91fe + checksum: 39314ec5e4468d177dd61fb51af87ec097e920fe0f0dc101e1bf71796740a7e49fd4f7f939cf91e130232714d6d2fffd948d72dc65dec10f87ac30339929f018 languageName: node linkType: hard "webpack-dev-server@npm:^5.0.0": - version: 5.0.4 - resolution: "webpack-dev-server@npm:5.0.4" + version: 5.1.0 + resolution: "webpack-dev-server@npm:5.1.0" dependencies: "@types/bonjour": ^3.5.13 "@types/connect-history-api-fallback": ^1.5.4 @@ -44451,8 +43522,7 @@ __metadata: colorette: ^2.0.10 compression: ^1.7.4 connect-history-api-fallback: ^2.0.0 - default-gateway: ^6.0.3 - express: ^4.17.3 + express: ^4.19.2 graceful-fs: ^4.2.6 html-entities: ^2.4.0 http-proxy-middleware: ^2.0.3 @@ -44460,14 +43530,13 @@ __metadata: launch-editor: ^2.6.1 open: ^10.0.3 p-retry: ^6.2.0 - rimraf: ^5.0.5 schema-utils: ^4.2.0 selfsigned: ^2.4.1 serve-index: ^1.9.1 sockjs: ^0.3.24 spdy: ^4.0.2 - webpack-dev-middleware: ^7.1.0 - ws: ^8.16.0 + webpack-dev-middleware: ^7.4.2 + ws: ^8.18.0 peerDependencies: webpack: ^5.0.0 peerDependenciesMeta: @@ -44477,7 +43546,7 @@ __metadata: optional: true bin: webpack-dev-server: bin/webpack-dev-server.js - checksum: b3535d01e8d895f4ce6d74b5f76e29398b712476216cd6d459365e5cc2f2fb1e49240aef6c23b2b943b04dbf768d7d18301af3eb064038bde4e11d03c241202d + checksum: 3128fffeb76b97cc4c506607f81bb644437f6961cf310915e22ecaf79a45c185893d7fc8e1844183fb44827061ec2f3d321e937840f02d4989959a09551a8e35 languageName: node linkType: hard @@ -44506,19 +43575,18 @@ __metadata: linkType: hard "webpack@npm:^5, webpack@npm:^5.70.0": - version: 5.91.0 - resolution: "webpack@npm:5.91.0" + version: 5.94.0 + resolution: "webpack@npm:5.94.0" dependencies: - "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.5 "@webassemblyjs/ast": ^1.12.1 "@webassemblyjs/wasm-edit": ^1.12.1 "@webassemblyjs/wasm-parser": ^1.12.1 acorn: ^8.7.1 - acorn-import-assertions: ^1.9.0 + acorn-import-attributes: ^1.9.5 browserslist: ^4.21.10 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.16.0 + enhanced-resolve: ^5.17.1 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 @@ -44538,7 +43606,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: f1073715dbb1ed5c070affef293d800a867708bcbc5aba4d8baee87660e0cf53c55966a6f36fab078d1d6c9567cdcd0a9086bdfb607cab87ea68c6449791b9a3 + checksum: 6a3d667be304a69cd6dcb8d676bc29f47642c0d389af514cfcd646eaaa809961bc6989fc4b2621a717dfc461130f29c6e20006d62a32e012dafaa9517813a4e6 languageName: node linkType: hard @@ -44678,7 +43746,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": +"which-typed-array@npm:^1.1.13, which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.2, which-typed-array@npm:^1.1.9": version: 1.1.15 resolution: "which-typed-array@npm:1.1.15" dependencies: @@ -44743,32 +43811,32 @@ __metadata: linkType: hard "winston-transport@npm:^4.5.0, winston-transport@npm:^4.7.0": - version: 4.7.0 - resolution: "winston-transport@npm:4.7.0" + version: 4.7.1 + resolution: "winston-transport@npm:4.7.1" dependencies: - logform: ^2.3.2 - readable-stream: ^3.6.0 + logform: ^2.6.1 + readable-stream: ^3.6.2 triple-beam: ^1.3.0 - checksum: ce074b5c76a99bee5236cf2b4d30fadfaf1e551d566f654f1eba303dc5b5f77169c21545ff5c5e4fdad9f8e815fc6d91b989f1db34161ecca6e860e62fd3a862 + checksum: e1dc070df1eb2ab0270a369fd7e8ff2b7a714ba9cf9a3f2c9a3509eb5fe60667c64e5cd4f37b3dd64a21017a93ea63fdcb2ac9176b12d2222a9e4244439d1b35 languageName: node linkType: hard "winston@npm:^3.13.0, winston@npm:^3.2.1": - version: 3.13.0 - resolution: "winston@npm:3.13.0" + version: 3.14.2 + resolution: "winston@npm:3.14.2" dependencies: "@colors/colors": ^1.6.0 "@dabh/diagnostics": ^2.0.2 async: ^3.2.3 is-stream: ^2.0.0 - logform: ^2.4.0 + logform: ^2.6.0 one-time: ^1.0.0 readable-stream: ^3.4.0 safe-stable-stringify: ^2.3.1 stack-trace: 0.0.x triple-beam: ^1.3.0 winston-transport: ^4.7.0 - checksum: 66f9fbbadb58e1632701e9c89391f217310c9455462148e163e060dcd25aed21351b0413bdbbf90e5c5fe9bc945fc5de6f53875ac7c7ef3061133a354fc678c0 + checksum: 9021637d3ab1d1e639d64e7217ed5ae63fb0e5325defdbce439f708e9b4e26c7a31eb4a731106790aa8ac6f80a3a89242de18d1991ab3838f9d84e55101f4607 languageName: node linkType: hard @@ -44837,17 +43905,6 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^2.3.0": - version: 2.4.3 - resolution: "write-file-atomic@npm:2.4.3" - dependencies: - graceful-fs: ^4.1.11 - imurmurhash: ^0.1.4 - signal-exit: ^3.0.2 - checksum: 2db81f92ae974fd87ab4a5e7932feacaca626679a7c98fcc73ad8fcea5a1950eab32fa831f79e9391ac99b562ca091ad49be37a79045bd65f595efbb8f4596ae - languageName: node - linkType: hard - "write-file-atomic@npm:^3.0.0": version: 3.0.3 resolution: "write-file-atomic@npm:3.0.3" @@ -44870,7 +43927,17 @@ __metadata: languageName: node linkType: hard -"ws@npm:*, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.13.0, ws@npm:^8.14.2, ws@npm:^8.16.0, ws@npm:^8.17.0, ws@npm:^8.8.0": +"write-file-atomic@npm:^5.0.1": + version: 5.0.1 + resolution: "write-file-atomic@npm:5.0.1" + dependencies: + imurmurhash: ^0.1.4 + signal-exit: ^4.0.1 + checksum: 8dbb0e2512c2f72ccc20ccedab9986c7d02d04039ed6e8780c987dc4940b793339c50172a1008eed7747001bfacc0ca47562668a069a7506c46c77d7ba3926a9 + languageName: node + linkType: hard + +"ws@npm:*, ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.13.0, ws@npm:^8.14.2, ws@npm:^8.17.0, ws@npm:^8.18.0, ws@npm:^8.8.0": version: 8.18.0 resolution: "ws@npm:8.18.0" peerDependencies: @@ -45040,7 +44107,7 @@ __metadata: languageName: node linkType: hard -"xtend@npm:^4.0.0, xtend@npm:^4.0.2": +"xtend@npm:^4.0.0": version: 4.0.2 resolution: "xtend@npm:4.0.2" checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a @@ -45129,12 +44196,12 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.0.0, yaml@npm:^2.0.0-10, yaml@npm:^2.1.1, yaml@npm:^2.2.1, yaml@npm:^2.2.2, yaml@npm:^2.3.2, yaml@npm:^2.3.3, yaml@npm:~2.4.2": - version: 2.4.5 - resolution: "yaml@npm:2.4.5" +"yaml@npm:^2.0.0, yaml@npm:^2.0.0-10, yaml@npm:^2.1.1, yaml@npm:^2.2.1, yaml@npm:^2.2.2, yaml@npm:^2.3.2, yaml@npm:^2.3.3, yaml@npm:~2.5.0": + version: 2.5.1 + resolution: "yaml@npm:2.5.1" bin: yaml: bin.mjs - checksum: f8efd407c07e095f00f3031108c9960b2b12971d10162b1ec19007200f6c987d2e28f73283f4731119aa610f177a3ea03d4a8fcf640600a25de1b74d00c69b3d + checksum: 31275223863fbd0b47ba9d2b248fbdf085db8d899e4ca43fff8a3a009497c5741084da6871d11f40e555d61360951c4c910b98216c1325d2c94753c0036d8172 languageName: node linkType: hard @@ -45347,17 +44414,6 @@ __metadata: languageName: node linkType: hard -"zip-stream@npm:^4.1.0": - version: 4.1.0 - resolution: "zip-stream@npm:4.1.0" - dependencies: - archiver-utils: ^2.1.0 - compress-commons: ^4.1.0 - readable-stream: ^3.6.0 - checksum: 4a73da856738b0634700b52f4ab3fe0bf0a532bea6820ad962d0bda0163d2d5525df4859f89a7238e204a378384e12551985049790c1894c3ac191866e85887f - languageName: node - linkType: hard - "zip-stream@npm:^5.0.1": version: 5.0.1 resolution: "zip-stream@npm:5.0.1" @@ -45369,12 +44425,23 @@ __metadata: languageName: node linkType: hard +"zip-stream@npm:^6.0.1": + version: 6.0.1 + resolution: "zip-stream@npm:6.0.1" + dependencies: + archiver-utils: ^5.0.0 + compress-commons: ^6.0.2 + readable-stream: ^4.0.0 + checksum: aa5abd6a89590eadeba040afbc375f53337f12637e5e98330012a12d9886cde7a3ccc28bd91aafab50576035bbb1de39a9a316eecf2411c8b9009c9f94f0db27 + languageName: node + linkType: hard + "zod-to-json-schema@npm:^3.20.4, zod-to-json-schema@npm:^3.21.4": - version: 3.22.5 - resolution: "zod-to-json-schema@npm:3.22.5" + version: 3.23.2 + resolution: "zod-to-json-schema@npm:3.23.2" peerDependencies: - zod: ^3.22.4 - checksum: 3c4f87c7cf0f8027ff5e40f30d7b6c823a7a5a521b1238c0dd82b2dfcf259d8c8ea01e030639b0ffa2ab50fd69632999fd40b54b4af49f75b3192c1416c4f8d0 + zod: ^3.23.3 + checksum: 6dc87a6045f5dcca23d009f2e212f3f5dbb790b1e80488162560359f30aa2babb6a2ea8d44953e9193c6c923300c58e5ae157a9dc089d0bcf5e2437b3158ca1b languageName: node linkType: hard