diff --git a/.changeset/afraid-foxes-provide.md b/.changeset/afraid-foxes-provide.md deleted file mode 100644 index e02702b895..0000000000 --- a/.changeset/afraid-foxes-provide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-sonarqube': patch ---- - -Additional export added in order to bind SonarQubeClient to its apiref diff --git a/.changeset/afraid-planets-crash.md b/.changeset/afraid-planets-crash.md deleted file mode 100644 index b31a492f3d..0000000000 --- a/.changeset/afraid-planets-crash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': minor ---- - -**BREAKING**: Renamed `RootHttpRouterConfigureOptions` to `RootHttpRouterConfigureContext`, and removed the unused type `ServiceOrExtensionPoint`. diff --git a/.changeset/brave-cougars-burn.md b/.changeset/brave-cougars-burn.md deleted file mode 100644 index 419378d25d..0000000000 --- a/.changeset/brave-cougars-burn.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -`scaffolder/next`: bump `react-jsonschema-form` libraries to `v5-stable` diff --git a/.changeset/brave-lemons-chew.md b/.changeset/brave-lemons-chew.md deleted file mode 100644 index 61bf7cc6af..0000000000 --- a/.changeset/brave-lemons-chew.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-playlist-backend': patch -'@backstage/plugin-catalog-backend': patch ---- - -Minor improvements to the descriptions provided with permission rules schemas diff --git a/.changeset/breezy-bees-care.md b/.changeset/breezy-bees-care.md new file mode 100644 index 0000000000..9a5b59fe03 --- /dev/null +++ b/.changeset/breezy-bees-care.md @@ -0,0 +1,5 @@ +--- +'@backstage/catalog-client': minor +--- + +Add `queryEntities` method to `CatalogApi`. diff --git a/.changeset/breezy-ears-rule.md b/.changeset/breezy-ears-rule.md deleted file mode 100644 index 753554187d..0000000000 --- a/.changeset/breezy-ears-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-gitlab': patch ---- - -The config now consistently uses the term 'instance' to refer to a single GitLab API host. diff --git a/.changeset/bright-eagles-love.md b/.changeset/bright-eagles-love.md deleted file mode 100644 index eade94f6f8..0000000000 --- a/.changeset/bright-eagles-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-incremental-ingestion': minor ---- - -Added new mechanism to handle deltas in incremental providers diff --git a/.changeset/bright-kids-raise.md b/.changeset/bright-kids-raise.md new file mode 100644 index 0000000000..e0d69e0c71 --- /dev/null +++ b/.changeset/bright-kids-raise.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-todo-backend': patch +--- + +todo-backend is now exposed as a plugin which uses the new plugin system diff --git a/.changeset/bright-plums-cough.md b/.changeset/bright-plums-cough.md deleted file mode 100644 index 9af30f002e..0000000000 --- a/.changeset/bright-plums-cough.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -**BREAKING**: Split out the hook for both lifecycle services so that the first parameter of `addShutdownHook` is the hook function, and the second is the options. diff --git a/.changeset/bright-teachers-compete.md b/.changeset/bright-teachers-compete.md deleted file mode 100644 index 3cc900d613..0000000000 --- a/.changeset/bright-teachers-compete.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -**BREAKING**: The plugin ID option passed to `createBackendPlugin` is now `pluginId`, rather than just `id`. This is to make it match `createBackendModule` more closely. diff --git a/.changeset/brown-islands-own.md b/.changeset/brown-islands-own.md deleted file mode 100644 index d91ab89fd8..0000000000 --- a/.changeset/brown-islands-own.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-devops': patch ---- - -Fixed `AssignedToCurrentUsersTeams` & `CreatedByCurrentUsersTeams` filter in `AzurePullRequestsPage` component. diff --git a/.changeset/brown-kings-wait.md b/.changeset/brown-kings-wait.md deleted file mode 100644 index db3fc0ee86..0000000000 --- a/.changeset/brown-kings-wait.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -The list of entities takes into account the title when its different from the name to sort the entities. diff --git a/.changeset/calm-avocados-exercise.md b/.changeset/calm-avocados-exercise.md deleted file mode 100644 index c62ae4bd83..0000000000 --- a/.changeset/calm-avocados-exercise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-common': patch ---- - -New K8s catalog entity annotations added that will replace now deprecated k8s annotations in the catalog-model package. K8s annotation imports should now be made from plugin-kubernetes-common. diff --git a/.changeset/chatty-lemons-reply.md b/.changeset/chatty-lemons-reply.md deleted file mode 100644 index 118f832646..0000000000 --- a/.changeset/chatty-lemons-reply.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-elasticsearch': patch ---- - -Export `decodeElasticSearchPageCursor` utility function diff --git a/.changeset/chatty-owls-care.md b/.changeset/chatty-owls-care.md deleted file mode 100644 index 9f39f51bb5..0000000000 --- a/.changeset/chatty-owls-care.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -The `backstage-cli repo test` command now sets a default Jest `--workerIdleMemoryLimit` of 1GB. If needed to ensure that tests are not run in band, `--maxWorkers=2` is set as well. This is the recommended workaround for dealing with Jest workers leaking memory and eventually hitting the heap limit. diff --git a/.changeset/chilled-brooms-jog.md b/.changeset/chilled-brooms-jog.md deleted file mode 100644 index d848246b2b..0000000000 --- a/.changeset/chilled-brooms-jog.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -**BREAKING**: The `CacheClient` interface must now also implement the `withOptions` method. The `.get()` method has also received a type parameter that helps ensure that `undefined` in the event of a cache miss is handled. - -Added a `cacheToPluginCacheManager` helper that converts a `CacheService` into a legacy `PluginCacheManager` instance. diff --git a/.changeset/chilled-sheep-collect.md b/.changeset/chilled-sheep-collect.md deleted file mode 100644 index b944685e16..0000000000 --- a/.changeset/chilled-sheep-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Removed unnecessary `@backstage/cli` dependency. diff --git a/.changeset/clean-queens-judge.md b/.changeset/clean-queens-judge.md deleted file mode 100644 index a394bfa9a7..0000000000 --- a/.changeset/clean-queens-judge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -The process of adding or modifying fields in the software-catalog search index has been simplified. For more details, see [how to customize fields in the Software Catalog index](https://backstage.io/docs/features/search/how-to-guides#how-to-customize-fields-in-the-software-catalog-index). diff --git a/.changeset/cold-cycles-switch.md b/.changeset/cold-cycles-switch.md deleted file mode 100644 index 0df71a82d3..0000000000 --- a/.changeset/cold-cycles-switch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Adding new Cluster detail fields to catalogClusterLocator. Replace deprecated imports with k8s annotations from plugin-kubernetes-common. diff --git a/.changeset/cool-clocks-prove.md b/.changeset/cool-clocks-prove.md new file mode 100644 index 0000000000..dfd7b8c5eb --- /dev/null +++ b/.changeset/cool-clocks-prove.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Fixed a bug where additional backend package entry points where not properly marked as internal during local development. diff --git a/.changeset/cool-spoons-bathe.md b/.changeset/cool-spoons-bathe.md deleted file mode 100644 index b6bcaf89aa..0000000000 --- a/.changeset/cool-spoons-bathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-lighthouse-backend': minor ---- - -Introduce Lighthouse Backend Plugin to run scheduled Lighthouse Audits diff --git a/.changeset/create-app-1674561612.md b/.changeset/create-app-1676993958.md similarity index 100% rename from .changeset/create-app-1674561612.md rename to .changeset/create-app-1676993958.md diff --git a/.changeset/cuddly-boxes-agree.md b/.changeset/cuddly-boxes-agree.md deleted file mode 100644 index 83f027ecb5..0000000000 --- a/.changeset/cuddly-boxes-agree.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': minor ---- - -Update DocsTable and EntityListDocsTable to accept overrides for Material Table options. diff --git a/.changeset/curvy-pets-hang.md b/.changeset/curvy-pets-hang.md new file mode 100644 index 0000000000..3a2d11ac12 --- /dev/null +++ b/.changeset/curvy-pets-hang.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +Tweaked type dependency check to trim wildcard type imports. diff --git a/.changeset/cyan-deers-walk.md b/.changeset/cyan-deers-walk.md deleted file mode 100644 index 236eb7935b..0000000000 --- a/.changeset/cyan-deers-walk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-node': patch ---- - -Fixed bug caused by recent migration to AWS SDK V3 for techdocs-node. Instead of s3ForcePathStyle, forcePathStyle should be passed. diff --git a/.changeset/dry-donkeys-cheer.md b/.changeset/dry-donkeys-cheer.md deleted file mode 100644 index 70ed45fa74..0000000000 --- a/.changeset/dry-donkeys-cheer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Added a check to ensure that Yarn v1 is used when creating new projects. diff --git a/.changeset/dull-fishes-suffer.md b/.changeset/dull-fishes-suffer.md deleted file mode 100644 index 54baae404e..0000000000 --- a/.changeset/dull-fishes-suffer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch ---- - -Removed the unused `TypesToServiceRef` type diff --git a/.changeset/dull-gorillas-sing.md b/.changeset/dull-gorillas-sing.md deleted file mode 100644 index 99246bea1c..0000000000 --- a/.changeset/dull-gorillas-sing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -The previous migration that adds the `search.original_value` column may leave some of the entities not updated. Add a migration script to trigger a reprocessing of the entities. diff --git a/.changeset/dull-pianos-shave.md b/.changeset/dull-pianos-shave.md deleted file mode 100644 index 8fae999bda..0000000000 --- a/.changeset/dull-pianos-shave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Added aria labels on the support button and sidebar diff --git a/.changeset/eight-falcons-explode.md b/.changeset/eight-falcons-explode.md deleted file mode 100644 index d9a1a2fe1f..0000000000 --- a/.changeset/eight-falcons-explode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Fixed an issue were the log redaction didn't properly escape RegExp characters. diff --git a/.changeset/eight-hotels-sparkle.md b/.changeset/eight-hotels-sparkle.md deleted file mode 100644 index 6846630e02..0000000000 --- a/.changeset/eight-hotels-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Show module name causing error during build diff --git a/.changeset/eight-radios-bake.md b/.changeset/eight-radios-bake.md new file mode 100644 index 0000000000..173739a625 --- /dev/null +++ b/.changeset/eight-radios-bake.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +throw error from catalog:fetch scaffolder action when entity is null and optional is false diff --git a/.changeset/eight-vans-drum.md b/.changeset/eight-vans-drum.md deleted file mode 100644 index 8e815a1701..0000000000 --- a/.changeset/eight-vans-drum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-lighthouse-common': minor ---- - -Introduce @backstage/plugin-lighthouse-common with the API implementation diff --git a/.changeset/eighty-geese-return.md b/.changeset/eighty-geese-return.md new file mode 100644 index 0000000000..49361de8e7 --- /dev/null +++ b/.changeset/eighty-geese-return.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-msgraph': patch +--- + +Revert using `baseUrl` for MS Graph provider as it breaks token retrieval diff --git a/.changeset/eighty-knives-repeat.md b/.changeset/eighty-knives-repeat.md deleted file mode 100644 index 3e32a3589d..0000000000 --- a/.changeset/eighty-knives-repeat.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-app-api': patch -'@backstage/backend-common': patch ---- - -Updated to match the new `CacheService` interface. diff --git a/.changeset/eleven-shoes-crash.md b/.changeset/eleven-shoes-crash.md deleted file mode 100644 index 8013f311d5..0000000000 --- a/.changeset/eleven-shoes-crash.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -scaffolder/next: Implementing a simple `OngoingTask` page diff --git a/.changeset/few-meals-buy.md b/.changeset/few-meals-buy.md deleted file mode 100644 index c49eb8c7ac..0000000000 --- a/.changeset/few-meals-buy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-aws': patch ---- - -Update to import `LocationSpec` from the correct package. diff --git a/.changeset/few-moons-accept.md b/.changeset/few-moons-accept.md deleted file mode 100644 index c790e837c8..0000000000 --- a/.changeset/few-moons-accept.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Replaced several monorepo lint rules with new rules from `@backstage/eslint-plugin`. See the [README](https://github.com/import-js/eslint-plugin-import/blob/main/packages/eslint-plugin/README.md) for a full list of rules. diff --git a/.changeset/few-trees-cross.md b/.changeset/few-trees-cross.md deleted file mode 100644 index ed70c3bddb..0000000000 --- a/.changeset/few-trees-cross.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Fixed Webpack loader patterns so that they properly match the file suffix only. diff --git a/.changeset/flat-cups-itch.md b/.changeset/flat-cups-itch.md deleted file mode 100644 index 250393c21a..0000000000 --- a/.changeset/flat-cups-itch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -lock versions of `@rjsf/*-beta` packages diff --git a/.changeset/flat-peaches-act.md b/.changeset/flat-peaches-act.md new file mode 100644 index 0000000000..e4b4138ee5 --- /dev/null +++ b/.changeset/flat-peaches-act.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-backend': patch +--- + +Techdocs backend explains a bit more about what might have caused the docs not being found when building techdocs. diff --git a/.changeset/four-candles-add.md b/.changeset/four-candles-add.md deleted file mode 100644 index fa975e0a58..0000000000 --- a/.changeset/four-candles-add.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@backstage/plugin-tech-insights-backend': patch -'@backstage/plugin-tech-insights-common': patch -'@backstage/plugin-tech-insights-node': minor -'@backstage/plugin-tech-insights': patch ---- - -TechInsightsApi interface now has getFactSchemas() method. -TechInsightsClient now implements method getFactSchemas(). - -**BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common - -These changes are **required** if you were importing this type directly. - -```diff -- import { FactSchema } from '@backstage/plugin-tech-insights-node'; -+ import { FactSchema } from '@backstage/plugin-tech-insights-common'; -``` diff --git a/.changeset/four-lizards-grin.md b/.changeset/four-lizards-grin.md new file mode 100644 index 0000000000..6fa5f57243 --- /dev/null +++ b/.changeset/four-lizards-grin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Fix export of `defaultCatalogCollatorEntityTransformer`. diff --git a/.changeset/four-rivers-enjoy.md b/.changeset/four-rivers-enjoy.md deleted file mode 100644 index b38babd8bd..0000000000 --- a/.changeset/four-rivers-enjoy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': patch ---- - -Fix MS Graph provider to use target URL for fetching access token diff --git a/.changeset/four-tables-fix.md b/.changeset/four-tables-fix.md deleted file mode 100644 index f17f57e253..0000000000 --- a/.changeset/four-tables-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Added explicit return type signature for `mockServices.config()`. diff --git a/.changeset/friendly-chefs-rule.md b/.changeset/friendly-chefs-rule.md deleted file mode 100644 index 872a36b5ae..0000000000 --- a/.changeset/friendly-chefs-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch ---- - -Removing extra imports for `run` script as `TestBackend` auto loads the default factories diff --git a/.changeset/friendly-scissors-shop.md b/.changeset/friendly-scissors-shop.md deleted file mode 100644 index 03c67ba491..0000000000 --- a/.changeset/friendly-scissors-shop.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -- **Deprecation** - Deprecated the following exports, please import them directly from `@backstage/plugin-scaffolder-react` instead - - ``` - createScaffolderLayout - ScaffolderLayouts - LayoutOptions - LayoutTemplate - ``` diff --git a/.changeset/fuzzy-trains-search.md b/.changeset/fuzzy-trains-search.md new file mode 100644 index 0000000000..229d25f3b5 --- /dev/null +++ b/.changeset/fuzzy-trains-search.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog': patch +--- + +Fix icon alignment in `CatalogSearchResultListItem` diff --git a/.changeset/gentle-pears-clean.md b/.changeset/gentle-pears-clean.md new file mode 100644 index 0000000000..d92c3709ae --- /dev/null +++ b/.changeset/gentle-pears-clean.md @@ -0,0 +1,5 @@ +--- +'@backstage/eslint-plugin': patch +--- + +Fixing a bug that we should check internal dependencies too diff --git a/.changeset/gold-bulldogs-talk.md b/.changeset/gold-bulldogs-talk.md deleted file mode 100644 index e5b6254ec5..0000000000 --- a/.changeset/gold-bulldogs-talk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search': minor ---- - -Update `SearchModal` component to use `SearchResult` extensions. diff --git a/.changeset/gold-lemons-eat.md b/.changeset/gold-lemons-eat.md deleted file mode 100644 index 8d9c0118b1..0000000000 --- a/.changeset/gold-lemons-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Updating the readme with better `csp` instructions diff --git a/.changeset/gold-masks-sleep.md b/.changeset/gold-masks-sleep.md deleted file mode 100644 index 425a1abdc0..0000000000 --- a/.changeset/gold-masks-sleep.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Fixed bug in Techdocs reader where a techdocs page with a hash in the URL did not always jump to the document anchor. diff --git a/.changeset/gorgeous-llamas-mate.md b/.changeset/gorgeous-llamas-mate.md deleted file mode 100644 index a2553875e9..0000000000 --- a/.changeset/gorgeous-llamas-mate.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-entity-feedback-backend': minor -'@backstage/plugin-entity-feedback-common': minor -'@backstage/plugin-entity-feedback': minor ---- - -Implement entity feedback plugin, check out the `README.md` for more details! diff --git a/.changeset/great-goats-talk.md b/.changeset/great-goats-talk.md deleted file mode 100644 index 92a1cd59ee..0000000000 --- a/.changeset/great-goats-talk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': minor ---- - -Adds a new tRPC API definition widget which users can utilize to integrate their tRPC API definitions into Backstage. diff --git a/.changeset/green-adults-retire.md b/.changeset/green-adults-retire.md deleted file mode 100644 index c13e8d664f..0000000000 --- a/.changeset/green-adults-retire.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-dev-utils': minor ---- - -Introduced a new package for backend development utilities. Similar to how `@backstage/dev-utils` is used in the frontend. diff --git a/.changeset/green-guests-flow.md b/.changeset/green-guests-flow.md deleted file mode 100644 index 688ff17dd9..0000000000 --- a/.changeset/green-guests-flow.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/backend-test-utils': patch -'@backstage/backend-app-api': patch -'@backstage/backend-common': patch -'@backstage/plugin-catalog-backend': patch ---- - -Updated usage of the lifecycle service. diff --git a/.changeset/grumpy-bikes-begin.md b/.changeset/grumpy-bikes-begin.md new file mode 100644 index 0000000000..a98e6651f5 --- /dev/null +++ b/.changeset/grumpy-bikes-begin.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-tech-insights-backend': patch +--- + +Add DB index to improve latency of latest fact query diff --git a/.changeset/grumpy-bottles-stare.md b/.changeset/grumpy-bottles-stare.md deleted file mode 100644 index 1e6040f57f..0000000000 --- a/.changeset/grumpy-bottles-stare.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': patch -'@backstage/plugin-scaffolder': patch ---- - -Upgrade `@rjsf` version 5 dependencies to `beta.18` diff --git a/.changeset/grumpy-fireants-drop.md b/.changeset/grumpy-fireants-drop.md deleted file mode 100644 index 92b08663f4..0000000000 --- a/.changeset/grumpy-fireants-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/codemods': patch ---- - -Moved `commander` to being a regular dependency. diff --git a/.changeset/happy-boxes-arrive.md b/.changeset/happy-boxes-arrive.md new file mode 100644 index 0000000000..85998c1bdd --- /dev/null +++ b/.changeset/happy-boxes-arrive.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +fix bug with `hasErrors` returning false when dealing with empty objects diff --git a/.changeset/happy-cows-moo.md b/.changeset/happy-cows-moo.md deleted file mode 100644 index a5e425f5d2..0000000000 --- a/.changeset/happy-cows-moo.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-devops-backend': patch ---- - -Fixed a bug where the azure devops host in URLs on the readme card was being URL encoded, breaking hosts with ports. diff --git a/.changeset/hip-chairs-double.md b/.changeset/hip-chairs-double.md deleted file mode 100644 index e2b03f2e66..0000000000 --- a/.changeset/hip-chairs-double.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -'@backstage/plugin-tech-radar': patch ---- - -Deprecate `RadarEntry.url` - use `RadarEntry.links` instead - -```diff -- url: 'https://www.javascript.com/', - key: 'javascript', - id: 'javascript', - title: 'JavaScript', - quadrant: 'languages', - links: [ -+ { -+ url: 'https://www.javascript.com/', -+ title: 'Learn more', -+ }, - ], -``` diff --git a/.changeset/hip-onions-tan.md b/.changeset/hip-onions-tan.md deleted file mode 100644 index 01be0d4867..0000000000 --- a/.changeset/hip-onions-tan.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend': patch ---- - -Change the router's response to include the error message instead of its object type in case it fails during a search query because the messages have more info. diff --git a/.changeset/hip-pugs-teach.md b/.changeset/hip-pugs-teach.md deleted file mode 100644 index 4a3820cecc..0000000000 --- a/.changeset/hip-pugs-teach.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@backstage/plugin-techdocs-module-addons-contrib': patch -'@backstage/plugin-techdocs-addons-test-utils': patch -'@backstage/plugin-apollo-explorer': patch -'@backstage/plugin-cicd-statistics': patch -'@backstage/plugin-codescene': patch -'@backstage/plugin-dynatrace': patch -'@backstage/plugin-org-react': patch -'@backstage/plugin-playlist': patch ---- - -Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages diff --git a/.changeset/hip-tables-prove.md b/.changeset/hip-tables-prove.md deleted file mode 100644 index bc2c4e83d6..0000000000 --- a/.changeset/hip-tables-prove.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Updated the `mockServices.rootLogger` options to accept a single level option instead. diff --git a/.changeset/honest-nails-bake.md b/.changeset/honest-nails-bake.md new file mode 100644 index 0000000000..03d5a080c9 --- /dev/null +++ b/.changeset/honest-nails-bake.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-octopus-deploy': minor +--- + +Initial version diff --git a/.changeset/hot-lions-cover.md b/.changeset/hot-lions-cover.md deleted file mode 100644 index 62064188a4..0000000000 --- a/.changeset/hot-lions-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-github': patch ---- - -Add support for filtering out forks diff --git a/.changeset/hot-wasps-cover.md b/.changeset/hot-wasps-cover.md deleted file mode 100644 index e142980b56..0000000000 --- a/.changeset/hot-wasps-cover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Updated to work with the new `type: 'pem'` with `createHttpServer` from `@backstage/backend-app-api` diff --git a/.changeset/hungry-news-fix.md b/.changeset/hungry-news-fix.md deleted file mode 100644 index c59113d9f4..0000000000 --- a/.changeset/hungry-news-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-sentry': patch ---- - -Fix broken module exports and dependencies to match a backend module, rather than a frontend plugin. diff --git a/.changeset/hungry-stingrays-type.md b/.changeset/hungry-stingrays-type.md deleted file mode 100644 index 8cb11f67a5..0000000000 --- a/.changeset/hungry-stingrays-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-backend': patch ---- - -Keep the tech docs sync event stream alive even if it is taking a while to build. diff --git a/.changeset/itchy-chairs-punch.md b/.changeset/itchy-chairs-punch.md deleted file mode 100644 index 034a9bbdae..0000000000 --- a/.changeset/itchy-chairs-punch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch ---- - -Aligned opaque type markers to all use a `$$type` property with namespacing. diff --git a/.changeset/itchy-goats-melt.md b/.changeset/itchy-goats-melt.md deleted file mode 100644 index d073dd4103..0000000000 --- a/.changeset/itchy-goats-melt.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch -'@backstage/plugin-scaffolder-backend-module-sentry': patch -'@backstage/plugin-scaffolder-backend-module-yeoman': patch -'@backstage/plugin-scaffolder-backend-module-rails': patch ---- - -Internal refactor to use the new `@backstage/plugin-scaffolder-node` package for some functionality diff --git a/.changeset/itchy-rings-rule.md b/.changeset/itchy-rings-rule.md deleted file mode 100644 index 3e8b9e8b2b..0000000000 --- a/.changeset/itchy-rings-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Fixed an issue where entities sometimes were not properly deleted during a full mutation. diff --git a/.changeset/khaki-poems-run.md b/.changeset/khaki-poems-run.md new file mode 100644 index 0000000000..74db902c02 --- /dev/null +++ b/.changeset/khaki-poems-run.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-entity-validation': patch +--- + +Fixed bug in EntityVaidation plugin where string in text box was unable to be updated. diff --git a/.changeset/khaki-toes-care.md b/.changeset/khaki-toes-care.md deleted file mode 100644 index e119208335..0000000000 --- a/.changeset/khaki-toes-care.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-common': minor ---- - -**BREAKING**: Renamed misspelled `LimitRangeFetchReponse` to `LimitRangeFetchResponse`. diff --git a/.changeset/late-rice-crash.md b/.changeset/late-rice-crash.md deleted file mode 100644 index b692310c01..0000000000 --- a/.changeset/late-rice-crash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Fixed regression that caused the `WelcomeTitle` to not be the right size when passed to the `title` property of the `
` component. A Storybook entry was also added for the `WelcomeTitle` diff --git a/.changeset/lazy-badgers-rule.md b/.changeset/lazy-badgers-rule.md deleted file mode 100644 index 748b9dbadc..0000000000 --- a/.changeset/lazy-badgers-rule.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-tech-insights-backend-module-jsonfc': patch ---- - -Surface the cause of the json rules engine diff --git a/.changeset/lazy-badgers-try.md b/.changeset/lazy-badgers-try.md deleted file mode 100644 index 4ffb32304a..0000000000 --- a/.changeset/lazy-badgers-try.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-node': minor ---- - -New package that takes over some of the types and functionality from `@backstage/plugin-scaffolder-backend` that are shared with other modules diff --git a/.changeset/lemon-tables-train.md b/.changeset/lemon-tables-train.md deleted file mode 100644 index 80b64bfe53..0000000000 --- a/.changeset/lemon-tables-train.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-aws': patch ---- - -Added support for `externalId` when assuming role in `AwsS3EntityProvider` diff --git a/.changeset/little-jars-lay.md b/.changeset/little-jars-lay.md deleted file mode 100644 index f8851f7adc..0000000000 --- a/.changeset/little-jars-lay.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/plugin-user-settings-backend': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-periskop-backend': patch -'@backstage/backend-common': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-bazaar-backend': patch -'@backstage/plugin-events-backend': patch -'@backstage/plugin-kafka-backend': patch -'@backstage/plugin-proxy-backend': patch -'@backstage/plugin-app-backend': patch ---- - -Updated usage of `createBackendPlugin`. diff --git a/.changeset/long-chefs-burn.md b/.changeset/long-chefs-burn.md deleted file mode 100644 index 03a7b76db9..0000000000 --- a/.changeset/long-chefs-burn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Updated database factory to pass service deps required for restoring database state during development. diff --git a/.changeset/long-nails-pump.md b/.changeset/long-nails-pump.md new file mode 100644 index 0000000000..d9eefc0249 --- /dev/null +++ b/.changeset/long-nails-pump.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Added a new `migrate package-exports` command that synchronizes package exports fields in all `package.json`s. diff --git a/.changeset/lovely-ladybugs-taste.md b/.changeset/lovely-ladybugs-taste.md deleted file mode 100644 index 24017e4dee..0000000000 --- a/.changeset/lovely-ladybugs-taste.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -**Deprecations**: The following are deprecated and should instead be imported from the new package `@backstage/plugin-scaffolder-node`: - -- `ActionContext` -- `createTemplateAction` -- `TaskSecrets` -- `TemplateAction` diff --git a/.changeset/many-nails-joke.md b/.changeset/many-nails-joke.md deleted file mode 100644 index 2ffd97dd0b..0000000000 --- a/.changeset/many-nails-joke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': minor ---- - -Added Markdown support in the `AboutCard` description section diff --git a/.changeset/many-pans-unite.md b/.changeset/many-pans-unite.md deleted file mode 100644 index 59c068cec1..0000000000 --- a/.changeset/many-pans-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-model': minor ---- - -Adds the tRPC API type to the catalog. diff --git a/.changeset/mean-squids-kneel.md b/.changeset/mean-squids-kneel.md deleted file mode 100644 index 41a1bd4086..0000000000 --- a/.changeset/mean-squids-kneel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-vault': patch ---- - -Surface additional context and details to the Backstage UI when the Vault plugin encounters non-successful HTTP responses from the Vault API. diff --git a/.changeset/metal-suns-rhyme.md b/.changeset/metal-suns-rhyme.md new file mode 100644 index 0000000000..3fefdca7c6 --- /dev/null +++ b/.changeset/metal-suns-rhyme.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Bumped the `msw` version in templates to 1.0.0 diff --git a/.changeset/modern-cats-worry.md b/.changeset/modern-cats-worry.md deleted file mode 100644 index b6698cb805..0000000000 --- a/.changeset/modern-cats-worry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Switched the order of reprocessing statements retroactively in migrations. This only improves the experience for those who at a later time perform a large upgrade of an old Backstage installation. diff --git a/.changeset/nasty-beans-accept.md b/.changeset/nasty-beans-accept.md deleted file mode 100644 index 51b3e88e49..0000000000 --- a/.changeset/nasty-beans-accept.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Update `SearchPage` template to use `SearchResult` extensions. diff --git a/.changeset/nasty-kids-deny.md b/.changeset/nasty-kids-deny.md deleted file mode 100644 index 4a434eb1f6..0000000000 --- a/.changeset/nasty-kids-deny.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/theme': patch ---- - -Use same table header color as @backstage/core-components Table to meet accessibility color contrast requirements. This change affects material-ui tables. diff --git a/.changeset/neat-schools-raise.md b/.changeset/neat-schools-raise.md deleted file mode 100644 index b778ba8795..0000000000 --- a/.changeset/neat-schools-raise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Kubernetes proxy endpoint now accepts content types that are not json diff --git a/.changeset/neat-zebras-run.md b/.changeset/neat-zebras-run.md deleted file mode 100644 index 4ce5d5c393..0000000000 --- a/.changeset/neat-zebras-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-app-api': patch ---- - -Fixed an issue where an explicit port the frontend base URL could break the app. diff --git a/.changeset/nervous-apricots-whisper.md b/.changeset/nervous-apricots-whisper.md deleted file mode 100644 index ce71486364..0000000000 --- a/.changeset/nervous-apricots-whisper.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Improve view: remove footer overlay on large screen diff --git a/.changeset/nervous-phones-shout.md b/.changeset/nervous-phones-shout.md deleted file mode 100644 index a4e46b3be9..0000000000 --- a/.changeset/nervous-phones-shout.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-test-utils': patch -'@backstage/backend-app-api': patch ---- - -Updates to match new `BackendFeature` type. diff --git a/.changeset/new-jobs-deny.md b/.changeset/new-jobs-deny.md new file mode 100644 index 0000000000..e7b5bff71a --- /dev/null +++ b/.changeset/new-jobs-deny.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': minor +--- + +Add possibility to re-use EntityPicker for filters with multiple select. diff --git a/.changeset/new-pumpkins-sleep.md b/.changeset/new-pumpkins-sleep.md deleted file mode 100644 index cc5b89806d..0000000000 --- a/.changeset/new-pumpkins-sleep.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-scaffolder-react': patch ---- - -bump `@rjsf` `v5` dependencies to 5.1.0 diff --git a/.changeset/nice-planets-wave.md b/.changeset/nice-planets-wave.md new file mode 100644 index 0000000000..2af1a14d83 --- /dev/null +++ b/.changeset/nice-planets-wave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-linguist-backend': minor +--- + +**BREAKING** The linguist-backend `createRouter` now requires that the `tokenManger` is passed to the router. diff --git a/.changeset/nine-glasses-invent.md b/.changeset/nine-glasses-invent.md deleted file mode 100644 index beb69b3b90..0000000000 --- a/.changeset/nine-glasses-invent.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes': patch ---- - -Condenses kubernetes ui plugin to fit more onscreen and increase visibility diff --git a/.changeset/nine-guests-compete.md b/.changeset/nine-guests-compete.md deleted file mode 100644 index 697236d0b7..0000000000 --- a/.changeset/nine-guests-compete.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -remove unused plugin-stack-overflow dependency diff --git a/.changeset/nine-ravens-kiss.md b/.changeset/nine-ravens-kiss.md deleted file mode 100644 index a507db6b03..0000000000 --- a/.changeset/nine-ravens-kiss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-adr': minor ---- - -The `AdrSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. diff --git a/.changeset/ninety-hats-serve.md b/.changeset/ninety-hats-serve.md deleted file mode 100644 index 762e53c242..0000000000 --- a/.changeset/ninety-hats-serve.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-azure': patch ---- - -This will add the ability to use Azure DevOps with multi project with a single value which is a new feature as previously this had to be done manually for each project that you wanted to add. - -Right now you would have to fill in multiple values in the config to use multiple projects: - -``` -yourFirstProviderId: # identifies your dataset / provider independent of config changes - organization: myorg - project: 'firstProject' # this will match the firstProject project - repository: '*' # this will match all repos - path: /catalog-info.yaml -yourSecondProviderId: # identifies your dataset / provider independent of config changes - organization: myorg - project: 'secondProject' # this will match the secondProject project - repository: '*' # this will match all repos - path: /catalog-info.yaml -``` - -With this change you can actually have all projects available where your PAT determines which you have access to, so that includes multiple projects: - -``` -yourFirstProviderId: # identifies your dataset / provider independent of config changes - organization: myorg - project: '*' # this will match all projects where your PAT has access to - repository: '*' # this will match all repos - path: /catalog-info.yaml -``` diff --git a/.changeset/ninety-turtles-wait.md b/.changeset/ninety-turtles-wait.md new file mode 100644 index 0000000000..683583528f --- /dev/null +++ b/.changeset/ninety-turtles-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +The HTML tag attributes in the documentation content inserted to shadow DOM is preserved to improve accessibility diff --git a/.changeset/odd-fireants-bathe.md b/.changeset/odd-fireants-bathe.md new file mode 100644 index 0000000000..d4b7f5dc5a --- /dev/null +++ b/.changeset/odd-fireants-bathe.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-adr-backend': patch +'@backstage/cli': patch +--- + +Adjust express dependencies to be the same as the rest of the project diff --git a/.changeset/odd-kangaroos-itch.md b/.changeset/odd-kangaroos-itch.md deleted file mode 100644 index 8529e5fe04..0000000000 --- a/.changeset/odd-kangaroos-itch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-graph': patch ---- - -Fix #16245: The CatalogGraphCard has parameter naming errors for CatalogGraphPage diff --git a/.changeset/old-foxes-shave.md b/.changeset/old-foxes-shave.md new file mode 100644 index 0000000000..4cd0808103 --- /dev/null +++ b/.changeset/old-foxes-shave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-api-docs': patch +--- + +Add ApiDefinitionDialog component for fast access to the API definition in ProvidedApiCards and ConsumedApiCards. diff --git a/.changeset/old-knives-wonder.md b/.changeset/old-knives-wonder.md deleted file mode 100644 index 93d2be4871..0000000000 --- a/.changeset/old-knives-wonder.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': minor ---- - -The `CatalogSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. diff --git a/.changeset/old-ways-know.md b/.changeset/old-ways-know.md deleted file mode 100644 index 60a1a923e8..0000000000 --- a/.changeset/old-ways-know.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -The `DatabaseManager.forPlugin` method now accepts additional service dependencies. There is no need to update existing code to pass these dependencies. diff --git a/.changeset/perfect-cheetahs-serve.md b/.changeset/perfect-cheetahs-serve.md deleted file mode 100644 index 08f7c1da21..0000000000 --- a/.changeset/perfect-cheetahs-serve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -Added the option to overwrite files in the `targetPath` of the `template:fetch` action diff --git a/.changeset/perfect-mayflies-greet.md b/.changeset/perfect-mayflies-greet.md new file mode 100644 index 0000000000..7e57507dae --- /dev/null +++ b/.changeset/perfect-mayflies-greet.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Updated frontend plugin template to use some more recent features diff --git a/.changeset/perfect-pears-care.md b/.changeset/perfect-pears-care.md deleted file mode 100644 index 2ea9f54a7f..0000000000 --- a/.changeset/perfect-pears-care.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-techdocs-backend': patch -'@backstage/plugin-techdocs-node': patch -'@techdocs/cli': patch ---- - -Added support for using a default `mkdocs.yml` configuration file when none is provided diff --git a/.changeset/pink-falcons-serve.md b/.changeset/pink-falcons-serve.md deleted file mode 100644 index 8cc6859c25..0000000000 --- a/.changeset/pink-falcons-serve.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor -'@backstage/plugin-scaffolder-react': minor ---- - -Embed scaffolder workflow in other components diff --git a/.changeset/polite-chicken-do.md b/.changeset/polite-chicken-do.md new file mode 100644 index 0000000000..33e4149253 --- /dev/null +++ b/.changeset/polite-chicken-do.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-vault-backend': patch +--- + +Ignore the `eslint` error diff --git a/.changeset/polite-falcons-jump.md b/.changeset/polite-falcons-jump.md new file mode 100644 index 0000000000..ab9209913d --- /dev/null +++ b/.changeset/polite-falcons-jump.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org': patch +--- + +Fix small UI-glitch in MemberListCard diff --git a/.changeset/poor-moons-confess.md b/.changeset/poor-moons-confess.md deleted file mode 100644 index 7489a3c9f1..0000000000 --- a/.changeset/poor-moons-confess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch ---- - -Return `EventSubscriber` from `addIncrementalEntityProvider` to hook up to `EventsBackend` diff --git a/.changeset/popular-dancers-join.md b/.changeset/popular-dancers-join.md deleted file mode 100644 index e7f6ab524f..0000000000 --- a/.changeset/popular-dancers-join.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -The Button component has been deprecated in favor of the LinkButton component diff --git a/.changeset/pre.json b/.changeset/pre.json index 01c51bcc4b..d3d0c1d42d 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,343 +1,254 @@ { - "mode": "exit", + "mode": "pre", "tag": "next", "initialVersions": { - "example-app": "0.2.79", - "@backstage/app-defaults": "1.1.0", - "example-backend": "0.2.79", - "@backstage/backend-app-api": "0.3.0", - "@backstage/backend-common": "0.18.0", - "@backstage/backend-defaults": "0.1.5", - "example-backend-next": "0.0.7", - "@backstage/backend-plugin-api": "0.3.0", - "@backstage/backend-tasks": "0.4.1", - "@backstage/backend-test-utils": "0.1.32", - "@backstage/catalog-client": "1.3.0", - "@backstage/catalog-model": "1.1.5", - "@backstage/cli": "0.22.1", + "example-app": "0.2.80", + "@backstage/app-defaults": "1.2.0", + "example-backend": "0.2.80", + "@backstage/backend-app-api": "0.4.0", + "@backstage/backend-common": "0.18.2", + "@backstage/backend-defaults": "0.1.7", + "@backstage/backend-dev-utils": "0.1.0", + "example-backend-next": "0.0.8", + "@backstage/backend-plugin-api": "0.4.0", + "@backstage/backend-tasks": "0.4.3", + "@backstage/backend-test-utils": "0.1.34", + "@backstage/catalog-client": "1.3.1", + "@backstage/catalog-model": "1.2.0", + "@backstage/cli": "0.22.2", "@backstage/cli-common": "0.1.11", - "@backstage/codemods": "0.1.42", + "@backstage/codemods": "0.1.43", "@backstage/config": "1.0.6", "@backstage/config-loader": "1.1.8", - "@backstage/core-app-api": "1.4.0", - "@backstage/core-components": "0.12.3", - "@backstage/core-plugin-api": "1.3.0", - "@backstage/create-app": "0.4.36", - "@backstage/dev-utils": "1.0.11", + "@backstage/core-app-api": "1.5.0", + "@backstage/core-components": "0.12.4", + "@backstage/core-plugin-api": "1.4.0", + "@backstage/create-app": "0.4.37", + "@backstage/dev-utils": "1.0.12", "e2e-test": "0.2.0", "@backstage/errors": "1.1.4", + "@backstage/eslint-plugin": "0.1.0", "@backstage/integration": "1.4.2", "@backstage/integration-aws-node": "0.1.1", - "@backstage/integration-react": "1.1.9", + "@backstage/integration-react": "1.1.10", "@backstage/release-manifests": "0.0.8", - "@backstage/repo-tools": "0.1.1", - "@techdocs/cli": "1.3.0", - "techdocs-cli-embedded-app": "0.2.78", - "@backstage/test-utils": "1.2.4", - "@backstage/theme": "0.2.16", + "@backstage/repo-tools": "0.1.2", + "@techdocs/cli": "1.3.2", + "techdocs-cli-embedded-app": "0.2.79", + "@backstage/test-utils": "1.2.5", + "@backstage/theme": "0.2.17", "@backstage/types": "1.0.2", "@backstage/version-bridge": "1.0.3", - "@backstage/plugin-adr": "0.3.0", - "@backstage/plugin-adr-backend": "0.2.5", - "@backstage/plugin-adr-common": "0.2.5", - "@backstage/plugin-airbrake": "0.3.14", - "@backstage/plugin-airbrake-backend": "0.2.13", - "@backstage/plugin-allure": "0.1.30", - "@backstage/plugin-analytics-module-ga": "0.1.25", - "@backstage/plugin-apache-airflow": "0.2.7", - "@backstage/plugin-api-docs": "0.8.14", - "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.0", - "@backstage/plugin-apollo-explorer": "0.1.7", - "@backstage/plugin-app-backend": "0.3.40", - "@backstage/plugin-auth-backend": "0.17.3", - "@backstage/plugin-auth-node": "0.2.9", - "@backstage/plugin-azure-devops": "0.2.5", - "@backstage/plugin-azure-devops-backend": "0.3.19", + "@backstage/plugin-adr": "0.4.0", + "@backstage/plugin-adr-backend": "0.3.0", + "@backstage/plugin-adr-common": "0.2.6", + "@backstage/plugin-airbrake": "0.3.15", + "@backstage/plugin-airbrake-backend": "0.2.15", + "@backstage/plugin-allure": "0.1.31", + "@backstage/plugin-analytics-module-ga": "0.1.26", + "@backstage/plugin-apache-airflow": "0.2.8", + "@backstage/plugin-api-docs": "0.9.0", + "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.1", + "@backstage/plugin-apollo-explorer": "0.1.8", + "@backstage/plugin-app-backend": "0.3.42", + "@backstage/plugin-auth-backend": "0.18.0", + "@backstage/plugin-auth-node": "0.2.11", + "@backstage/plugin-azure-devops": "0.2.6", + "@backstage/plugin-azure-devops-backend": "0.3.21", "@backstage/plugin-azure-devops-common": "0.3.0", - "@backstage/plugin-azure-sites": "0.1.3", - "@backstage/plugin-azure-sites-backend": "0.1.2", + "@backstage/plugin-azure-sites": "0.1.4", + "@backstage/plugin-azure-sites-backend": "0.1.4", "@backstage/plugin-azure-sites-common": "0.1.0", - "@backstage/plugin-badges": "0.2.38", - "@backstage/plugin-badges-backend": "0.1.34", - "@backstage/plugin-bazaar": "0.2.3", - "@backstage/plugin-bazaar-backend": "0.2.3", + "@backstage/plugin-badges": "0.2.39", + "@backstage/plugin-badges-backend": "0.1.36", + "@backstage/plugin-bazaar": "0.2.4", + "@backstage/plugin-bazaar-backend": "0.2.5", "@backstage/plugin-bitbucket-cloud-common": "0.2.3", - "@backstage/plugin-bitrise": "0.1.41", - "@backstage/plugin-catalog": "1.7.2", - "@backstage/plugin-catalog-backend": "1.7.0", - "@backstage/plugin-catalog-backend-module-aws": "0.1.13", - "@backstage/plugin-catalog-backend-module-azure": "0.1.11", - "@backstage/plugin-catalog-backend-module-bitbucket": "0.2.7", - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.1.7", - "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.5", - "@backstage/plugin-catalog-backend-module-gerrit": "0.1.8", - "@backstage/plugin-catalog-backend-module-github": "0.2.3", - "@backstage/plugin-catalog-backend-module-gitlab": "0.1.11", - "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.1.1", - "@backstage/plugin-catalog-backend-module-ldap": "0.5.7", - "@backstage/plugin-catalog-backend-module-msgraph": "0.4.6", - "@backstage/plugin-catalog-backend-module-openapi": "0.1.6", - "@backstage/plugin-catalog-common": "1.0.10", - "@internal/plugin-catalog-customized": "0.0.6", - "@backstage/plugin-catalog-graph": "0.2.26", - "@backstage/plugin-catalog-graphql": "0.3.17", - "@backstage/plugin-catalog-import": "0.9.4", - "@backstage/plugin-catalog-node": "1.3.1", - "@backstage/plugin-catalog-react": "1.2.4", - "@backstage/plugin-cicd-statistics": "0.1.16", - "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.10", - "@backstage/plugin-circleci": "0.3.14", - "@backstage/plugin-cloudbuild": "0.3.14", - "@backstage/plugin-code-climate": "0.1.14", - "@backstage/plugin-code-coverage": "0.2.7", - "@backstage/plugin-code-coverage-backend": "0.2.6", - "@backstage/plugin-codescene": "0.1.9", - "@backstage/plugin-config-schema": "0.1.37", - "@backstage/plugin-cost-insights": "0.12.3", + "@backstage/plugin-bitrise": "0.1.42", + "@backstage/plugin-catalog": "1.8.0", + "@backstage/plugin-catalog-backend": "1.7.2", + "@backstage/plugin-catalog-backend-module-aws": "0.1.15", + "@backstage/plugin-catalog-backend-module-azure": "0.1.13", + "@backstage/plugin-catalog-backend-module-bitbucket": "0.2.9", + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.1.9", + "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.7", + "@backstage/plugin-catalog-backend-module-gerrit": "0.1.10", + "@backstage/plugin-catalog-backend-module-github": "0.2.5", + "@backstage/plugin-catalog-backend-module-gitlab": "0.1.13", + "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.2.0", + "@backstage/plugin-catalog-backend-module-ldap": "0.5.9", + "@backstage/plugin-catalog-backend-module-msgraph": "0.5.0", + "@backstage/plugin-catalog-backend-module-openapi": "0.1.8", + "@backstage/plugin-catalog-common": "1.0.11", + "@internal/plugin-catalog-customized": "0.0.7", + "@backstage/plugin-catalog-graph": "0.2.27", + "@backstage/plugin-catalog-graphql": "0.3.18", + "@backstage/plugin-catalog-import": "0.9.5", + "@backstage/plugin-catalog-node": "1.3.3", + "@backstage/plugin-catalog-react": "1.3.0", + "@backstage/plugin-cicd-statistics": "0.1.17", + "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.11", + "@backstage/plugin-circleci": "0.3.15", + "@backstage/plugin-cloudbuild": "0.3.15", + "@backstage/plugin-code-climate": "0.1.15", + "@backstage/plugin-code-coverage": "0.2.8", + "@backstage/plugin-code-coverage-backend": "0.2.8", + "@backstage/plugin-codescene": "0.1.10", + "@backstage/plugin-config-schema": "0.1.38", + "@backstage/plugin-cost-insights": "0.12.4", "@backstage/plugin-cost-insights-common": "0.1.1", - "@backstage/plugin-dynatrace": "1.0.4", - "@backstage/plugin-events-backend": "0.2.1", - "@backstage/plugin-events-backend-module-aws-sqs": "0.1.2", - "@backstage/plugin-events-backend-module-azure": "0.1.2", - "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.1.2", - "@backstage/plugin-events-backend-module-gerrit": "0.1.2", - "@backstage/plugin-events-backend-module-github": "0.1.2", - "@backstage/plugin-events-backend-module-gitlab": "0.1.2", - "@backstage/plugin-events-backend-test-utils": "0.1.2", - "@backstage/plugin-events-node": "0.2.1", - "@internal/plugin-todo-list": "1.0.9", - "@internal/plugin-todo-list-backend": "1.0.9", + "@backstage/plugin-dynatrace": "2.0.0", + "@backstage/plugin-entity-feedback": "0.1.0", + "@backstage/plugin-entity-feedback-backend": "0.1.0", + "@backstage/plugin-entity-feedback-common": "0.1.0", + "@backstage/plugin-entity-validation": "0.1.0", + "@backstage/plugin-events-backend": "0.2.3", + "@backstage/plugin-events-backend-module-aws-sqs": "0.1.4", + "@backstage/plugin-events-backend-module-azure": "0.1.4", + "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.1.4", + "@backstage/plugin-events-backend-module-gerrit": "0.1.4", + "@backstage/plugin-events-backend-module-github": "0.1.4", + "@backstage/plugin-events-backend-module-gitlab": "0.1.4", + "@backstage/plugin-events-backend-test-utils": "0.1.4", + "@backstage/plugin-events-node": "0.2.3", + "@internal/plugin-todo-list": "1.0.10", + "@internal/plugin-todo-list-backend": "1.0.10", "@internal/plugin-todo-list-common": "1.0.8", - "@backstage/plugin-explore": "0.3.45", - "@backstage/plugin-explore-backend": "0.0.2", + "@backstage/plugin-explore": "0.4.0", + "@backstage/plugin-explore-backend": "0.0.4", "@backstage/plugin-explore-common": "0.0.1", - "@backstage/plugin-explore-react": "0.0.25", - "@backstage/plugin-firehydrant": "0.1.31", - "@backstage/plugin-fossa": "0.2.46", - "@backstage/plugin-gcalendar": "0.3.10", - "@backstage/plugin-gcp-projects": "0.3.33", - "@backstage/plugin-git-release-manager": "0.3.27", - "@backstage/plugin-github-actions": "0.5.14", - "@backstage/plugin-github-deployments": "0.1.45", - "@backstage/plugin-github-issues": "0.2.3", - "@backstage/plugin-github-pull-requests-board": "0.1.8", - "@backstage/plugin-gitops-profiles": "0.3.32", - "@backstage/plugin-gocd": "0.1.20", - "@backstage/plugin-graphiql": "0.2.46", - "@backstage/plugin-graphql-backend": "0.1.30", - "@backstage/plugin-home": "0.4.30", - "@backstage/plugin-ilert": "0.2.3", - "@backstage/plugin-jenkins": "0.7.13", - "@backstage/plugin-jenkins-backend": "0.1.30", - "@backstage/plugin-jenkins-common": "0.1.12", - "@backstage/plugin-kafka": "0.3.14", - "@backstage/plugin-kafka-backend": "0.2.33", - "@backstage/plugin-kubernetes": "0.7.7", - "@backstage/plugin-kubernetes-backend": "0.9.1", - "@backstage/plugin-kubernetes-common": "0.5.1", - "@backstage/plugin-lighthouse": "0.3.14", - "@backstage/plugin-newrelic": "0.3.32", - "@backstage/plugin-newrelic-dashboard": "0.2.7", - "@backstage/plugin-org": "0.6.4", - "@backstage/plugin-org-react": "0.1.3", - "@backstage/plugin-pagerduty": "0.5.7", - "@backstage/plugin-periskop": "0.1.12", - "@backstage/plugin-periskop-backend": "0.1.11", - "@backstage/plugin-permission-backend": "0.5.15", + "@backstage/plugin-explore-react": "0.0.26", + "@backstage/plugin-firehydrant": "0.1.32", + "@backstage/plugin-fossa": "0.2.47", + "@backstage/plugin-gcalendar": "0.3.11", + "@backstage/plugin-gcp-projects": "0.3.34", + "@backstage/plugin-git-release-manager": "0.3.28", + "@backstage/plugin-github-actions": "0.5.15", + "@backstage/plugin-github-deployments": "0.1.46", + "@backstage/plugin-github-issues": "0.2.4", + "@backstage/plugin-github-pull-requests-board": "0.1.9", + "@backstage/plugin-gitops-profiles": "0.3.33", + "@backstage/plugin-gocd": "0.1.21", + "@backstage/plugin-graphiql": "0.2.47", + "@backstage/plugin-graphql-backend": "0.1.32", + "@backstage/plugin-graphql-voyager": "0.1.0", + "@backstage/plugin-home": "0.4.31", + "@backstage/plugin-ilert": "0.2.4", + "@backstage/plugin-jenkins": "0.7.14", + "@backstage/plugin-jenkins-backend": "0.1.32", + "@backstage/plugin-jenkins-common": "0.1.13", + "@backstage/plugin-kafka": "0.3.15", + "@backstage/plugin-kafka-backend": "0.2.35", + "@backstage/plugin-kubernetes": "0.7.8", + "@backstage/plugin-kubernetes-backend": "0.9.3", + "@backstage/plugin-kubernetes-common": "0.6.0", + "@backstage/plugin-lighthouse": "0.4.0", + "@backstage/plugin-lighthouse-backend": "0.1.0", + "@backstage/plugin-lighthouse-common": "0.1.0", + "@backstage/plugin-linguist": "0.1.0", + "@backstage/plugin-linguist-backend": "0.1.0", + "@backstage/plugin-linguist-common": "0.1.0", + "@backstage/plugin-microsoft-calendar": "0.1.0", + "@backstage/plugin-newrelic": "0.3.33", + "@backstage/plugin-newrelic-dashboard": "0.2.8", + "@backstage/plugin-org": "0.6.5", + "@backstage/plugin-org-react": "0.1.4", + "@backstage/plugin-pagerduty": "0.5.8", + "@backstage/plugin-periskop": "0.1.13", + "@backstage/plugin-periskop-backend": "0.1.13", + "@backstage/plugin-permission-backend": "0.5.17", "@backstage/plugin-permission-common": "0.7.3", - "@backstage/plugin-permission-node": "0.7.3", - "@backstage/plugin-permission-react": "0.4.9", - "@backstage/plugin-playlist": "0.1.5", - "@backstage/plugin-playlist-backend": "0.2.3", + "@backstage/plugin-permission-node": "0.7.5", + "@backstage/plugin-permission-react": "0.4.10", + "@backstage/plugin-playlist": "0.1.6", + "@backstage/plugin-playlist-backend": "0.2.5", "@backstage/plugin-playlist-common": "0.1.4", - "@backstage/plugin-proxy-backend": "0.2.34", - "@backstage/plugin-rollbar": "0.4.14", - "@backstage/plugin-rollbar-backend": "0.1.37", - "@backstage/plugin-scaffolder": "1.10.0", - "@backstage/plugin-scaffolder-backend": "1.10.0", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.15", - "@backstage/plugin-scaffolder-backend-module-rails": "0.4.8", - "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.0", - "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.13", - "@backstage/plugin-scaffolder-common": "1.2.4", - "@backstage/plugin-scaffolder-react": "1.0.0", - "@backstage/plugin-search": "1.0.7", - "@backstage/plugin-search-backend": "1.2.1", - "@backstage/plugin-search-backend-module-elasticsearch": "1.1.1", - "@backstage/plugin-search-backend-module-pg": "0.5.1", - "@backstage/plugin-search-backend-node": "1.1.1", + "@backstage/plugin-proxy-backend": "0.2.36", + "@backstage/plugin-rollbar": "0.4.15", + "@backstage/plugin-rollbar-backend": "0.1.39", + "@backstage/plugin-scaffolder": "1.11.0", + "@backstage/plugin-scaffolder-backend": "1.11.0", + "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.17", + "@backstage/plugin-scaffolder-backend-module-rails": "0.4.10", + "@backstage/plugin-scaffolder-backend-module-sentry": "0.1.2", + "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.15", + "@backstage/plugin-scaffolder-common": "1.2.5", + "@backstage/plugin-scaffolder-node": "0.1.0", + "@backstage/plugin-scaffolder-react": "1.1.0", + "@backstage/plugin-search": "1.1.0", + "@backstage/plugin-search-backend": "1.2.3", + "@backstage/plugin-search-backend-module-elasticsearch": "1.1.3", + "@backstage/plugin-search-backend-module-pg": "0.5.3", + "@backstage/plugin-search-backend-node": "1.1.3", "@backstage/plugin-search-common": "1.2.1", - "@backstage/plugin-search-react": "1.4.0", - "@backstage/plugin-sentry": "0.4.7", - "@backstage/plugin-shortcuts": "0.3.6", - "@backstage/plugin-sonarqube": "0.6.2", - "@backstage/plugin-sonarqube-backend": "0.1.5", - "@backstage/plugin-sonarqube-react": "0.1.1", - "@backstage/plugin-splunk-on-call": "0.4.3", - "@backstage/plugin-stack-overflow": "0.1.10", - "@backstage/plugin-stack-overflow-backend": "0.1.9", - "@backstage/plugin-tech-insights": "0.3.6", - "@backstage/plugin-tech-insights-backend": "0.5.6", - "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.24", - "@backstage/plugin-tech-insights-common": "0.2.9", - "@backstage/plugin-tech-insights-node": "0.3.8", - "@backstage/plugin-tech-radar": "0.6.0", - "@backstage/plugin-techdocs": "1.4.3", - "@backstage/plugin-techdocs-addons-test-utils": "1.0.9", - "@backstage/plugin-techdocs-backend": "1.5.1", - "@backstage/plugin-techdocs-module-addons-contrib": "1.0.9", - "@backstage/plugin-techdocs-node": "1.4.4", - "@backstage/plugin-techdocs-react": "1.1.2", - "@backstage/plugin-todo": "0.2.16", - "@backstage/plugin-todo-backend": "0.1.37", - "@backstage/plugin-user-settings": "0.6.2", - "@backstage/plugin-user-settings-backend": "0.1.4", - "@backstage/plugin-vault": "0.1.8", - "@backstage/plugin-vault-backend": "0.2.6", - "@backstage/plugin-xcmetrics": "0.2.34", - "@backstage/plugin-scaffolder-node": "0.0.0", - "@backstage/backend-dev-utils": "0.0.0", - "@backstage/eslint-plugin": "0.0.0", - "@backstage/plugin-entity-validation": "0.0.0", - "@backstage/plugin-graphql-voyager": "0.0.0", - "@backstage/plugin-lighthouse-backend": "0.0.0", - "@backstage/plugin-lighthouse-common": "0.0.0" + "@backstage/plugin-search-react": "1.5.0", + "@backstage/plugin-sentry": "0.5.0", + "@backstage/plugin-shortcuts": "0.3.7", + "@backstage/plugin-sonarqube": "0.6.3", + "@backstage/plugin-sonarqube-backend": "0.1.7", + "@backstage/plugin-sonarqube-react": "0.1.2", + "@backstage/plugin-splunk-on-call": "0.4.4", + "@backstage/plugin-stack-overflow": "0.1.11", + "@backstage/plugin-stack-overflow-backend": "0.1.11", + "@backstage/plugin-tech-insights": "0.3.7", + "@backstage/plugin-tech-insights-backend": "0.5.8", + "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.26", + "@backstage/plugin-tech-insights-common": "0.2.10", + "@backstage/plugin-tech-insights-node": "0.4.0", + "@backstage/plugin-tech-radar": "0.6.1", + "@backstage/plugin-techdocs": "1.5.0", + "@backstage/plugin-techdocs-addons-test-utils": "1.0.10", + "@backstage/plugin-techdocs-backend": "1.5.3", + "@backstage/plugin-techdocs-module-addons-contrib": "1.0.10", + "@backstage/plugin-techdocs-node": "1.5.0", + "@backstage/plugin-techdocs-react": "1.1.3", + "@backstage/plugin-todo": "0.2.17", + "@backstage/plugin-todo-backend": "0.1.39", + "@backstage/plugin-user-settings": "0.7.0", + "@backstage/plugin-user-settings-backend": "0.1.6", + "@backstage/plugin-vault": "0.1.9", + "@backstage/plugin-vault-backend": "0.2.8", + "@backstage/plugin-xcmetrics": "0.2.35", + "@backstage/plugin-octopus-deploy": "0.0.0", + "@backstage/plugin-stackstorm": "0.0.0" }, "changesets": [ - "afraid-foxes-provide", - "afraid-planets-crash", - "brave-cougars-burn", - "breezy-ears-rule", - "bright-eagles-love", - "bright-plums-cough", - "bright-teachers-compete", - "brown-islands-own", - "calm-avocados-exercise", - "chatty-owls-care", - "chilled-sheep-collect", - "clean-queens-judge", - "cold-cycles-switch", - "cool-spoons-bathe", - "create-app-1674561612", - "cuddly-boxes-agree", - "cyan-deers-walk", - "dry-donkeys-cheer", - "dull-fishes-suffer", - "dull-gorillas-sing", - "eight-falcons-explode", - "eight-hotels-sparkle", - "eight-vans-drum", - "eleven-shoes-crash", - "few-moons-accept", - "flat-cups-itch", - "four-candles-add", - "four-rivers-enjoy", - "four-tables-fix", - "friendly-chefs-rule", - "friendly-scissors-shop", - "gold-bulldogs-talk", - "gold-lemons-eat", - "gold-masks-sleep", - "great-goats-talk", - "green-adults-retire", - "green-guests-flow", - "grumpy-bottles-stare", - "grumpy-fireants-drop", - "happy-cows-moo", - "hip-chairs-double", - "hip-onions-tan", - "hip-pugs-teach", - "hip-tables-prove", - "hot-lions-cover", - "hot-wasps-cover", - "hungry-news-fix", - "itchy-chairs-punch", - "itchy-goats-melt", - "khaki-toes-care", - "late-rice-crash", - "lazy-badgers-rule", - "lazy-badgers-try", - "lemon-tables-train", - "little-jars-lay", - "long-chefs-burn", - "lovely-ladybugs-taste", - "many-nails-joke", - "many-pans-unite", - "mean-squids-kneel", - "modern-cats-worry", - "nasty-beans-accept", - "neat-schools-raise", - "neat-zebras-run", - "nervous-apricots-whisper", - "nervous-mangos-rhyme", - "nervous-phones-shout", - "new-pumpkins-sleep", - "nine-glasses-invent", - "nine-guests-compete", - "nine-ravens-kiss", - "ninety-hats-serve", - "old-knives-wonder", - "old-ways-know", - "perfect-cheetahs-serve", - "pink-falcons-serve", - "poor-moons-confess", - "popular-dancers-join", - "pretty-ladybugs-taste", - "proud-glasses-live", - "purple-feet-smile", - "quick-ladybugs-reply", - "quick-mice-change", - "rare-berries-give", - "rare-melons-battle", - "red-kiwis-compare", - "renovate-0b349f9", - "renovate-0c3644c", - "renovate-53e8b07", - "rich-snakes-rest", - "rotten-mayflies-love", - "selfish-frogs-punch", - "serious-pigs-watch", - "sharp-lobsters-build", - "shiny-years-tap", - "short-apes-relate", - "shy-buses-mix", - "shy-steaks-invite", - "silent-peas-fly", - "silly-buckets-joke", - "silly-socks-lie", - "silly-turkeys-hang", - "silver-wolves-breathe", - "slow-carrots-sniff", - "slow-moles-sin", - "smart-dingos-raise", - "soft-actors-worry", - "soft-boxes-buy", - "soft-snails-notice", - "spotty-coats-clean", - "stale-dots-smile", - "stale-experts-punch", - "stupid-ladybugs-brake", - "swift-fishes-smash", - "tall-falcons-teach", - "tall-tables-hide", - "tall-years-relate", - "tasty-jobs-help", - "thick-clocks-pump", - "thick-tables-travel", - "thin-donkeys-attack", - "thin-scissors-press", - "tough-jeans-camp", - "twenty-islands-wonder", - "twenty-parents-relate", - "two-melons-lie", - "violet-tips-rhyme", - "weak-radios-sing", - "wicked-beers-walk", - "wild-donkeys-rescue", - "witty-moose-itch", - "yellow-roses-tell", - "young-beans-float", - "young-points-drop", - "young-singers-learn" + "breezy-bees-care", + "bright-kids-raise", + "create-app-1676993958", + "curvy-pets-hang", + "eight-radios-bake", + "eighty-geese-return", + "four-lizards-grin", + "gentle-pears-clean", + "grumpy-bikes-begin", + "happy-boxes-arrive", + "honest-nails-bake", + "long-nails-pump", + "new-jobs-deny", + "nice-planets-wave", + "ninety-turtles-wait", + "odd-fireants-bathe", + "old-foxes-shave", + "perfect-mayflies-greet", + "polite-chicken-do", + "polite-falcons-jump", + "quick-schools-dress", + "quick-tables-listen", + "rare-buses-swim", + "rare-grapes-count", + "rare-pandas-hope", + "silly-suits-run", + "six-melons-rhyme", + "slimy-lobsters-kneel", + "slow-insects-cheat", + "slow-suits-grab", + "spotty-bees-tell", + "spotty-wasps-complain", + "swift-bags-wave", + "ten-tigers-marry", + "thin-candles-wait", + "twenty-jeans-speak", + "yellow-bananas-yawn" ] } diff --git a/.changeset/pretty-ladybugs-taste.md b/.changeset/pretty-ladybugs-taste.md deleted file mode 100644 index 5c87cde123..0000000000 --- a/.changeset/pretty-ladybugs-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Adds new type, TableOptions, extending Material Table Options. diff --git a/.changeset/proud-glasses-live.md b/.changeset/proud-glasses-live.md deleted file mode 100644 index ded7a53ce7..0000000000 --- a/.changeset/proud-glasses-live.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-adr': patch ---- - -Support displaying an icon on `AdrSearchResultListItem` diff --git a/.changeset/purple-days-film.md b/.changeset/purple-days-film.md new file mode 100644 index 0000000000..09d760c33e --- /dev/null +++ b/.changeset/purple-days-film.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-node': patch +--- + +Fixed bug that prevented deletion of stale files when non-empty directories where tried to be deleted as well. diff --git a/.changeset/purple-feet-smile.md b/.changeset/purple-feet-smile.md deleted file mode 100644 index 0416284edf..0000000000 --- a/.changeset/purple-feet-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-tech-radar': patch ---- - -Allow to set additional links to the entry description. diff --git a/.changeset/quick-coats-sneeze.md b/.changeset/quick-coats-sneeze.md new file mode 100644 index 0000000000..24f7f70e83 --- /dev/null +++ b/.changeset/quick-coats-sneeze.md @@ -0,0 +1,5 @@ +--- +'@techdocs/cli': minor +--- + +Running `@techdocs/cli generate` with the `--verbose` flag will now print the mkdocs output. diff --git a/.changeset/quick-ladybugs-reply.md b/.changeset/quick-ladybugs-reply.md deleted file mode 100644 index 971f6f635b..0000000000 --- a/.changeset/quick-ladybugs-reply.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@techdocs/cli': patch ---- - -Fixed publish command missing awsBucketRootPath option. -Fixed publish command having the gcsBucketRootPath option misconfigured, previously returning a boolean vs a string. diff --git a/.changeset/quick-mice-change.md b/.changeset/quick-mice-change.md deleted file mode 100644 index aeee24a021..0000000000 --- a/.changeset/quick-mice-change.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-test-utils': patch -'@backstage/backend-defaults': patch ---- - -Use the new `*ServiceFactory` exports from `@backstage/backend-app-api` diff --git a/.changeset/quick-schools-dress.md b/.changeset/quick-schools-dress.md new file mode 100644 index 0000000000..511709461e --- /dev/null +++ b/.changeset/quick-schools-dress.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs-addons-test-utils': patch +--- + +Fix bug/problem with test helper diff --git a/.changeset/quick-tables-listen.md b/.changeset/quick-tables-listen.md new file mode 100644 index 0000000000..fab9ef7969 --- /dev/null +++ b/.changeset/quick-tables-listen.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-stackstorm': minor +--- + +Add StackStorm plugin to Backstage which is interfacing with StackStorm API. It allows users to view workflow executions, packs and actions. For installation and configuration instructions please view [README.md](https://github.com/backstage/backstage/tree/master/plugins/stackstorm/README.md) diff --git a/.changeset/quiet-ghosts-float.md b/.changeset/quiet-ghosts-float.md new file mode 100644 index 0000000000..dc8df90206 --- /dev/null +++ b/.changeset/quiet-ghosts-float.md @@ -0,0 +1,12 @@ +--- +'@backstage/plugin-entity-validation': patch +'@backstage/core-components': patch +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-circleci': patch +'@backstage/plugin-playlist': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-explore': patch +--- + +Switch to using `LinkButton` instead of the deprecated `Button` diff --git a/.changeset/quiet-pets-count.md b/.changeset/quiet-pets-count.md deleted file mode 100644 index bc7da8f3e7..0000000000 --- a/.changeset/quiet-pets-count.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-test-utils': patch -'@backstage/backend-app-api': patch ---- - -Updated usage of `ServiceFactory`. diff --git a/.changeset/rare-berries-give.md b/.changeset/rare-berries-give.md deleted file mode 100644 index 39e360bf48..0000000000 --- a/.changeset/rare-berries-give.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Packages without a declared `backstage.role` are now ignored. diff --git a/.changeset/rare-buses-swim.md b/.changeset/rare-buses-swim.md new file mode 100644 index 0000000000..4626343ca3 --- /dev/null +++ b/.changeset/rare-buses-swim.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-tasks': patch +--- + +Added the adapted query to mysql and sqlite3 databases to not returning warning on logs diff --git a/.changeset/rare-grapes-count.md b/.changeset/rare-grapes-count.md new file mode 100644 index 0000000000..fdeb653f3c --- /dev/null +++ b/.changeset/rare-grapes-count.md @@ -0,0 +1,45 @@ +--- +'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch +'@backstage/plugin-catalog-backend-module-bitbucket-server': patch +'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch +'@backstage/plugin-events-backend-module-bitbucket-cloud': patch +'@backstage/plugin-catalog-backend-module-msgraph': patch +'@backstage/plugin-catalog-backend-module-gerrit': patch +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/plugin-catalog-backend-module-gitlab': patch +'@backstage/plugin-events-backend-module-aws-sqs': patch +'@backstage/plugin-catalog-backend-module-azure': patch +'@backstage/plugin-events-backend-module-gerrit': patch +'@backstage/plugin-events-backend-module-github': patch +'@backstage/plugin-events-backend-module-gitlab': patch +'@backstage/plugin-events-backend-module-azure': patch +'@backstage/plugin-catalog-backend-module-aws': patch +'@backstage/backend-plugin-api': patch +'@backstage/backend-test-utils': patch +'@backstage/plugin-scaffolder-backend': patch +'@backstage/backend-defaults': patch +'@backstage/backend-app-api': patch +'@backstage/core-plugin-api': patch +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-techdocs-backend': patch +'@backstage/backend-common': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-sonarqube-react': patch +'@backstage/catalog-model': patch +'@backstage/plugin-catalog-common': patch +'@backstage/plugin-events-backend': patch +'@backstage/plugin-jenkins-common': patch +'@backstage/plugin-techdocs-react': patch +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-cost-insights': patch +'@backstage/plugin-catalog-node': patch +'@backstage/test-utils': patch +'@backstage/plugin-app-backend': patch +'@backstage/plugin-events-node': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-sonarqube': patch +'@backstage/plugin-catalog': patch +'@backstage/plugin-jenkins': patch +--- + +Internal refactor of `/alpha` exports. diff --git a/.changeset/rare-melons-battle.md b/.changeset/rare-melons-battle.md deleted file mode 100644 index 85fd72c763..0000000000 --- a/.changeset/rare-melons-battle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': minor ---- - -Add `initialFilter` prop to EntityLifecyclePicker. This allows you to set an initial lifecycle for the catalog. diff --git a/.changeset/rare-pandas-hope.md b/.changeset/rare-pandas-hope.md new file mode 100644 index 0000000000..6e8e81fcfb --- /dev/null +++ b/.changeset/rare-pandas-hope.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-playlist': patch +--- + +Internal update to work with newer versions of react-router diff --git a/.changeset/red-kiwis-compare.md b/.changeset/red-kiwis-compare.md deleted file mode 100644 index 6045367105..0000000000 --- a/.changeset/red-kiwis-compare.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -The shutdown signal handlers are now installed as part of the backend instance rather than the lifecycle service, and explicitly cause the process to exit. diff --git a/.changeset/red-toes-suffer.md b/.changeset/red-toes-suffer.md deleted file mode 100644 index 3d819fb298..0000000000 --- a/.changeset/red-toes-suffer.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-playlist-backend': patch -'@backstage/plugin-bazaar-backend': patch -'@backstage/plugin-vault-backend': patch ---- - -Moving the backend-test-utils to devDependencies. diff --git a/.changeset/renovate-0b349f9.md b/.changeset/renovate-0b349f9.md deleted file mode 100644 index 810adfbc46..0000000000 --- a/.changeset/renovate-0b349f9.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-kubernetes-common': patch -'@backstage/plugin-kubernetes': patch ---- - -Updated dependency `@kubernetes/client-node` to `0.18.1`. diff --git a/.changeset/renovate-0c3644c.md b/.changeset/renovate-0c3644c.md deleted file mode 100644 index c32438b452..0000000000 --- a/.changeset/renovate-0c3644c.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/cli': patch -'@backstage/plugin-scaffolder-backend': patch ---- - -Updated dependency `esbuild` to `^0.17.0`. diff --git a/.changeset/renovate-3672e5e.md b/.changeset/renovate-3672e5e.md new file mode 100644 index 0000000000..c94eec2245 --- /dev/null +++ b/.changeset/renovate-3672e5e.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +Updated dependency `del` to `^7.0.0`. diff --git a/.changeset/renovate-4775edd.md b/.changeset/renovate-4775edd.md new file mode 100644 index 0000000000..6472fac254 --- /dev/null +++ b/.changeset/renovate-4775edd.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-catalog-graphql': patch +--- + +Updated dependency `@graphql-codegen/cli` to `^3.0.0`. +Updated dependency `@graphql-codegen/graphql-modules-preset` to `^3.0.0`. +Updated dependency `@graphql-codegen/typescript` to `^3.0.0`. +Updated dependency `@graphql-codegen/typescript-resolvers` to `^3.0.0`. diff --git a/.changeset/renovate-488b7e7.md b/.changeset/renovate-488b7e7.md new file mode 100644 index 0000000000..35940f474b --- /dev/null +++ b/.changeset/renovate-488b7e7.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Updated dependency `@types/passport-microsoft` to `^1.0.0`. diff --git a/.changeset/renovate-53e8b07.md b/.changeset/renovate-53e8b07.md deleted file mode 100644 index cb19d8fe8b..0000000000 --- a/.changeset/renovate-53e8b07.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Updated dependency `@asyncapi/react-component` to `1.0.0-next.47`. diff --git a/.changeset/renovate-fb85ae7.md b/.changeset/renovate-fb85ae7.md new file mode 100644 index 0000000000..920469850c --- /dev/null +++ b/.changeset/renovate-fb85ae7.md @@ -0,0 +1,125 @@ +--- +'@backstage/backend-common': patch +'@backstage/backend-test-utils': patch +'@backstage/catalog-client': patch +'@backstage/cli': patch +'@backstage/config-loader': patch +'@backstage/core-app-api': patch +'@backstage/core-components': patch +'@backstage/core-plugin-api': patch +'@backstage/integration-react': patch +'@backstage/integration': patch +'@backstage/release-manifests': patch +'@backstage/test-utils': patch +'@backstage/plugin-adr-backend': patch +'@backstage/plugin-adr': patch +'@backstage/plugin-airbrake-backend': patch +'@backstage/plugin-airbrake': patch +'@backstage/plugin-allure': patch +'@backstage/plugin-analytics-module-ga': patch +'@backstage/plugin-apache-airflow': patch +'@backstage/plugin-api-docs': patch +'@backstage/plugin-apollo-explorer': patch +'@backstage/plugin-app-backend': patch +'@backstage/plugin-auth-backend': patch +'@backstage/plugin-auth-node': patch +'@backstage/plugin-azure-devops-backend': patch +'@backstage/plugin-azure-devops': patch +'@backstage/plugin-azure-sites-backend': patch +'@backstage/plugin-azure-sites': patch +'@backstage/plugin-badges': patch +'@backstage/plugin-bitbucket-cloud-common': patch +'@backstage/plugin-bitrise': patch +'@backstage/plugin-catalog-backend-module-azure': patch +'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch +'@backstage/plugin-catalog-backend-module-bitbucket-server': patch +'@backstage/plugin-catalog-backend-module-bitbucket': patch +'@backstage/plugin-catalog-backend-module-gerrit': patch +'@backstage/plugin-catalog-backend-module-github': patch +'@backstage/plugin-catalog-backend-module-gitlab': patch +'@backstage/plugin-catalog-backend-module-msgraph': patch +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-catalog-graphql': patch +'@backstage/plugin-catalog-import': patch +'@backstage/plugin-circleci': patch +'@backstage/plugin-cloudbuild': patch +'@backstage/plugin-code-climate': patch +'@backstage/plugin-code-coverage-backend': patch +'@backstage/plugin-code-coverage': patch +'@backstage/plugin-codescene': patch +'@backstage/plugin-config-schema': patch +'@backstage/plugin-cost-insights': patch +'@backstage/plugin-dynatrace': patch +'@backstage/plugin-entity-feedback-backend': patch +'@backstage/plugin-entity-feedback': patch +'@backstage/plugin-entity-validation': patch +'@backstage/plugin-explore-backend': patch +'@backstage/plugin-explore-react': patch +'@backstage/plugin-explore': patch +'@backstage/plugin-firehydrant': patch +'@backstage/plugin-fossa': patch +'@backstage/plugin-gcalendar': patch +'@backstage/plugin-gcp-projects': patch +'@backstage/plugin-git-release-manager': patch +'@backstage/plugin-github-actions': patch +'@backstage/plugin-github-deployments': patch +'@backstage/plugin-github-issues': patch +'@backstage/plugin-github-pull-requests-board': patch +'@backstage/plugin-gitops-profiles': patch +'@backstage/plugin-gocd': patch +'@backstage/plugin-graphiql': patch +'@backstage/plugin-graphql-backend': patch +'@backstage/plugin-graphql-voyager': patch +'@backstage/plugin-home': patch +'@backstage/plugin-ilert': patch +'@backstage/plugin-jenkins-backend': patch +'@backstage/plugin-jenkins': patch +'@backstage/plugin-kafka': patch +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-lighthouse': patch +'@backstage/plugin-linguist-backend': patch +'@backstage/plugin-linguist': patch +'@backstage/plugin-microsoft-calendar': patch +'@backstage/plugin-newrelic': patch +'@backstage/plugin-octopus-deploy': patch +'@backstage/plugin-org-react': patch +'@backstage/plugin-org': patch +'@backstage/plugin-pagerduty': patch +'@backstage/plugin-periskop-backend': patch +'@backstage/plugin-periskop': patch +'@backstage/plugin-permission-backend': patch +'@backstage/plugin-permission-common': patch +'@backstage/plugin-permission-node': patch +'@backstage/plugin-playlist-backend': patch +'@backstage/plugin-playlist': patch +'@backstage/plugin-proxy-backend': patch +'@backstage/plugin-rollbar-backend': patch +'@backstage/plugin-rollbar': patch +'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch +'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-search': patch +'@backstage/plugin-sentry': patch +'@backstage/plugin-shortcuts': patch +'@backstage/plugin-sonarqube-backend': patch +'@backstage/plugin-sonarqube': patch +'@backstage/plugin-splunk-on-call': patch +'@backstage/plugin-stack-overflow-backend': patch +'@backstage/plugin-stack-overflow': patch +'@backstage/plugin-stackstorm': patch +'@backstage/plugin-tech-insights': patch +'@backstage/plugin-tech-radar': patch +'@backstage/plugin-techdocs-addons-test-utils': patch +'@backstage/plugin-techdocs-backend': patch +'@backstage/plugin-techdocs-module-addons-contrib': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-todo-backend': patch +'@backstage/plugin-todo': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-vault-backend': patch +'@backstage/plugin-vault': patch +'@backstage/plugin-xcmetrics': patch +--- + +Updated dependency `msw` to `^1.0.0`. diff --git a/.changeset/rich-bags-sleep.md b/.changeset/rich-bags-sleep.md deleted file mode 100644 index 14312ac7f4..0000000000 --- a/.changeset/rich-bags-sleep.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-pagerduty': patch ---- - -The PagerDutyCard now supports an optional `readOnly` property (``) for suppressing the rendering of the "Create Incident" button from the Backstage UI. diff --git a/.changeset/rich-snakes-rest.md b/.changeset/rich-snakes-rest.md deleted file mode 100644 index 7b42491ba1..0000000000 --- a/.changeset/rich-snakes-rest.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-explore': minor ---- - -The `ToolSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. diff --git a/.changeset/rich-wombats-rescue.md b/.changeset/rich-wombats-rescue.md new file mode 100644 index 0000000000..d62f38cb4a --- /dev/null +++ b/.changeset/rich-wombats-rescue.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Updated the `aria-label` of the `HeaderTabs` component. diff --git a/.changeset/rotten-birds-build.md b/.changeset/rotten-birds-build.md deleted file mode 100644 index e165129998..0000000000 --- a/.changeset/rotten-birds-build.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-microsoft-calendar': minor ---- - -Created a new plugin `@backstage/plugin-microsoft-calendar` to display events from a Microsoft Calendar. - -please refer to the [README.md](https://github.com/backstage/backstage/blob/master/plugins/microsoft-calendar/README.md) for step-by-step instructions to setup the plugin in your Backstage instance. diff --git a/.changeset/rotten-mayflies-love.md b/.changeset/rotten-mayflies-love.md deleted file mode 100644 index 24d4e4d1be..0000000000 --- a/.changeset/rotten-mayflies-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-user-settings': patch ---- - -Added a message to advise a page reload when toggling feature flags diff --git a/.changeset/selfish-frogs-punch.md b/.changeset/selfish-frogs-punch.md deleted file mode 100644 index 6484576af8..0000000000 --- a/.changeset/selfish-frogs-punch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -**BREAKING**: Switched out `LogMeta` type for `JsonObject`. diff --git a/.changeset/serious-grapes-brush.md b/.changeset/serious-grapes-brush.md deleted file mode 100644 index 94eead7282..0000000000 --- a/.changeset/serious-grapes-brush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-github': patch ---- - -Use github team slug and login annotations rather than entity name to infer location annotations diff --git a/.changeset/serious-pigs-watch.md b/.changeset/serious-pigs-watch.md deleted file mode 100644 index 2efd8697f3..0000000000 --- a/.changeset/serious-pigs-watch.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch -'@backstage/plugin-catalog': patch -'@backstage/plugin-explore': patch -'@backstage/plugin-search-react': patch ---- - -`ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. - -Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. diff --git a/.changeset/sharp-lobsters-build.md b/.changeset/sharp-lobsters-build.md deleted file mode 100644 index d00333581b..0000000000 --- a/.changeset/sharp-lobsters-build.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/backend-plugin-api': patch ---- - -The `register` methods passed to `createBackendPlugin` and `createBackendModule` -now have dedicated `BackendPluginRegistrationPoints` and -`BackendModuleRegistrationPoints` arguments, respectively. This lets us make it -clear on a type level that it's not possible to pass in extension points as -dependencies to plugins (should only ever be done for modules). This has no -practical effect on code that was already well behaved. diff --git a/.changeset/shiny-years-tap.md b/.changeset/shiny-years-tap.md deleted file mode 100644 index d0d0c14c0a..0000000000 --- a/.changeset/shiny-years-tap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-github-issues': patch ---- - -Updated README.md examples to use correct components and fixed some syntax errors. diff --git a/.changeset/short-apes-relate.md b/.changeset/short-apes-relate.md deleted file mode 100644 index d93c046a4d..0000000000 --- a/.changeset/short-apes-relate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': minor ---- - -**BREAKING** Renaming `*Factory` exports to `*ServiceFactory` instead. For example `configFactory` now is exported as `configServiceFactory`. diff --git a/.changeset/short-mayflies-fix.md b/.changeset/short-mayflies-fix.md new file mode 100644 index 0000000000..9d68a85da7 --- /dev/null +++ b/.changeset/short-mayflies-fix.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-pagerduty': patch +--- + +Update readme link for discord channel diff --git a/.changeset/shy-buses-mix.md b/.changeset/shy-buses-mix.md deleted file mode 100644 index b7db90d03c..0000000000 --- a/.changeset/shy-buses-mix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-react': minor ---- - -refactor `createAsyncValidators` to be recursive to ensure validators are called in nested schemas. diff --git a/.changeset/shy-steaks-invite.md b/.changeset/shy-steaks-invite.md deleted file mode 100644 index b4a70589f9..0000000000 --- a/.changeset/shy-steaks-invite.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-bitbucket': patch -'@backstage/plugin-catalog-backend-module-github': patch -'@backstage/plugin-catalog-backend-module-gitlab': patch -'@backstage/plugin-catalog-backend-module-azure': patch -'@backstage/plugin-azure-devops-backend': patch -'@backstage/plugin-git-release-manager': patch -'@backstage/core-components': patch -'@backstage/plugin-playlist-backend': patch -'@backstage/plugin-apache-airflow': patch -'@backstage/plugin-circleci': patch -'@backstage/plugin-bitrise': patch -'@backstage/plugin-sentry': patch ---- - -Internal refactor to not use deprecated `substr` diff --git a/.changeset/silent-peas-fly.md b/.changeset/silent-peas-fly.md deleted file mode 100644 index 8148cb5d12..0000000000 --- a/.changeset/silent-peas-fly.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Moved the options of the `config` and `rootHttpRouter` services out to the factories themselves, where they belong diff --git a/.changeset/silly-buckets-joke.md b/.changeset/silly-buckets-joke.md deleted file mode 100644 index 113272c965..0000000000 --- a/.changeset/silly-buckets-joke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': patch ---- - -Fixed a bug reading the `user.select` field expected from the `app-config.yaml` configuration diff --git a/.changeset/silly-socks-lie.md b/.changeset/silly-socks-lie.md deleted file mode 100644 index ae7e1c0b2a..0000000000 --- a/.changeset/silly-socks-lie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-entity-validation': minor ---- - -First implementation for the entity validation UI. For more information refer to its `README.md`. diff --git a/.changeset/silly-suits-run.md b/.changeset/silly-suits-run.md new file mode 100644 index 0000000000..ec371e4077 --- /dev/null +++ b/.changeset/silly-suits-run.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +Add /entities/by-query endpoint returning paginated entities. + +The endpoint supports cursor base pagination and server side sorting of the entities diff --git a/.changeset/silly-turkeys-hang.md b/.changeset/silly-turkeys-hang.md deleted file mode 100644 index 9f712a43c8..0000000000 --- a/.changeset/silly-turkeys-hang.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-scaffolder-react': patch ---- - -Add `ScaffolderLayouts` to `NextScaffolderPage` diff --git a/.changeset/silver-badgers-heal.md b/.changeset/silver-badgers-heal.md deleted file mode 100644 index b1f239c3dc..0000000000 --- a/.changeset/silver-badgers-heal.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -'@backstage/plugin-techdocs-module-addons-contrib': patch -'@backstage/plugin-techdocs': patch ---- - -Create a TechDocs `` addon that allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page. - -Here's an example on how to use it in a Backstage app: - -```diff -import { - DefaultTechDocsHome, - TechDocsIndexPage, - TechDocsReaderPage, -} from '@backstage/plugin-techdocs'; -import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha'; -+import { LightBox } from '@backstage/plugin-techdocs-module-addons-contrib'; - -const AppRoutes = () => { - - // other plugin routes - }> - - - } - > - -+ - - - ; -}; -``` diff --git a/.changeset/silver-wolves-breathe.md b/.changeset/silver-wolves-breathe.md deleted file mode 100644 index 8c1529e142..0000000000 --- a/.changeset/silver-wolves-breathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-sentry': minor ---- - -Add option to filter issues based on the time it was triggered diff --git a/.changeset/six-melons-rhyme.md b/.changeset/six-melons-rhyme.md new file mode 100644 index 0000000000..dbb878fc89 --- /dev/null +++ b/.changeset/six-melons-rhyme.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +scaffolder/next: Added the ability to get the fields definition in the schema in the validation function diff --git a/.changeset/slimy-lobsters-kneel.md b/.changeset/slimy-lobsters-kneel.md new file mode 100644 index 0000000000..40ff476a64 --- /dev/null +++ b/.changeset/slimy-lobsters-kneel.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-linguist-backend': patch +--- + +Fixed bug in LinguistBackendApi that caused initial batch of entities to be skipped. diff --git a/.changeset/slow-carrots-sniff.md b/.changeset/slow-carrots-sniff.md deleted file mode 100644 index d32c2a281e..0000000000 --- a/.changeset/slow-carrots-sniff.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': minor ---- - -Improve performance when loading users via group membership. -Users data is now loaded from a paged query, rather than having to make an extra call per user to load each user's profiles. - -Note, there are still additional per user calls made to load user avatars diff --git a/.changeset/slow-insects-cheat.md b/.changeset/slow-insects-cheat.md new file mode 100644 index 0000000000..70b7bbf69b --- /dev/null +++ b/.changeset/slow-insects-cheat.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-techdocs': minor +'@backstage/plugin-catalog': minor +'@backstage/plugin-explore': patch +--- + +Add ability to pass icon as function to have ability to customize it by search item diff --git a/.changeset/slow-moles-sin.md b/.changeset/slow-moles-sin.md deleted file mode 100644 index 02e1952312..0000000000 --- a/.changeset/slow-moles-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-circleci': patch ---- - -Making workflow a link diff --git a/.changeset/slow-sloths-do.md b/.changeset/slow-sloths-do.md deleted file mode 100644 index 2d86d477bf..0000000000 --- a/.changeset/slow-sloths-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-graph': patch ---- - -Expose additional props on the `CatalogGraphCard` to allow for custom node & label rendering or kind/relation filtering. diff --git a/.changeset/nervous-mangos-rhyme.md b/.changeset/slow-suits-grab.md similarity index 58% rename from .changeset/nervous-mangos-rhyme.md rename to .changeset/slow-suits-grab.md index 23e92c65a7..4a741cac6b 100644 --- a/.changeset/nervous-mangos-rhyme.md +++ b/.changeset/slow-suits-grab.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-backend-module-msgraph': patch --- -Extract default transformers to their own file +properly support custom graph api URL diff --git a/.changeset/smart-dingos-raise.md b/.changeset/smart-dingos-raise.md deleted file mode 100644 index ea3b0ec82e..0000000000 --- a/.changeset/smart-dingos-raise.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -Renamed the export `scaffolderCatalogModule` to `catalogModuleTemplateKind` in order to follow the new recommended naming patterns of backend system items. This is technically a breaking change but in an alpha export, so take care to change your imports if you have already migrated to the new backend system. diff --git a/.changeset/soft-actors-worry.md b/.changeset/soft-actors-worry.md deleted file mode 100644 index 5186499292..0000000000 --- a/.changeset/soft-actors-worry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': minor ---- - -**BREAKING** `HttpServerCertificateOptions` when specified with a `key` and `cert` should also have the `type: 'pem'` instead of `type: 'plain'` diff --git a/.changeset/soft-boxes-buy.md b/.changeset/soft-boxes-buy.md deleted file mode 100644 index 581f69cacd..0000000000 --- a/.changeset/soft-boxes-buy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-gitlab': patch ---- - -Implement Group and User Catalog Provider diff --git a/.changeset/soft-snails-notice.md b/.changeset/soft-snails-notice.md deleted file mode 100644 index ed39ee9591..0000000000 --- a/.changeset/soft-snails-notice.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Prefer schema ordering of template properties during review content generation. diff --git a/.changeset/spotty-bees-tell.md b/.changeset/spotty-bees-tell.md new file mode 100644 index 0000000000..5267d8a6a0 --- /dev/null +++ b/.changeset/spotty-bees-tell.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch +'@backstage/plugin-catalog-backend-module-aws': patch +--- + +Fix missing `dependencies` in `package.json` diff --git a/.changeset/spotty-coats-clean.md b/.changeset/spotty-coats-clean.md deleted file mode 100644 index 1a48da5688..0000000000 --- a/.changeset/spotty-coats-clean.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-adr': patch ---- - -Render the common `` component when the `backstage.io/adr-location` annotation is missing from the component diff --git a/.changeset/spotty-spiders-love.md b/.changeset/spotty-spiders-love.md deleted file mode 100644 index e0ac3b3cc7..0000000000 --- a/.changeset/spotty-spiders-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Make catalog search result list a bit more customizable diff --git a/.changeset/spotty-wasps-complain.md b/.changeset/spotty-wasps-complain.md new file mode 100644 index 0000000000..7b1e42b2a0 --- /dev/null +++ b/.changeset/spotty-wasps-complain.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-react': patch +--- + +Fix alignment bug for owners on `TemplateCard` diff --git a/.changeset/stale-dots-smile.md b/.changeset/stale-dots-smile.md deleted file mode 100644 index dc1abc926e..0000000000 --- a/.changeset/stale-dots-smile.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-model': patch ---- - -Add deprecation tag to kubernetes constants in catalog, constants are now defined in plugin-kubernetes-common diff --git a/.changeset/stale-experts-punch.md b/.changeset/stale-experts-punch.md deleted file mode 100644 index 85872bfffe..0000000000 --- a/.changeset/stale-experts-punch.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/plugin-user-settings-backend': patch -'@backstage/plugin-periskop-backend': patch -'@backstage/plugin-bazaar-backend': patch -'@backstage/plugin-kafka-backend': patch -'@backstage/plugin-proxy-backend': patch ---- - -Added a Backend System plugin feature diff --git a/.changeset/stupid-ladybugs-brake.md b/.changeset/stupid-ladybugs-brake.md deleted file mode 100644 index 5a14b82937..0000000000 --- a/.changeset/stupid-ladybugs-brake.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-search-react': minor ---- - -- Create the search results extensions, for more details see the documentation [here](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions); -- Update the `SearchResult`, `SearchResultList` and `SearchResultGroup` components to use extensions and default their props to optionally accept a query, when the query is not passed, the component tries to get it from the search context. diff --git a/.changeset/sweet-yaks-taste.md b/.changeset/sweet-yaks-taste.md deleted file mode 100644 index cbbbaea497..0000000000 --- a/.changeset/sweet-yaks-taste.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-cost-insights': patch ---- - -Fix bug in EntityCostsCard if cost aggregation array is empty. Allow title override on the Cost Insights Page diff --git a/.changeset/swift-bags-wave.md b/.changeset/swift-bags-wave.md new file mode 100644 index 0000000000..8f57c7f89b --- /dev/null +++ b/.changeset/swift-bags-wave.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-sonarqube-react': patch +'@backstage/plugin-sonarqube': patch +--- + +Moved imports from `/alpha` to main public exports. diff --git a/.changeset/swift-fishes-smash.md b/.changeset/swift-fishes-smash.md deleted file mode 100644 index cf3f00129c..0000000000 --- a/.changeset/swift-fishes-smash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -`HttpRouterFactoryOptions.getPath` is now optional as a default value is always provided in the factory. diff --git a/.changeset/tall-falcons-teach.md b/.changeset/tall-falcons-teach.md deleted file mode 100644 index d6608a6597..0000000000 --- a/.changeset/tall-falcons-teach.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Navigation items in mobile sidebar now have aria label. diff --git a/.changeset/tall-years-relate.md b/.changeset/tall-years-relate.md deleted file mode 100644 index 73a0e875b0..0000000000 --- a/.changeset/tall-years-relate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-airbrake': patch ---- - -Adds a boolean helper function to airbrake plugin for use on the EntityPage to show/hide airbrake tab depending on whether the entity's `catalog-info.yaml` has an airbrake id set in the metadata diff --git a/.changeset/tasty-jobs-help.md b/.changeset/tasty-jobs-help.md deleted file mode 100644 index ad1df8fb8c..0000000000 --- a/.changeset/tasty-jobs-help.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-graphql-voyager': minor ---- - -Add the new GraphQL Voyager tool as a plugin for backstage, expose necessary API and components needed for it. - -For more information on how to use this plugin and configure it, please navigate to the [README](https://github.com/backstage/backstage/tree/master/plugins/graphql-voyager/README.md) of the plugin. diff --git a/.changeset/ten-tigers-marry.md b/.changeset/ten-tigers-marry.md new file mode 100644 index 0000000000..f90f7b3ea2 --- /dev/null +++ b/.changeset/ten-tigers-marry.md @@ -0,0 +1,16 @@ +--- +'@backstage/plugin-proxy-backend': patch +--- + +The proxy-backend plugin now supports reviving request bodies that have previously been consumed by an express middleware (e.g. `express.json()`). This is done by setting `reviveConsumedRequestBodies: true` on the proxy `RouterOptions`. In order to preserve the current behavior, the proxy will **not** revive request bodies by default. + +The following is an example of a proxy `createRouter` invocation that revives request bodies: + +```diff +const router = await createRouter({ + config, + logger, + discovery, ++ reviveConsumedRequestBodies: true, +}); +``` diff --git a/.changeset/thick-clocks-pump.md b/.changeset/thick-clocks-pump.md deleted file mode 100644 index 6b3b6e86de..0000000000 --- a/.changeset/thick-clocks-pump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Fixed bug in review step refactor that caused schema-based display settings for individual property values to be discarded. diff --git a/.changeset/thick-tables-travel.md b/.changeset/thick-tables-travel.md deleted file mode 100644 index d74ed18b8a..0000000000 --- a/.changeset/thick-tables-travel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-events-node': patch ---- - -Make `EventParams` typed for implementing tidier event handling. diff --git a/.changeset/thin-candles-wait.md b/.changeset/thin-candles-wait.md new file mode 100644 index 0000000000..c7e18367b5 --- /dev/null +++ b/.changeset/thin-candles-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-sonarqube': patch +--- + +Show a more appropriate icon if there are no code smells and/or vulnerabilities. diff --git a/.changeset/thin-donkeys-attack.md b/.changeset/thin-donkeys-attack.md deleted file mode 100644 index 2fd0aebb6a..0000000000 --- a/.changeset/thin-donkeys-attack.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Removed the `ref` from all `mockServices`. diff --git a/.changeset/thin-scissors-press.md b/.changeset/thin-scissors-press.md deleted file mode 100644 index 2891d4ca66..0000000000 --- a/.changeset/thin-scissors-press.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-azure-sites': patch ---- - -Fixed `AzureSites` plugin start and stop issue #15904 -Fixed `AzureSites` UI load issue #15907 diff --git a/.changeset/three-geckos-press.md b/.changeset/three-geckos-press.md deleted file mode 100644 index fc1af4fdc0..0000000000 --- a/.changeset/three-geckos-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search': patch ---- - -Implement a `showCounts` option to display result counts per type in `SearchType.Accordion` diff --git a/.changeset/tidy-kings-cough.md b/.changeset/tidy-kings-cough.md deleted file mode 100644 index e908572c8b..0000000000 --- a/.changeset/tidy-kings-cough.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -The name of the header used to specify a cluster to the proxy endpoint is now visible in the API reference. diff --git a/.changeset/tough-jeans-camp.md b/.changeset/tough-jeans-camp.md deleted file mode 100644 index 8c7a53190f..0000000000 --- a/.changeset/tough-jeans-camp.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/eslint-plugin': minor ---- - -Added a new ESLint plugin with common rules for Backstage projects. See the [README](https://github.com/import-js/eslint-plugin-import/blob/main/packages/eslint-plugin/README.md) for more details. diff --git a/.changeset/tall-tables-hide.md b/.changeset/tricky-jars-film.md similarity index 51% rename from .changeset/tall-tables-hide.md rename to .changeset/tricky-jars-film.md index 3e8011aff2..9533634614 100644 --- a/.changeset/tall-tables-hide.md +++ b/.changeset/tricky-jars-film.md @@ -2,4 +2,4 @@ '@backstage/plugin-catalog-backend-module-incremental-ingestion': patch --- -Updated README to include newer API options for incremental entity providers +Move `@backstage/backend-defaults` to `devDependencies` diff --git a/.changeset/twenty-islands-wonder.md b/.changeset/twenty-islands-wonder.md deleted file mode 100644 index fe3c5a05c8..0000000000 --- a/.changeset/twenty-islands-wonder.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-react': minor ---- - -Aligned buttons on "Unregister entity" dialog to keep them on the same line diff --git a/.changeset/twenty-jeans-speak.md b/.changeset/twenty-jeans-speak.md new file mode 100644 index 0000000000..fddcc2eedd --- /dev/null +++ b/.changeset/twenty-jeans-speak.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Added authentication provider for Azure Easy Authentication. diff --git a/.changeset/twenty-parents-relate.md b/.changeset/twenty-parents-relate.md deleted file mode 100644 index a883873c16..0000000000 --- a/.changeset/twenty-parents-relate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -All mock service factories and mock service implementations are now available via the new experimental `mockServices` export. diff --git a/.changeset/twenty-pugs-explain.md b/.changeset/twenty-pugs-explain.md deleted file mode 100644 index 9ac77d2ffb..0000000000 --- a/.changeset/twenty-pugs-explain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -**BREAKING**: The `CacheService` has been changed to remove the indirection of `getClient`, instead making the `CacheClient` methods directly available on the `CacheService`. In order to allow for the creation of clients with default options, there is now a new `.withOptions` method that must be implemented as part of the service interface. diff --git a/.changeset/two-melons-lie.md b/.changeset/two-melons-lie.md deleted file mode 100644 index f7abd749d5..0000000000 --- a/.changeset/two-melons-lie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Switch to inline source maps for test transpilation, simplifying editor setups. diff --git a/.changeset/violet-tips-rhyme.md b/.changeset/violet-tips-rhyme.md deleted file mode 100644 index c2d95cfbf9..0000000000 --- a/.changeset/violet-tips-rhyme.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search': patch ---- - -Updated colors for each tab used on search modal, to improve color contrast. Aria label added to tabs wrapper component. `disableRipple` property on the `Tab` component removed to improve keyboard navigation indicator. diff --git a/.changeset/weak-radios-sing.md b/.changeset/weak-radios-sing.md deleted file mode 100644 index dff287b565..0000000000 --- a/.changeset/weak-radios-sing.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Added an experimental mode for the `package start` command for backend packages. Enabled by setting `EXPERIMENTAL_BACKEND_START`. diff --git a/.changeset/wicked-beers-walk.md b/.changeset/wicked-beers-walk.md deleted file mode 100644 index 160a171eb1..0000000000 --- a/.changeset/wicked-beers-walk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Updated `packages/app/cypress/.eslintrc.json` to remove the unnecessary `import/no-extraneous-dependencies` rule. diff --git a/.changeset/wild-donkeys-rescue.md b/.changeset/wild-donkeys-rescue.md deleted file mode 100644 index 43dc3743bb..0000000000 --- a/.changeset/wild-donkeys-rescue.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-test-utils': patch -'@backstage/backend-app-api': patch ---- - -Updated usages of `LogMeta`. diff --git a/.changeset/wild-melons-shout.md b/.changeset/wild-melons-shout.md deleted file mode 100644 index 5a79612f22..0000000000 --- a/.changeset/wild-melons-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -Switch `ServiceFactory` to be an opaque type, keeping only the `service` field as public API, but also adding a type parameter for the service scope. diff --git a/.changeset/witty-moose-itch.md b/.changeset/witty-moose-itch.md deleted file mode 100644 index e2593bf7e7..0000000000 --- a/.changeset/witty-moose-itch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': minor ---- - -The `TechDocsSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. diff --git a/.changeset/yellow-bananas-yawn.md b/.changeset/yellow-bananas-yawn.md new file mode 100644 index 0000000000..d9c522a429 --- /dev/null +++ b/.changeset/yellow-bananas-yawn.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': patch +--- + +The API report generation process is now able to detect and generate reports for additional entry points declared in the package `"exports"` field. diff --git a/.changeset/yellow-roses-tell.md b/.changeset/yellow-roses-tell.md deleted file mode 100644 index ad645df294..0000000000 --- a/.changeset/yellow-roses-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -Switched `BackendFeature` to be an opaque type. diff --git a/.changeset/young-beans-float.md b/.changeset/young-beans-float.md deleted file mode 100644 index ef52b2080a..0000000000 --- a/.changeset/young-beans-float.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -'@backstage/plugin-lighthouse': minor ---- - -Require @backstage/plugin-lighthouse-common package where API implementation moved to. - -**BREAKING**: the following types have been moved to @backstage/plugin-lighthouse-common: - -- `Audit` -- `AuditBase` -- `AuditCompleted` -- `AuditFailed` -- `AuditRunning` -- `FetchError` -- `LASListRequest` -- `LASListResponse` -- `LighthouseApi` -- `LighthouseCategoryAbbr` -- `LighthouseCategoryId` -- `LighthouseConfigSettings` -- `LighthouseRestApi` -- `TriggerAuditPayload` -- `Website` -- `WebsiteListResponse` diff --git a/.changeset/young-points-drop.md b/.changeset/young-points-drop.md deleted file mode 100644 index 4309d54c2c..0000000000 --- a/.changeset/young-points-drop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': patch ---- - -Increased default page size to 999 (from 100) to reduce the number of calls made to the Microsoft Graph API. diff --git a/.changeset/young-scissors-cough.md b/.changeset/young-scissors-cough.md new file mode 100644 index 0000000000..fa35588224 --- /dev/null +++ b/.changeset/young-scissors-cough.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Added a workaround for the cyclic dependency bug across `@backstage/backend-common` and `@backstage/backend-app-api`. diff --git a/.changeset/young-singers-learn.md b/.changeset/young-singers-learn.md deleted file mode 100644 index 9df5d91fe3..0000000000 --- a/.changeset/young-singers-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-splunk-on-call': patch ---- - -Refactor plugin Card component to not rerender contents unnecessarily. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index e9f23287b7..e4b99b3be1 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -6,7 +6,7 @@ contact_links: url: 'https://github.com/backstage/backstage/discussions' - about: 'Alternatively, you can use the Backstage Community Discord' name: Chat - url: 'https://discord.gg/MUpMjP2' + url: 'https://discord.gg/backstage-687207715902193673' - about: 'Please check the FAQ before filing new issues' name: 'Backstage FAQ' url: 'https://backstage.io/docs/FAQ' diff --git a/.github/uffizzi/docker-compose.uffizzi.yml b/.github/uffizzi/docker-compose.uffizzi.yml index 49039cad2a..76a7b4eafc 100644 --- a/.github/uffizzi/docker-compose.uffizzi.yml +++ b/.github/uffizzi/docker-compose.uffizzi.yml @@ -10,9 +10,10 @@ services: image: '${BACKSTAGE_IMAGE}' environment: - POSTGRES_HOST: db + POSTGRES_HOST: localhost + POSTGRES_PORT: 5432 POSTGRES_USER: postgres - POSTGRES_PASSWORD: example + POSTGRES_PASSWORD: kiTMoTsiEuyQ43GrL4Hv NODE_ENV: production deploy: resources: @@ -26,4 +27,8 @@ services: db: image: postgres environment: - POSTGRES_PASSWORD: example + POSTGRES_PASSWORD: kiTMoTsiEuyQ43GrL4Hv + deploy: + resources: + limits: + memory: 250M diff --git a/.github/uffizzi/uffizzi.production.app-config.yaml b/.github/uffizzi/uffizzi.production.app-config.yaml index d4b70641da..30cffa11c9 100644 --- a/.github/uffizzi/uffizzi.production.app-config.yaml +++ b/.github/uffizzi/uffizzi.production.app-config.yaml @@ -9,13 +9,17 @@ backend: baseUrl: ${UFFIZZI_URL} auth: keys: - # random mock key for uffizi deployments + # random mock key for Uffizzi deployments - secret: 5TXvdjVZFxF7qf9K5RAYRDoGrLzJooqa listen: port: 7007 database: - client: better-sqlite3 - connection: ':memory:' + client: pg + connection: + host: ${POSTGRES_HOST} + port: ${POSTGRES_PORT} + user: ${POSTGRES_USER} + password: ${POSTGRES_PASSWORD} cache: store: memory cors: diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index e6380a17f0..63fa474115 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -33,6 +33,7 @@ Blackbox bool boolean Brex +bugfixes builtins callout CDNs @@ -240,6 +241,7 @@ OAuth octokit oidc Okta +Olausson Oldsberg onboarding Onboarding diff --git a/.github/workflows/automate_changeset_feedback.yml b/.github/workflows/automate_changeset_feedback.yml index aaf0bb1294..f96a9fbb39 100644 --- a/.github/workflows/automate_changeset_feedback.yml +++ b/.github/workflows/automate_changeset_feedback.yml @@ -1,6 +1,7 @@ name: Automate changeset feedback on: pull_request_target: + branches: ['master'] permissions: pull-requests: write @@ -28,7 +29,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@v0.6.0 + - uses: backstage/actions/changeset-feedback@v0.6.2 name: Generate feedback with: diff-ref: 'origin/master' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 16573cf5b8..18af36c8c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -63,7 +63,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -181,7 +181,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 2e6573ede8..be27a732d6 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -8,7 +8,7 @@ jobs: cron: runs-on: ubuntu-latest steps: - - uses: backstage/actions/cron@v0.6.0 + - uses: backstage/actions/cron@v0.6.2 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 909a36199c..d45cc557d5 100644 --- a/.github/workflows/deploy_docker-image.yml +++ b/.github/workflows/deploy_docker-image.yml @@ -26,7 +26,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index 1f87c30af2..ec7124ed35 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -14,7 +14,8 @@ jobs: env: CI: true - NODE_OPTIONS: --max-old-space-size=4096 + NODE_OPTIONS: --max-old-space-size=7168 + DOCUSAURUS_SSR_CONCURRENCY: 5 steps: - uses: actions/checkout@v3 @@ -32,7 +33,7 @@ jobs: run: yarn install --immutable - name: microsite yarn install run: yarn install --immutable - working-directory: microsite + working-directory: microsite-next - name: storybook yarn install run: yarn install --immutable working-directory: storybook @@ -42,20 +43,20 @@ jobs: - name: build microsite run: yarn build - working-directory: microsite + working-directory: microsite-next - name: build storybook run: yarn build-storybook working-directory: storybook - name: move storybook dist into microsite - run: mv storybook/dist/ microsite/build/backstage/storybook + run: mv storybook/dist/ microsite-next/build/storybook - name: Check the build output - run: ls microsite/build/backstage && ls microsite/build/backstage/storybook + run: ls microsite-next/build && ls microsite-next/build/storybook - name: Deploy both microsite and storybook to gh-pages uses: JamesIves/github-pages-deploy-action@v4.4.1 with: branch: gh-pages - folder: microsite/build/backstage + folder: microsite-next/build diff --git a/.github/workflows/deploy_nightly.yml b/.github/workflows/deploy_nightly.yml index c9cd22640c..49907042b5 100644 --- a/.github/workflows/deploy_nightly.yml +++ b/.github/workflows/deploy_nightly.yml @@ -26,7 +26,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/deploy_packages.yml b/.github/workflows/deploy_packages.yml index fa43271a96..058f4f6089 100644 --- a/.github/workflows/deploy_packages.yml +++ b/.github/workflows/deploy_packages.yml @@ -68,7 +68,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} @@ -145,7 +145,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/issue.yaml b/.github/workflows/issue.yaml index 9f2e5827be..e64f919bdb 100644 --- a/.github/workflows/issue.yaml +++ b/.github/workflows/issue.yaml @@ -10,4 +10,4 @@ jobs: if: github.repository == 'backstage/backstage' steps: - name: Issue sync - uses: backstage/actions/issue-sync@v0.6.0 + uses: backstage/actions/issue-sync@v0.6.2 diff --git a/.github/workflows/pr-review-comment.yaml b/.github/workflows/pr-review-comment.yaml index 261ce56177..52db29c699 100644 --- a/.github/workflows/pr-review-comment.yaml +++ b/.github/workflows/pr-review-comment.yaml @@ -35,7 +35,7 @@ jobs: const prNumber = artifact.name.slice('pr_number-'.length) core.setOutput('pr-number', prNumber); - - uses: backstage/actions/re-review@v0.6.0 + - uses: backstage/actions/re-review@v0.6.2 with: app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }} private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }} diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml index b84fe5c2e6..b299f314a7 100644 --- a/.github/workflows/sync_code-formatting.yml +++ b/.github/workflows/sync_code-formatting.yml @@ -20,12 +20,12 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: Run Prettier on ADOPTERS.md - uses: creyD/prettier_action@v4.2 + uses: creyD/prettier_action@v4.3 with: # Modifies commit only if prettier autofixed the ADOPTERS.md prettier_options: --config docs/prettier.config.js --write ADOPTERS.md diff --git a/.github/workflows/sync_snyk-github-issues.yml b/.github/workflows/sync_snyk-github-issues.yml index dfd114c66a..a89b7c8e65 100644 --- a/.github/workflows/sync_snyk-github-issues.yml +++ b/.github/workflows/sync_snyk-github-issues.yml @@ -23,7 +23,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/uffizzi-build.yml b/.github/workflows/uffizzi-build.yml index 714b108898..30a3489264 100644 --- a/.github/workflows/uffizzi-build.yml +++ b/.github/workflows/uffizzi-build.yml @@ -27,7 +27,7 @@ jobs: registry-url: https://registry.npmjs.org/ - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: linux-v16 diff --git a/.github/workflows/verify_e2e-linux.yml b/.github/workflows/verify_e2e-linux.yml index 16ddb04086..4fda0749c0 100644 --- a/.github/workflows/verify_e2e-linux.yml +++ b/.github/workflows/verify_e2e-linux.yml @@ -52,7 +52,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index 8a49b8fe31..145eefbd26 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -49,7 +49,7 @@ jobs: with: node-version: ${{ matrix.node-version }} - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v1.1.3 + uses: microsoft/setup-msbuild@v1.3.1 - name: setup chrome uses: browser-actions/setup-chrome@latest - name: yarn install diff --git a/.github/workflows/verify_kubernetes.yml b/.github/workflows/verify_kubernetes.yml index 6d8a7682b5..83280f8e85 100644 --- a/.github/workflows/verify_kubernetes.yml +++ b/.github/workflows/verify_kubernetes.yml @@ -28,7 +28,7 @@ jobs: registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} diff --git a/.github/workflows/verify_microsite-next.yml b/.github/workflows/verify_microsite-next.yml index ea0cbae0be..6c9edf2031 100644 --- a/.github/workflows/verify_microsite-next.yml +++ b/.github/workflows/verify_microsite-next.yml @@ -17,6 +17,7 @@ jobs: env: CI: true NODE_OPTIONS: --max-old-space-size=4096 + DOCUSAURUS_SSR_CONCURRENCY: 5 steps: - uses: actions/checkout@v3 @@ -28,10 +29,16 @@ jobs: # Skip caching of microsite dependencies, it keeps the global cache size # smaller, which make Windows builds a lot faster for the rest of the project. + - name: top-level install + run: yarn install --immutable + - name: yarn install run: yarn install --immutable working-directory: microsite-next + - name: build API reference + run: yarn build:api-docs + - name: verify yarn dependency duplicates run: node scripts/verify-lockfile-duplicates.js diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index 38b685c539..8cde5b6e9b 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -35,7 +35,7 @@ jobs: node-version: ${{ matrix.node-version }} registry-url: https://registry.npmjs.org/ # Needed for auth - name: yarn install - uses: backstage/actions/yarn-install@v0.6.0 + uses: backstage/actions/yarn-install@v0.6.2 with: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: storybook yarn install diff --git a/.prettierignore b/.prettierignore index 8f1fae0456..ad2bd355ed 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,6 +5,7 @@ coverage *.hbs templates api-report.md +*-api-report.md cli-report.md plugins/scaffolder-backend/sample-templates .vscode diff --git a/ADOPTERS.md b/ADOPTERS.md index 4329a00664..f518a00338 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -159,7 +159,7 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [Doctolib](https://doctolib.engineering/) | [@djiit](https://github.com/djiit) | Rails modularization effort awareness, tech organization discoverability. Improving the daily workflows and collaboration processes of our engineers. | | [Twilio](https://www.twilio.com) | [Kyle Smith](https://github.com/knksmith57) | Developer portal, universal software catalog, and centralized taxonomy platform. | | [OVHcloud](https://www.ovhcloud.com/fr/) | [Jean-Philippe Blary](https://github.com/blaryjp), [Arnaud Bauer](mailto:arnaud.bauer@ovhcloud.com), [Flavien Chantelot](https://github.com/Dorn-) | We're providing Backstage to our collaborators to ease their daily jobs, and let them extends it using plugins. | -| [Procter & Gamble](https://us.pg.com/) | [Binita Nayak](https://github.com/binitan), [Josh Rose](https://github.com/joshuarose), [RJ Winkler](https://github.com/rjwink) | P&G leverages Backstage to build internal developer portal to ensure developers' happiness. This developer portal shall act as single source of information needed by development teams to seamlessly create, find and maintain their software components/resources/documentation. | +| [Procter & Gamble](https://us.pg.com/) | [Binita Nayak](https://github.com/binitan), | P&G leverages Backstage to build internal developer portal to ensure developers' happiness. This developer portal shall act as single source of information needed by development teams to seamlessly create, find and maintain their software components/resources/documentation. | | [SANS Institute](https://www.sans.org) | [Christopher Klewin](mailto:cklewin@sans.org) | Developer portal for centralized visibility, reporting, and tooling across multiple organizations. | | [Okay](https://www.okayhq.com/) | [Tomas Barreto](mailto:tomas@okayhq.com) | Service catalog, developer portal, and technical documentation | | [Kaluza](https://www.kaluza.com) | [James Condron](mailto:james.condron@kaluza.com) | To provide an automated golden path to developers, with a focus on discovery and documentation | @@ -230,4 +230,4 @@ _You can do this by using the [Adopter form](https://info.backstage.spotify.com/ | [XP Inc.](https://www.linkedin.com/company/xpinc/) | [Gabriel Santos](https://www.linkedin.com/in/gabriel-santos-6bb740a/) | Developer Portal Catalog (components, APIs, resources, users, groups) and organization relations. | [OVO Energy](https://www.ovoenergy.com/) | [Michael Wizner](https://github.com/mwz), [Dan Laird](https://github.com/dlaird-ovo), [Samantha Betts](https://github.com/sammbetts) | Developer Experience Tool with an aim to to improve processes, boost productivity, finding of information/docs and building tech engagement throughout the business. | [MusicTribe](https://careers.musictribe.com/) | [Alex Ford](mailto:alex.j.ford@gmail.com), [Tiago Barbosa](https://github.com/t1agob) | We are starting to use Backstage as a developer portal to share API specifications and documentation, to quickly onboard new projects with the software templates, and to help developers discover software through the catalog. - +| [Cazoo](https://www.cazoo.co.uk/) | [Abz Mungul](https://www.linkedin.com/in/abzmungul/), [Scott Edwards](https://www.linkedin.com/in/scott-edwards-tech/) | We're assessing Backstage as our developer platform at Cazoo with a focus on reducing cognitive load for our engineers. We're currently aiming for 3 outcomes: creating visibility into service ownership across teams, improving the discoverability of event schemas and relationships, and improving the discoverability of technical documentation and best practices. | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f3de7bf0e5..c2df005a1c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -72,7 +72,7 @@ Have you started using Backstage? Adding your company to [ADOPTERS](ADOPTERS.md) So...feel ready to jump in? Let's do this. 👏🏻💯 -Start by reading our [Getting Started for Contributors](https://backstage.io/docs/getting-started/contributors) page to get yourself setup with a fresh copy of Backstage ready for your contributions. If you need help, just jump into our [Discord chatroom](https://discord.gg/MUpMjP2). +Start by reading our [Getting Started for Contributors](https://backstage.io/docs/getting-started/contributors) page to get yourself setup with a fresh copy of Backstage ready for your contributions. If you need help, just jump into our [Discord chatroom](https://discord.gg/backstage-687207715902193673). ## Coding Guidelines @@ -136,7 +136,7 @@ Changesets **are** needed for new packages, as that is what triggers the package 1. Run `yarn changeset` 2. Select which packages you want to include a changeset for -3. Select impact of change that you're introducing, using `minor` for breaking changes and `patch` otherwise. We do not use `major` changes while packages are at version `0.x`. +3. Select impact of the change you're introducing. If the package you are changing is at version `0.x`, use `minor` for breaking changes and `patch` otherwise. If the package is at `1.0.0` or higher, use `major` for breaking changes, `minor` for backwards compatible API changes, and `patch` otherwise. See the [Semantic Versioning specification](https://semver.org/#semantic-versioning-specification-semver) for more details. 4. Explain your changes in the generated changeset. See [examples of well written changesets](https://backstage.io/docs/getting-started/contributors#writing-changesets). 5. Add generated changeset to Git 6. Push the commit with your changeset to the branch associated with your PR diff --git a/README.md b/README.md index 8a2bd338d9..60324a7789 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![CNCF Status](https://img.shields.io/badge/cncf%20status-incubation-blue.svg)](https://www.cncf.io/projects) [![Main CI Build](https://github.com/backstage/backstage/workflows/Main%20Master%20Build/badge.svg)](https://github.com/backstage/backstage/actions?query=workflow%3A%22Main+Master+Build%22) -[![Discord](https://img.shields.io/discord/687207715902193673)](https://discord.gg/EBHEGzX) +[![Discord](https://img.shields.io/discord/687207715902193673)](https://discord.gg/backstage-687207715902193673) ![Code style](https://img.shields.io/badge/code_style-prettier-ff69b4.svg) [![Codecov](https://img.shields.io/codecov/c/github/backstage/backstage)](https://codecov.io/gh/backstage/backstage) [![](https://img.shields.io/github/v/release/backstage/backstage)](https://github.com/backstage/backstage/releases) @@ -45,7 +45,7 @@ Check out [the documentation](https://backstage.io/docs/getting-started) on how ## Community -- [Discord chatroom](https://discord.gg/MUpMjP2) - Get support or discuss the project +- [Discord chatroom](https://discord.gg/backstage-687207715902193673) - Get support or discuss the project - [Contributing to Backstage](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md) - Start here if you want to contribute - [RFCs](https://github.com/backstage/backstage/labels/rfc) - Help shape the technical direction - [FAQ](https://backstage.io/docs/FAQ) - Frequently Asked Questions diff --git a/app-config.yaml b/app-config.yaml index dd72051189..22f3f4c9c5 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -17,7 +17,7 @@ app: - title: Discord Chatroom icon: chat links: - - url: https://discord.gg/MUpMjP2 + - url: https://discord.gg/backstage-687207715902193673 title: '#backstage' backend: @@ -118,6 +118,11 @@ proxy: headers: Authorization: 'Api-Token ${DYNATRACE_ACCESS_TOKEN}' + '/stackstorm': + target: https://your.stackstorm.instance.com/api + headers: + St2-Api-Key: ${ST2_API_KEY} + organization: name: My Company @@ -441,5 +446,8 @@ apacheAirflow: gocd: baseUrl: https://your.gocd.instance.com +stackstorm: + webUrl: https://your.stackstorm.webui.instance.com + permission: enabled: true diff --git a/docs/FAQ.md b/docs/FAQ.md index fcd5542f74..5b93f07d78 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -231,7 +231,7 @@ We take security seriously. When it comes to packages and code we scan our repositories periodically and update our packages to the latest versions. When it comes to deployment of Backstage within an organisation it depends on the deployment and security setup in your organisation. Reach out to us on -[Discord](https://discord.gg/MUpMjP2) if you have specific queries. +[Discord](https://discord.gg/backstage-687207715902193673) if you have specific queries. Please report sensitive security issues via Spotify's [bug-bounty program](https://hackerone.com/spotify) rather than GitHub. diff --git a/docs/api/utility-apis.md b/docs/api/utility-apis.md index a69c874307..44c00d1ab7 100644 --- a/docs/api/utility-apis.md +++ b/docs/api/utility-apis.md @@ -290,9 +290,7 @@ The figure below shows the relationship between FooApi via the fooApiRef. -
    -Figure showing the relationship between utility APIs, the apps that provide them, and the plugins that consume them -
    +![Figure showing the relationship between utility APIs, the apps that provide them, and the plugins that consume them](../assets/utility-apis-fig1.svg) The current method for connecting Utility API providers and consumers is via the React tree using an `ApiProvider`, which is added to the `AppProvider` of the diff --git a/docs/assets/header.png b/docs/assets/header.png new file mode 100644 index 0000000000..3c39971d36 Binary files /dev/null and b/docs/assets/header.png differ diff --git a/docs/auth/bitbucket/provider.md b/docs/auth/bitbucket/provider.md index 36859dab45..b03201893c 100644 --- a/docs/auth/bitbucket/provider.md +++ b/docs/auth/bitbucket/provider.md @@ -61,7 +61,7 @@ how this is done. Note that for the Bitbucket provider, you'll want to use factory. The `@backstage/plugin-auth-backend` plugin also comes with two built-in -resolves that can be used if desired. The first one is the +resolvers that can be used if desired. The first one is the `bitbucketUsernameSignInResolver`, which identifies users by matching their Bitbucket username to `bitbucket.org/username` annotations of `User` entities in the catalog. Note that you must populate your catalog with matching entities or diff --git a/docs/auth/bitbucketServer/provider.md b/docs/auth/bitbucketServer/provider.md new file mode 100644 index 0000000000..96c7db263e --- /dev/null +++ b/docs/auth/bitbucketServer/provider.md @@ -0,0 +1,52 @@ +--- +id: provider +title: Bitbucket Server Authentication Provider +sidebar_label: Bitbucket Server +description: Adding Bitbucket Server OAuth as an authentication provider in Backstage +--- + +The Backstage `core-plugin-api` package comes with a Bitbucket Server authentication provider that can authenticate +users using Bitbucket Server. This does **NOT** work with Bitbucket Cloud. + +## Create an Application Link in Bitbucket Server + +To add Bitbucket Server authentication, you must create an outgoing application link. Follow the steps described in +the [Bitbucket Server documentation](https://confluence.atlassian.com/bitbucketserver/configure-an-outgoing-link-1108483656.html) +to create one. + +## Configuration + +The provider configuration can then be added to your `app-config.yaml` under the root `auth` configuration: + +```yaml +auth: + environment: development + providers: + bitbucketServer: + development: + host: bitbucket.org + clientId: ${AUTH_BITBUCKET_SERVER_CLIENT_ID} + clientSecret: ${AUTH_BITBUCKET_SERVER_CLIENT_SECRET} +``` + +The Bitbucket Server provider is a structure with two configuration keys: + +- `clientId`: The client ID that was generated by Bitbucket, e.g. `b0f868455c15dcdff5c5fb5d173ae684`. +- `clientSecret`: The client secret tied to the generated client ID. + +## Adding the provider to the Backstage frontend + +To add the provider to the frontend, add the `bitbucketServerAuthApi` reference and `SignInPage` component as shown +in [Adding the provider to the sign-in page](../index.md#adding-the-provider-to-the-sign-in-page). + +## Using Bitbucket Server for sign-in + +In order to use the Bitbucket Server provider for sign-in, you must configure it with a `signIn.resolver`. See +the [Sign-In Resolver documentation](../identity-resolver.md) for more details on how this is done. Note that for the +Bitbucket Server provider, you'll want to use `bitbucketServer` as the provider ID, +and `providers.bitbucketServer.create` for the provider factory. + +The `@backstage/plugin-auth-backend` plugin also comes with a built-in resolver that can be used if desired. +The `emailMatchingUserEntityProfileEmail` identifies users by matching their Bitbucket Server email address to the email +address of `User` entities in the catalog. Note that you must populate your catalog with matching entities or users will +not be able to sign in with this resolver. diff --git a/docs/auth/index.md b/docs/auth/index.md index fa185c0c23..8e15830aa8 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -18,6 +18,7 @@ Backstage comes with many common authentication providers in the core library: - [Auth0](auth0/provider.md) - [Azure](microsoft/provider.md) - [Bitbucket](bitbucket/provider.md) +- [Bitbucket Server](bitbucketServer/provider.md) - [Cloudflare Access](cloudflare/access.md) - [GitHub](github/provider.md) - [GitLab](gitlab/provider.md) diff --git a/docs/auth/microsoft/azure-easyauth.md b/docs/auth/microsoft/azure-easyauth.md new file mode 100644 index 0000000000..3571a3e5c5 --- /dev/null +++ b/docs/auth/microsoft/azure-easyauth.md @@ -0,0 +1,120 @@ +--- +id: azure-easy-auth +title: Azure EasyAuth Provider +sidebar_label: Azure EasyAuth +description: Adding Azure's EasyAuth Proxy as an authentication provider in Backstage +--- + +## Backstage Changes + +Add the following into your `app-config.yaml` or `app-config.production.yaml` file + +Add a `providerFactories` entry to the router in +`packages/backend/src/plugins/auth.ts`. + +```ts +import { providers } from '@backstage/plugin-auth-backend'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + const authProviderFactories = { + 'azure-easyauth': providers.easyAuth.create({ + signIn: { + resolver: async (info, ctx) => { + const { + fullProfile: { id }, + } = info.result; + + if (!id) { + throw new Error('User profile contained no id'); + } + + return await ctx.signInWithCatalogUser({ + annotations: { + 'graph.microsoft.com/user-id': id, + }, + }); + }, + }, + }), + }; + + return await createRouter({ + logger: env.logger, + config: env.config, + database: env.database, + discovery: env.discovery, + tokenManager: env.tokenManager, + providerFactories: authProviderFactories, + }); +} +``` + +Now the backend is ready to serve auth requests on the +`/api/auth/azure-easyauth/refresh` endpoint. All that's left is to update the frontend +sign-in mechanism to poll that endpoint through the IAP, on the user's behalf. + +## Frontend Changes + +It is recommended to use the `ProxiedSignInPage` for this provider, which is +installed in `packages/app/src/App.tsx` like this: + +```diff ++import { ProxiedSignInPage } from '@backstage/core-components'; + + const app = createApp({ + components: { ++ SignInPage: props => , +``` + +See the [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) section for more information. + +## Azure Configuration + +How to configure azure depends on the service you're enable AAD auth on the app service. + +### Azure App Services + +To use EasyAuth with App Services, turn on Active Directory authentication +You must also enable the token store. + +The following example shows how to do this via a bicep template: + +```bicep +resource webApp 'Microsoft.Web/sites@2022-03-01' existing = { + name: 'MY-WEBAPP-NAME' + + resource authConfig 'config' = { + name: 'authsettingsV2' + properties: { + globalValidation: { + redirectToProvider: 'AzureActiveDirectory' + requireAuthentication: true + unauthenticatedClientAction: 'RedirectToLoginPage' + } + login: { + tokenStore: { + enabled: true + } + } + platform: { + enabled: true + } + identityProviders: { + azureActiveDirectory: { + enabled: true + login: { + loginParameters: [ 'domain_hint=MYCOMPANY.COM' ] + } + registration: { + clientId: 'CLIENT-ID' + clientSecretSettingName: 'CLIENT-SECRET-NAME' + openIdIssuer: 'https://sts.windows.net/${tenant().tenantId}/v2.0' + } + } + } + } + } +} +``` diff --git a/docs/backend-system/architecture/01-index.md b/docs/backend-system/architecture/01-index.md index a9f08c7907..aff730b0d1 100644 --- a/docs/backend-system/architecture/01-index.md +++ b/docs/backend-system/architecture/01-index.md @@ -1,12 +1,12 @@ --- id: index title: Backend System Architecture -sidebar_label: System Architecture +sidebar_label: Overview # prettier-ignore description: The structure and architecture of the new Backend System and its component parts --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** ## Building Blocks diff --git a/docs/backend-system/architecture/02-backends.md b/docs/backend-system/architecture/02-backends.md index 53670aba12..b6079d71b4 100644 --- a/docs/backend-system/architecture/02-backends.md +++ b/docs/backend-system/architecture/02-backends.md @@ -6,7 +6,7 @@ sidebar_label: Backend description: Backend instances --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** ## The Backend Instance diff --git a/docs/backend-system/architecture/03-services.md b/docs/backend-system/architecture/03-services.md index 875cb3aaea..8a86d90efb 100644 --- a/docs/backend-system/architecture/03-services.md +++ b/docs/backend-system/architecture/03-services.md @@ -6,7 +6,7 @@ sidebar_label: Services description: Services for backend plugins --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** Backend services provide shared functionality available to all backend plugins and modules. They are made available through service references that embed a type that represents the service interface, similar to how [Utility APIs](../../api/utility-apis.md) work in the Backstage frontend system. To use a service in your plugin or module you request an implementation of that service using the service reference. diff --git a/docs/backend-system/architecture/04-plugins.md b/docs/backend-system/architecture/04-plugins.md index e73f086c43..04271b17da 100644 --- a/docs/backend-system/architecture/04-plugins.md +++ b/docs/backend-system/architecture/04-plugins.md @@ -6,7 +6,7 @@ sidebar_label: Plugins description: Backend plugins --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** Plugins provide the actual base features of a Backstage backend. Each plugin operates completely independently of all other plugins and they only communicate with each other through network calls. This means that there is a strong degree of isolation between plugins, and that each plugin can be considered a separate microservice. While a default Backstage project has all plugins installed within a single backend, it is also possible to split this setup into multiple backends, with each backend housing one or more plugins. diff --git a/docs/backend-system/architecture/05-extension-points.md b/docs/backend-system/architecture/05-extension-points.md index 278c565472..6d320037ba 100644 --- a/docs/backend-system/architecture/05-extension-points.md +++ b/docs/backend-system/architecture/05-extension-points.md @@ -6,7 +6,7 @@ sidebar_label: Extension Points description: Extension points of backend plugins --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** While plugins are able to accept options for lightweight forms of customization and extension, you quickly hit a limit where you need something more powerful to allow users to extend your plugin. For this purpose, the backend system provides a mechanism for plugins to provide extension points, which can be used to expose deeper customizations for your plugin. Extension points are used by modules, which are installed in the backend adjacent to plugins. Modules are covered more in-depth in the [next section](./06-modules.md). diff --git a/docs/backend-system/architecture/06-modules.md b/docs/backend-system/architecture/06-modules.md index 2f359eaa75..b4a2e8338a 100644 --- a/docs/backend-system/architecture/06-modules.md +++ b/docs/backend-system/architecture/06-modules.md @@ -6,7 +6,7 @@ sidebar_label: Modules description: Modules for backend plugins --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** Backend modules are used to extend [plugins](./04-plugins.md) with additional features or change existing behavior. They must always be installed in the same backend instance as the plugin that they extend, and may only extend a single plugin. Modules interact with their target plugin using the [extension points](./05-extension-points.md) registered by the plugin, while also being able to depend on the [services](./03-services.md) of that plugin. @@ -43,7 +43,3 @@ export const catalogModuleExampleCustomProcessor = createBackendModule({ Notice that we're placing the extension point we want to interact with in the `deps` option, while also depending on the logger service at the same time. When initializing modules we can depend on both extension points and services interchangeably. You can also depend on multiple extension points at once, in case the implementation of the module requires it. It is typically best to keep modules slim and to each only add a single new feature. It is often the case that it is better to create two separate modules rather than one that provides both features. The one limitation here is that modules can not interact with each other and need to be self contained. - -## HTTP Handlers - -Since modules have access to the same services as the plugin they extend, they are also able to register their own HTTP handlers. For more information about the HTTP service, see [core services](../core-services/01-index.md). When registering HTTP handlers, it is important to try to avoid any future conflict with the plugin itself, or other modules. A recommended naming pattern is to register the handlers under the `/modules/` path, where `` is the kebab-case ID of the module, for example `/modules/example-custom-processor/v1/validators`. In a standard backend setup the full path would then be `/api/catalog/modules/example-custom-processor/v1/validators`. diff --git a/docs/backend-system/architecture/07-naming-patterns.md b/docs/backend-system/architecture/07-naming-patterns.md index b62e049f08..b541cc09ba 100644 --- a/docs/backend-system/architecture/07-naming-patterns.md +++ b/docs/backend-system/architecture/07-naming-patterns.md @@ -6,7 +6,7 @@ sidebar_label: Naming Patterns description: Naming patterns in the backend system --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** These are the naming patterns to adhere to within the backend system. They help us keep exports consistent across packages and make it easier to understand the usage and intent of exports. diff --git a/docs/backend-system/building-backends/01-index.md b/docs/backend-system/building-backends/01-index.md index bda2aa7eaa..66bf68ab07 100644 --- a/docs/backend-system/building-backends/01-index.md +++ b/docs/backend-system/building-backends/01-index.md @@ -6,17 +6,17 @@ sidebar_label: Overview description: Building backends using the new backend system --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** > NOTE: If you have an existing backend that is not yet using the new backend > system, see [migrating](./08-migrating.md). +This section covers how to set up and customize your own Backstage backend. It covers some aspects of how backend instances fit into the larger system, but for a more in-depth explanation of the role of backends in the backend system, see [the architecture section](../architecture/02-backends.md). + # Overview A minimal Backstage backend is very lightweight. It is a single package with a `package.json` file and a `src/index.ts` file, not counting surrounding tooling and documentation. The package is typically placed within the `packages/backend` folder of a Backstage monorepo, but that is up to you. The backend package is part of any project created with `@backstage/create-app`, so you typically do not need to create it yourself. -You'll get a brief description here, but for a more in-depth explanation of the role of backends in the backend system, see [the architecture section](../architecture/02-backends.md). - When you create a new project with `@backstage/create-app`, you'll get a backend package with a `src/index.ts` that looks something like this: ```ts diff --git a/docs/backend-system/building-backends/08-migrating.md b/docs/backend-system/building-backends/08-migrating.md index e503d627ef..567476532f 100644 --- a/docs/backend-system/building-backends/08-migrating.md +++ b/docs/backend-system/building-backends/08-migrating.md @@ -6,7 +6,7 @@ sidebar_label: Migration Guide description: How to migrate existing backends to the new backend system --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. As such, it is not considered stable, and it is not recommended to migrate production backends to the new backend system until it has a stable release.** ## Overview 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 cae5052d04..1556b6b377 100644 --- a/docs/backend-system/building-plugins-and-modules/01-index.md +++ b/docs/backend-system/building-plugins-and-modules/01-index.md @@ -6,16 +6,14 @@ sidebar_label: Overview description: Building backend plugins and modules using the new backend system --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** > NOTE: If you have an existing backend and/or backend plugins that are not yet > using the new backend system, see [migrating](./08-migrating.md). -## Overview - -Backend [plugins](../architecture/04-plugins.md) and -[modules](../architecture/06-modules.md), sometimes collectively referred to as -backend _features_, are the building blocks that adopters add to their +This section covers how to build your own backend [plugins](../architecture/04-plugins.md) and +[modules](../architecture/06-modules.md). They are sometimes collectively referred to as +backend _features_, and are the building blocks that adopters add to their [backends](../architecture/02-backends.md). ## Creating a new Plugin @@ -74,7 +72,7 @@ Backend modules are used to extend [plugins](../architecture/04-plugins.md) with additional features or change existing behavior. They must always be installed in the same backend instance as the plugin that they extend, and may only extend a single plugin. Modules interact with their target plugin using the [extension -points](./05-extension-points.md) registered by the plugin, while also being +points](../architecture/05-extension-points.md) registered by the plugin, while also being able to depend on the [services](../architecture/03-services.md) of that plugin. That last point is worth reiterating: injected `plugin` scoped services will be the exact 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 37c5698512..7f93fab45b 100644 --- a/docs/backend-system/building-plugins-and-modules/02-testing.md +++ b/docs/backend-system/building-plugins-and-modules/02-testing.md @@ -6,7 +6,7 @@ sidebar_label: Testing description: Learn how to test your backend plugins and modules --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** Utilities for testing backend plugins and modules are available in `@backstage/backend-test-utils`. This section describes those facilities. diff --git a/docs/backend-system/building-plugins-and-modules/08-migrating.md b/docs/backend-system/building-plugins-and-modules/08-migrating.md index 687f4c1d5e..cf5aa8106f 100644 --- a/docs/backend-system/building-plugins-and-modules/08-migrating.md +++ b/docs/backend-system/building-plugins-and-modules/08-migrating.md @@ -6,7 +6,7 @@ sidebar_label: Migration Guide description: How to migrate existing backend plugins to the new backend system --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** Migrating an existing backend plugin to the new backend system is fairly straightforward. The process is similar across the majority of plugins which just return a `Router` that is then wired up in the `index.ts` file of your backend. The primary thing that we need to do is to make sure that the dependencies that are required by the plugin are available, and then registering the router with the HTTP router service. diff --git a/docs/backend-system/core-services/01-index.md b/docs/backend-system/core-services/01-index.md index b6682c2708..c688055c96 100644 --- a/docs/backend-system/core-services/01-index.md +++ b/docs/backend-system/core-services/01-index.md @@ -1,12 +1,12 @@ --- id: index title: Core Backend Service APIs -sidebar_label: Core Services +sidebar_label: Overview # prettier-ignore description: Core backend service APIs --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** The default backend provides several [core services](https://github.com/backstage/backstage/blob/master/packages/backend-plugin-api/src/services/definitions/coreServices.ts) out of the box which includes access to configuration, logging, URL Readers, databases and more. diff --git a/docs/backend-system/index.md b/docs/backend-system/index.md index de598167ae..87eb008129 100644 --- a/docs/backend-system/index.md +++ b/docs/backend-system/index.md @@ -1,15 +1,15 @@ --- id: index title: The Backend System -sidebar_label: Overview +sidebar_label: Introduction # prettier-ignore description: The Backend System --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** ## Status -The new backend system is under active development, and only a small number of plugins have been migrated so far. It is possible to try it out, but it is not recommended to use this new system in production yet. +The new backend system is in alpha, and only a small number of plugins have been migrated so far. It is possible to try it out, but it is not recommended to use this new system in production yet. You can find an example backend setup in [the `backend-next` package](https://github.com/backstage/backstage/tree/master/packages/backend-next). diff --git a/docs/dls/design.md b/docs/dls/design.md index a2091aeb10..3444ff3ad2 100644 --- a/docs/dls/design.md +++ b/docs/dls/design.md @@ -26,7 +26,7 @@ that growth, check out the issues in this GitHub repo! The Backstage Design Team is small but mighty, and we truly cherish the amazing opportunity we have to work with the Backstage Open Source community! Have an idea? A component request? Feel free to communicate with us via -[Discord](https://discord.gg/EBHEGzX) (_#design_ channel). Collaboration trumps +[Discord](https://discord.gg/backstage-687207715902193673) (_#design_ channel). Collaboration trumps individual speed, and we want to work with you to make Backstage work for all of our users. @@ -38,7 +38,7 @@ loop! Keep an eye on our where we're headed and review the [open design issues](https://github.com/backstage/backstage/issues?q=is%3Aopen+is%3Aissue+label%3Adesign), to see if you can help. We'll also be posting updates in the _#design_ channel -on [Discord](https://discord.gg/EBHEGzX). Not only that, we want to keep you +on [Discord](https://discord.gg/backstage-687207715902193673). Not only that, we want to keep you informed on the decisions we've made and why we've made them. ## 🛠 Our Practice @@ -101,14 +101,14 @@ focused on building up our core Backstage user experience. We’ll be labeling o issues in GitHub with ‘design’ and/or ‘storybook’ - so feel free to browse and tackle the tasks that interest you. If you have any questions regarding an issue, you can ask them in the comments section of the issue or on -[Discord](https://discord.gg/EBHEGzX). We absolutely adore our external +[Discord](https://discord.gg/backstage-687207715902193673). We absolutely adore our external contributors and will send you virtual [semlas](https://en.wikipedia.org/wiki/Semla) for your contributions! ### Request a component Create an issue (label it design and assign it to katz95) or send us a message -on [Discord](https://discord.gg/EBHEGzX) (_#design_ channel) with details of +on [Discord](https://discord.gg/backstage-687207715902193673) (_#design_ channel) with details of what the component is and its relevant use cases. Your request will be reviewed by our design team and you should hear back from us within 1-2 business days. We’ll get back to you and let you know whether your requested component will get @@ -124,7 +124,7 @@ components we’ve designed to the Storybook as well. Community to share our design assets. You can duplicate our UI Kit and design your own plugin for Backstage. -**[Discord](https://discord.gg/EBHEGzX)** - all design questions should be +**[Discord](https://discord.gg/backstage-687207715902193673)** - all design questions should be directed to the _#design_ channel. **[Customize Backstage's look and feel](https://backstage.io/docs/getting-started/app-custom-theme)** - @@ -142,4 +142,4 @@ scenes, we’re setting up a few foundational elements to make sure that contributing to Backstage as a designer is easy. From styling guidelines to UX principles to Figma documents, we’ll make sure you’re equipped to chip in on this project. We’re excited to work with you! In the meantime, we’d love to hear -from you on [Discord](https://discord.gg/EBHEGzX). +from you on [Discord](https://discord.gg/backstage-687207715902193673). diff --git a/docs/features/search/architecture.md b/docs/features/search/architecture.md index f1183cec5f..62f3a68ff6 100644 --- a/docs/features/search/architecture.md +++ b/docs/features/search/architecture.md @@ -9,7 +9,9 @@ to support a wide variety of search engines, while providing a simple developer experience for plugin developers, and a good out-of-the-box experience for Backstage end-users. -Search Architecture + + +![Search Architecture](../../assets/search/architecture.drawio.svg) At a base-level, we want to support the following: diff --git a/docs/features/software-catalog/system-model.md b/docs/features/software-catalog/system-model.md index 16ad48abcf..af359bb18a 100644 --- a/docs/features/software-catalog/system-model.md +++ b/docs/features/software-catalog/system-model.md @@ -63,7 +63,7 @@ BigTable databases, Pub/Sub topics, S3 buckets or CDNs. Modelling them together with components and systems will better allow us to visualize resource footprint, and create tooling around them. -##Organizational Entities +## Organizational Entities ### User @@ -120,7 +120,7 @@ product or use-case, share the same entity types in their APIs, and integrate well with each other. Other domains could be “Content Ingestion”, “Ads” or “Search”. -##Other +## Other ### Location @@ -128,7 +128,8 @@ A location is a marker that references other places to look for catalog data. ### Type -The type field in the system has no set meaning. It is up to the user to assign their own types and use them as desired, such as for link validation or creating custom UI components. Some common pre-defined types are depicted in the ecosystem modeling diagram. +The type field in the system has no set meaning. It is up to the user to assign their own types and use them as desired, such as for link validation or creating custom UI components. Some common pre-defined types are depicted in the +[ecosystem modeling diagram](#ecosystem-modeling). ### Template diff --git a/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md b/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md index 6e37a4df3e..f9d2c4eb0c 100644 --- a/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md +++ b/docs/features/software-templates/migrating-from-v1beta2-to-v1beta3.md @@ -211,7 +211,7 @@ input: ### Summary -Of course, we're always available on [discord](https://discord.gg/MUpMjP2) if +Of course, we're always available on [discord](https://discord.gg/backstage-687207715902193673) if you're stuck or something's not working as expected. You can also [raise an issue](https://github.com/backstage/backstage/issues/new/choose) with feedback or bugs! diff --git a/docs/features/software-templates/testing-scaffolder-alpha.md b/docs/features/software-templates/testing-scaffolder-alpha.md new file mode 100644 index 0000000000..76479b137e --- /dev/null +++ b/docs/features/software-templates/testing-scaffolder-alpha.md @@ -0,0 +1,234 @@ +--- +id: testing-scaffolder-alpha +title: 'Experimental: Testing out the alpha Scaffolder plugin' +# prettier-ignore +description: Docs on the upcoming breaking release for the scaffolder plugin +--- + +## What's `scaffolder/next`? + +The `alpha` version, or as you might have seen referred to in other places the `scaffolder/next` release, is a new version of the `scaffolder` plugin that will be the first breaking change to the plugin, so you can also think of it as `@backstage/plugin-scaffolder@2.0.0`. +Its mostly a rewrite of a lot of the frontend components and pages that had very limited test coverage, which made adding new features to the `scaffolder` plugin quite hard, and we were lacking in confidence when making changes. + +There is of course some other things that have changed when re-writing this, which are essentially what has caused some breaking changes. +Now, this is not like previous scaffolder changes where you would have to change all of your templates as this is only the frontend plugin that is going to have breaking changes. You can read more about the [breaking changes](#breaking-changes) below. + +## What's new? + +First off, the main dependency that we have for the frontend which is responsible for rendering the `JSONSchema` into `material-ui` components is [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form). +This dependency in the current version of the plugin is 3.x.x, which is now 2 major versions out of date. Long story short, `v4` of this plugin contained some bug fixes, and new features but we we're unable to upgrade due to some issues with having support for `material-ui@v4`, so we had to wait for `v5` to be released, and because of the `FieldExtensions` and how they are very tightly coupled to the `react-jsonschema-form` library, we also wanted to make sure that this release was stable before getting people to migrate their `Field Extensions`. + +With that in mind, this release has `v5` of `react-jsonschema-form`, and with that comes all the new features and bugfixes in `v4` that we were waiting for - one of the main ones being the ability to use `if / then / else` syntax in the `template.yaml` definitions! 🎉 + +We've also rebuilt how validation works in the `scaffolder` components, which now means that we've opened the ability to have `async` validation functions in your `Field Extensions`. + +Some of the pages have gotten a little bit of an overhaul in terms of UI based on some research and feedback from the community and internally. + +- The `TemplateList` page has gotten some new `Card` components which show a little more information than the previous version with a little `material-ui` standards. +- The `WizardPage` has received some new updates with the stepper now running horizontally, and the `Review` step being a dedicated step in the stepper. +- The `OngoingTask` page now does not show the logs by default, and instead has a much cleaner interface for tracking the ongoing steps and the pipeline of actions that are currently showing. + - You can also now provide your own `OutputsComponent` which can be used to render the outputs from an ongoing / completed task in a way that suits your templates the best. For instance, if your template produces `Pull Requests`, it could be useful to render these in an interactive way where you can see the statuses of each of these `Pull Requests` in the `Ongoing Task` page. + +There's also a lot of bug fixes, and other things, but these are the main ones that we wanted to highlight. + +## How do I test out the `alpha` version? + +With the release of [`v1.11.0`](https://github.com/backstage/backstage/releases/tag/v1.11.0) it's now possible to run the `scaffolder/next` plugin and it be a drop in replacement for the current version that you use today. This means that you can start using the new code, and start testing it out. Once we have collected enough feedback, and squashed any bugs that might block us from releasing, it will be promoted from the `/alpha` exports and replace the existing code leading to breaking changes if you haven't already made these changes as part of this testing pilot. Those that have chosen to opt into this testing pilot means that once we promote it from the `/alpha` exports, you will need to update your code to point to the original exports from the `scaffolder` plugin, just like the code is today but with the [breaking changes](#breaking-changes) that you already made to your `Custom Field Extensions`. + +It's also worth calling out that if you do test this out, and find some issues or something not working out as expected, feel free to raise an issue in the [repo](https://github.com/backstage/backstage) or reach out to us on Discord! + +### Make the required changes to `App.tsx` + +The `ScaffolderPage` router has a completely different export for the `scaffolder/next` work, so you will want to change any import from the old `ScaffolderPage` to the new `NextScaffolderPage` + +```diff +- import { ScaffolderPage } from '@backstage/plugin-scaffolder'; ++ import { NextScaffolderPage } from '@backstage/plugin-scaffolder/alpha'; + +``` + +And this API should be the exact same as the previous Router, so you should be able to make a change like the following further down in this file: + +```diff + + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + ]} + /> + } + > + + + ... other extensions + + + + ... other layouts + + +``` + +### Make the required changes to your `CustomFieldExtensions` + +There's differently named function for creating field extensions part of the `/alpha` exports as these are the ones that can contain breaking changes because of the breaking changes that have been applied in `react-jsonschema-form`. + +Let's take the following example: + +```ts +export const EntityNamePickerFieldExtension = scaffolderPlugin.provide( + createScaffolderFieldExtension({ + component: EntityNamePicker, + name: 'EntityNamePicker', + validation: entityNamePickerValidation, + schema: EntityNamePickerSchema, + }), +); +``` + +References for `createScaffolderFieldExtension` have an `/alpha` version of `createNextScaffolderFieldExtension`, which should be used instead. + +```diff +-import { createScaffolderFieldExtension } from '@backstage/plugin-scaffolder'; ++import { createNextScaffolderFieldExtension } from '@backstage/plugin-scaffolder/alpha'; + +export const EntityNamePickerFieldExtension = scaffolderPlugin.provide( +- createScaffolderFieldExtension({ ++ createNextScaffolderFieldExtension({ + component: EntityNamePicker, + name: 'EntityNamePicker', + validation: entityNamePickerValidation, + }), +); +``` + +Once you've done this you will find that you will have two squiggly lines under the properties that are passed in. One for the component and one for the validation (if provided.) + +Let's take the following code for the `EntityNamePicker` component: + +```ts +export const EntityNamePicker = ( + props: FieldExtensionComponentProps, +) => { + const { + onChange, + required, + schema: { title = 'Name', description = 'Unique name of the component' }, + rawErrors, + formData, + uiSchema: { 'ui:autofocus': autoFocus }, + idSchema, + placeholder, + } = props; + ... +} +``` + +There's another `/alpha` export that you need to replace `FieldExtensionComponentProps` with which is the `NextFieldExtensionComponentProps`. + +```diff +- import { FieldExtensionComponentProps } from '@backstage/plugin-scaffolder-react'; ++ import { NextFieldExtensionComponentProps } from '@backstage/plugin-scaffolder-react/alpha'; + +export const EntityNamePicker = ( +- props: FieldExtensionComponentProps, ++ props: NextFieldExtensionComponentProps, +) => { + const { + onChange, + required, + schema: { title = 'Name', description = 'Unique name of the component' }, + rawErrors, + formData, +- uiSchema: { 'ui:autofocus': autoFocus }, ++ uiSchema: { 'ui:autofocus': autoFocus } = {}, + idSchema, + placeholder, + } = props; + ... +} +``` + +You'll notice that there's an additional change here, which is that we're now defaulting the `uiSchema` to an empty object. This is because the `uiSchema` is now optional, and if you don't provide it, it will be `undefined` instead of an empty object. There's more around this in the [breaking changes](#breaking-changes) section. + +To fix the previous validation error, you will need to change the import for the `FieldValidation` type that is used in the `validation` function. + +Let's take the following example of the validation function: + +```ts +import { FieldValidation } from '@rjsf/utils'; +import { KubernetesValidatorFunctions } from '@backstage/catalog-model'; + +export const entityNamePickerValidation = ( + value: string, + validation: FieldValidation, +) => { + if (!KubernetesValidatorFunctions.isValidObjectName(value)) { + validation.addError( + 'Must start and end with an alphanumeric character, and contain only alphanumeric characters, hyphens, underscores, and periods. Maximum length is 63 characters.', + ); + } +}; +``` + +You will need to change the import for `FieldValidation` to point at the new `react-jsonschema-form` dependency. + +> Note: you will probably need to install this dependency too, by using `yarn add @rjsf/utils` in the package where you define these validation functions, this could also be in the `packages/app` folder, so you can install it there if needed. + +```diff +- import { FieldValidation } from '@rjsf/core'; ++ import { FieldValidation } from '@rjsf/utils; +import { KubernetesValidatorFunctions } from '@backstage/catalog-model'; + +export const entityNamePickerValidation = ( + value: string, + validation: FieldValidation, +) => { +``` + +## Breaking Changes + +Once we fully release the code that is in the `/alpha` exports right now onto the current API and release v2.0.0 of `@backstage/plugin-scaffolder` the breaking changes will be as follows: + +### `uiSchema` is now optional + +Later releases of `react-jsonschema-form` have made the `uiSchema` optional, and if you don't provide it, it will be `undefined` instead of an empty object. This means that you will need to make sure that you're defaulting the `uiSchema` to an empty object if you're using it in your code. + +```diff + const { + onChange, + required, + schema: { title = 'Name', description = 'Unique name of the component' }, + rawErrors, + formData, +- uiSchema: { 'ui:autofocus': autoFocus }, ++ uiSchema: { 'ui:autofocus': autoFocus } = {}, + idSchema, + placeholder, + } = props; +``` + +### `formData` can also be `undefined` + +If you were using the `formData` and assuming that it was set to an empty object when building `Field Extensions` that return objects, then this will be `undefined` now due to a change in the `react-jsonschema-form` library. + +```diff + const { + onChange, + required, + schema: { title = 'Name', description = 'Unique name of the component' }, + rawErrors, +- formData, ++ formData = {}, // or maybe some other default value that you would prefer + uiSchema: { 'ui:autofocus': autoFocus } = {}, + idSchema, + placeholder, + } = props; +``` diff --git a/docs/features/techdocs/addons.md b/docs/features/techdocs/addons.md index 60999f599c..bd709ee15f 100644 --- a/docs/features/techdocs/addons.md +++ b/docs/features/techdocs/addons.md @@ -39,7 +39,9 @@ representative of physical spaces in the TechDocs UI: - `Component`: A [proposed-but-not-yet-implemented](https://github.com/backstage/backstage/issues/11109) virtual location, aimed at simplifying a common type of Addon. -TechDocs Addon Location Guide + + +![TechDocs Addon Location Guide](../../assets/techdocs/addon-locations.png) ### Addon Registry diff --git a/docs/features/techdocs/architecture.md b/docs/features/techdocs/architecture.md index d781f71917..2cb8543ccd 100644 --- a/docs/features/techdocs/architecture.md +++ b/docs/features/techdocs/architecture.md @@ -9,7 +9,9 @@ description: Documentation on TechDocs Architecture When you deploy Backstage (with TechDocs enabled by default), you get a basic out-of-the box experience. -TechDocs Architecture diagram + + +![TechDocs Architecture diagram](../../assets/techdocs/architecture-basic.drawio.svg) > Note: See below for our recommended deployment architecture which takes care > of stability, scalability and speed. Also look at the @@ -42,7 +44,9 @@ storage system (e.g. AWS S3, GCS or Azure Blob Storage). Read more in This is how we recommend deploying TechDocs in a production environment. -TechDocs Architecture diagram + + +![TechDocs Architecture diagram](../../assets/techdocs/architecture-recommended.drawio.svg) The key difference in the recommended deployment approach is where the docs are built. diff --git a/docs/features/techdocs/configuration.md b/docs/features/techdocs/configuration.md index 38a0143bea..e95db2fad0 100644 --- a/docs/features/techdocs/configuration.md +++ b/docs/features/techdocs/configuration.md @@ -51,7 +51,7 @@ techdocs: # techdocs.builder can be either 'local' or 'external'. # Using the default build strategy, if builder is set to 'local' and you open a TechDocs page, - # techdocs-backend will try to generate the docs, publish to storage and show the generated docs afterwords. + # techdocs-backend will try to generate the docs, publish to storage and show the generated docs afterwards. # This is the "Basic" setup of the TechDocs Architecture. # Using the default build strategy, if builder is set to 'external' (or anything other than 'local'), techdocs-backend # will only fetch the docs and will NOT try to generate and publish. diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md index 578a631798..3f7edd23a0 100644 --- a/docs/features/techdocs/getting-started.md +++ b/docs/features/techdocs/getting-started.md @@ -89,11 +89,15 @@ const AppRoutes = () => { I know, you're curious to see how it looks, aren't you? See the image below: -TechDocs Report Issue Add-on + + +![TechDocs Report Issue Add-on](../../assets/techdocs/report-issue-addon.png) By clicking the open new issue button, you will be redirected to the new issue page according to the source code provider you are using: -TechDocs Report Issue Template + + +![TechDocs Report Issue Template](../../assets/techdocs/report-issue-template.png) That's it! Now, we need the TechDocs Backend plugin for the frontend to work. diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md index 0441d3f589..a436321fe2 100644 --- a/docs/getting-started/configuration.md +++ b/docs/getting-started/configuration.md @@ -136,9 +136,7 @@ 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 -

    +![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 @@ -214,9 +212,7 @@ 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 -

    +![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. @@ -262,21 +258,18 @@ otherwise something went terribly wrong. - Register a new component, by going to `create` and choose `Register existing component` -

    - Software template main screen, with a blue button to add an existing component -

    + + + ![Software template main screen, with a blue button to add an existing component](../assets/getting-started/b-existing-1.png) - As URL use `https://github.com/backstage/demo/blob/master/catalog-info.yaml`. This is used by our [demo site](https://demo.backstage.io). -

    - Register a new component wizard, asking for an URL to the existing component YAML file -

    -- Hit `Analyze` and review the changes. Apply them if correct + ![Register a new component wizard, asking for an URL to the existing component YAML file](../assets/getting-started/b-existing-2.png) -

    - Register a new component wizard, showing the metadata for the component YAML we use in this tutorial -

    +- Hit `Analyze` and review the changes. Apply them if correct. + + ![Register a new component wizard, showing the metadata for the component YAML we use in this tutorial](../assets/getting-started/b-existing-3.png) - You should receive a message that your entities have been added. - If you go back to `Home`, you should be able to find `demo`. You should be @@ -286,14 +279,12 @@ otherwise something went terribly wrong. - Go to `create` and choose to create a website with the `Example Node.js Template` - Type in a name, let's use `tutorial` and click `Next Step` -

    - Software template deployment input screen asking for a name -

    + +![Software template deployment input screen asking for a name](../assets/getting-started/b-scaffold-1.png) - You should see the following screen: -

    - Software template deployment input screen asking for the GitHub username, and name of the new repo to create -

    + +![Software template deployment input screen asking for the GitHub username, and name of the new repo to create](../assets/getting-started/b-scaffold-2.png) - For host, it should default to github.com - As owner, type your GitHub username @@ -308,7 +299,7 @@ Achievement unlocked. You've set up an installation of the core Backstage App, made it persistent, and configured it so you are now able to use software templates. -Let us know how your experience was: [on discord](https://discord.gg/EBHEGzX), +Let us know how your experience was: [on discord](https://discord.gg/backstage-687207715902193673), file issues for any [feature](https://github.com/backstage/backstage/issues/new?labels=help+wanted&template=feature_template.md) or diff --git a/docs/getting-started/configure-app-with-plugins.md b/docs/getting-started/configure-app-with-plugins.md index ebe98f9ddc..835da0cd49 100644 --- a/docs/getting-started/configure-app-with-plugins.md +++ b/docs/getting-started/configure-app-with-plugins.md @@ -22,7 +22,8 @@ to an entity in the software catalog. 1. Add the plugin's npm package to the repo: ```bash - yarn workspace app add @backstage/plugin-circleci + # From your Backstage root directory + yarn add --cwd packages/app @backstage/plugin-circleci ``` Note the plugin is added to the `app` package, rather than the root diff --git a/docs/getting-started/create-an-app.md b/docs/getting-started/create-an-app.md index 05c12ffb75..535bc848fc 100644 --- a/docs/getting-started/create-an-app.md +++ b/docs/getting-started/create-an-app.md @@ -34,9 +34,7 @@ npx @backstage/create-app This will create a new Backstage App inside the current folder. The name of the app-folder is the name that was provided when prompted. -

    - create app -

    +![create app](../assets/getting-started/create-app_output.png) Inside that directory, it will generate all the files and folder structure needed for you to run your app. diff --git a/docs/getting-started/homepage.md b/docs/getting-started/homepage.md index 7db41d7768..9fa91e694f 100644 --- a/docs/getting-started/homepage.md +++ b/docs/getting-started/homepage.md @@ -82,16 +82,9 @@ const routes = ( Let's update the route for "Home" in the Backstage sidebar to point to the new homepage. We'll also add a Sidebar item to quickly open Catalog. - - - - - - - - - -
    Sidebar without CatalogSidebar with Catalog
    BeforeAfter
    +| Before | After | +| --------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | +| ![Sidebar without Catalog](../assets/getting-started/sidebar-without-catalog.png) | ![Sidebar with Catalog](../assets/getting-started/sidebar-with-catalog.png) | The code for the Backstage sidebar is most likely inside your [`packages/app/src/components/Root/Root.tsx`](https://github.com/backstage/backstage/blob/master/packages/app/src/components/Root/Root.tsx). @@ -121,7 +114,9 @@ export const Root = ({ children }: PropsWithChildren<{}>) => ( That's it! You should now have _(although slightly boring)_ a homepage! -Screenshot of a blank homepage + + +![Screenshot of a blank homepage](../assets/getting-started/simple-homepage.png) In the next steps, we will make it interesting and useful! diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 962919015b..2617cfb654 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -54,9 +54,7 @@ npx @backstage/create-app@latest The wizard will ask you for the name of the app, which will also be the name of the directory -

    - Screenshot of the wizard asking for a name for the app. -

    +![Screenshot of the wizard asking for a name for the app.](../assets/getting-started/wizard.png) ### Run the Backstage app @@ -69,9 +67,7 @@ cd my-backstage-app yarn dev ``` -

    - Screenshot of the command output, with the message web pack compiled successfully. -

    +![Screenshot of the command output, with the message web pack compiled successfully](../assets/getting-started/startup.png) It might take a little while, but as soon as the message `[0] webpack compiled successfully` appears, you can open a browser and directly @@ -80,16 +76,14 @@ You can start exploring the demo immediately. Please note that the in-memory database will be cleared when you restart the app, so you'll most likely want to carry on with the database steps. -

    - Screenshot of the Backstage portal. -

    +![Screenshot of the Backstage portal.](../assets/getting-started/portal.png) In the next part of this tutorial, you'll learn how to change to a persistent database, configure authentication, and add your first integration. Continue with [getting started: Configuring Backstage](configuration.md). Share your experiences, comments, or suggestions with us: -[on discord](https://discord.gg/EBHEGzX), file issues for any +[on discord](https://discord.gg/backstage-687207715902193673), file issues for any [feature](https://github.com/backstage/backstage/issues/new?labels=help+wanted&template=feature_template.md) or [plugin suggestions](https://github.com/backstage/backstage/issues/new?labels=plugin&template=plugin_template.md&title=%5BPlugin%5D+THE+PLUGIN+NAME), diff --git a/docs/getting-started/running-backstage-locally.md b/docs/getting-started/running-backstage-locally.md index e7e96316f4..d56bdf7990 100644 --- a/docs/getting-started/running-backstage-locally.md +++ b/docs/getting-started/running-backstage-locally.md @@ -86,7 +86,7 @@ option will be GitHub. To setup GitHub authentication in Backstage, see --- Congratulations! That should be it. Let us know how it went -[on discord](https://discord.gg/EBHEGzX), file issues for any +[on discord](https://discord.gg/backstage-687207715902193673), file issues for any [feature](https://github.com/backstage/backstage/issues/new?labels=help+wanted&template=feature_template.md) or [plugin suggestions](https://github.com/backstage/backstage/issues/new?labels=plugin&template=plugin_template.md&title=%5BPlugin%5D+THE+PLUGIN+NAME), diff --git a/docs/integrations/aws-s3/discovery.md b/docs/integrations/aws-s3/discovery.md index 748aeb2392..4a2b953bc9 100644 --- a/docs/integrations/aws-s3/discovery.md +++ b/docs/integrations/aws-s3/discovery.md @@ -63,7 +63,7 @@ As this provider is not one of the default providers, you will first need to ins the AWS catalog plugin: ```bash -# From the Backstage root directory +# From your Backstage root directory yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-aws ``` diff --git a/docs/integrations/gerrit/discovery.md b/docs/integrations/gerrit/discovery.md index 7ed05d2b3b..5d822effb5 100644 --- a/docs/integrations/gerrit/discovery.md +++ b/docs/integrations/gerrit/discovery.md @@ -17,7 +17,7 @@ As this provider is not one of the default providers, you will first need to ins the Gerrit provider plugin: ```bash -# From the Backstage root directory +# From your Backstage root directory yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-gerrit ``` diff --git a/docs/integrations/gitlab/discovery.md b/docs/integrations/gitlab/discovery.md index 5a4dc8abdd..9a065e776a 100644 --- a/docs/integrations/gitlab/discovery.md +++ b/docs/integrations/gitlab/discovery.md @@ -36,7 +36,7 @@ As this provider is not one of the default providers, you will first need to ins the gitlab catalog plugin: ```bash -# From the Backstage root directory +# From your Backstage root directory yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-gitlab ``` diff --git a/docs/integrations/gitlab/org.md b/docs/integrations/gitlab/org.md index 100b2c09fd..2ab72b4bd6 100644 --- a/docs/integrations/gitlab/org.md +++ b/docs/integrations/gitlab/org.md @@ -20,9 +20,9 @@ integrations: ``` This will query all users and groups from your gitlab installation. Depending on the size -of the Gitlab Instance, this can take some time our resources. +of the Gitlab Instance, this can take some time and resources. -The token that is used for the Organization Integration, has to be an Admin PAT. +The token that is used for the Organization Integration, has to be an Admin Personal Access Token (PAT). ```yaml catalog: diff --git a/docs/local-dev/cli-build-system.md b/docs/local-dev/cli-build-system.md index cc364d0ca5..2eb695e3a3 100644 --- a/docs/local-dev/cli-build-system.md +++ b/docs/local-dev/cli-build-system.md @@ -556,7 +556,22 @@ The overrides in a single `package.json` may for example look like this: }, ``` -If you want to configure editor integration for tests we recommend executing the bundled configuration directly with Jest rather than running through the Yarn test script. For example, with the Jest extension for VS Code the configuration would look something like this: +### Debugging Jest Tests + +For your productivity working with unit tests it's quite essential to have your debugging configured in IDE. It will help you to identify the root cause of the issue faster. + +#### IntelliJ IDEA + +1. Update Jest configuration template by: + +- Click on "Edit Configurations" on top panel +- In the modal dialog click on link "Edit configuration templates..." located in the bottom left corner. +- In "Jest package" you have to point to relative path of jest module (it will be suggested by IntelliJ), i.e. `~/proj/backstage/node_modules/jest` +- In "Jest config" point to your jest configuration file, use absolute path for that, i.e. `--config /Users/user/proj/backstage/packages/cli/config/jest.js --runInBand` + +2. Now you can run any tests by clicking on green arrow located on `describe` or `it`. + +#### VS Code ```jsonc { @@ -571,7 +586,7 @@ If you want to configure editor integration for tests we recommend executing the } ``` -If you also want to enable source maps when debugging tests, you can do so by setting the `ENABLE_SOURCE_MAPS` environment variable. For example, a complete launch configuration for VS Code debugging may look like this: +A complete launch configuration for VS Code debugging may look like this: ```json { @@ -583,9 +598,6 @@ If you also want to enable source maps when debugging tests, you can do so by se "disableOptimisticBPs": true, "program": "${workspaceFolder}/node_modules/.bin/jest", "cwd": "${workspaceFolder}", - "env": { - "ENABLE_SOURCE_MAPS": "true" - }, "args": [ "--config", "node_modules/@backstage/cli/config/jest.js", @@ -638,8 +650,34 @@ The following is an excerpt of a typical setup of an isomorphic library package: "files": ["dist"], ``` +## Subpath Exports + +The Backstage CLI supports implementation of subpath exports through the `"exports"` field in `package.json`. It might for example look like this: + +```json + "name": "@backstage/plugin-foo", + "exports": { + ".": "./src/index.ts", + "./components": "./src/components.ts", + }, +``` + +This in turn would allow you to import anything exported in `src/index.ts` via `@backstage/plugins-foo`, and `src/components.ts` via `@backstage/plugins-foo/components`. Note that patterns are not supported, meaning the exports may not contain `*` wildcards. + +As with the rest of the Backstage CLI build system, the setup is optimized for local development, which is why the `"exports"` targets point directly to source files. The `package build` command will detect the `"exports"` field and automatically generate the corresponding `dist` files, and the `prepublish` command will rewrite the `"exports"` field to point to the `dist` files, as well as generating folder-based entry points for backwards compatibility. + +TypeScript support is currently handled though the `typesVersions` field, as there is not yet a module resolution mode that works well with `"exports"`. You can craft the `typesVersions` yourself, but it will also be automatically generated by the `migrate package-exports` command. + +To add subpath exports to an existing package, simply add the desired `"exports"` fields and then run the following command: + +```bash +yarn backstage-cli package migrate package-exports +``` + ## Experimental Type Build +> Note: Experimental type builds are deprecated and will be removed in the future. They have been replaced by [subpath exports](#subpath-exports). + The Backstage CLI has an experimental feature where multiple different type definition files can be generated for different release stages. The release stages are marked in the [TSDoc](https://tsdoc.org/) for each individual export, using either `@public`, `@alpha`, or `@beta`. Rather than just building a single `index.d.ts` file, the build process will instead output `index.d.ts`, `index.beta.d.ts`, and `index.alpha.d.ts`. Each of these files will have exports from more unstable release stages stripped, meaning that `index.d.ts` will omit all exports marked with `@alpha` or `@beta`, while `index.beta.d.ts` will omit all exports marked with `@alpha`. This feature is aimed at projects that publish to package registries and wish to maintain different levels of API stability within each package. There is no need to use this within a single monorepo, as it has no effect due to only applying to built and published packages. diff --git a/docs/local-dev/cli-commands.md b/docs/local-dev/cli-commands.md index b43825d733..e34dd63295 100644 --- a/docs/local-dev/cli-commands.md +++ b/docs/local-dev/cli-commands.md @@ -120,7 +120,6 @@ Build a package for production deployment or publishing Options: --role <name> Run the command with an explicit package role --minify Minify the generated code. Does not apply to app or backend packages. - --experimental-type-build Enable experimental type build. Does not apply to app or backend packages. --skip-build-dependencies Skip the automatic building of local dependencies. Applies to backend packages only. --stats If bundle stats are available, write them to the output directory. Applies to app packages only. --config <path> Config files to load instead of app-config.yaml. Applies to app packages only. (default: []) diff --git a/docs/overview/roadmap.md b/docs/overview/roadmap.md index 2ac211bf97..8e3d73ded6 100644 --- a/docs/overview/roadmap.md +++ b/docs/overview/roadmap.md @@ -111,4 +111,4 @@ guidelines to get started. If you have specific questions about the roadmap, please create an [issue](https://github.com/backstage/backstage/issues/new/choose), ping us on -[Discord](https://discord.gg/qxsEfa8Vq8), or [book time](https://info.backstage.spotify.com/office-hours) with the Spotify team. +[Discord](https://discord.gg/backstage-687207715902193673), or [book time](https://info.backstage.spotify.com/office-hours) with the Spotify team. diff --git a/docs/overview/support.md b/docs/overview/support.md index 662a37c6ae..a0444c4d34 100644 --- a/docs/overview/support.md +++ b/docs/overview/support.md @@ -4,7 +4,7 @@ title: Support and community description: Support and Community Details and Links --- -- [Discord chatroom](https://discord.gg/MUpMjP2) - Get support or discuss the +- [Discord chatroom](https://discord.gg/backstage-687207715902193673) - Get support or discuss the project. - [Stack Overflow](https://stackoverflow.com/questions/tagged/backstage) - Browse or ask questions on Stack Overflow. - [Good First Issues](https://github.com/backstage/backstage/contribute) - Start diff --git a/docs/overview/what-is-backstage.md b/docs/overview/what-is-backstage.md index 38b67e81de..f18993770a 100644 --- a/docs/overview/what-is-backstage.md +++ b/docs/overview/what-is-backstage.md @@ -5,7 +5,7 @@ title: What is Backstage? description: Backstage is an open platform for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure --- -![software-catalog](https://backstage.io/blog/assets/6/header.png) +![software-catalog](../assets/header.png) [Backstage](https://backstage.io/) is an open platform for building developer portals. Powered by a centralized software catalog, Backstage restores order to @@ -61,4 +61,4 @@ Backstage is a CNCF Incubation project after graduating from Sandbox. Read the a administrators together in one place. If you have questions or want support, please join our -[Discord chatroom](https://discord.gg/EBHEGzX). +[Discord chatroom](https://discord.gg/backstage-687207715902193673). diff --git a/docs/permissions/getting-started.md b/docs/permissions/getting-started.md index d2c467ff08..e71601b703 100644 --- a/docs/permissions/getting-started.md +++ b/docs/permissions/getting-started.md @@ -47,7 +47,8 @@ The permissions framework uses a new `permission-backend` plugin to accept autho 1. Add `@backstage/plugin-permission-backend` as a dependency of your Backstage backend: ```bash -$ yarn workspace backend add @backstage/plugin-permission-backend +# From your Backstage root directory +$ yarn add --cwd packages/backend @backstage/plugin-permission-backend ``` 2. Add the following to a new file, `packages/backend/src/plugins/permission.ts`. This adds the permission-backend router, and configures it with a policy which allows everything. diff --git a/docs/permissions/plugin-authors/01-setup.md b/docs/permissions/plugin-authors/01-setup.md index a38b81e679..c368505849 100644 --- a/docs/permissions/plugin-authors/01-setup.md +++ b/docs/permissions/plugin-authors/01-setup.md @@ -39,9 +39,10 @@ The source code is available here: 2. Add these packages as dependencies for your Backstage app: - ``` - $ yarn workspace backend add @internal/plugin-todo-list-backend @internal/plugin-todo-list-common - $ yarn workspace app add @internal/plugin-todo-list + ```sh + # From your Backstage root directory + $ yarn add --cwd packages/backend @internal/plugin-todo-list-backend @internal/plugin-todo-list-common + $ yarn add --cwd packages/app @internal/plugin-todo-list ``` 3. Include the backend and frontend plugin in your application: 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 2ceb8057f4..44a3e43718 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 @@ -100,7 +100,7 @@ Edit `plugins/todo-list-backend/src/service/router.ts`: Pass the `permissions` object to the plugin in `packages/backend/src/plugins/todolist.ts`: ```diff - import { IdentityClient } from '@backstage/plugin-auth-backend'; + import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; import { createRouter } from '@internal/plugin-todo-list-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; @@ -112,7 +112,7 @@ Pass the `permissions` object to the plugin in `packages/backend/src/plugins/tod }: PluginEnvironment): Promise { return await createRouter({ logger, - identity: new IdentityClient({ + identity: DefaultIdentityClient.create({ discovery, issuer: await discovery.getExternalBaseUrl('auth'), }), diff --git a/docs/plugins/backend-plugin.md b/docs/plugins/backend-plugin.md index 517779d161..c4414c8e55 100644 --- a/docs/plugins/backend-plugin.md +++ b/docs/plugins/backend-plugin.md @@ -66,7 +66,7 @@ To actually attach and run the plugin router, you will make some modifications to your backend. ```bash -# From the Backstage root directory +# From your Backstage root directory yarn add --cwd packages/backend @internal/plugin-carmen-backend@^0.1.1 # Change this to match the plugin's package.json ``` diff --git a/docs/plugins/new-backend-system.md b/docs/plugins/new-backend-system.md index 785d364ae2..2ff061a60b 100644 --- a/docs/plugins/new-backend-system.md +++ b/docs/plugins/new-backend-system.md @@ -4,11 +4,11 @@ title: New Backend System description: Details of the upcoming backend system --- -> **DISCLAIMER: The new backend system is under active development and is not considered stable** +> **DISCLAIMER: The new backend system is in alpha, and still under active development. While we have reviewed the interfaces carefully, they may still be iterated on before the stable release.** ## Status -The new backend system is under active development, and only a small number of plugins have been migrated so far. It is possible to try it out, but it is not recommended to use this new system in production yet. +The new backend system is in alpha, and only a small number of plugins have been migrated so far. It is possible to try it out, but it is not recommended to use this new system in production yet. You can find an example backend setup in [the backend-next package](https://github.com/backstage/backstage/tree/master/packages/backend-next). diff --git a/docs/plugins/testing.md b/docs/plugins/testing.md index baee47c695..2fa086c444 100644 --- a/docs/plugins/testing.md +++ b/docs/plugins/testing.md @@ -371,14 +371,4 @@ Note: wrapping in the test application **requires** you to do a `find()` or # Debugging Jest Tests -Currently, debugging Jest tests using IntelliJ or `node-debugger` is possible -but can be -[problematic to set up.](https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000634564-Debugging-Jest-unit-tests) - -It is possible, but you might spend a decent amount of time configuring your -IDE. - -In most cases, we have found that using `console.log` works well. - -Note: if your console.logs are not being displayed, focus your specific unit -test from the command line by running them like so `yarn test MyTest`. +You can find it [here](https://backstage.io/docs/local-dev/cli-build-system#debugging-jest-tests) diff --git a/docs/releases/v1.0.0.md b/docs/releases/v1.0.0.md index 44a4f48213..6906ef8ae7 100644 --- a/docs/releases/v1.0.0.md +++ b/docs/releases/v1.0.0.md @@ -85,7 +85,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/releases/tag/v1.0.0) for this release - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) diff --git a/docs/releases/v1.1.0.md b/docs/releases/v1.1.0.md index 0417423247..daf31a536f 100644 --- a/docs/releases/v1.1.0.md +++ b/docs/releases/v1.1.0.md @@ -63,7 +63,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.1.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) diff --git a/docs/releases/v1.10.0-next.2-changelog.md b/docs/releases/v1.10.0-next.2-changelog.md index 8f1dec1e8d..4d8243799b 100644 --- a/docs/releases/v1.10.0-next.2-changelog.md +++ b/docs/releases/v1.10.0-next.2-changelog.md @@ -127,7 +127,7 @@ - e4469d0ec1: The ADR plugin can now work with sites other than GitHub. Expanded the ADR backend plugin to provide endpoints to facilitate this. - **BREAKING** The ADR plugin now uses UrlReaders. You will have to [configure integrations](https://backstage.io/docs/integrations/index#configuration) for all sites you want to get ADRs from. If you would like to create your own implementation that has different behavior, you can override the AdrApi [just like you can with other apis.](https://backstage.io/docs/api/utility-apis#app-apis) The previously used Octokit implementation has been completely removed. + **BREAKING** The ADR plugin now uses UrlReaders. You will have to [configure integrations](https://backstage.io/docs/integrations#configuration) for all sites you want to get ADRs from. If you would like to create your own implementation that has different behavior, you can override the AdrApi [just like you can with other apis.](https://backstage.io/docs/api/utility-apis#app-apis) The previously used Octokit implementation has been completely removed. ### Patch Changes @@ -424,7 +424,7 @@ - e4469d0ec1: The ADR plugin can now work with sites other than GitHub. Expanded the ADR backend plugin to provide endpoints to facilitate this. - **BREAKING** The ADR plugin now uses UrlReaders. You will have to [configure integrations](https://backstage.io/docs/integrations/index#configuration) for all sites you want to get ADRs from. If you would like to create your own implementation that has different behavior, you can override the AdrApi [just like you can with other apis.](https://backstage.io/docs/api/utility-apis#app-apis) The previously used Octokit implementation has been completely removed. + **BREAKING** The ADR plugin now uses UrlReaders. You will have to [configure integrations](https://backstage.io/docs/integrations#configuration) for all sites you want to get ADRs from. If you would like to create your own implementation that has different behavior, you can override the AdrApi [just like you can with other apis.](https://backstage.io/docs/api/utility-apis#app-apis) The previously used Octokit implementation has been completely removed. - 21ffbdd5ee: Clarify that default ADR parsers support MADR specification v2.x diff --git a/docs/releases/v1.10.0.md b/docs/releases/v1.10.0.md index 93ab357370..b06ab63747 100644 --- a/docs/releases/v1.10.0.md +++ b/docs/releases/v1.10.0.md @@ -71,7 +71,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.10.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) diff --git a/docs/releases/v1.11.0-changelog.md b/docs/releases/v1.11.0-changelog.md new file mode 100644 index 0000000000..42f9e9720b --- /dev/null +++ b/docs/releases/v1.11.0-changelog.md @@ -0,0 +1,2876 @@ +# Release v1.11.0 + +## @backstage/app-defaults@1.2.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-permission-react@0.4.10 + +## @backstage/backend-app-api@0.4.0 + +### Minor Changes + +- 01a075ec1d: **BREAKING**: Renamed `RootHttpRouterConfigureOptions` to `RootHttpRouterConfigureContext`, and removed the unused type `ServiceOrExtensionPoint`. +- 4ae71b7f2e: **BREAKING** Renaming `*Factory` exports to `*ServiceFactory` instead. For example `configFactory` now is exported as `configServiceFactory`. +- d31d8e00b3: **BREAKING** `HttpServerCertificateOptions` when specified with a `key` and `cert` should also have the `type: 'pem'` instead of `type: 'plain'` + +### Patch Changes + +- a18da2f8b5: Fixed an issue were the log redaction didn't properly escape RegExp characters. +- 5febb216fe: Updated to match the new `CacheService` interface. +- e716946103: Updated usage of the lifecycle service. +- f60cca9da1: Updated database factory to pass service deps required for restoring database state during development. +- 610d65e143: Updates to match new `BackendFeature` type. +- 725383f69d: Tweaked messaging in the README. +- b86efa2d04: Updated usage of `ServiceFactory`. +- ab22515647: The shutdown signal handlers are now installed as part of the backend instance rather than the lifecycle service, and explicitly cause the process to exit. +- b729f9f31f: Moved the options of the `config` and `rootHttpRouter` services out to the factories themselves, where they belong +- ed8b5967d7: `HttpRouterFactoryOptions.getPath` is now optional as a default value is always provided in the factory. +- 71a5ec0f06: Updated usages of `LogMeta`. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/backend-tasks@0.4.3 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-node@0.7.5 + +## @backstage/backend-dev-utils@0.1.0 + +### Minor Changes + +- 9d9cdea117: Introduced a new package for backend development utilities. Similar to how `@backstage/dev-utils` is used in the frontend. + +### Patch Changes + +- 725383f69d: Tweaked messaging in the README. + +## @backstage/backend-plugin-api@0.4.0 + +### Minor Changes + +- e716946103: **BREAKING**: Split out the hook for both lifecycle services so that the first parameter of `addShutdownHook` is the hook function, and the second is the options. +- 0ff03319be: **BREAKING**: The plugin ID option passed to `createBackendPlugin` is now `pluginId`, rather than just `id`. This is to make it match `createBackendModule` more closely. +- 71a5ec0f06: **BREAKING**: Switched out `LogMeta` type for `JsonObject`. +- 5febb216fe: **BREAKING**: The `CacheService` has been changed to remove the indirection of `getClient`, instead making the `CacheClient` methods directly available on the `CacheService`. In order to allow for the creation of clients with default options, there is now a new `.withOptions` method that must be implemented as part of the service interface. +- b86efa2d04: Switch `ServiceFactory` to be an opaque type, keeping only the `service` field as public API, but also adding a type parameter for the service scope. +- 610d65e143: Switched `BackendFeature` to be an opaque type. + +### Patch Changes + +- 9c9456fd33: Removed the unused `TypesToServiceRef` type +- 181c03edb5: Aligned opaque type markers to all use a `$type` property with namespacing. +- 725383f69d: Tweaked messaging in the README. +- ae88f61e00: The `register` methods passed to `createBackendPlugin` and `createBackendModule` + now have dedicated `BackendPluginRegistrationPoints` and + `BackendModuleRegistrationPoints` arguments, respectively. This lets us make it + clear on a type level that it's not possible to pass in extension points as + dependencies to plugins (should only ever be done for modules). This has no + practical effect on code that was already well behaved. +- Updated dependencies + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/catalog-model@1.2.0 + +### Minor Changes + +- d51668882d: Adds the tRPC API type to the catalog. + +### Patch Changes + +- aece6c57d2: Add additional validation for location references. +- 2518ef5b8a: Add deprecation tag to kubernetes constants in catalog, constants are now defined in plugin-kubernetes-common +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## @backstage/core-app-api@1.5.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- dff4d8ddb1: Fixed an issue where an explicit port the frontend base URL could break the app. +- Updated dependencies + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## @backstage/core-plugin-api@1.4.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## @backstage/eslint-plugin@0.1.0 + +### Minor Changes + +- 179d301518: Added a new ESLint plugin with common rules for Backstage projects. See the [README](https://github.com/import-js/eslint-plugin-import/blob/main/packages/eslint-plugin/README.md) for more details. + +## @backstage/plugin-adr@0.4.0 + +### Minor Changes + +- 0a32911d8a: Display title, status and date in ADR navigation, sourced from ADR content and reverse order. +- ec34b535c0: The `AdrSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- ec34b535c0: Support displaying an icon on `AdrSearchResultListItem` +- 496cf6aff0: Render the common `` component when the `backstage.io/adr-location` annotation is missing from the component +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-adr-common@0.2.6 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-adr-backend@0.3.0 + +### Minor Changes + +- 0a32911d8a: Display title, status and date in ADR navigation, sourced from ADR content and reverse order. + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/plugin-adr-common@0.2.6 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-api-docs@0.9.0 + +### Minor Changes + +- 9ed53218a5: Adds a new tRPC API definition widget which users can utilize to integrate their tRPC API definitions into Backstage. + +### Patch Changes + +- 60996f8aba: Updating the readme with better `csp` instructions +- 6856ab98f4: Updated dependency `@asyncapi/react-component` to `1.0.0-next.47`. +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-auth-backend@0.18.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + +## @backstage/plugin-catalog@1.8.0 + +### Minor Changes + +- 0c1fc3986c: Added Markdown support in the `AboutCard` description section +- 0eaa579f89: The `CatalogSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- d7f55f6bd2: The list of entities takes into account the title when its different from the name to sort the entities. + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- 7d46ca2f68: Make catalog search result list a bit more customizable + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/integration-react@1.1.10 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.2.0 + +### Minor Changes + +- 1ba120faa3: Added new mechanism to handle deltas in incremental providers + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 407dc01fc9: Removing extra imports for `run` script as `TestBackend` auto loads the default factories +- b7e36660d5: Return `EventSubscriber` from `addIncrementalEntityProvider` to hook up to `EventsBackend` +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- 77c41b6924: Updated README to include newer API options for incremental entity providers +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.0 + +### Minor Changes + +- fb568e2683: Improve performance when loading users via group membership. + Users data is now loaded from a paged query, rather than having to make an extra call per user to load each user's profiles. + + Note, there are still additional per user calls made to load user avatars + +### Patch Changes + +- 4c86436fdf: Fix MS Graph provider to use target URL for fetching access token +- 0daa328c3a: Extract default transformers to their own file +- 28f9883440: Fixed a bug reading the `user.select` field expected from the `app-config.yaml` configuration +- c5b119ad9c: Increased default page size to 999 (from 100) to reduce the number of calls made to the Microsoft Graph API. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + +## @backstage/plugin-catalog-react@1.3.0 + +### Minor Changes + +- 929e1afe1b: Add `initialFilter` prop to EntityLifecyclePicker. This allows you to set an initial lifecycle for the catalog. +- fab93c2fe8: Aligned buttons on "Unregister entity" dialog to keep them on the same line + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.10 + +## @backstage/plugin-entity-feedback@0.1.0 + +### Minor Changes + +- a3c86a7ed2: Implement entity feedback plugin, check out the `README.md` for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/plugin-entity-feedback-common@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-entity-feedback-backend@0.1.0 + +### Minor Changes + +- a3c86a7ed2: Implement entity feedback plugin, check out the `README.md` for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-entity-feedback-common@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/plugin-auth-node@0.2.11 + +## @backstage/plugin-entity-feedback-common@0.1.0 + +### Minor Changes + +- a3c86a7ed2: Implement entity feedback plugin, check out the `README.md` for more details! + +## @backstage/plugin-entity-validation@0.1.0 + +### Minor Changes + +- d34b3267f9: First implementation for the entity validation UI. For more information refer to its `README.md`. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/plugin-catalog-common@1.0.11 + +## @backstage/plugin-explore@0.4.0 + +### Minor Changes + +- 0eaa579f89: The `ToolSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/errors@1.1.4 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-explore-react@0.0.26 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-graphql-voyager@0.1.0 + +### Minor Changes + +- d1fb4b7bf1: Add the new GraphQL Voyager tool as a plugin for backstage, expose necessary API and components needed for it. + + For more information on how to use this plugin and configure it, please navigate to the [README](https://github.com/backstage/backstage/tree/master/plugins/graphql-voyager/README.md) of the plugin. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-kubernetes-common@0.6.0 + +### Minor Changes + +- 1728c1ef01: **BREAKING**: Renamed misspelled `LimitRangeFetchReponse` to `LimitRangeFetchResponse`. + +### Patch Changes + +- 2518ef5b8a: New K8s catalog entity annotations added that will replace now deprecated k8s annotations in the catalog-model package. K8s annotation imports should now be made from plugin-kubernetes-common. +- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. +- Updated dependencies + - @backstage/catalog-model@1.2.0 + +## @backstage/plugin-lighthouse@0.4.0 + +### Minor Changes + +- eef62546ce: Require @backstage/plugin-lighthouse-common package where API implementation moved to. + + **BREAKING**: the following types have been moved to @backstage/plugin-lighthouse-common: + + - `Audit` + - `AuditBase` + - `AuditCompleted` + - `AuditFailed` + - `AuditRunning` + - `FetchError` + - `LASListRequest` + - `LASListResponse` + - `LighthouseApi` + - `LighthouseCategoryAbbr` + - `LighthouseCategoryId` + - `LighthouseConfigSettings` + - `LighthouseRestApi` + - `TriggerAuditPayload` + - `Website` + - `WebsiteListResponse` + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 4bdd6bcb3c: Prefer Link over plain anchors +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/plugin-lighthouse-common@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-lighthouse-backend@0.1.0 + +### Minor Changes + +- eef62546ce: Introduce Lighthouse Backend Plugin to run scheduled Lighthouse Audits + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-lighthouse-common@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + +## @backstage/plugin-lighthouse-common@0.1.0 + +### Minor Changes + +- eef62546ce: Introduce @backstage/plugin-lighthouse-common with the API implementation + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + +## @backstage/plugin-linguist@0.1.0 + +### Minor Changes + +- 75cfee5688: Introduced the Linguist plugin, checkout the plugin's `README.md` for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-linguist-backend@0.1.0 + +### Minor Changes + +- 75cfee5688: Introduced the Linguist plugin, checkout the plugin's `README.md` for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + +## @backstage/plugin-linguist-common@0.1.0 + +### Minor Changes + +- 75cfee5688: Introduced the Linguist plugin, checkout the plugin's `README.md` for more details! + +## @backstage/plugin-microsoft-calendar@0.1.0 + +### Minor Changes + +- 44412375bb: Created a new plugin `@backstage/plugin-microsoft-calendar` to display events from a Microsoft Calendar. + + please refer to the [README.md](https://github.com/backstage/backstage/blob/master/plugins/microsoft-calendar/README.md) for step-by-step instructions to setup the plugin in your Backstage instance. + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-scaffolder@1.11.0 + +### Minor Changes + +- d6bb12a2e7: - **Deprecation** - Deprecated the following exports, please import them directly from `@backstage/plugin-scaffolder-react` instead + + createScaffolderLayout + ScaffolderLayouts + LayoutOptions + LayoutTemplate + +- a521379688: Migrating the `TemplateEditorPage` to work with the new components from `@backstage/plugin-scaffolder-react` + +- 074f7e81b5: Added a missing validator check for items in an array + +- 8c2966536b: Embed scaffolder workflow in other components + +### Patch Changes + +- 04f717a8e1: `scaffolder/next`: bump `react-jsonschema-form` libraries to `v5-stable` +- b46f385eff: scaffolder/next: Implementing a simple `OngoingTask` page +- cbab8ac107: lock versions of `@rjsf/*-beta` packages +- 346d6b6630: Upgrade `@rjsf` version 5 dependencies to `beta.18` +- ccbf91051b: bump `@rjsf` `v5` dependencies to 5.1.0 +- d2ddde2108: Add `ScaffolderLayouts` to `NextScaffolderPage` +- 0f0da2f256: Prefer schema ordering of template properties during review content generation. +- 38992bdbaf: Fixed bug in review step refactor that caused schema-based display settings for individual property values to be discarded. +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.1.0 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-react@0.4.10 + - @backstage/plugin-scaffolder-common@1.2.5 + +## @backstage/plugin-scaffolder-backend@1.11.0 + +### Minor Changes + +- 0b2952ee4b: Added the option to overwrite files in the `targetPath` of the `template:fetch` action +- 127154930f: Renamed the export `scaffolderCatalogModule` to `catalogModuleTemplateKind` in order to follow the new recommended naming patterns of backend system items. This is technically a breaking change but in an alpha export, so take care to change your imports if you have already migrated to the new backend system. + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. + +- ad3edc402d: **Deprecations**: The following are deprecated and should instead be imported from the new package `@backstage/plugin-scaffolder-node`: + + - `ActionContext` + - `createTemplateAction` + - `TaskSecrets` + - `TemplateAction` + +- 6c70919f1a: Provide better error messaging when GitHub fails due to missing team definitions + +- 66cf22fdc4: Updated dependency `esbuild` to `^0.17.0`. + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-scaffolder-common@1.2.5 + +## @backstage/plugin-scaffolder-node@0.1.0 + +### Minor Changes + +- d72866f0cc: New package that takes over some of the types and functionality from `@backstage/plugin-scaffolder-backend` that are shared with other modules + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/catalog-model@1.2.0 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-common@1.2.5 + +## @backstage/plugin-scaffolder-react@1.1.0 + +### Minor Changes + +- a07750745b: Added `DescriptionField` field override to the `next/scaffolder` +- a521379688: Migrating the `TemplateEditorPage` to work with the new components from `@backstage/plugin-scaffolder-react` +- 8c2966536b: Embed scaffolder workflow in other components +- 5555e17313: refactor `createAsyncValidators` to be recursive to ensure validators are called in nested schemas. + +### Patch Changes + +- 04f717a8e1: `scaffolder/next`: bump `react-jsonschema-form` libraries to `v5-stable` +- b46f385eff: scaffolder/next: Implementing a simple `OngoingTask` page +- cbab8ac107: lock versions of `@rjsf/*-beta` packages +- 346d6b6630: Upgrade `@rjsf` version 5 dependencies to `beta.18` +- ccbf91051b: bump `@rjsf` `v5` dependencies to 5.1.0 +- d2ddde2108: Add `ScaffolderLayouts` to `NextScaffolderPage` +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-scaffolder-common@1.2.5 + +## @backstage/plugin-search@1.1.0 + +### Minor Changes + +- 0eaa579f89: Update `SearchModal` component to use `SearchResult` extensions. + +### Patch Changes + +- 26fb21aa8b: Implement a `showCounts` option to display result counts per type in `SearchType.Accordion` +- 66e2aab4c4: Updated colors for each tab used on search modal, to improve color contrast. Aria label added to tabs wrapper component. `disableRipple` property on the `Tab` component removed to improve keyboard navigation indicator. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-search-react@1.5.0 + +### Minor Changes + +- 0eaa579f89: - Create the search results extensions, for more details see the documentation [here](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions); + - Update the `SearchResult`, `SearchResultList` and `SearchResultGroup` components to use extensions and default their props to optionally accept a query, when the query is not passed, the component tries to get it from the search context. + +### Patch Changes + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-sentry@0.5.0 + +### Minor Changes + +- 6a8d6b9a0c: Add option to filter issues based on the time it was triggered + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-tech-insights-node@0.4.0 + +### Minor Changes + +- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. + TechInsightsClient now implements method getFactSchemas(). + + **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common + + These changes are **required** if you were importing this type directly. + + ```diff + - import { FactSchema } from '@backstage/plugin-tech-insights-node'; + + import { FactSchema } from '@backstage/plugin-tech-insights-common'; + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + +## @backstage/plugin-techdocs@1.5.0 + +### Minor Changes + +- 20840b36b4: Update DocsTable and EntityListDocsTable to accept overrides for Material Table options. +- 0eaa579f89: The `TechDocsSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- c8e09cc383: Fixed bug in Techdocs reader where a techdocs page with a hash in the URL did not always jump to the document anchor. + +- cad5607411: Improve view: remove footer overlay on large screen + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- 4660b63947: Create a TechDocs `` addon that allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page. + + Here's an example on how to use it in a Backstage app: + + ```diff + import { + DefaultTechDocsHome, + TechDocsIndexPage, + TechDocsReaderPage, + } from '@backstage/plugin-techdocs'; + import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha'; + +import { LightBox } from '@backstage/plugin-techdocs-module-addons-contrib'; + + const AppRoutes = () => { + + // other plugin routes + }> + + + } + > + + + + + + ; + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-react@1.1.3 + +## @backstage/plugin-techdocs-node@1.5.0 + +### Minor Changes + +- dd1e37649f: Deprecated getMkDocsYml in favor of getMkdocsYml (lowercase 'd') + +### Patch Changes + +- 87ab76e55c: Fixed bug caused by recent migration to AWS SDK V3 for techdocs-node. Instead of s3ForcePathStyle, forcePathStyle should be passed. +- 339d9a5b5c: Added support for using a default `mkdocs.yml` configuration file when none is provided +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-aws-node@0.1.1 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-user-settings@0.7.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- c4940b6322: Added a message to advise a page reload when toggling feature flags +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## @backstage/backend-common@0.18.2 + +### Patch Changes + +- 5febb216fe: **BREAKING**: The `CacheClient` interface must now also implement the `withOptions` method. The `.get()` method has also received a type parameter that helps ensure that `undefined` in the event of a cache miss is handled. + + Added a `cacheToPluginCacheManager` helper that converts a `CacheService` into a legacy `PluginCacheManager` instance. + +- 5febb216fe: Updated to match the new `CacheService` interface. + +- e716946103: Updated usage of the lifecycle service. + +- d31d8e00b3: Updated to work with the new `type: 'pem'` with `createHttpServer` from `@backstage/backend-app-api` + +- 0ff03319be: Updated usage of `createBackendPlugin`. + +- f60cca9da1: The `DatabaseManager.forPlugin` method now accepts additional service dependencies. There is no need to update existing code to pass these dependencies. + +- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. + +- Updated dependencies + - @backstage/backend-app-api@0.4.0 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-dev-utils@0.1.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/backend-defaults@0.1.7 + +### Patch Changes + +- 725383f69d: Tweaked messaging in the README. +- e412d33025: Use the new `*ServiceFactory` exports from `@backstage/backend-app-api` +- Updated dependencies + - @backstage/backend-app-api@0.4.0 + - @backstage/backend-plugin-api@0.4.0 + +## @backstage/backend-tasks@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 + +## @backstage/backend-test-utils@0.1.34 + +### Patch Changes + +- baf6e4c96a: Removed unnecessary `@backstage/cli` dependency. +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 1835311713: Added explicit return type signature for `mockServices.config()`. +- e716946103: Updated usage of the lifecycle service. +- 7e7557a2be: Updated the `mockServices.rootLogger` options to accept a single level option instead. +- 610d65e143: Updates to match new `BackendFeature` type. +- e412d33025: Use the new `*ServiceFactory` exports from `@backstage/backend-app-api` +- b86efa2d04: Updated usage of `ServiceFactory`. +- 17b573e4be: The new backend system testing utilities have now been marked as stable API. +- f1adb2e36b: Removed the `ref` from all `mockServices`. +- d0901c9ba4: All mock service factories and mock service implementations are now available via the new experimental `mockServices` export. +- 71a5ec0f06: Updated usages of `LogMeta`. +- Updated dependencies + - @backstage/backend-app-api@0.4.0 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + +## @backstage/catalog-client@1.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/errors@1.1.4 + +## @backstage/cli@0.22.2 + +### Patch Changes + +- 561df21ea3: The `backstage-cli repo test` command now sets a default Jest `--workerIdleMemoryLimit` of 1GB. If needed to ensure that tests are not run in band, `--maxWorkers=2` is set as well. This is the recommended workaround for dealing with Jest workers leaking memory and eventually hitting the heap limit. +- 2815981057: Show module name causing error during build +- dd8a9afe66: Replaced several monorepo lint rules with new rules from `@backstage/eslint-plugin`. See the [README](https://github.com/import-js/eslint-plugin-import/blob/main/packages/eslint-plugin/README.md) for a full list of rules. +- a9c50af76b: Fixed Webpack loader patterns so that they properly match the file suffix only. +- 66cf22fdc4: Updated dependency `esbuild` to `^0.17.0`. +- 6d3abfded1: Switch to inline source maps for test transpilation, simplifying editor setups. +- 90616df9a8: Added an experimental mode for the `package start` command for backend packages. Enabled by setting `EXPERIMENTAL_BACKEND_START`. +- Updated dependencies + - @backstage/eslint-plugin@0.1.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/release-manifests@0.0.8 + - @backstage/types@1.0.2 + +## @backstage/codemods@0.1.43 + +### Patch Changes + +- 02f1316e57: Moved `commander` to being a regular dependency. +- Updated dependencies + - @backstage/cli-common@0.1.11 + +## @backstage/core-components@0.12.4 + +### Patch Changes + +- 68ce7d0417: Added aria labels on the support button and sidebar +- 5637ebed92: Added a global override for `window.open` that helps prevent security vulnerabilities. +- 910015f5b7: The Button component has been deprecated in favor of the LinkButton component +- 20840b36b4: Adds new type, TableOptions, extending Material Table Options. +- e81a6e0ab5: Updated Link URL validation to be more strict. +- 85b04f659a: Internal refactor to not use deprecated `substr` +- 66e2aab4c4: Navigation items in mobile sidebar now have aria label. +- Updated dependencies + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/version-bridge@1.0.3 + +## @backstage/create-app@0.4.37 + +### Patch Changes + +- 12a7b316ee: Bumped create-app version. +- 86a8dfd7b0: Added a check to ensure that Yarn v1 is used when creating new projects. +- 0eaa579f89: Update `SearchPage` template to use `SearchResult` extensions. +- 02f1316e57: Updated `packages/app/cypress/.eslintrc.json` to remove the unnecessary `import/no-extraneous-dependencies` rule. +- Updated dependencies + - @backstage/cli-common@0.1.11 + +## @backstage/dev-utils@1.0.12 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/app-defaults@1.2.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/integration-react@1.1.10 + - @backstage/test-utils@1.2.5 + +## @backstage/integration-react@1.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + +## @backstage/repo-tools@0.1.2 + +### Patch Changes + +- ff63acf30a: Packages without a declared `backstage.role` are now ignored. +- Updated dependencies + - @backstage/cli-common@0.1.11 + - @backstage/errors@1.1.4 + +## @techdocs/cli@1.3.2 + +### Patch Changes + +- dd1e37649f: Deprecated getMkDocsYml in favor of getMkdocsYml (lowercase 'd') + +- dcacf94912: Fix proxying to mkdocs + + The domain localhost may point to both 127.0.0.1 and ::1, ipv4 and ipv6 + and when node tries to lookup localhost it might prefer ipv6 while mkdocs + is only listening on ipv4. This tells node-proxy to target the ipv4 address + instead of relying on localhost hostname lookup. + +- 339d9a5b5c: Added support for using a default `mkdocs.yml` configuration file when none is provided + +- 6e0b6a0d50: Fixed publish command missing awsBucketRootPath option. + Fixed publish command having the gcsBucketRootPath option misconfigured, previously returning a boolean vs a string. + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-techdocs-node@1.5.0 + - @backstage/catalog-model@1.2.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + +## @backstage/test-utils@1.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.10 + +## @backstage/theme@0.2.17 + +### Patch Changes + +- b7705e176c: Use same table header color as @backstage/core-components Table to meet accessibility color contrast requirements. This change affects material-ui tables. + +## @backstage/plugin-adr-common@0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/integration@1.4.2 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-airbrake@0.3.15 + +### Patch Changes + +- 41377156d0: Adds a boolean helper function to airbrake plugin for use on the EntityPage to show/hide airbrake tab depending on whether the entity's `catalog-info.yaml` has an airbrake id set in the metadata +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/dev-utils@1.0.12 + - @backstage/test-utils@1.2.5 + +## @backstage/plugin-airbrake-backend@0.2.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + +## @backstage/plugin-allure@0.1.31 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-analytics-module-ga@0.1.26 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-apache-airflow@0.2.8 + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- 4bdd6bcb3c: Prefer Link over plain anchors +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-api-docs-module-protoc-gen-doc@0.1.1 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend + +## @backstage/plugin-apollo-explorer@0.1.8 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-app-backend@0.3.42 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/types@1.0.2 + +## @backstage/plugin-auth-node@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-azure-devops@0.2.6 + +### Patch Changes + +- 347b16ecea: Fixed `AssignedToCurrentUsersTeams` & `CreatedByCurrentUsersTeams` filter in `AzurePullRequestsPage` component. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/plugin-azure-devops-common@0.3.0 + +## @backstage/plugin-azure-devops-backend@0.3.21 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- cc926a59bd: Fixed a bug where the azure devops host in URLs on the readme card was being URL encoded, breaking hosts with ports. +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-azure-devops-common@0.3.0 + +## @backstage/plugin-azure-sites@0.1.4 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 98a00a09d5: Fixed `AzureSites` plugin start and stop issue #15904 + Fixed `AzureSites` UI load issue #15907 +- 4bdd6bcb3c: Prefer Link over plain anchors +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-azure-sites-common@0.1.0 + +## @backstage/plugin-azure-sites-backend@0.1.4 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-azure-sites-common@0.1.0 + +## @backstage/plugin-badges@0.2.39 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-badges-backend@0.1.36 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-bazaar@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/cli@0.22.2 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + +## @backstage/plugin-bazaar-backend@0.2.5 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + +## @backstage/plugin-bitrise@0.1.42 + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-catalog-backend@1.7.2 + +### Patch Changes + +- 071354eb7d: Add additional validation as security precations for output entities. +- b977c2e69f: Minor improvements to the descriptions provided with permission rules schemas +- 2380506364: The process of adding or modifying fields in the software-catalog search index has been simplified. For more details, see [how to customize fields in the Software Catalog index](https://backstage.io/docs/features/search/how-to-guides#how-to-customize-fields-in-the-software-catalog-index). +- 9573651919: The previous migration that adds the `search.original_value` column may leave some of the entities not updated. Add a migration script to trigger a reprocessing of the entities. +- 9f71a2fd20: Location rule target patterns now also match hidden files, i.e. path components with a leading dot. +- e716946103: Updated usage of the lifecycle service. +- 1aec041c34: Fixed an issue where entities sometimes were not properly deleted during a full mutation. +- 0ff03319be: Updated usage of `createBackendPlugin`. +- fc73f6aae5: Switched the order of reprocessing statements retroactively in migrations. This only improves the experience for those who at a later time perform a large upgrade of an old Backstage installation. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + - @backstage/plugin-scaffolder-common@1.2.5 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-catalog-backend-module-aws@0.1.15 + +### Patch Changes + +- 671c6af700: Update to import `LocationSpec` from the correct package. +- 8e025f1347: Added support for `externalId` when assuming role in `AwsS3EntityProvider` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-backend-module-azure@0.1.13 + +### Patch Changes + +- 2890f47517: This will add the ability to use Azure DevOps with multi project with a single value which is a new feature as previously this had to be done manually for each project that you wanted to add. + + Right now you would have to fill in multiple values in the config to use multiple projects: + + yourFirstProviderId: # identifies your dataset / provider independent of config changes + organization: myorg + project: 'firstProject' # this will match the firstProject project + repository: '*' # this will match all repos + path: /catalog-info.yaml + yourSecondProviderId: # identifies your dataset / provider independent of config changes + organization: myorg + project: 'secondProject' # this will match the secondProject project + repository: '*' # this will match all repos + path: /catalog-info.yaml + + With this change you can actually have all projects available where your PAT determines which you have access to, so that includes multiple projects: + + yourFirstProviderId: # identifies your dataset / provider independent of config changes + organization: myorg + project: '*' # this will match all projects where your PAT has access to + repository: '*' # this will match all repos + path: /catalog-info.yaml + +- 85b04f659a: Internal refactor to not use deprecated `substr` + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.9 + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.3 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.3 + - @backstage/plugin-catalog-common@1.0.11 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## @backstage/plugin-catalog-backend-module-github@0.2.5 + +### Patch Changes + +- 66158754b4: Add support for filtering out forks +- 80afd5ff8b: Use github team slug and login annotations rather than entity name to infer location annotations +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + +## @backstage/plugin-catalog-backend-module-gitlab@0.1.13 + +### Patch Changes + +- 49948f644f: The config now consistently uses the term 'instance' to refer to a single GitLab API host. +- 85b04f659a: Internal refactor to not use deprecated `substr` +- 52c5685ceb: Implement Group and User Catalog Provider +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/catalog-model@1.2.0 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-common@1.0.11 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-catalog-graph@0.2.27 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- fe19058b74: Fix #16245: The CatalogGraphCard has parameter naming errors for CatalogGraphPage +- 1827710136: Expose additional props on the `CatalogGraphCard` to allow for custom node & label rendering or kind/relation filtering. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + +## @backstage/plugin-catalog-graphql@0.3.18 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-import@0.9.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-catalog-common@1.0.11 + +## @backstage/plugin-catalog-node@1.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + +## @backstage/plugin-cicd-statistics@0.1.17 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-cicd-statistics@0.1.17 + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-circleci@0.3.15 + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- 1616e06047: Making workflow a link +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-cloudbuild@0.3.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-code-climate@0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-code-coverage@0.2.8 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-code-coverage-backend@0.2.8 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## @backstage/plugin-codescene@0.1.10 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-config-schema@0.1.38 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## @backstage/plugin-cost-insights@0.12.4 + +### Patch Changes + +- dfa0bb737e: Fix bug in EntityCostsCard if cost aggregation array is empty. Allow title override on the Cost Insights Page +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + - @backstage/plugin-cost-insights-common@0.1.1 + +## @backstage/plugin-dynatrace@2.0.0 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-events-backend@0.2.3 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/plugin-events-node@0.2.3 + - @backstage/config@1.0.6 + +## @backstage/plugin-events-backend-module-aws-sqs@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/plugin-events-node@0.2.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + +## @backstage/plugin-events-backend-module-azure@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + +## @backstage/plugin-events-backend-module-gerrit@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + +## @backstage/plugin-events-backend-module-github@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/config@1.0.6 + +## @backstage/plugin-events-backend-module-gitlab@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/config@1.0.6 + +## @backstage/plugin-events-backend-test-utils@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.3 + +## @backstage/plugin-events-node@0.2.3 + +### Patch Changes + +- 19d4abf72c: Make `EventParams` typed for implementing tidier event handling. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + +## @backstage/plugin-explore-backend@0.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-explore-react@0.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-explore-common@0.0.1 + +## @backstage/plugin-firehydrant@0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-fossa@0.2.47 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-gcalendar@0.3.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-gcp-projects@0.3.34 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-git-release-manager@0.3.28 + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/integration@1.4.2 + +## @backstage/plugin-github-actions@0.5.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/integration@1.4.2 + +## @backstage/plugin-github-deployments@0.1.46 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + +## @backstage/plugin-github-issues@0.2.4 + +### Patch Changes + +- 3f88ae9d0a: Updated README.md examples to use correct components and fixed some syntax errors. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## @backstage/plugin-github-pull-requests-board@0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/integration@1.4.2 + +## @backstage/plugin-gitops-profiles@0.3.33 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-gocd@0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-graphiql@0.2.47 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-graphql-backend@0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-catalog-graphql@0.3.18 + +## @backstage/plugin-home@0.4.31 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 3d1d867d42: Fixed regression that caused the `WelcomeTitle` to not be the right size when passed to the `title` property of the `
    ` component. A Storybook entry was also added for the `WelcomeTitle` +- c553a625d2: remove unused plugin-stack-overflow dependency +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-ilert@0.2.4 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-jenkins@0.7.14 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/plugin-jenkins-common@0.1.13 + +## @backstage/plugin-jenkins-backend@0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-jenkins-common@0.1.13 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-jenkins-common@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-kafka@0.3.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-kafka-backend@0.2.35 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-kubernetes@0.7.8 + +### Patch Changes + +- 145a79a15b: Condenses kubernetes ui plugin to fit more onscreen and increase visibility +- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.6.0 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-kubernetes-backend@0.9.3 + +### Patch Changes + +- 2518ef5b8a: Adding new Cluster detail fields to catalogClusterLocator. Replace deprecated imports with k8s annotations from plugin-kubernetes-common. +- 7ff81f7692: Kubernetes proxy endpoint now accepts content types that are not json +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. +- a53d06afe5: The name of the header used to specify a cluster to the proxy endpoint is now visible in the API reference. +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.6.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + +## @backstage/plugin-newrelic@0.3.33 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-newrelic-dashboard@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-org@0.6.5 + +### Patch Changes + +- 5a4fa8859b: Updated `LinksGroup` to use `Link` over `ListItem` as this makes the links more obvious and follows the pattern already used in the `GroupProfileCard`. Also updated the `GroupProfileCard` `ExtraDetails` story in Storybook to enable the `showLinks` feature with this off there is no difference between it and the `default` story. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-org-react@0.1.4 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + +## @backstage/plugin-pagerduty@0.5.8 + +### Patch Changes + +- 804746dd58: The PagerDutyCard now supports an optional `readOnly` property (``) for suppressing the rendering of the "Create Incident" button from the Backstage UI. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-periskop@0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-periskop-backend@0.1.13 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + +## @backstage/plugin-permission-backend@0.5.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + +## @backstage/plugin-permission-node@0.7.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-permission-react@0.4.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-playlist@0.1.6 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/errors@1.1.4 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.10 + - @backstage/plugin-playlist-common@0.1.4 + +## @backstage/plugin-playlist-backend@0.2.5 + +### Patch Changes + +- b977c2e69f: Minor improvements to the descriptions provided with permission rules schemas +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + - @backstage/plugin-playlist-common@0.1.4 + +## @backstage/plugin-proxy-backend@0.2.36 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + +## @backstage/plugin-rollbar@0.4.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-rollbar-backend@0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.17 + +### Patch Changes + +- d72866f0cc: Internal refactor to use the new `@backstage/plugin-scaffolder-node` package for some functionality +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/plugin-scaffolder-backend@1.11.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.10 + +### Patch Changes + +- d72866f0cc: Internal refactor to use the new `@backstage/plugin-scaffolder-node` package for some functionality +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/plugin-scaffolder-backend@1.11.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.2 + +### Patch Changes + +- da418c89e4: Fix broken module exports and dependencies to match a backend module, rather than a frontend plugin. +- d72866f0cc: Internal refactor to use the new `@backstage/plugin-scaffolder-node` package for some functionality +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.15 + +### Patch Changes + +- d72866f0cc: Internal refactor to use the new `@backstage/plugin-scaffolder-node` package for some functionality +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + +## @backstage/plugin-scaffolder-common@1.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/types@1.0.2 + +## @backstage/plugin-search-backend@1.2.3 + +### Patch Changes + +- 1b30c9a0f7: Change the router's response to include the error message instead of its object type in case it fails during a search query because the messages have more info. +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + - @backstage/plugin-search-backend-node@1.1.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-search-backend-module-elasticsearch@1.1.3 + +### Patch Changes + +- 896566906b: Export `decodeElasticSearchPageCursor` utility function +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/plugin-search-backend-node@1.1.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-search-backend-module-pg@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-search-backend-node@1.1.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-search-backend-node@1.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-shortcuts@0.3.7 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/types@1.0.2 + +## @backstage/plugin-sonarqube@0.6.3 + +### Patch Changes + +- 6310eacc11: Additional export added in order to bind SonarQubeClient to its apiref +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-sonarqube-react@0.1.2 + +## @backstage/plugin-sonarqube-backend@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-sonarqube-react@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-splunk-on-call@0.4.4 + +### Patch Changes + +- 3598136ac7: Refactor plugin Card component to not rerender contents unnecessarily. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @backstage/plugin-stack-overflow@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/plugin-home@0.4.31 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/config@1.0.6 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-stack-overflow-backend@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-tech-insights@0.3.7 + +### Patch Changes + +- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. + TechInsightsClient now implements method getFactSchemas(). + + **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common + + These changes are **required** if you were importing this type directly. + + ```diff + - import { FactSchema } from '@backstage/plugin-tech-insights-node'; + + import { FactSchema } from '@backstage/plugin-tech-insights-common'; + ``` + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## @backstage/plugin-tech-insights-backend@0.5.8 + +### Patch Changes + +- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. + TechInsightsClient now implements method getFactSchemas(). + + **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common + + These changes are **required** if you were importing this type directly. + + ```diff + - import { FactSchema } from '@backstage/plugin-tech-insights-node'; + + import { FactSchema } from '@backstage/plugin-tech-insights-common'; + ``` + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/plugin-tech-insights-node@0.4.0 + - @backstage/catalog-model@1.2.0 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.26 + +### Patch Changes + +- d6b912f963: Surface the cause of the json rules engine +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/plugin-tech-insights-node@0.4.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-tech-insights-common@0.2.10 + +### Patch Changes + +- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. + TechInsightsClient now implements method getFactSchemas(). + + **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common + + These changes are **required** if you were importing this type directly. + + ```diff + - import { FactSchema } from '@backstage/plugin-tech-insights-node'; + + import { FactSchema } from '@backstage/plugin-tech-insights-common'; + ``` + +- Updated dependencies + - @backstage/types@1.0.2 + +## @backstage/plugin-tech-radar@0.6.1 + +### Patch Changes + +- acf6c8c10b: Deprecate `RadarEntry.url` - use `RadarEntry.links` instead + + ```diff + - url: 'https://www.javascript.com/', + key: 'javascript', + id: 'javascript', + title: 'JavaScript', + quadrant: 'languages', + links: [ + + { + + url: 'https://www.javascript.com/', + + title: 'Learn more', + + }, + ], + ``` + +- 18024a231c: Allow to set additional links to the entry description. + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.10 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/plugin-techdocs@1.5.0 + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/integration-react@1.1.10 + - @backstage/test-utils@1.2.5 + - @backstage/plugin-techdocs-react@1.1.3 + +## @backstage/plugin-techdocs-backend@1.5.3 + +### Patch Changes + +- 6f097023fc: Keep the tech docs sync event stream alive even if it is taking a while to build. +- 339d9a5b5c: Added support for using a default `mkdocs.yml` configuration file when none is provided +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-techdocs-node@1.5.0 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.10 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages + +- 4660b63947: Create a TechDocs `` addon that allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page. + + Here's an example on how to use it in a Backstage app: + + ```diff + import { + DefaultTechDocsHome, + TechDocsIndexPage, + TechDocsReaderPage, + } from '@backstage/plugin-techdocs'; + import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha'; + +import { LightBox } from '@backstage/plugin-techdocs-module-addons-contrib'; + + const AppRoutes = () => { + + // other plugin routes + }> + + + } + > + + + + + + ; + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-techdocs-react@1.1.3 + +## @backstage/plugin-techdocs-react@1.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/version-bridge@1.0.3 + +## @backstage/plugin-todo@0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-todo-backend@0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## @backstage/plugin-user-settings-backend@0.1.6 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + +## @backstage/plugin-vault@0.1.9 + +### Patch Changes + +- fd7a77b9c4: Surface additional context and details to the Backstage UI when the Vault plugin encounters non-successful HTTP responses from the Vault API. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-vault-backend@0.2.8 + +### Patch Changes + +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-xcmetrics@0.2.35 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/errors@1.1.4 + +## example-app@0.2.80 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.1.0 + - @backstage/plugin-scaffolder@1.11.0 + - @backstage/plugin-azure-devops@0.2.6 + - @backstage/cli@0.22.2 + - @backstage/plugin-techdocs@1.5.0 + - @backstage/core-components@0.12.4 + - @backstage/plugin-microsoft-calendar@0.1.0 + - @backstage/plugin-catalog-graph@0.2.27 + - @backstage/plugin-code-coverage@0.2.8 + - @backstage/plugin-azure-sites@0.1.4 + - @backstage/plugin-lighthouse@0.4.0 + - @backstage/plugin-shortcuts@0.3.7 + - @backstage/plugin-home@0.4.31 + - @backstage/plugin-tech-insights@0.3.7 + - @backstage/plugin-search@1.1.0 + - @backstage/plugin-api-docs@0.9.0 + - @backstage/plugin-entity-feedback@0.1.0 + - @backstage/plugin-tech-radar@0.6.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.10 + - @backstage/plugin-dynatrace@2.0.0 + - @backstage/plugin-playlist@0.1.6 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/plugin-kubernetes@0.7.8 + - @backstage/core-plugin-api@1.4.0 + - @backstage/app-defaults@1.2.0 + - @backstage/plugin-user-settings@0.7.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-pagerduty@0.5.8 + - @backstage/plugin-explore@0.4.0 + - @backstage/plugin-linguist@0.1.0 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/plugin-apache-airflow@0.2.8 + - @backstage/plugin-circleci@0.3.15 + - @backstage/plugin-sentry@0.5.0 + - @backstage/plugin-org@0.6.5 + - @backstage/plugin-cost-insights@0.12.4 + - @backstage/plugin-airbrake@0.3.15 + - @internal/plugin-catalog-customized@0.0.7 + - @backstage/config@1.0.6 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-badges@0.2.39 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-catalog-import@0.9.5 + - @backstage/plugin-cloudbuild@0.3.15 + - @backstage/plugin-gcalendar@0.3.11 + - @backstage/plugin-gcp-projects@0.3.34 + - @backstage/plugin-github-actions@0.5.15 + - @backstage/plugin-gocd@0.1.21 + - @backstage/plugin-graphiql@0.2.47 + - @backstage/plugin-jenkins@0.7.14 + - @backstage/plugin-kafka@0.3.15 + - @backstage/plugin-newrelic@0.3.33 + - @backstage/plugin-newrelic-dashboard@0.2.8 + - @backstage/plugin-permission-react@0.4.10 + - @backstage/plugin-rollbar@0.4.15 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-stack-overflow@0.1.11 + - @backstage/plugin-techdocs-react@1.1.3 + - @backstage/plugin-todo@0.2.17 + +## example-backend@0.2.80 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/plugin-playlist-backend@0.2.5 + - @backstage/plugin-search-backend-module-elasticsearch@1.1.3 + - @backstage/backend-common@0.18.2 + - @backstage/plugin-kubernetes-backend@0.9.3 + - @backstage/plugin-lighthouse-backend@0.1.0 + - @backstage/plugin-code-coverage-backend@0.2.8 + - @backstage/plugin-azure-devops-backend@0.3.21 + - @backstage/plugin-azure-sites-backend@0.1.4 + - @backstage/plugin-adr-backend@0.3.0 + - @backstage/plugin-tech-insights-backend@0.5.8 + - @backstage/plugin-tech-insights-node@0.4.0 + - @backstage/plugin-entity-feedback-backend@0.1.0 + - @backstage/plugin-search-backend@1.2.3 + - @backstage/plugin-techdocs-backend@1.5.3 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.10 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.26 + - @backstage/plugin-scaffolder-backend@1.11.0 + - @backstage/plugin-events-backend@0.2.3 + - @backstage/plugin-kafka-backend@0.2.35 + - @backstage/plugin-proxy-backend@0.2.36 + - @backstage/plugin-app-backend@0.3.42 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-auth-backend@0.18.0 + - @backstage/plugin-linguist-backend@0.1.0 + - @backstage/plugin-events-node@0.2.3 + - example-app@0.2.80 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-badges-backend@0.1.36 + - @backstage/plugin-explore-backend@0.0.4 + - @backstage/plugin-graphql-backend@0.1.32 + - @backstage/plugin-jenkins-backend@0.1.32 + - @backstage/plugin-permission-backend@0.5.17 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + - @backstage/plugin-rollbar-backend@0.1.39 + - @backstage/plugin-search-backend-module-pg@0.5.3 + - @backstage/plugin-search-backend-node@1.1.3 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-todo-backend@0.1.39 + +## example-backend-next@0.0.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/plugin-scaffolder-backend@1.11.0 + - @backstage/plugin-app-backend@0.3.42 + - @backstage/backend-defaults@0.1.7 + +## techdocs-cli-embedded-app@0.2.79 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/cli@0.22.2 + - @backstage/plugin-techdocs@1.5.0 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/app-defaults@1.2.0 + - @backstage/config@1.0.6 + - @backstage/integration-react@1.1.10 + - @backstage/test-utils@1.2.5 + - @backstage/plugin-techdocs-react@1.1.3 + +## @internal/plugin-catalog-customized@0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/plugin-catalog-react@1.3.0 + +## @internal/plugin-todo-list@1.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + +## @internal/plugin-todo-list-backend@1.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 diff --git a/docs/releases/v1.11.0.md b/docs/releases/v1.11.0.md new file mode 100644 index 0000000000..1afed5fbb6 --- /dev/null +++ b/docs/releases/v1.11.0.md @@ -0,0 +1,100 @@ +--- +id: v1.11.0 +title: v1.11.0 +description: Backstage Release v1.11.0 +--- + +These are the release notes for the v1.11.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### Scaffolder Alpha + +With this release, we’ve been working on getting things ready for testing for the upcoming Scaffolder v2.0.0 release, and there’s now the ability to test the upcoming version in the form of an alpha! It would be great if you have the time to test out the new release to see if all your templates work as expected. There’s some documentation on how to test out the new version and what’s new under [testing scaffolder alpha](https://backstage.io/docs/features/software-templates/testing-scaffolder-alpha). + +We’d love to hear if you have any issues when testing the new version, please reach out on Discord or [create a new issue](http://github.com/backstage/backstage/issues/new) if there’s anything you find! + +### Backend System Alpha + +The [new Backend System](https://backstage.io/docs/backend-system/) is now in alpha. We encourage plugin owners to try out the new system by adding support for it in their plugin backends, but we do not yet recommend migrating over to using this new system for production backend deployments. + +This new system aims to greatly simplify the setup and wiring of Backstage backends. It formalizes and simplifies how common services and plugins are installed and interact with each other, and restructures both plugins and backends to make them much easier to maintain. + +The documentation starts [here](https://backstage.io/docs/backend-system/). Migration guides exist to help you get your [backend](https://backstage.io/docs/backend-system/building-backends/migrating) and [plugins](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating) migrated, but you don’t have to do it all in one go - the path forward can be incremental. + +If you were already using the new backend system before this release, you may also be interested in the following. + +There have been a number of tweaks to types and exports, following a thorough API review before its alpha release. Notably, + +Service factories are now exported with the pattern `ServiceFactory` instead of `Factory`, e.g. `configServiceFactory` +The `createBackendPlugin` parameter that used to be named `id` is now `pluginId` +The interface of the `CacheService` has changed slightly, so you may want to use the new `cacheToPluginCacheManager` to get compatibility with your not-yet-converted backend plugins +The `scaffolderCatalogModule` that was exported from the Scaffolder backend is renamed to `catalogModuleTemplateKind`, to fit the proper naming patterns + +There are a few smaller tweaks as well, that you can read about in the [`@backstage/backend-app-api`](https://github.com/backstage/backstage/blob/master/packages/backend-app-api/CHANGELOG.md) and [`@backstage/backend-plugin-api`](https://github.com/backstage/backstage/blob/master/packages/backend-plugin-api/CHANGELOG.md) changelogs. + +### New package: `@backstage/eslint-plugin` + +We created a separate ESlint plugin package that houses some rules that are helpful for Backstage monorepos. Not only does it make a convenient bundle of them all, it also comes with a pretty healthy speed boost. [The pull request](https://github.com/backstage/backstage/pull/16174) contains some more details. + +### New plugin: Entity Feedback + +A plugin that allows users to rate the quality of entities in your Backstage catalog. Allowing your users to rate entities brings them into the feedback loop that can help notify owners if something is wrong with their entity (i.e. taking inspiration from the feedback model of TechDocs). Check out [the README](https://github.com/backstage/backstage/tree/master/plugins/entity-feedback)! + +Contributed by [@kuangp](https://github.com/kuangp) in [#15881](https://github.com/backstage/backstage/pull/15881) + +### New plugin: Entity Validator + +This plugin helps users create and edit their YAML definitions of entities, with live validation. It leverages the actual catalog backend for checks, so that you can submit catalog info file changes that fit your particular organization with greater confidence. Installation instructions and details are in [the README](https://github.com/backstage/backstage/tree/master/plugins/entity-validation). + +Contributed by [@ivangonzalezacuna](https://github.com/ivangonzalezacuna) in [#16050](https://github.com/backstage/backstage/pull/16050) + +### New Plugin: Microsoft Calendar + +This plugin lets you show your MS calendars directly in Backstage. More information and installation instructions in [the README](https://github.com/backstage/backstage/tree/master/plugins/microsoft-calendar)! + +Contributed by [@Abhay-soni-developer](https://github.com/Abhay-soni-developer) in [#16101](https://github.com/backstage/backstage/pull/16101) + +### New plugin: GraphQL Voyager + +This nifty plugin presents a graph structure of your entire GraphQL API. Check out [its README](https://github.com/backstage/backstage/tree/master/plugins/graphql-voyager) for a screenshot and instructions on installing it. + +Contributed by [@MitchWijt](https://github.com/MitchWijt) in [#16015](https://github.com/backstage/backstage/pull/16015) + +### New plugin: Linguist + +This plugin lets you see a nice visual representation of the breakdown of languages that a component’s repository is using, similar to the repository information that e.g. GitHub presents. More about that [in the README](https://github.com/backstage/backstage/tree/master/plugins/linguist)! + +Contributed by [@ahhhndre](https://github.com/ahhhndre) in [#14718](https://github.com/backstage/backstage/pull/14718) + +### Lighthouse Backend + +The [Lighthouse plugin](https://github.com/backstage/backstage/tree/master/plugins/lighthouse) now has a [corresponding backend](https://github.com/backstage/backstage/tree/master/plugins/lighthouse-backend). This allows you to conveniently schedule audits from within Backstage. + +Note that as part of this, a `@backstage/plugin-lighthouse-common` package was also created, and types that were common to the frontend and backend were moved there. This means that if you were explicitly importing types from the frontend package, you may see compilation errors and need to add a dependency on the new common package and point your imports there instead. + +Contributed by [@dpfaffenbauer](https://github.com/dpfaffenbauer) in [#15846](https://github.com/backstage/backstage/pull/15846) + +## Security Fixes + +`@backstage/core-components`, `@backstage/catalog-model`, and `@backstage/plugin-catalog-backend`, have all had precautionary validation added, please upgrade to the latest versions of these packages. Special thanks to Philip Olausson ([Programmatic](https://www.programmatic.se/)) who found these issues as part of [Roadie's](https://roadie.io/) regular third-party pen testing. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) + +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.11.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://mailchi.mp/spotify/backstage-community) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.12.0-next.0-changelog.md b/docs/releases/v1.12.0-next.0-changelog.md new file mode 100644 index 0000000000..b7f71b53e6 --- /dev/null +++ b/docs/releases/v1.12.0-next.0-changelog.md @@ -0,0 +1,2364 @@ +# Release v1.12.0-next.0 + +## @backstage/catalog-client@1.4.0-next.0 + +### Minor Changes + +- 8c030b1826: Add `queryEntities` method to `CatalogApi`. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-catalog@1.9.0-next.0 + +### Minor Changes + +- 3f75b7607c: Add ability to pass icon as function to have ability to customize it by search item + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## @backstage/plugin-catalog-backend@1.8.0-next.0 + +### Minor Changes + +- 7f4ea3d360: Add /entities/by-query endpoint returning paginated entities. + + The endpoint supports cursor base pagination and server side sorting of the entities + +### Patch Changes + +- ac8929f2f3: Fix export of `defaultCatalogCollatorEntityTransformer`. +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-catalog-react@1.4.0-next.0 + +### Minor Changes + +- 0a5b73b292: Add possibility to re-use EntityPicker for filters with multiple select. + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.11-next.0 + +## @backstage/plugin-linguist-backend@0.2.0-next.0 + +### Minor Changes + +- 4a1c318853: **BREAKING** The linguist-backend `createRouter` now requires that the `tokenManger` is passed to the router. + +### Patch Changes + +- 2ea5782162: Fixed bug in LinguistBackendApi that caused initial batch of entities to be skipped. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-linguist-common@0.1.0 + +## @backstage/plugin-octopus-deploy@0.1.0-next.0 + +### Minor Changes + +- b7fff1171f: Initial version + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-stackstorm@0.1.0-next.0 + +### Minor Changes + +- f3a15259e9: Add StackStorm plugin to Backstage which is interfacing with StackStorm API. It allows users to view workflow executions, packs and actions. For installation and configuration instructions please view [README.md](https://github.com/backstage/backstage/tree/master/plugins/stackstorm/README.md) + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-techdocs@1.6.0-next.0 + +### Minor Changes + +- 3f75b7607c: Add ability to pass icon as function to have ability to customize it by search item + +### Patch Changes + +- f320c299c6: The HTML tag attributes in the documentation content inserted to shadow DOM is preserved to improve accessibility +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## @backstage/app-defaults@1.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-permission-react@0.4.11-next.0 + +## @backstage/backend-app-api@0.4.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-node@0.7.6-next.0 + +## @backstage/backend-common@0.18.3-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-app-api@0.4.1-next.0 + - @backstage/backend-dev-utils@0.1.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/backend-defaults@0.1.8-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-app-api@0.4.1-next.0 + +## @backstage/backend-plugin-api@0.4.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/backend-tasks@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 + +## @backstage/backend-test-utils@0.1.35-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-app-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + +## @backstage/catalog-model@1.2.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## @backstage/cli@0.22.4-next.0 + +### Patch Changes + +- b4cd145b57: Added a new `migrate package-exports` command that synchronizes package exports fields in all `package.json`s. +- 8bf24946c6: Adjust express dependencies to be the same as the rest of the project +- 17271841de: Updated frontend plugin template to use some more recent features +- Updated dependencies + - @backstage/eslint-plugin@0.1.2-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/release-manifests@0.0.8 + - @backstage/types@1.0.2 + +## @backstage/core-app-api@1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## @backstage/core-components@0.12.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/version-bridge@1.0.3 + +## @backstage/core-plugin-api@1.4.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## @backstage/create-app@0.4.38-next.0 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.11 + +## @backstage/dev-utils@1.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/test-utils@1.2.6-next.0 + - @backstage/app-defaults@1.2.1-next.0 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + +## @backstage/eslint-plugin@0.1.2-next.0 + +### Patch Changes + +- a061c466d6: Fixing a bug that we should check internal dependencies too + +## @backstage/integration-react@1.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + +## @backstage/repo-tools@0.1.3-next.0 + +### Patch Changes + +- 32a4a05838: Tweaked type dependency check to trim wildcard type imports. +- 6ba8faf22a: The API report generation process is now able to detect and generate reports for additional entry points declared in the package `"exports"` field. +- Updated dependencies + - @backstage/cli-common@0.1.11 + - @backstage/errors@1.1.4 + +## @techdocs/cli@1.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/plugin-techdocs-node@1.5.1-next.0 + +## @backstage/test-utils@1.2.6-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.11-next.0 + +## @backstage/plugin-adr@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-adr-common@0.2.7-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## @backstage/plugin-adr-backend@0.3.1-next.0 + +### Patch Changes + +- 8bf24946c6: Adjust express dependencies to be the same as the rest of the project +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/plugin-adr-common@0.2.7-next.0 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-adr-common@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/integration@1.4.2 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-airbrake@0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/test-utils@1.2.6-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/dev-utils@1.0.13-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-airbrake-backend@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-allure@0.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-analytics-module-ga@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-apache-airflow@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + +## @backstage/plugin-api-docs@0.9.1-next.0 + +### Patch Changes + +- 095e755d9b: Add ApiDefinitionDialog component for fast access to the API definition in ProvidedApiCards and ConsumedApiCards. +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-apollo-explorer@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-app-backend@0.3.43-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/types@1.0.2 + +## @backstage/plugin-auth-backend@0.18.1-next.0 + +### Patch Changes + +- 529de8c421: Added authentication provider for Azure Easy Authentication. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + +## @backstage/plugin-auth-node@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-azure-devops@0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-azure-devops-common@0.3.0 + +## @backstage/plugin-azure-devops-backend@0.3.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-azure-devops-common@0.3.0 + +## @backstage/plugin-azure-sites@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-azure-sites-common@0.1.0 + +## @backstage/plugin-azure-sites-backend@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-azure-sites-common@0.1.0 + +## @backstage/plugin-badges@0.2.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-badges-backend@0.1.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-bazaar@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/cli@0.22.4-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-bazaar-backend@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + +## @backstage/plugin-bitrise@0.1.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-catalog-backend-module-aws@0.1.17-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- bf611cf019: Fix missing `dependencies` in `package.json` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-kubernetes-common@0.6.1-next.0 + +## @backstage/plugin-catalog-backend-module-azure@0.1.14-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.3 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.10-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.3 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.8-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.11-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## @backstage/plugin-catalog-backend-module-github@0.2.6-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-backend-module-gitlab@0.1.14-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.2.2-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- bf611cf019: Fix missing `dependencies` in `package.json` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-defaults@0.1.8-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-backend-module-msgraph@0.5.2-next.0 + +### Patch Changes + +- a4ebd51352: Revert using `baseUrl` for MS Graph provider as it breaks token retrieval +- 928a12a9b3: Internal refactor of `/alpha` exports. +- 2c234a8932: properly support custom graph api URL +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-common@1.0.12-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-catalog-graph@0.2.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-catalog-graphql@0.3.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + +## @backstage/plugin-catalog-import@0.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + +## @backstage/plugin-catalog-node@1.3.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## @backstage/plugin-cicd-statistics@0.1.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-cicd-statistics@0.1.18-next.0 + +## @backstage/plugin-circleci@0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-cloudbuild@0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-code-climate@0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-code-coverage@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-code-coverage-backend@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## @backstage/plugin-codescene@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-config-schema@0.1.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + +## @backstage/plugin-cost-insights@0.12.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-cost-insights-common@0.1.1 + +## @backstage/plugin-dynatrace@3.0.0-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-entity-feedback@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-entity-feedback-common@0.1.0 + +## @backstage/plugin-entity-feedback-backend@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-entity-feedback-common@0.1.0 + +## @backstage/plugin-entity-validation@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-events-backend@0.2.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-events-backend-module-aws-sqs@0.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + +## @backstage/plugin-events-backend-module-azure@0.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + +## @backstage/plugin-events-backend-module-gerrit@0.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + +## @backstage/plugin-events-backend-module-github@0.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-events-backend-module-gitlab@0.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-events-backend-test-utils@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.4-next.0 + +## @backstage/plugin-events-node@0.2.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + +## @backstage/plugin-explore@0.4.1-next.0 + +### Patch Changes + +- 3f75b7607c: Add ability to pass icon as function to have ability to customize it by search item +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-explore-react@0.0.27-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## @backstage/plugin-explore-backend@0.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-explore-react@0.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/plugin-explore-common@0.0.1 + +## @backstage/plugin-firehydrant@0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-fossa@0.2.48-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-gcalendar@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-gcp-projects@0.3.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-git-release-manager@0.3.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + +## @backstage/plugin-github-actions@0.5.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + +## @backstage/plugin-github-deployments@0.1.47-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-github-issues@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + +## @backstage/plugin-github-pull-requests-board@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + +## @backstage/plugin-gitops-profiles@0.3.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-gocd@0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-graphiql@0.2.48-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-graphql-backend@0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-catalog-graphql@0.3.19-next.0 + +## @backstage/plugin-graphql-voyager@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-home@0.4.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-ilert@0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-jenkins@0.7.15-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-jenkins-common@0.1.14-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-jenkins-backend@0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-jenkins-common@0.1.14-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-jenkins-common@0.1.14-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-kafka@0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-kafka-backend@0.2.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-kubernetes@0.7.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-kubernetes-common@0.6.1-next.0 + +## @backstage/plugin-kubernetes-backend@0.9.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-kubernetes-common@0.6.1-next.0 + +## @backstage/plugin-kubernetes-common@0.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + +## @backstage/plugin-lighthouse@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-lighthouse-common@0.1.0 + +## @backstage/plugin-lighthouse-backend@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-lighthouse-common@0.1.0 + +## @backstage/plugin-linguist@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-linguist-common@0.1.0 + +## @backstage/plugin-microsoft-calendar@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-newrelic@0.3.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-newrelic-dashboard@0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + +## @backstage/plugin-org@0.6.6-next.0 + +### Patch Changes + +- 36bccb5252: Fix small UI-glitch in MemberListCard +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-org-react@0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-pagerduty@0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-periskop@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-periskop-backend@0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-permission-backend@0.5.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + +## @backstage/plugin-permission-node@0.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-permission-react@0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-permission-common@0.7.3 + +## @backstage/plugin-playlist@0.1.7-next.0 + +### Patch Changes + +- 122a37a880: Internal update to work with newer versions of react-router +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.11-next.0 + - @backstage/plugin-playlist-common@0.1.4 + - @backstage/plugin-search-react@1.5.1-next.0 + +## @backstage/plugin-playlist-backend@0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + - @backstage/plugin-playlist-common@0.1.4 + +## @backstage/plugin-proxy-backend@0.2.37-next.0 + +### Patch Changes + +- 3e3eea4bc7: The proxy-backend plugin now supports reviving request bodies that have previously been consumed by an express middleware (e.g. `express.json()`). This is done by setting `reviveConsumedRequestBodies: true` on the proxy `RouterOptions`. In order to preserve the current behavior, the proxy will **not** revive request bodies by default. + + The following is an example of a proxy `createRouter` invocation that revives request bodies: + + ```diff + const router = await createRouter({ + config, + logger, + discovery, + + reviveConsumedRequestBodies: true, + }); + ``` + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-rollbar@0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-rollbar-backend@0.1.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + +## @backstage/plugin-scaffolder@1.11.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-scaffolder-react@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-react@0.4.11-next.0 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + +## @backstage/plugin-scaffolder-backend@1.11.1-next.0 + +### Patch Changes + +- c6c78b4acb: throw error from catalog:fetch scaffolder action when entity is null and optional is false +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.11.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.11.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## @backstage/plugin-scaffolder-common@1.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/types@1.0.2 + +## @backstage/plugin-scaffolder-node@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + +## @backstage/plugin-scaffolder-react@1.1.1-next.0 + +### Patch Changes + +- c8d78b9ae9: fix bug with `hasErrors` returning false when dealing with empty objects +- 928a12a9b3: Internal refactor of `/alpha` exports. +- cc418d652a: scaffolder/next: Added the ability to get the fields definition in the schema in the validation function +- d4100d0ec4: Fix alignment bug for owners on `TemplateCard` +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + +## @backstage/plugin-search@1.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## @backstage/plugin-search-backend@1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + - @backstage/plugin-search-backend-node@1.1.4-next.0 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-search-backend-module-elasticsearch@1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/plugin-search-backend-node@1.1.4-next.0 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-search-backend-module-pg@0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-search-backend-node@1.1.4-next.0 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-search-backend-node@1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-search-react@1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-sentry@0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-shortcuts@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + +## @backstage/plugin-sonarqube@0.6.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- 8ae65a0bc1: Moved imports from `/alpha` to main public exports. +- d3d624e8e8: Show a more appropriate icon if there are no code smells and/or vulnerabilities. +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/plugin-sonarqube-react@0.1.4-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-sonarqube-backend@0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-sonarqube-react@0.1.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- 8ae65a0bc1: Moved imports from `/alpha` to main public exports. +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + +## @backstage/plugin-splunk-on-call@0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-stack-overflow@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-home@0.4.32-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## @backstage/plugin-stack-overflow-backend@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-tech-insights@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + +## @backstage/plugin-tech-insights-backend@0.5.9-next.0 + +### Patch Changes + +- f244b58916: Add DB index to improve latency of latest fact query +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/plugin-tech-insights-node@0.4.1-next.0 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/plugin-tech-insights-node@0.4.1-next.0 + +## @backstage/plugin-tech-insights-node@0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + +## @backstage/plugin-tech-radar@0.6.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.11-next.0 + +### Patch Changes + +- 2b00d8a225: Fix bug/problem with test helper +- Updated dependencies + - @backstage/plugin-techdocs@1.6.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/test-utils@1.2.6-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-search-react@1.5.1-next.0 + +## @backstage/plugin-techdocs-backend@1.5.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-node@1.5.1-next.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + +## @backstage/plugin-techdocs-node@1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-aws-node@0.1.1 + - @backstage/plugin-search-common@1.2.1 + +## @backstage/plugin-techdocs-react@1.1.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/version-bridge@1.0.3 + +## @backstage/plugin-todo@0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-todo-backend@0.1.40-next.0 + +### Patch Changes + +- 4120513412: todo-backend is now exposed as a plugin which uses the new plugin system +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## @backstage/plugin-user-settings@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + +## @backstage/plugin-user-settings-backend@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + +## @backstage/plugin-vault@0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## @backstage/plugin-vault-backend@0.2.10-next.0 + +### Patch Changes + +- 66b3a3956b: Ignore the `eslint` error +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## @backstage/plugin-xcmetrics@0.2.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## example-app@0.2.81-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.1.1-next.0 + - @backstage/cli@0.22.4-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/plugin-techdocs@1.6.0-next.0 + - @backstage/plugin-api-docs@0.9.1-next.0 + - @backstage/plugin-org@0.6.6-next.0 + - @backstage/plugin-stackstorm@0.1.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/plugin-cost-insights@0.12.5-next.0 + - @backstage/plugin-scaffolder@1.11.1-next.0 + - @backstage/plugin-jenkins@0.7.15-next.0 + - @backstage/plugin-playlist@0.1.7-next.0 + - @backstage/plugin-explore@0.4.1-next.0 + - @backstage/plugin-catalog-graph@0.2.28-next.0 + - @backstage/plugin-catalog-import@0.9.6-next.0 + - @backstage/app-defaults@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-airbrake@0.3.16-next.0 + - @backstage/plugin-apache-airflow@0.2.9-next.0 + - @backstage/plugin-azure-devops@0.2.7-next.0 + - @backstage/plugin-azure-sites@0.1.5-next.0 + - @backstage/plugin-badges@0.2.40-next.0 + - @backstage/plugin-circleci@0.3.16-next.0 + - @backstage/plugin-cloudbuild@0.3.16-next.0 + - @backstage/plugin-code-coverage@0.2.9-next.0 + - @backstage/plugin-dynatrace@3.0.0-next.0 + - @backstage/plugin-entity-feedback@0.1.1-next.0 + - @backstage/plugin-gcalendar@0.3.12-next.0 + - @backstage/plugin-gcp-projects@0.3.35-next.0 + - @backstage/plugin-github-actions@0.5.16-next.0 + - @backstage/plugin-gocd@0.1.22-next.0 + - @backstage/plugin-graphiql@0.2.48-next.0 + - @backstage/plugin-home@0.4.32-next.0 + - @backstage/plugin-kafka@0.3.16-next.0 + - @backstage/plugin-kubernetes@0.7.9-next.0 + - @backstage/plugin-lighthouse@0.4.1-next.0 + - @backstage/plugin-linguist@0.1.1-next.0 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/plugin-microsoft-calendar@0.1.1-next.0 + - @backstage/plugin-newrelic@0.3.34-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.9-next.0 + - @backstage/plugin-pagerduty@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.11-next.0 + - @backstage/plugin-rollbar@0.4.16-next.0 + - @backstage/plugin-search@1.1.1-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + - @backstage/plugin-sentry@0.5.1-next.0 + - @backstage/plugin-shortcuts@0.3.8-next.0 + - @backstage/plugin-stack-overflow@0.1.12-next.0 + - @backstage/plugin-tech-insights@0.3.8-next.0 + - @backstage/plugin-tech-radar@0.6.2-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.11-next.0 + - @backstage/plugin-todo@0.2.18-next.0 + - @backstage/plugin-user-settings@0.7.1-next.0 + - @internal/plugin-catalog-customized@0.0.8-next.0 + +## example-backend@0.2.81-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-todo-backend@0.1.40-next.0 + - @backstage/plugin-scaffolder-backend@1.11.1-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/plugin-tech-insights-backend@0.5.9-next.0 + - @backstage/plugin-linguist-backend@0.2.0-next.0 + - @backstage/plugin-adr-backend@0.3.1-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/plugin-techdocs-backend@1.5.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-events-backend@0.2.4-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/plugin-app-backend@0.3.43-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/plugin-proxy-backend@0.2.37-next.0 + - @backstage/plugin-auth-backend@0.18.1-next.0 + - @backstage/plugin-badges-backend@0.1.37-next.0 + - @backstage/plugin-code-coverage-backend@0.2.9-next.0 + - @backstage/plugin-entity-feedback-backend@0.1.1-next.0 + - @backstage/plugin-jenkins-backend@0.1.33-next.0 + - @backstage/plugin-kubernetes-backend@0.9.4-next.0 + - @backstage/plugin-lighthouse-backend@0.1.1-next.0 + - @backstage/plugin-playlist-backend@0.2.6-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.11-next.0 + - example-app@0.2.81-next.0 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-azure-devops-backend@0.3.22-next.0 + - @backstage/plugin-azure-sites-backend@0.1.5-next.0 + - @backstage/plugin-explore-backend@0.0.5-next.0 + - @backstage/plugin-graphql-backend@0.1.33-next.0 + - @backstage/plugin-kafka-backend@0.2.36-next.0 + - @backstage/plugin-permission-backend@0.5.18-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + - @backstage/plugin-rollbar-backend@0.1.40-next.0 + - @backstage/plugin-search-backend@1.2.4-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.1.4-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.4-next.0 + - @backstage/plugin-search-backend-node@1.1.4-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.27-next.0 + - @backstage/plugin-tech-insights-node@0.4.1-next.0 + +## example-backend-next@0.0.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-todo-backend@0.1.40-next.0 + - @backstage/plugin-scaffolder-backend@1.11.1-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-defaults@0.1.8-next.0 + - @backstage/plugin-app-backend@0.3.43-next.0 + +## e2e-test@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.4.38-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/errors@1.1.4 + +## techdocs-cli-embedded-app@0.2.80-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.22.4-next.0 + - @backstage/plugin-techdocs@1.6.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/test-utils@1.2.6-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + - @backstage/app-defaults@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + +## @internal/plugin-catalog-customized@0.0.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + +## @internal/plugin-todo-list@1.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## @internal/plugin-todo-list-backend@1.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 diff --git a/docs/releases/v1.2.0.md b/docs/releases/v1.2.0.md index b2d50a09a2..3751217ae4 100644 --- a/docs/releases/v1.2.0.md +++ b/docs/releases/v1.2.0.md @@ -60,7 +60,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.2.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) diff --git a/docs/releases/v1.3.0.md b/docs/releases/v1.3.0.md index 8014e0a121..96aa88a05e 100644 --- a/docs/releases/v1.3.0.md +++ b/docs/releases/v1.3.0.md @@ -58,7 +58,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.3.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap), and [Plugins](https://backstage.io/plugins) diff --git a/docs/releases/v1.4.0.md b/docs/releases/v1.4.0.md index 20b1739f4a..9a178ea8ff 100644 --- a/docs/releases/v1.4.0.md +++ b/docs/releases/v1.4.0.md @@ -63,7 +63,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.4.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) diff --git a/docs/releases/v1.5.0.md b/docs/releases/v1.5.0.md index ca4ae11185..d7bbfa62a2 100644 --- a/docs/releases/v1.5.0.md +++ b/docs/releases/v1.5.0.md @@ -53,7 +53,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.5.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) diff --git a/docs/releases/v1.6.0.md b/docs/releases/v1.6.0.md index a1ece6bf94..417491c1e4 100644 --- a/docs/releases/v1.6.0.md +++ b/docs/releases/v1.6.0.md @@ -53,7 +53,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.6.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) diff --git a/docs/releases/v1.7.0.md b/docs/releases/v1.7.0.md index cb87ead4c9..56eda8b20d 100644 --- a/docs/releases/v1.7.0.md +++ b/docs/releases/v1.7.0.md @@ -114,7 +114,7 @@ start using this new release. - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.7.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), diff --git a/docs/releases/v1.8.0.md b/docs/releases/v1.8.0.md index cbe16a0cba..78cc5ab7cd 100644 --- a/docs/releases/v1.8.0.md +++ b/docs/releases/v1.8.0.md @@ -71,7 +71,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.8.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) diff --git a/docs/releases/v1.9.0.md b/docs/releases/v1.9.0.md index 53a1769108..a677acb643 100644 --- a/docs/releases/v1.9.0.md +++ b/docs/releases/v1.9.0.md @@ -78,7 +78,7 @@ Below you can find a list of links and references to help you learn about and st - [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) - [GitHub repository](https://github.com/backstage/backstage) - Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) -- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support - [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.9.0-changelog.md) - Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) diff --git a/docs/tutorials/configuring-plugin-databases.md b/docs/tutorials/configuring-plugin-databases.md index ed550f1801..8cd5ce99a9 100644 --- a/docs/tutorials/configuring-plugin-databases.md +++ b/docs/tutorials/configuring-plugin-databases.md @@ -21,8 +21,8 @@ instance or cluster. With infrastructure defined as code or data (Terraform, AWS CloudFormation, etc.), you may have database credentials which lack permissions to create new databases or you do not have control over the database names. In these -instances, you can set the database connection configuration on a [per plugin basis] -(#connection-configuration-per-plugin). +instances, you can set the database connection configuration on a +[per plugin basis](#connection-configuration-per-plugin). Backstage supports all of these use cases with the `DatabaseManager` provided by `@backstage/backend-common`. We will now cover how to use and configure @@ -37,7 +37,7 @@ package. If you intend to use both PostgreSQL and SQLite, you can install both of them. ```bash -# From the Backstage root directory +# From your Backstage root directory # install pg if you need PostgreSQL yarn add --cwd packages/backend pg diff --git a/microsite-next/docusaurus.config.js b/microsite-next/docusaurus.config.js index 2b37ae20b2..c3956bb308 100644 --- a/microsite-next/docusaurus.config.js +++ b/microsite-next/docusaurus.config.js @@ -13,6 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +// @ts-check + +/** @type {import('@docusaurus/types').Config} */ module.exports = { title: 'Backstage Software Catalog and Developer Platform', tagline: 'An open platform for building developer portals', @@ -40,10 +44,9 @@ module.exports = { presets: [ [ '@docusaurus/preset-classic', + /** @type {import('@docusaurus/preset-classic').Options} */ { docs: { - showLastUpdateAuthor: true, - showLastUpdateTime: true, editUrl: 'https://github.com/backstage/backstage/edit/master/docs/', path: '../docs', sidebarPath: 'sidebars.json', @@ -60,138 +63,180 @@ module.exports = { }, ], ], - plugins: [], - themeConfig: { - navbar: { - title: 'Backstage Software Catalog and Developer Platform', - items: [ - { - href: 'https://github.com/backstage/backstage', - label: 'GitHub', - position: 'left', + webpack: { + jsLoader: isServer => ({ + loader: require.resolve('swc-loader'), + options: { + jsc: { + parser: { + syntax: 'typescript', + tsx: true, + }, + target: 'es2017', }, - { - to: 'docs/overview/what-is-backstage', - label: 'Docs', - position: 'left', + module: { + type: isServer ? 'commonjs' : 'es6', }, - { - to: '/plugins', - label: 'Plugins', - position: 'left', - }, - { - to: '/blog', - label: 'Blog', - position: 'left', - }, - { - to: 'docs/releases/v1.8.0', - label: 'Releases', - position: 'left', - }, - { - to: '/demos', - label: 'Demos', - position: 'left', - }, - { - to: '/community', - label: 'Community', - position: 'left', - }, - ], - }, - image: 'img/sharing-opengraph.png', - footer: { - links: [ - { - items: [ - { - html: '', - }, - ], - }, - { - title: 'Docs', - items: [ - { - label: 'What is Backstage?', - to: 'docs/overview/what-is-backstage', - }, - { - label: 'Getting started', - to: 'docs/getting-started/', - }, - { - label: 'Software Catalog', - to: 'docs/features/software-catalog/software-catalog-overview', - }, - { - label: 'Create a Plugin', - to: 'docs/plugins/create-a-plugin', - }, - { - label: 'Designing for Backstage', - to: 'docs/dls/design', - }, - ], - }, - { - title: 'Community', - items: [ - { - label: 'Support chatroom', - to: 'https://discord.gg/MUpMjP2', - }, - { - label: 'Contributing', - to: 'https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md', - }, - { - label: 'Adopting', - to: 'https://backstage.spotify.com', - }, - { - label: 'Subscribe to our newsletter', - to: 'https://mailchi.mp/spotify/backstage-community', - }, - { - label: 'CNCF Incubation', - to: 'https://www.cncf.io/projects/', - }, - ], - }, - { - title: 'More', - items: [ - { - label: 'Open Source @ Spotify', - to: 'https://spotify.github.io/', - }, - { - label: 'Spotify Engineering Blog', - to: 'https://engineering.atspotify.com/', - }, - { - label: 'Spotify for Developers', - to: 'https://developer.spotify.com/', - }, - { - label: 'Github', - to: 'https://github.com/backstage/', - }, - ], - }, - ], - copyright: - '

    Made with ❤️ at Spotify

    ', - }, - algolia: { - appId: 'AZYC4ZFNTN', - apiKey: '7dbd2089b0d445ee0d87db71abfc794f', - indexName: 'backstage', - searchParameters: {}, - }, + }, + }), }, + plugins: [ + 'docusaurus-plugin-sass', + () => ({ + configureWebpack() { + return { + module: { + rules: [ + { + test: /\.ya?ml$/, + use: 'yaml-loader', + }, + ], + }, + }; + }, + }), + ], + themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + { + colorMode: { + defaultMode: 'dark', + disableSwitch: true, + }, + navbar: { + logo: { + alt: 'Backstage Software Catalog and Developer Platform', + src: 'img/logo.svg', + }, + items: [ + { + href: 'https://github.com/backstage/backstage', + label: 'GitHub', + position: 'left', + }, + { + to: 'docs/overview/what-is-backstage', + label: 'Docs', + position: 'left', + }, + { + to: '/plugins', + label: 'Plugins', + position: 'left', + }, + { + to: '/blog', + label: 'Blog', + position: 'left', + }, + { + to: 'docs/releases/v1.11.0', + label: 'Releases', + position: 'left', + }, + { + to: '/demos', + label: 'Demos', + position: 'left', + }, + { + to: '/community', + label: 'Community', + position: 'left', + }, + ], + }, + image: 'img/sharing-opengraph.png', + footer: { + links: [ + { + items: [ + { + html: '', + }, + ], + }, + { + title: 'Docs', + items: [ + { + label: 'What is Backstage?', + to: 'docs/overview/what-is-backstage', + }, + { + label: 'Getting started', + to: 'docs/getting-started/', + }, + { + label: 'Software Catalog', + to: 'docs/features/software-catalog/software-catalog-overview', + }, + { + label: 'Create a Plugin', + to: 'docs/plugins/create-a-plugin', + }, + { + label: 'Designing for Backstage', + to: 'docs/dls/design', + }, + ], + }, + { + title: 'Community', + items: [ + { + label: 'Support chatroom', + to: 'https://discord.gg/backstage-687207715902193673', + }, + { + label: 'Contributing', + to: 'https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md', + }, + { + label: 'Adopting', + to: 'https://backstage.spotify.com', + }, + { + label: 'Subscribe to our newsletter', + to: 'https://mailchi.mp/spotify/backstage-community', + }, + { + label: 'CNCF Incubation', + to: 'https://www.cncf.io/projects/', + }, + ], + }, + { + title: 'More', + items: [ + { + label: 'Open Source @ Spotify', + to: 'https://spotify.github.io/', + }, + { + label: 'Spotify Engineering Blog', + to: 'https://engineering.atspotify.com/', + }, + { + label: 'Spotify for Developers', + to: 'https://developer.spotify.com/', + }, + { + label: 'Github', + to: 'https://github.com/backstage/', + }, + ], + }, + ], + copyright: + '

    Made with ❤️ at Spotify

    ', + }, + algolia: { + apiKey: '1f0ba86672ccfc3576faa94583e5b318', + indexName: 'crawler_Backstage Docusaurus 2', + appId: 'JCMFNHCHI8', + searchParameters: {}, + }, + }, }; diff --git a/microsite-next/package.json b/microsite-next/package.json index 478fce0196..c223e87584 100644 --- a/microsite-next/package.json +++ b/microsite-next/package.json @@ -17,17 +17,26 @@ "docusaurus": "docusaurus" }, "devDependencies": { + "@docusaurus/module-type-aliases": "2.3.1", "@spotify/prettier-config": "^14.0.0", + "@tsconfig/docusaurus": "^1.0.6", + "@types/webpack-env": "^1.18.0", "js-yaml": "^4.1.0", "prettier": "^2.6.2", - "replace": "^1.2.2" + "replace": "^1.2.2", + "typescript": "^4.9.4", + "yaml-loader": "^0.8.0" }, "prettier": "@spotify/prettier-config", "dependencies": { - "@docusaurus/core": "2.2.0", - "@docusaurus/preset-classic": "2.2.0", + "@docusaurus/core": "2.3.1", + "@docusaurus/preset-classic": "2.3.1", + "@swc/core": "^1.3.36", "clsx": "^1.1.1", + "docusaurus-plugin-sass": "^0.2.3", "react": "^17.0.2", - "react-dom": "^17.0.2" + "react-dom": "^17.0.2", + "sass": "^1.57.1", + "swc-loader": "^0.2.3" } } diff --git a/microsite-next/sidebars.json b/microsite-next/sidebars.json index 67c4209976..f489771fa0 100644 --- a/microsite-next/sidebars.json +++ b/microsite-next/sidebars.json @@ -1,6 +1,9 @@ { "releases": { "Release Notes": [ + "releases/v1.11.0", + "releases/v1.10.0", + "releases/v1.9.0", "releases/v1.8.0", "releases/v1.7.0", "releases/v1.6.0", @@ -85,7 +88,8 @@ "features/kubernetes/installation", "features/kubernetes/configuration", "features/kubernetes/authentication", - "features/kubernetes/troubleshooting" + "features/kubernetes/troubleshooting", + "features/kubernetes/proxy" ] }, { @@ -101,6 +105,7 @@ "features/software-templates/writing-custom-actions", "features/software-templates/writing-custom-field-extensions", "features/software-templates/writing-custom-step-layouts", + "features/software-templates/testing-scaffolder-alpha", "features/software-templates/migrating-from-v1beta2-to-v1beta3" ] }, @@ -199,7 +204,8 @@ "label": "GitLab", "items": [ "integrations/gitlab/locations", - "integrations/gitlab/discovery" + "integrations/gitlab/discovery", + "integrations/gitlab/org" ] }, { @@ -237,8 +243,7 @@ "plugins/proxying", "plugins/backend-plugin", "plugins/call-existing-api", - "plugins/url-reader", - "plugins/new-backend-system" + "plugins/url-reader" ] }, { @@ -361,6 +366,43 @@ "architecture-decisions/adrs-adr012", "architecture-decisions/adrs-adr013" ], - "FAQ": ["FAQ"] + "FAQ": ["FAQ"], + "Experimental Backend System": [ + "backend-system/index", + { + "type": "category", + "label": "Architecture", + "items": [ + "backend-system/architecture/index", + "backend-system/architecture/services", + "backend-system/architecture/plugins", + "backend-system/architecture/extension-points", + "backend-system/architecture/modules", + "backend-system/architecture/naming-patterns" + ] + }, + { + "type": "category", + "label": "Building Backends", + "items": [ + "backend-system/building-backends/index", + "backend-system/building-backends/migrating" + ] + }, + { + "type": "category", + "label": "Building Plugins & Modules", + "items": [ + "backend-system/building-plugins-and-modules/index", + "backend-system/building-plugins-and-modules/testing", + "backend-system/building-plugins-and-modules/migrating" + ] + }, + { + "type": "category", + "label": "Core Services", + "items": ["backend-system/core-services/index"] + } + ] } } diff --git a/microsite-next/src/components/bannerSection/bannerSection.module.scss b/microsite-next/src/components/bannerSection/bannerSection.module.scss new file mode 100644 index 0000000000..2beabf9738 --- /dev/null +++ b/microsite-next/src/components/bannerSection/bannerSection.module.scss @@ -0,0 +1,35 @@ +.bannerSection { + display: block; + + &:global(.greyBackground) { + background: linear-gradient(90.49deg, #121212 15.36%, #282828 70.44%); + } + + &:global(.greenGradientBackground) { + background: linear-gradient(70.44deg, #121212 55%, #5d817b); + } + + &:global(.greenBottomGradientBackground) { + background: linear-gradient( + 178.64deg, + hsla(0, 0%, 100%, 0) 57.61%, + hsla(0, 0%, 100%, 0.17) 127.71% + ), + linear-gradient( + 144.35deg, + rgba(98, 197, 179, 0) 56.68%, + rgba(98, 197, 179, 0.59) 109.25% + ), + linear-gradient( + 192.29deg, + rgba(155, 240, 225, 0) 54.17%, + rgba(155, 240, 225, 0.67) 137.34% + ); + } + + &:global(.greenCallToActionGradientBackground) { + background: linear-gradient(87.29deg, #9bf0e1 17.71%, #36baa2 80.85%); + + color: var(--ifm-color-gray-900); + } +} diff --git a/microsite-next/src/components/bannerSection/bannerSection.tsx b/microsite-next/src/components/bannerSection/bannerSection.tsx new file mode 100644 index 0000000000..64c8d246c8 --- /dev/null +++ b/microsite-next/src/components/bannerSection/bannerSection.tsx @@ -0,0 +1,34 @@ +import clsx from 'clsx'; +import React, { PropsWithChildren } from 'react'; + +import bannerStyles from './bannerSection.module.scss'; + +export type IBannerSectionProps = PropsWithChildren<{ + className?: string; + greyBackground?: boolean; + greenGradientBackground?: boolean; + greenBottomGradientBackground?: boolean; + greenCallToActionGradientBackground?: boolean; +}>; + +export const BannerSection = ({ + children, + className, + greyBackground = false, + greenGradientBackground = false, + greenBottomGradientBackground = false, + greenCallToActionGradientBackground = false, +}: IBannerSectionProps) => ( +
    +
    + {children} +
    +
    +); diff --git a/microsite-next/src/components/bannerSection/bannerSectionGrid.module.scss b/microsite-next/src/components/bannerSection/bannerSectionGrid.module.scss new file mode 100644 index 0000000000..c57b82ac57 --- /dev/null +++ b/microsite-next/src/components/bannerSection/bannerSectionGrid.module.scss @@ -0,0 +1,20 @@ +$desktopUpBreakpoint: 997px; + +.sectionGridContainer { + gap: 2rem; + display: grid; + + :global(.gridHeader) { + grid-column: 1 / -1; + } +} + +.gridContainer { + gap: 2rem; + display: grid; + align-items: center; + + @media (min-width: $desktopUpBreakpoint) { + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + } +} diff --git a/microsite-next/src/components/bannerSection/bannerSectionGrid.tsx b/microsite-next/src/components/bannerSection/bannerSectionGrid.tsx new file mode 100644 index 0000000000..dc9853d1fe --- /dev/null +++ b/microsite-next/src/components/bannerSection/bannerSectionGrid.tsx @@ -0,0 +1,32 @@ +import clsx from 'clsx'; +import React, { PropsWithChildren, ReactNode } from 'react'; + +import bannerGridStyles from './bannerSectionGrid.module.scss'; + +export type IBannerSectionColumnsProps = PropsWithChildren<{ + header?: ReactNode; + className?: string; +}>; + +export const BannerSectionGrid = ({ + header, + children, + className, +}: IBannerSectionColumnsProps) => { + return ( +
    + {header &&
    {header}
    } + +
    + {Array.isArray(children) + ? children.map((child, index) => + React.cloneElement(child, { + key: index, + className: clsx(child.props.className), + }), + ) + : children} +
    +
    + ); +}; diff --git a/microsite-next/src/components/contentBlock/contentBlock.module.scss b/microsite-next/src/components/contentBlock/contentBlock.module.scss new file mode 100644 index 0000000000..9a34c55390 --- /dev/null +++ b/microsite-next/src/components/contentBlock/contentBlock.module.scss @@ -0,0 +1,30 @@ +.contentBlock { + height: 100%; + + gap: 1.5rem; + display: grid; + align-items: center; + + > *, + h1, + h2 { + margin: 0; + padding: 0; + } + + :global(.contentBlockTitle) { + align-self: start; + } + + :global(.bulletLine) { + width: 50px; + margin-bottom: 0.5rem; + } + + :global(.actionButtons) { + gap: 1rem; + display: grid; + align-self: end; + grid-template-columns: repeat(auto-fit, minmax(100px, auto)); + } +} diff --git a/microsite-next/src/components/contentBlock/contentBlock.tsx b/microsite-next/src/components/contentBlock/contentBlock.tsx new file mode 100644 index 0000000000..aae065db44 --- /dev/null +++ b/microsite-next/src/components/contentBlock/contentBlock.tsx @@ -0,0 +1,53 @@ +import Link from '@docusaurus/Link'; +import clsx from 'clsx'; +import React, { FC, PropsWithChildren, ReactNode } from 'react'; + +import contentBlockStyles from './contentBlock.module.scss'; + +export interface ContentBlockActionButtonProps { + label: string; + link: string; +} + +export type IContentBlockProps = PropsWithChildren<{ + title?: ReactNode; + className?: string; + topImgSrc?: string; + hasBulletLine?: boolean; + actionButtons?: ContentBlockActionButtonProps[]; +}>; + +export const ContentBlock = ({ + children, + title, + className, + topImgSrc, + hasBulletLine, + actionButtons, +}: IContentBlockProps) => ( +
    + {topImgSrc && {topImgSrc}} + +
    + {hasBulletLine &&
    } + + {title && React.isValidElement(title) ? title :

    {title}

    } +
    + + {children && React.isValidElement(children) ? children :

    {children}

    } + + {actionButtons && ( +
    + {actionButtons.map(({ link, label }, index) => ( + + {label} + + ))} +
    + )} +
    +); diff --git a/microsite-next/src/css/customTheme.css b/microsite-next/src/css/customTheme.css index 3b71d51d62..1a39467516 100644 --- a/microsite-next/src/css/customTheme.css +++ b/microsite-next/src/css/customTheme.css @@ -25,7 +25,7 @@ background-color: white; } -/* Utility API Styling */ +/* #region Utility API Styling */ .textGreen { color: #82b366; } @@ -44,4 +44,15 @@ .textAlignCenter { text-align: center; } -/* End of Utility API Styling */ +/* #endregion */ + +/* #region Utility component styles */ +.bulletLine { + height: 3px; + background: linear-gradient( + 89.75deg, + #9bf0e1 -1.5%, + rgba(155, 240, 225, 0) 111.48% + ); +} +/* #endregion */ diff --git a/microsite-next/src/pages/community/community.module.scss b/microsite-next/src/pages/community/community.module.scss new file mode 100644 index 0000000000..3f829b0100 --- /dev/null +++ b/microsite-next/src/pages/community/community.module.scss @@ -0,0 +1,28 @@ +.communityPage { + // --ifm-spacing-horizontal: 2rem; + + font-size: 1.25rem; + + h1 { + font-size: 54px; + line-height: 56px; + word-break: break-word; + } + + p { + text-align: justify; + } +} + +.listContainer { + height: 100%; + align-items: stretch !important; + grid-template-rows: auto 1fr; + + ul { + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + } +} diff --git a/microsite-next/src/pages/community/index.tsx b/microsite-next/src/pages/community/index.tsx new file mode 100644 index 0000000000..d334b04ee2 --- /dev/null +++ b/microsite-next/src/pages/community/index.tsx @@ -0,0 +1,270 @@ +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import { BannerSection } from '@site/src/components/bannerSection/bannerSection'; +import { BannerSectionGrid } from '@site/src/components/bannerSection/bannerSectionGrid'; +import Layout from '@theme/Layout'; +import { clsx } from 'clsx'; +import React from 'react'; + +import { ContentBlock } from '../../components/contentBlock/contentBlock'; +import communityStyles from './community.module.scss'; + +interface ICollectionItem { + title?: string; + content: React.ReactNode; + label: string; + link: string; +} + +const Community = () => { + const { siteConfig } = useDocusaurusContext(); + + //#region Collection Data + const communityListItems: ICollectionItem[] = [ + { + content: 'Chat and get support on our', + label: 'Discord', + link: 'https://discord.gg/backstage-687207715902193673', + }, + { + content: 'Get into contributing with the', + label: 'Good First Issues', + link: 'https://github.com/backstage/backstage/contribute', + }, + { + content: 'Subscribe to the', + label: 'Community newsletter', + link: 'https://info.backstage.spotify.com/newsletter_subscribe', + }, + { + content: 'Join the', + label: 'Twitter community', + link: 'https://twitter.com/i/communities/1494019781716062215', + }, + ]; + + const officialInitiatives: ICollectionItem[] = [ + { + title: 'Community sessions', + content: + 'Maintainers and adopters meet monthly to share updates, demos, and ideas. Yep, all sessions are recorded!', + link: '/on-demand', + label: 'Join a session', + }, + { + title: 'Newsletter', + content: + "The official monthly Backstage newsletter. Don't miss the latest news from your favorite project!", + link: 'https://info.backstage.spotify.com/newsletter_subscribe', + label: 'Subscribe', + }, + { + title: 'Contributor Spotlight', + content: + "A recognition for valuable community work. Nominate contributing members for their efforts! We'll put them in the spotlight ❤️", + link: '/nominate', + label: 'Nominate now', + }, + ]; + + const communityInitiatives: ICollectionItem[] = [ + { + title: 'Open Mic Meetup', + content: ( + <> + A casual get together of Backstage users sharing their experiences and + helping each other. Hosted by{' '} + Roadie.io and{' '} + Frontside Software. + + ), + link: 'https://backstage-openmic.com/', + label: 'Learn more', + }, + { + title: 'Backstage Weekly Newsletter', + content: ( + <> + A weekly newsletter with news, updates and things community from your + friends at Roadie.io. + + ), + link: 'https://roadie.io/backstage-weekly/', + label: 'Learn more', + }, + ]; + + const trainingNCertifications: ICollectionItem[] = [ + { + title: 'Open Mic Meetup', + content: + 'This is a course produced and curated by the Linux Foundation. This course introduces you to Backstage and how to get started with the project.', + link: 'https://training.linuxfoundation.org/training/introduction-to-backstage-developer-portals-made-easy-lfs142x/', + label: 'Learn more', + }, + ]; + + const partners: { name: string; url: string; logo: string }[] = [ + { + name: 'Frontside Software', + url: 'https://frontside.com/backstage/', + logo: 'img/partner-logo-frontside.png', + }, + { + name: 'Roadie', + url: 'https://roadie.io/', + logo: 'img/partner-logo-roadie.png', + }, + { + name: 'ThoughtWorks', + url: 'https://www.thoughtworks.com', + logo: 'img/partner-logo-thoughtworks.png', + }, + { + name: 'VMWare', + url: 'https://www.vmware.com', + logo: 'img/partner-logo-vmware.png', + }, + ]; + //#endregion + + return ( + +
    + + + Backstage Community} + > + Join the vibrant community around Backstage through social media + and different meetups. To ensure that you have a welcoming + environment, we follow the + + {' '} + CNCF Code of Conduct{' '} + + in everything we do. + + + +
      + {communityListItems.map( + ({ content: text, link, label }, index) => ( +
    • +

      + {text} {label} +

      +
    • + ), + )} +
    +
    +
    +
    + + + +

    Offical Backstage initiatives

    + +

    Stay tuned to the latest developments

    + + } + > + {officialInitiatives.map( + ({ title, content, link, label }, index) => ( + + {content} + + ), + )} +
    +
    + + + Community initiatives} + > + {communityInitiatives.map( + ({ title, content, link, label }, index) => ( + +

    {content}

    +
    + ), + )} +
    +
    + + + Trainings and Certifications + } + > + {trainingNCertifications.map( + ({ title, content, link, label }, index) => ( + +

    {content}

    +
    + ), + )} +
    +
    + + + Commercial Partners} + > + {partners.map(({ name, url, logo }, index) => ( +
    + + {name} + +
    + ))} +
    +
    +
    +
    + ); +}; + +export default Community; diff --git a/microsite-next/src/pages/demos/demos.module.scss b/microsite-next/src/pages/demos/demos.module.scss new file mode 100644 index 0000000000..b99874297e --- /dev/null +++ b/microsite-next/src/pages/demos/demos.module.scss @@ -0,0 +1,24 @@ +.communityPage { + // --ifm-spacing-horizontal: 2rem; + + font-size: 1.25rem; + + h1 { + font-size: 54px; + line-height: 56px; + word-break: break-word; + } +} + +.banner { + p { + flex: 1; + text-align: justify; + } + + iframe { + width: 100%; + height: 100%; + min-height: 500px; + } +} diff --git a/microsite-next/src/pages/demos/index.tsx b/microsite-next/src/pages/demos/index.tsx new file mode 100644 index 0000000000..2ca77e5c89 --- /dev/null +++ b/microsite-next/src/pages/demos/index.tsx @@ -0,0 +1,206 @@ +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import { BannerSection } from '@site/src/components/bannerSection/bannerSection'; +import { BannerSectionGrid } from '@site/src/components/bannerSection/bannerSectionGrid'; +import { ContentBlock } from '@site/src/components/contentBlock/contentBlock'; +import Layout from '@theme/Layout'; +import { clsx } from 'clsx'; +import React from 'react'; + +import demosStyles from './demos.module.scss'; + +interface IDemoItem { + title: string; + content: React.ReactNode; + actionItemLink?: string; + media: { + type: 'image' | 'video'; + link: string; + }; +} + +const Demos = () => { + const { siteConfig } = useDocusaurusContext(); + + //#region Collection Data + const demoItems: IDemoItem[] = [ + { + title: 'See us in action', + content: ( + <> +

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

    +

    + To see how other companies have already started using Backstage, + watch these presentations from{' '} + Expedia,{' '} + Zalando, and{' '} + TELUS. For + more, join our{' '} + + Community Sessions + +

    +

    + To explore the UI and basic features of Backstage firsthand, go to:{' '} + demo.backstage.io. (Tip:{' '} + click “All” to view all the example components in the software + catalog.) +

    + + ), + media: { + type: 'image', + link: `${siteConfig.baseUrl}img/demo-screen.png`, + }, + }, + { + title: 'Introduction to Backstage', + content: + 'Backstage is an open source platform for building developer portals. We’ve been using our homegrown version at Spotify for years — so it’s already packed with features. (We have over 120 internal plugins, built by 60 different teams.) In this live demo recording, Stefan Ålund, product manager for Backstage, tells the origin story of Backstage and gives you a tour of how we use it here at Spotify.', + actionItemLink: 'https://www.youtube.com/watch?v=1XtJ5FAOjPk', + media: { + type: 'video', + link: 'https://www.youtube.com/embed/1XtJ5FAOjPk', + }, + }, + { + title: 'Control cloud costs', + content: ( + <> +

    + How do you control cloud costs while maintaining the speed and + independence of your development teams? With the{' '} + Cost Insights plugin{' '} + for Backstage, managing cloud costs becomes just another part of an + engineer’s daily development process. They get a clear view of their + spending — and can decide for themselves how they want to optimize + it. Learn more about the{' '} + + Cost Insights plugin + +

    + + ), + actionItemLink: 'https://youtu.be/YLAd5hdXR_Q', + media: { + type: 'video', + link: 'https://www.youtube.com/embed/YLAd5hdXR_Q', + }, + }, + { + title: 'Make documentation easy', + content: ( + <> +

    + Documentation! Everyone needs it, no one wants to create it, and no + one can ever find it. Backstage follows a “docs like code” approach: + you write documentation in Markdown files right alongside your code. + This makes documentation easier to create, maintain, find — and, you + know, actually use. This demo video showcases Spotify’s internal + version of TechDocs. Learn more about{' '} + + TechDocs + + . +

    + + ), + actionItemLink: 'https://youtu.be/mOLCgdPw1iA', + media: { + type: 'video', + link: 'https://www.youtube.com/embed/mOLCgdPw1iA', + }, + }, + { + title: 'Manage your tech health', + content: + 'Instead of manually updating a spreadsheet, what if you had a beautiful dashboard that could give you an instant, interactive picture of your entire org’s tech stack? That’s how we do it at Spotify. With our Tech Insights plugin for Backstage, anyone at Spotify can see which version of which software anyone else at Spotify is using — and a whole a lot more. From managing migrations to fighting tech entropy, Backstage makes managing our tech health actually kind of pleasant.', + actionItemLink: + 'https://www.youtube.com/watch?v=K3xz6VAbgH8&list=PLf1KFlSkDLIBtMGwRDfaVlKMqTMrjD2yO&index=6', + media: { + type: 'video', + link: 'https://www.youtube.com/embed/K3xz6VAbgH8', + }, + }, + { + title: 'Create a microservice', + content: + 'You’re a Spotify engineer about to build a new microservice (or any component) using Spring Boot. Where do you start? Search for a quick start guide online? Create an empty repo on GitHub? Copy and paste an old project? Nope. Just go to Backstage, and you’ll be up and running in two minutes — with a “Hello World” app, CI, and documentation all automatically set up and configured in a standardized way.', + actionItemLink: 'https://www.youtube.com/watch?v=U1iwe3L5pzc', + media: { + type: 'video', + link: 'https://www.youtube.com/embed/U1iwe3L5pzc', + }, + }, + { + title: 'Search all your services', + content: + 'All of Spotify’s services are automatically indexed in Backstage. So our engineers can stop playing detective — no more spamming Slack channels asking if anyone knows who owns a particular service and where you can find its API, only to discover that the owner went on sabbatical three months ago and you have to hunt them down on a mountain in Tibet where they’re on a 12-day silent meditation retreat. At Spotify, anyone can always find anyone else’s service, inspect its APIs, and contact its current owner — all with one search.', + actionItemLink: 'https://www.youtube.com/watch?v=vcDL9tOv7Eo', + media: { + type: 'video', + link: 'https://www.youtube.com/embed/vcDL9tOv7Eo', + }, + }, + { + title: 'Manage data pipelines', + content: + 'We manage a lot of data pipelines (also known as workflows) here at Spotify. So, of course, we made a great workflows plugin for our version of Backstage. All our workflow tools — including a scheduler, log inspector, data lineage graph, and configurable alerts — are integrated into one simple interface.', + actionItemLink: 'https://www.youtube.com/watch?v=rH46MLNZIPM', + media: { + type: 'video', + link: 'https://www.youtube.com/embed/rH46MLNZIPM', + }, + }, + ]; + //#endregion + + return ( + +
    + {demoItems.map((demoItem, index) => ( + + + {demoItem.title}} + actionButtons={[ + { + link: demoItem.actionItemLink, + label: 'WATCH NOW', + }, + ]} + > + {demoItem.content} + + +
    + {demoItem.media.type === 'image' ? ( + {demoItem.title} + ) : ( + + )} +
    +
    +
    + ))} +
    +
    + ); +}; + +export default Demos; diff --git a/microsite-next/src/pages/home/_home.tsx b/microsite-next/src/pages/home/_home.tsx new file mode 100644 index 0000000000..4ba5539348 --- /dev/null +++ b/microsite-next/src/pages/home/_home.tsx @@ -0,0 +1,538 @@ +import BrowserOnly from '@docusaurus/BrowserOnly'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import { BannerSection } from '@site/src/components/bannerSection/bannerSection'; +import { BannerSectionGrid } from '@site/src/components/bannerSection/bannerSectionGrid'; +import { ContentBlock } from '@site/src/components/contentBlock/contentBlock'; +import Layout from '@theme/Layout'; +import { clsx } from 'clsx'; +import React, { useState } from 'react'; + +import homeStyles from './home.module.scss'; +import { HubSpotNewAdoptersForm } from './_hubSpotNewAdoptersForm'; + +const hiddenNewsletterBannerKey = 'hiddenNewsletterBanner'; + +const HomePage = () => { + const { siteConfig } = useDocusaurusContext(); + + const [hiddenNewsletterBanner, setHideNewsletterBanner] = useState(() => { + return JSON.parse(localStorage.getItem(hiddenNewsletterBannerKey)) || false; + }); + + const hideNewsletterBanner = (shouldHide: boolean) => { + localStorage.setItem(hiddenNewsletterBannerKey, JSON.stringify(shouldHide)); + setHideNewsletterBanner(shouldHide); + }; + + return ( + +
    + + +
    + 🗞️ Want to stay up to date with Backstage? Sign up for our{' '} + + Newsletter + + ! +
    + +
    hideNewsletterBanner(true)} + > + + + +
    +
    + ) + } + > + An open platform for building developer portals} + actionButtons={[ + { + link: 'https://github.com/backstage/backstage#getting-started', + label: 'GITHUB', + }, + { + link: 'https://info.backstage.spotify.com/office-hours', + label: 'OFFICE HOURS', + }, + ]} + > + Powered by a centralized software catalog, Backstage restores + order to your infrastructure and enables your product teams to + ship high-quality code quickly — without compromising autonomy. + + +
    + + +
    + + + + + + + At Spotify, we've always believed in the speed and ingenuity that + comes from having autonomous development teams. But as we learned + firsthand, the faster you grow, the more fragmented and complex + your software ecosystem becomes. And then everything slows down + again. + + + + By centralizing services and standardizing your tooling, Backstage + streamlines your development environment from end to end. Instead + of restricting autonomy, standardization frees your engineers from + infrastructure complexity. So you can return to building and + scaling, quickly and safely. + + + + + +
    +
    + Software Catalog Planet GIF + +

    Backstage Software Catalog

    + +

    Build an ecosystem, not a wilderness

    +
    + + + + Software Catalog Filter Sidebar + + + + Backstage makes it easy for one team to manage 10 services — and + makes it possible for your company to manage thousands of them + + + + Every team can see all the services they own and related resources + (deployments, data pipelines, pull request status, etc.) + + + + All that information can be shared with plugins inside Backstage + to enable other management features, like resource monitoring and + testing + + + + Libraries, websites, ML models — you name it, Backstage knows all + about it, including who owns it, dependencies, and more + + + + No more orphan software hiding in the dark corners of your tech + stack + +
    +
    + + +
    +

    Learn more about the software catalog

    + + + READ + +
    +
    + + +
    +
    + Software Templates Rocket GIF + +

    Backstage Software Templates

    + +

    Standards can set you free

    +
    + + + + Software Templates Cards + + + + Using templates, engineers can spin up a new microservice with + your organization's best practices built-in, right from the start + + + + Click a button to create a Spring Boot project with your repo + automatically configured on GitHub and your CI already running the + first build + + + + Go instead of Java? CircleCI instead of Jenkins? Serverless + instead of Kubernetes? GCP instead of AWS? Customize your recipes + with your best practices baked-in + + + + When the right way is also the easiest way, engineers get up and + running faster — and more safely + +
    +
    + + +
    +

    Build your own software templates

    + + + CONTRIBUTE + +
    +
    + + +
    +
    + Backstage TechDocs File Copy GIF + +

    Backstage TechDocs

    + +

    Docs like code

    +
    + + + + Backstage TechDocs Markdown to HTML + + + + Whenever you use a Backstage Software Template, your project + automatically gets a TechDocs site, for free + + + + With our docs-like-code approach, engineers write their + documentation in Markdown files right alongside their code + + + + Updating code? Update your documentation while you're there — with + docs and code in the same place, it becomes a natural part of your + workstream + + + + Since all your documentation is in Backstage, finding any TechDoc + is just a search query away + +
    +
    + + +
    +

    Learn more about TechDocs

    + + + DOCS + +
    +
    + + +
    +
    + Search Platform Telescope GIF + +

    Backstage Search Platform

    + +

    A search platform made just for you

    +
    + + + + Search Platform Search Bar + + + + Backstage Search more than just a box you type questions into — + it's an entire platform all by itself, which you can customize to + fit your organization's needs + + + + Bring your own search engine, create a customized search page + experience, or edit the look and feel of each search result + + + + With an extensible backend, you can search beyond the Software + Catalog and index any source you'd like — whether it's TechDocs or + Confluence and Stack Overflow + + + + New hires and seasoned employees alike can easily search your + infrastructure instead of getting lost in it + +
    +
    + + +
    +

    Learn more about Backstage Search

    + + + READ + +
    +
    + + + + Backstage Kubernetes Flag GIF + +

    Backstage Kubernetes

    + +

    Manage your services, not clusters

    + + } + > + + Backstage features the first Kubernetes monitoring tool designed + around the needs of service owners, not cluster admins + + + + Get all your service's deployments in one, aggregated view — no + more digging through cluster logs in a CLI, no more combing + through lists of services you don't own + + + + Since Backstage uses the Kubernetes API, it's cloud agnostic — so + it works no matter which cloud provider or managed Kubernetes + service you use, and even works in multi-cloud orgs + + + + Now you don't have to switch dashboards when you move from local + testing to production, or from one cloud provider to another + +
    +
    + + +
    +

    Learn more about the K8s plugin

    + + + READ + +
    +
    + + +
    +
    + Plugins Building Blocks GIF + +

    + Customize Backstage with plugins +

    + +

    An app store for your infrastructure

    +
    + + + + Plugins Cards + + + + Want scalable website testing? Add the{' '} + + Lighthouse{' '} + + plugin. Wondering about recommended frameworks? Add the{' '} + + Tech Radar{' '} + + plugin. + + + + If you don't see the plugin you need, it's simple to build your + own + + + + Building internal plugins lets you tailor your version of + Backstage to be a perfect fit for your infrastructure + + + + Building open source plugins{' '} + contributes to the entire Backstage ecosystem, which benefits + everyone + +
    +
    + + +
    +

    Build a plugin

    + + + CONTRIBUTE + +
    +
    + + +
    +

    + Backstage is a{' '} + + Cloud Native Computing Foundation + {' '} + incubation project +

    + + CNCF Logo +
    +
    + + +
    + + ); +}; + +export const Home = () => { + return {() => }; +}; diff --git a/microsite-next/src/pages/home/_hubSpotNewAdoptersForm.tsx b/microsite-next/src/pages/home/_hubSpotNewAdoptersForm.tsx new file mode 100644 index 0000000000..36f00dff75 --- /dev/null +++ b/microsite-next/src/pages/home/_hubSpotNewAdoptersForm.tsx @@ -0,0 +1,52 @@ +import clsx from 'clsx'; +import React, { useEffect, useState } from 'react'; + +import hubSpotStyles from './hubSpotNewAdoptersForm.module.scss'; + +export const HubSpotNewAdoptersForm = () => { + const [isClosed, setClosed] = useState(true); + + useEffect(() => { + const script = document.createElement('script'); + script.src = 'https://js.hsforms.net/forms/v2.js'; + document.body.appendChild(script); + + script.addEventListener('load', () => { + // @ts-ignore + if (window.hbspt) { + // @ts-ignore + window.hbspt.forms.create({ + portalId: '21894833', + formId: '9a5aa2af-87f3-4a44-819f-88ee243bb61e', + target: `.${hubSpotStyles.hubSpotNewAdopterFormContent}`, + pageId: '79735607665', + }); + } + }); + }, []); + + return ( +
    + + +
    +
    + ); +}; diff --git a/microsite-next/src/pages/home/home.module.scss b/microsite-next/src/pages/home/home.module.scss new file mode 100644 index 0000000000..57f2b9acde --- /dev/null +++ b/microsite-next/src/pages/home/home.module.scss @@ -0,0 +1,109 @@ +$desktopUpBreakpoint: 997px; + +.homePage { + font-size: 1.25rem; + + h1 { + font-size: 54px; + line-height: 56px; + word-break: break-word; + } + + :global(.buttonsContainer) { + gap: 1rem; + display: grid; + grid-template-columns: repeat(2, auto); + } +} + +.newsletterBanner { + --ifm-link-hover-color: var(--ifm-color-info); + + flex-direction: row; + color: var(--ifm-button-color); + background-color: var(--ifm-color-primary); + + :global(.bannerContent) { + flex: 1; + } + + :global(.bannerCloseButton) { + color: var(--ifm-color-secondary); + } +} + +.svgContainer { + position: relative; + + :global(img.laptopSvg) { + width: 100%; + } + + :global(img.laptopScreenGif) { + position: absolute; + top: 3%; + left: 17%; + width: 70%; + } +} + +// Shared container styles +.catalogContainer, +.softwareTemplatesContainer { + gap: 2rem; + display: grid; + align-items: center; + + picture { + display: block; + text-align: center; + } + + :global([class*='Title']), + :global([class*='title']), + :global([class*='gridHeader']) { + img { + max-width: 190px; + max-height: 190px; + } + } +} + +.catalogContainer { + @media (min-width: $desktopUpBreakpoint) { + grid-template-columns: repeat(4, 1fr); + + picture { + grid-row: span 2; + grid-column: span 2; + } + + :global(.catalogTitle) { + grid-column: span 2; + } + } +} + +.softwareTemplatesContainer { + @media (min-width: $desktopUpBreakpoint) { + grid: repeat(2, auto) / repeat(4, 1fr); + + picture { + grid-row-start: 3; + grid-column: span 4; + } + + :global(.softwareTemplatesTitle) { + grid-column: span 4; + } + } +} + +.kubernetesSectionContainer { + :global([class*='gridHeader']) { + img { + max-width: 190px; + max-height: 190px; + } + } +} diff --git a/microsite-next/src/pages/home/hubSpotNewAdoptersForm.module.scss b/microsite-next/src/pages/home/hubSpotNewAdoptersForm.module.scss new file mode 100644 index 0000000000..77e1a87a53 --- /dev/null +++ b/microsite-next/src/pages/home/hubSpotNewAdoptersForm.module.scss @@ -0,0 +1,38 @@ +.hubSpotNewAdopterFormContainer { + top: 50%; + right: 0; + display: flex; + position: fixed; + transform: translateY(-50%); + + transition: all 250ms ease-in-out; + + &:global(.adoptersFormHidden) { + transform: translate(500px, -50%); + } + + > button { + top: 50%; + left: -2rem; + position: fixed; + + transform: rotate(-90deg) translateX(-50%); + transform-origin: top left; + } +} + +.hubSpotNewAdopterFormContent { + height: 600px; + max-width: 500px; + overflow-y: hidden; + border-radius: 8px 0 0 8px; + background-color: var(--ifm-color-white); + + form { + width: 100%; + height: 100%; + overflow-y: auto; + + padding-right: 2rem; + } +} diff --git a/microsite-next/src/pages/index.tsx b/microsite-next/src/pages/index.tsx index 3bbf03b0e2..853a4b2c82 100644 --- a/microsite-next/src/pages/index.tsx +++ b/microsite-next/src/pages/index.tsx @@ -1,11 +1,3 @@ -import Layout from '@theme/Layout'; -import React from 'react'; +import { Home } from './home/_home'; -function Index() { - return ( - -

    HELLO

    -
    - ); -} -export default Index; +export default Home; diff --git a/microsite-next/src/pages/plugins/_pluginCard.tsx b/microsite-next/src/pages/plugins/_pluginCard.tsx new file mode 100644 index 0000000000..dec62af06f --- /dev/null +++ b/microsite-next/src/pages/plugins/_pluginCard.tsx @@ -0,0 +1,54 @@ +import Link from '@docusaurus/Link'; +import React from 'react'; + +export interface IPluginData { + author: string; + authorUrl: string; + category: string; + description: string; + documentation: string; + iconUrl: string; + title: string; + order?: number; +} + +const defaultIconUrl = 'img/logo-gradient-on-dark.svg'; + +export const PluginCard = ({ + author, + authorUrl, + category, + description, + documentation, + iconUrl, + title, +}: IPluginData) => ( +
    +
    + {title} + +

    {title}

    + +

    + by {author} +

    + + + {category} + +
    + +
    +

    {description}

    +
    + +
    + + Explore + +
    +
    +); diff --git a/microsite-next/src/pages/plugins/index.tsx b/microsite-next/src/pages/plugins/index.tsx new file mode 100644 index 0000000000..f8c6f78819 --- /dev/null +++ b/microsite-next/src/pages/plugins/index.tsx @@ -0,0 +1,87 @@ +import Link from '@docusaurus/Link'; +import Layout from '@theme/Layout'; +import clsx from 'clsx'; +import React from 'react'; + +import { IPluginData, PluginCard } from './_pluginCard'; +import pluginsStyles from './plugins.module.scss'; + +//#region Plugin data import +const maxDescLength = 160; + +const truncatePluginDescription = (pluginData: IPluginData) => + pluginData.description.length > maxDescLength + ? { + ...pluginData, + description: pluginData.description.slice(0, maxDescLength) + '...', + } + : pluginData; + +const pluginsContext = require.context( + '../../../../microsite/data/plugins', + false, + /\.ya?ml/, +); + +const plugins = pluginsContext.keys().reduce( + (acum, id) => { + const pluginData: IPluginData = pluginsContext(id).default; + + acum[ + pluginData.category === 'Core Feature' ? 'corePlugins' : 'otherPlugins' + ].push(truncatePluginDescription(pluginData)); + + return acum; + }, + { corePlugins: [] as IPluginData[], otherPlugins: [] as IPluginData[] }, +); + +plugins.corePlugins.sort((a, b) => a.order - b.order); +plugins.otherPlugins.sort((a, b) => a.order - b.order); +//#endregion + +const Plugins = () => ( + +
    +
    +
    +

    Plugin Marketplace

    + +

    + Open source plugins that you can add to your Backstage deployment. + Learn how to build a plugin. +

    +
    + + + Add to Marketplace + +
    + +
    + +

    Core Features

    + +
    + {plugins.corePlugins.map(pluginData => ( + + ))} +
    + +

    All Plugins

    + +
    + {plugins.otherPlugins.map(pluginData => ( + + ))} +
    +
    +
    +); + +export default Plugins; diff --git a/microsite-next/src/pages/plugins/plugins.module.scss b/microsite-next/src/pages/plugins/plugins.module.scss new file mode 100644 index 0000000000..d21444583a --- /dev/null +++ b/microsite-next/src/pages/plugins/plugins.module.scss @@ -0,0 +1,33 @@ +.pluginsPage { + :global(.marketplaceBanner) { + display: flex; + align-items: center; + } + + :global(.marketplaceContent) { + flex: 1; + } + + :global(.card .card__header) { + display: grid; + row-gap: 0.25rem; + column-gap: 1rem; + align-items: center; + grid-template-columns: auto 1fr; + + > * { + margin: 0; + } + + :global(img) { + width: 80px; + grid-row: 1/4; + } + } + + :global(.pluginsContainer) { + gap: 1rem; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + } +} diff --git a/microsite-next/tsconfig.json b/microsite-next/tsconfig.json new file mode 100644 index 0000000000..ae8fe2298a --- /dev/null +++ b/microsite-next/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@tsconfig/docusaurus/tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "types": [ + "node", + "@docusaurus/module-type-aliases", + "@docusaurus/theme-classic", + "@types/webpack-env" + ] + } +} diff --git a/microsite-next/typings.d.ts b/microsite-next/typings.d.ts new file mode 100644 index 0000000000..d5cf927a7c --- /dev/null +++ b/microsite-next/typings.d.ts @@ -0,0 +1 @@ +declare module '*.scss'; diff --git a/microsite-next/yarn.lock b/microsite-next/yarn.lock index e03c6d93c5..d633230dd6 100644 --- a/microsite-next/yarn.lock +++ b/microsite-next/yarn.lock @@ -1660,9 +1660,9 @@ __metadata: languageName: node linkType: hard -"@docusaurus/core@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/core@npm:2.2.0" +"@docusaurus/core@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/core@npm:2.3.1" dependencies: "@babel/core": ^7.18.6 "@babel/generator": ^7.18.7 @@ -1674,13 +1674,13 @@ __metadata: "@babel/runtime": ^7.18.6 "@babel/runtime-corejs3": ^7.18.6 "@babel/traverse": ^7.18.8 - "@docusaurus/cssnano-preset": 2.2.0 - "@docusaurus/logger": 2.2.0 - "@docusaurus/mdx-loader": 2.2.0 + "@docusaurus/cssnano-preset": 2.3.1 + "@docusaurus/logger": 2.3.1 + "@docusaurus/mdx-loader": 2.3.1 "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/utils": 2.2.0 - "@docusaurus/utils-common": 2.2.0 - "@docusaurus/utils-validation": 2.2.0 + "@docusaurus/utils": 2.3.1 + "@docusaurus/utils-common": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 "@slorber/static-site-generator-webpack-plugin": ^4.0.7 "@svgr/webpack": ^6.2.1 autoprefixer: ^10.4.7 @@ -1701,7 +1701,7 @@ __metadata: del: ^6.1.1 detect-port: ^1.3.0 escape-html: ^1.0.3 - eta: ^1.12.3 + eta: ^2.0.0 file-loader: ^6.2.0 fs-extra: ^10.1.0 html-minifier-terser: ^6.1.0 @@ -1740,40 +1740,40 @@ __metadata: react-dom: ^16.8.4 || ^17.0.0 bin: docusaurus: bin/docusaurus.mjs - checksum: ff47e6cf85b0f7dc0a9e5b9b0d26e33a6f7385f067566ff4f9b026d044839e4dfb4c3bc9476cfab7a7e95a0065478a534cda403dac3bb7bac9987406f1978a11 + checksum: 812aecae45af3f4d02fd16e89517ca9f1ba22821a078aaa890f5797ac7e0cc0c79e7623eb999e885cf7e7652a6ffda8ff7c06dfd85ca29aaab600993c3d9980d languageName: node linkType: hard -"@docusaurus/cssnano-preset@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/cssnano-preset@npm:2.2.0" +"@docusaurus/cssnano-preset@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/cssnano-preset@npm:2.3.1" dependencies: cssnano-preset-advanced: ^5.3.8 postcss: ^8.4.14 postcss-sort-media-queries: ^4.2.1 tslib: ^2.4.0 - checksum: eff9707414867bf844ef5d84bde1c843593b9b7f542dd1a0a7acc88798b0c5ddb721124229912c234bd88b93cb18d8d69c6115cbf706c2a790497f7d9dd23757 + checksum: a3d00ce86b16caffde36734bb2f4541d2c0df5e8ab6891a78ad05bccc631a895fecb04c385626ebcb8f905510c28fa6158288585673ae96565532d4ee4b60d4f languageName: node linkType: hard -"@docusaurus/logger@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/logger@npm:2.2.0" +"@docusaurus/logger@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/logger@npm:2.3.1" dependencies: chalk: ^4.1.2 tslib: ^2.4.0 - checksum: b3ce6e18721a34793a892221485c941d5f7112ae96d569f7918d12c1f50bde9c99bc4195f4d225e874b2bd5800a35413bfeaf78b63c6fbae5f3015d44d118eee + checksum: eff5f258aeac9c643431426256e3bc4515074cc3cc754fa643579ba427ba232ecace9a9579ae5af542330b22d7361892a1eaf84526983a0c821c5ca3ee895176 languageName: node linkType: hard -"@docusaurus/mdx-loader@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/mdx-loader@npm:2.2.0" +"@docusaurus/mdx-loader@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/mdx-loader@npm:2.3.1" dependencies: "@babel/parser": ^7.18.8 "@babel/traverse": ^7.18.8 - "@docusaurus/logger": 2.2.0 - "@docusaurus/utils": 2.2.0 + "@docusaurus/logger": 2.3.1 + "@docusaurus/utils": 2.3.1 "@mdx-js/mdx": ^1.6.22 escape-html: ^1.0.3 file-loader: ^6.2.0 @@ -1790,16 +1790,16 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: fee586498f43c46581062e681424c4637e75d505d813d8bf25f5315c912560f6600cd925bc5b07a93d5d5966741439578e7e72f30030b4c58a5cfdf72e0d8928 + checksum: 4a1c9ef0e8506ab4d9cb4714ff7437664e238e0f2878a5eb4a2e082897bbee7ae8d0b61ba9d45ffa820beb5ce75aa0050201db815b00c18fc136aaa4c6411c21 languageName: node linkType: hard -"@docusaurus/module-type-aliases@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/module-type-aliases@npm:2.2.0" +"@docusaurus/module-type-aliases@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/module-type-aliases@npm:2.3.1" dependencies: "@docusaurus/react-loadable": 5.5.2 - "@docusaurus/types": 2.2.0 + "@docusaurus/types": 2.3.1 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -1809,21 +1809,21 @@ __metadata: peerDependencies: react: "*" react-dom: "*" - checksum: ebcb9dff2f88b5962cd34aaa78b1a48531da4776229ef507665e3f053cccb185aadcc16c3703f21031e14ccb6c8312662a6eec1a2a06bc0a423221ad200e1e9e + checksum: 74f799f81455dc8ff3e6edf07428996764014c2c7b416e6b5d160af15f00ad3aa1ab75dee5356645ec7f2ea832fb2aca6e9a32b19d64abeb9e3d57c4195f1e50 languageName: node linkType: hard -"@docusaurus/plugin-content-blog@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/plugin-content-blog@npm:2.2.0" +"@docusaurus/plugin-content-blog@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/plugin-content-blog@npm:2.3.1" dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/logger": 2.2.0 - "@docusaurus/mdx-loader": 2.2.0 - "@docusaurus/types": 2.2.0 - "@docusaurus/utils": 2.2.0 - "@docusaurus/utils-common": 2.2.0 - "@docusaurus/utils-validation": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/logger": 2.3.1 + "@docusaurus/mdx-loader": 2.3.1 + "@docusaurus/types": 2.3.1 + "@docusaurus/utils": 2.3.1 + "@docusaurus/utils-common": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 cheerio: ^1.0.0-rc.12 feed: ^4.2.2 fs-extra: ^10.1.0 @@ -1836,21 +1836,21 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 6d51e3b17b6fdeb4e04ddebe4d4ba8c7cc830bdc066c2b7898e4dee185e408f0d28ea873d18b5ee4406a568a9b05f70d17c986a9ed16b16b1450d34ca190fd06 + checksum: abc668ceab15269f57be7f74acbec2e139b4f6b90af8771d246a9036d124b49b0d9fd4890e9566df7a4ba960f2da0316c18741eed1be0646f2b4602465219ddd languageName: node linkType: hard -"@docusaurus/plugin-content-docs@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/plugin-content-docs@npm:2.2.0" +"@docusaurus/plugin-content-docs@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/plugin-content-docs@npm:2.3.1" dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/logger": 2.2.0 - "@docusaurus/mdx-loader": 2.2.0 - "@docusaurus/module-type-aliases": 2.2.0 - "@docusaurus/types": 2.2.0 - "@docusaurus/utils": 2.2.0 - "@docusaurus/utils-validation": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/logger": 2.3.1 + "@docusaurus/mdx-loader": 2.3.1 + "@docusaurus/module-type-aliases": 2.3.1 + "@docusaurus/types": 2.3.1 + "@docusaurus/utils": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 "@types/react-router-config": ^5.0.6 combine-promises: ^1.1.0 fs-extra: ^10.1.0 @@ -1863,116 +1863,132 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 3a262b49dd6f9d59f4e10dd25185bb4280dbf77b62e28a1dd658d5db0861ae8c82dd025f24212f0d8fec0a46a37f6ef0f2cde25ac736d445247e8727177da660 + checksum: bcf8d921407d11b497926a1f61a1dc8c96f82fbe5a1959cc106b082e555f8fb6f42cf9262a658acf33d9543e5eb3e778049d91f71e4a2855993dc759c845cf31 languageName: node linkType: hard -"@docusaurus/plugin-content-pages@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/plugin-content-pages@npm:2.2.0" +"@docusaurus/plugin-content-pages@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/plugin-content-pages@npm:2.3.1" dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/mdx-loader": 2.2.0 - "@docusaurus/types": 2.2.0 - "@docusaurus/utils": 2.2.0 - "@docusaurus/utils-validation": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/mdx-loader": 2.3.1 + "@docusaurus/types": 2.3.1 + "@docusaurus/utils": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 fs-extra: ^10.1.0 tslib: ^2.4.0 webpack: ^5.73.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 1e22fb8deb9b8f612ebe1ea6f8b1ce76acfc6eb8cbc0d5fc9b99b99d64e2f356d0fb136247e9f72cd84b2788eaf953a640d23ff7e2a5d650de6ec06468181a94 + checksum: 8543050ed7330f54a28c0daeef11662eed3f3a08a6d0015b1a32db3d5e9ec46f0c6a8a5a4cb3e871ce953074d60424cc418b7ffa280695294626855a7a1a146a languageName: node linkType: hard -"@docusaurus/plugin-debug@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/plugin-debug@npm:2.2.0" +"@docusaurus/plugin-debug@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/plugin-debug@npm:2.3.1" dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/types": 2.2.0 - "@docusaurus/utils": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/types": 2.3.1 + "@docusaurus/utils": 2.3.1 fs-extra: ^10.1.0 react-json-view: ^1.21.3 tslib: ^2.4.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: edf2a416b790591c66ffa8ca1fd4ed15ab2d2dc15cd67c5253714502a6828739a7a47996c3664731c6b24da1da5862ddfef60defb84bd3b8273313267db0cb54 + checksum: e660575f900eedbeab6e222eb4f8ef6a7a49815c91a97839a4839737c0b3101698bf7c6e035cbafaa49010340010a9ec0d37270dc81a470b3bae42662c7a24b8 languageName: node linkType: hard -"@docusaurus/plugin-google-analytics@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/plugin-google-analytics@npm:2.2.0" +"@docusaurus/plugin-google-analytics@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/plugin-google-analytics@npm:2.3.1" dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/types": 2.2.0 - "@docusaurus/utils-validation": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/types": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 tslib: ^2.4.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 44ad3a6c1b661516cb87553103565af64a6f145d823b16882d5c7d23b99e091b7c4ba8323c5f6fe756e70fbb0f9f31d56c74512dc17da6d3c16dfabd17d719ac + checksum: 9306ae89cd5fb8ca86fd58809d7e624f988411d8908a151e9b6d9e8d0b84e08f1e3eba46024bc4321bcaeb3e9bc38e919b0bcf561adc9d40fa97c8ffeb232888 languageName: node linkType: hard -"@docusaurus/plugin-google-gtag@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/plugin-google-gtag@npm:2.2.0" +"@docusaurus/plugin-google-gtag@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/plugin-google-gtag@npm:2.3.1" dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/types": 2.2.0 - "@docusaurus/utils-validation": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/types": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 tslib: ^2.4.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 4e7d6fcc3f30f1d54933fdeb59d3065989596e91940304965635867808d89c7b864a394f5fab2bcde98037539bf6840efc692e856fb7a4ae32ce8b5f8a4e191a + checksum: 494f0405d79aa9cb36d1ea4cf739499ad15b59fe876573ab5b304b5e84ab6ef4d428ebdc26647777b0816af452f62959b5ddb25e5bbf73c7fb3d6568258980d0 languageName: node linkType: hard -"@docusaurus/plugin-sitemap@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/plugin-sitemap@npm:2.2.0" +"@docusaurus/plugin-google-tag-manager@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/plugin-google-tag-manager@npm:2.3.1" dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/logger": 2.2.0 - "@docusaurus/types": 2.2.0 - "@docusaurus/utils": 2.2.0 - "@docusaurus/utils-common": 2.2.0 - "@docusaurus/utils-validation": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/types": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 + tslib: ^2.4.0 + peerDependencies: + react: ^16.8.4 || ^17.0.0 + react-dom: ^16.8.4 || ^17.0.0 + checksum: d0b2ccc212652bb4f1c1bd61420e7f235325d4f2e8de0f5b25282305f54209d05da981c1253325bcae9afbc7575bd5c246d037d2be5fbda06f2842ba8335ab47 + languageName: node + linkType: hard + +"@docusaurus/plugin-sitemap@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/plugin-sitemap@npm:2.3.1" + dependencies: + "@docusaurus/core": 2.3.1 + "@docusaurus/logger": 2.3.1 + "@docusaurus/types": 2.3.1 + "@docusaurus/utils": 2.3.1 + "@docusaurus/utils-common": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 fs-extra: ^10.1.0 sitemap: ^7.1.1 tslib: ^2.4.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 8ae78093d17a96fc2c6f3829d425731dae3af19b0eec29c61a6465342462a8c24da4c5a10f1a1b1813630d2408f2e11fa17af652b74b4e8fda975d4a00bf1389 + checksum: 667d2abbf46efffc4d20e38fe435a19392f07726446193a017306652ee9db3d478e971eefb209e1a5c243b6b82af3de72d4b975b8e74aa93bda4711ce8c309bc languageName: node linkType: hard -"@docusaurus/preset-classic@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/preset-classic@npm:2.2.0" +"@docusaurus/preset-classic@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/preset-classic@npm:2.3.1" dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/plugin-content-blog": 2.2.0 - "@docusaurus/plugin-content-docs": 2.2.0 - "@docusaurus/plugin-content-pages": 2.2.0 - "@docusaurus/plugin-debug": 2.2.0 - "@docusaurus/plugin-google-analytics": 2.2.0 - "@docusaurus/plugin-google-gtag": 2.2.0 - "@docusaurus/plugin-sitemap": 2.2.0 - "@docusaurus/theme-classic": 2.2.0 - "@docusaurus/theme-common": 2.2.0 - "@docusaurus/theme-search-algolia": 2.2.0 - "@docusaurus/types": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/plugin-content-blog": 2.3.1 + "@docusaurus/plugin-content-docs": 2.3.1 + "@docusaurus/plugin-content-pages": 2.3.1 + "@docusaurus/plugin-debug": 2.3.1 + "@docusaurus/plugin-google-analytics": 2.3.1 + "@docusaurus/plugin-google-gtag": 2.3.1 + "@docusaurus/plugin-google-tag-manager": 2.3.1 + "@docusaurus/plugin-sitemap": 2.3.1 + "@docusaurus/theme-classic": 2.3.1 + "@docusaurus/theme-common": 2.3.1 + "@docusaurus/theme-search-algolia": 2.3.1 + "@docusaurus/types": 2.3.1 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 70214f17766097a2e9c4b21a343bf323f7ed3d2e23c6169577cd14333a074fa15aabff6532c1774ec17c54f50c1616dbd8625c41a115d2fe799b2b7fa830c2c9 + checksum: e4128a1bcb64d5ced04a281476ec1ae2d5523040d41ed57a8f744fb83659a2a2be902e94989de69ab1e6d693ec26c60d1ef6b2fe3ec96d5af6c9b3ef58f5b0cd languageName: node linkType: hard @@ -1988,22 +2004,22 @@ __metadata: languageName: node linkType: hard -"@docusaurus/theme-classic@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/theme-classic@npm:2.2.0" +"@docusaurus/theme-classic@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/theme-classic@npm:2.3.1" dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/mdx-loader": 2.2.0 - "@docusaurus/module-type-aliases": 2.2.0 - "@docusaurus/plugin-content-blog": 2.2.0 - "@docusaurus/plugin-content-docs": 2.2.0 - "@docusaurus/plugin-content-pages": 2.2.0 - "@docusaurus/theme-common": 2.2.0 - "@docusaurus/theme-translations": 2.2.0 - "@docusaurus/types": 2.2.0 - "@docusaurus/utils": 2.2.0 - "@docusaurus/utils-common": 2.2.0 - "@docusaurus/utils-validation": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/mdx-loader": 2.3.1 + "@docusaurus/module-type-aliases": 2.3.1 + "@docusaurus/plugin-content-blog": 2.3.1 + "@docusaurus/plugin-content-docs": 2.3.1 + "@docusaurus/plugin-content-pages": 2.3.1 + "@docusaurus/theme-common": 2.3.1 + "@docusaurus/theme-translations": 2.3.1 + "@docusaurus/types": 2.3.1 + "@docusaurus/utils": 2.3.1 + "@docusaurus/utils-common": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 "@mdx-js/react": ^1.6.22 clsx: ^1.2.1 copy-text-to-clipboard: ^3.0.1 @@ -2020,20 +2036,20 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: ccfb0bef12178d0fbe3329a3238cd6bf7223ee03d890594676c06490eabfd59908bb1872c1a007f605db4edf402bc49cdf14aa7116550e95844d5135a92c2969 + checksum: 273812924fc29b2316aff554ae0302509ebeaca5aa829b58253e74d22a66e69444f1c324a2d5e8e170e6c6f27dd0d6927e6c6a22a7e0c14567ff777d04a5b0c1 languageName: node linkType: hard -"@docusaurus/theme-common@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/theme-common@npm:2.2.0" +"@docusaurus/theme-common@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/theme-common@npm:2.3.1" dependencies: - "@docusaurus/mdx-loader": 2.2.0 - "@docusaurus/module-type-aliases": 2.2.0 - "@docusaurus/plugin-content-blog": 2.2.0 - "@docusaurus/plugin-content-docs": 2.2.0 - "@docusaurus/plugin-content-pages": 2.2.0 - "@docusaurus/utils": 2.2.0 + "@docusaurus/mdx-loader": 2.3.1 + "@docusaurus/module-type-aliases": 2.3.1 + "@docusaurus/plugin-content-blog": 2.3.1 + "@docusaurus/plugin-content-docs": 2.3.1 + "@docusaurus/plugin-content-pages": 2.3.1 + "@docusaurus/utils": 2.3.1 "@types/history": ^4.7.11 "@types/react": "*" "@types/react-router-config": "*" @@ -2041,30 +2057,31 @@ __metadata: parse-numeric-range: ^1.3.0 prism-react-renderer: ^1.3.5 tslib: ^2.4.0 + use-sync-external-store: ^1.2.0 utility-types: ^3.10.0 peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 23cbba8e7e24494c6d106ce3d0b90ef461580bfacef9f27dfbc4f0b33fcb349394faf2bedf0a44db8c455535e50e828e82270c8f159c3d8d60f0e0980170be4e + checksum: 6b902e9e782721c3c49bcdee5d969ea1c1138ebcb03891e34f827b16f2c06f43a86d95f240a60ed084539e9b16435312a41be7bff4e724f4fb209998dd4d3a59 languageName: node linkType: hard -"@docusaurus/theme-search-algolia@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/theme-search-algolia@npm:2.2.0" +"@docusaurus/theme-search-algolia@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/theme-search-algolia@npm:2.3.1" dependencies: "@docsearch/react": ^3.1.1 - "@docusaurus/core": 2.2.0 - "@docusaurus/logger": 2.2.0 - "@docusaurus/plugin-content-docs": 2.2.0 - "@docusaurus/theme-common": 2.2.0 - "@docusaurus/theme-translations": 2.2.0 - "@docusaurus/utils": 2.2.0 - "@docusaurus/utils-validation": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/logger": 2.3.1 + "@docusaurus/plugin-content-docs": 2.3.1 + "@docusaurus/theme-common": 2.3.1 + "@docusaurus/theme-translations": 2.3.1 + "@docusaurus/utils": 2.3.1 + "@docusaurus/utils-validation": 2.3.1 algoliasearch: ^4.13.1 algoliasearch-helper: ^3.10.0 clsx: ^1.2.1 - eta: ^1.12.3 + eta: ^2.0.0 fs-extra: ^10.1.0 lodash: ^4.17.21 tslib: ^2.4.0 @@ -2072,23 +2089,23 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 42b6cb0322d6c772b7796ea6e9693d596554ebd087792ad71238cebedf3b632bfa8005138d521bce1ff118f49aea7d72e5dc97a03f236b4728a2dc7576870071 + checksum: 965303068e43b11f58d20b95bb6dfc01d5e575c2070d2730b94303bd2a1d33794075cae43bfe472f08061bd8770f14c8eb54932274e6b39f954ab34e7cfc5689 languageName: node linkType: hard -"@docusaurus/theme-translations@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/theme-translations@npm:2.2.0" +"@docusaurus/theme-translations@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/theme-translations@npm:2.3.1" dependencies: fs-extra: ^10.1.0 tslib: ^2.4.0 - checksum: 7fe7d104fd094f2af2321986a86edef1eb8ab25415ea94ab1b242d08aec7627b3d5790001631621cd80c57c710714308aad5adfbf570cb74e0f01fda93b610be + checksum: dd3796be63c4c946af789c3da18ed2704a2fa90d8e752ba2b780a124dc13369ba590218afad0ac4ea2342f7331ccb9eb1be086226c950b8384978d94a15c57ad languageName: node linkType: hard -"@docusaurus/types@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/types@npm:2.2.0" +"@docusaurus/types@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/types@npm:2.3.1" dependencies: "@types/history": ^4.7.11 "@types/react": "*" @@ -2101,13 +2118,13 @@ __metadata: peerDependencies: react: ^16.8.4 || ^17.0.0 react-dom: ^16.8.4 || ^17.0.0 - checksum: 5166ca49bb9333e4d733e4bf8d49d65e11ea6b39e4d8eecc24e1de24d61d2459c52dd8bd27362b66b03e41df96acf1a449145211b3bf0c5a59a987c77102e8f1 + checksum: 91e52f37b97964112aa0d50ee4a6f534d7da941443af5ddc96418817c6ce532a98c73e67045ac703b582c7ed703ebb360205eec30da7f738c0105f2b3ae1a246 languageName: node linkType: hard -"@docusaurus/utils-common@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/utils-common@npm:2.2.0" +"@docusaurus/utils-common@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/utils-common@npm:2.3.1" dependencies: tslib: ^2.4.0 peerDependencies: @@ -2115,29 +2132,30 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: 05d23a2f82a1bc119e3ad6b37481c9bc984f62efd3a79046567216784b78fb20fe7452252d610bb4c063e4ded8a7ab7efa1dc9f9f228357c20b9f4729c7a0576 + checksum: 405dc5b8aba9a97b2670ba8ff3911bbdaed274edc15214ab482a7159a07ad1c9b3198835a7bee42de4e0320d42bd402ed89ae6896744a364d64d89d9f78bcfb0 languageName: node linkType: hard -"@docusaurus/utils-validation@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/utils-validation@npm:2.2.0" +"@docusaurus/utils-validation@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/utils-validation@npm:2.3.1" dependencies: - "@docusaurus/logger": 2.2.0 - "@docusaurus/utils": 2.2.0 + "@docusaurus/logger": 2.3.1 + "@docusaurus/utils": 2.3.1 joi: ^17.6.0 js-yaml: ^4.1.0 tslib: ^2.4.0 - checksum: a30e47cf84628950176cc02a121f31b200b46cdccf02e80d76f24b51b9d33fccee35c43047f507b8fb48deb38f863580ecbcdc1393718c6f3a14fcd40d5d1ab6 + checksum: 1e5529d1d0c4fcd9006adf2e5b545458a7dba3877563fb444dcec472f27a3d8492d4c6fb5dd1071bb6e668a13a845d74b8f6c4b6387babfa0e467a9b8b237fda languageName: node linkType: hard -"@docusaurus/utils@npm:2.2.0": - version: 2.2.0 - resolution: "@docusaurus/utils@npm:2.2.0" +"@docusaurus/utils@npm:2.3.1": + version: 2.3.1 + resolution: "@docusaurus/utils@npm:2.3.1" dependencies: - "@docusaurus/logger": 2.2.0 + "@docusaurus/logger": 2.3.1 "@svgr/webpack": ^6.2.1 + escape-string-regexp: ^4.0.0 file-loader: ^6.2.0 fs-extra: ^10.1.0 github-slugger: ^1.4.0 @@ -2156,7 +2174,7 @@ __metadata: peerDependenciesMeta: "@docusaurus/types": optional: true - checksum: d027a6d2417e043ac463402aadca22f1101f942daaf02330d9bb4743dcbe3bd2fd46d27dedf316fcf2b6698713fede974ba59eb5d4bc92c8959e23bc25e7a03a + checksum: e8bce9bbd98bf63664fcd7c0a5f8dec30dad31ed19e18d724b43189b04ecdc1174537e1d987293575ec18d421236fb92d3d39d28477e921507260a39c3f6d6d0 languageName: node linkType: hard @@ -2382,9 +2400,9 @@ __metadata: linkType: hard "@sideway/formula@npm:^3.0.0": - version: 3.0.0 - resolution: "@sideway/formula@npm:3.0.0" - checksum: 8ae26a0ed6bc84f7310be6aae6eb9d81e97f382619fc69025d346871a707eaab0fa38b8c857e3f0c35a19923de129f42d35c50b8010c928d64aab41578580ec4 + version: 3.0.1 + resolution: "@sideway/formula@npm:3.0.1" + checksum: e4beeebc9dbe2ff4ef0def15cec0165e00d1612e3d7cea0bc9ce5175c3263fc2c818b679bd558957f49400ee7be9d4e5ac90487e1625b4932e15c4aa7919c57a languageName: node linkType: hard @@ -2585,6 +2603,115 @@ __metadata: languageName: node linkType: hard +"@swc/core-darwin-arm64@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-darwin-arm64@npm:1.3.36" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-darwin-x64@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-darwin-x64@npm:1.3.36" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@swc/core-linux-arm-gnueabihf@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.36" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@swc/core-linux-arm64-gnu@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.36" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-arm64-musl@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.36" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-linux-x64-gnu@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.36" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-x64-musl@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-x64-musl@npm:1.3.36" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-win32-arm64-msvc@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.36" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-win32-ia32-msvc@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.36" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@swc/core-win32-x64-msvc@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.36" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@swc/core@npm:^1.3.36": + version: 1.3.36 + resolution: "@swc/core@npm:1.3.36" + dependencies: + "@swc/core-darwin-arm64": 1.3.36 + "@swc/core-darwin-x64": 1.3.36 + "@swc/core-linux-arm-gnueabihf": 1.3.36 + "@swc/core-linux-arm64-gnu": 1.3.36 + "@swc/core-linux-arm64-musl": 1.3.36 + "@swc/core-linux-x64-gnu": 1.3.36 + "@swc/core-linux-x64-musl": 1.3.36 + "@swc/core-win32-arm64-msvc": 1.3.36 + "@swc/core-win32-ia32-msvc": 1.3.36 + "@swc/core-win32-x64-msvc": 1.3.36 + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm-gnueabihf": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + checksum: 36e96e86d1ab8fd84eb51e7264a7ae781ee7e507d36b9ccc028d7f31a2ccf2949f074656e34139c970196774d24d55a54c3aa5c53d04eb6e3569c71cbfed0c0d + languageName: node + linkType: hard + "@szmarczak/http-timer@npm:^1.1.2": version: 1.1.2 resolution: "@szmarczak/http-timer@npm:1.1.2" @@ -2608,6 +2735,13 @@ __metadata: languageName: node linkType: hard +"@tsconfig/docusaurus@npm:^1.0.6": + version: 1.0.6 + resolution: "@tsconfig/docusaurus@npm:1.0.6" + checksum: fb0d7965c01fe64fc6369a72695b903d654bd5fb145f373d707c2bae3c2d828703517d812cef1c041ae44b108f44e52778b9d9837a54fdf782e68e6619a90a4d + languageName: node + linkType: hard + "@types/body-parser@npm:*": version: 1.19.2 resolution: "@types/body-parser@npm:1.19.2" @@ -2951,6 +3085,13 @@ __metadata: languageName: node linkType: hard +"@types/webpack-env@npm:^1.18.0": + version: 1.18.0 + resolution: "@types/webpack-env@npm:1.18.0" + checksum: ecf4daa31cb37d474ac0ce058d83a3cadeb9881ca8107ae93c2299eaa9954943aae09b43e143c62ccbe4288a14db00c918c9debd707afe17c3998f873eaabc59 + languageName: node + linkType: hard + "@types/ws@npm:^8.5.1": version: 8.5.3 resolution: "@types/ws@npm:8.5.3" @@ -3565,15 +3706,24 @@ __metadata: version: 0.0.0-use.local resolution: "backstage-microsite@workspace:." dependencies: - "@docusaurus/core": 2.2.0 - "@docusaurus/preset-classic": 2.2.0 + "@docusaurus/core": 2.3.1 + "@docusaurus/module-type-aliases": 2.3.1 + "@docusaurus/preset-classic": 2.3.1 "@spotify/prettier-config": ^14.0.0 + "@swc/core": ^1.3.36 + "@tsconfig/docusaurus": ^1.0.6 + "@types/webpack-env": ^1.18.0 clsx: ^1.1.1 + docusaurus-plugin-sass: ^0.2.3 js-yaml: ^4.1.0 prettier: ^2.6.2 react: ^17.0.2 react-dom: ^17.0.2 replace: ^1.2.2 + sass: ^1.57.1 + swc-loader: ^0.2.3 + typescript: ^4.9.4 + yaml-loader: ^0.8.0 languageName: unknown linkType: soft @@ -3939,7 +4089,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.4.2, chokidar@npm:^3.5.3": +"chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.4.2, chokidar@npm:^3.5.3": version: 3.5.3 resolution: "chokidar@npm:3.5.3" dependencies: @@ -4790,6 +4940,18 @@ __metadata: languageName: node linkType: hard +"docusaurus-plugin-sass@npm:^0.2.3": + version: 0.2.3 + resolution: "docusaurus-plugin-sass@npm:0.2.3" + dependencies: + sass-loader: ^10.1.1 + peerDependencies: + "@docusaurus/core": ^2.0.0-beta + sass: ^1.30.0 + checksum: 928b02fd7c63835d54cdcce2eeda01cb6124707c6d43ef8e77db06474d3e3b4b7282cc0d88fed378cf1f3db2fc93ba8c11366965bb9b668eae19ca805e578acb + languageName: node + linkType: hard + "dom-converter@npm:^0.2.0": version: 0.2.0 resolution: "dom-converter@npm:0.2.0" @@ -5114,10 +5276,10 @@ __metadata: languageName: node linkType: hard -"eta@npm:^1.12.3": - version: 1.12.3 - resolution: "eta@npm:1.12.3" - checksum: 390c1cd320755cb98fd5a4a911539e8ed498fc49b82414f0023033ff606d80a34e6df0aeeb9fb0b519b318a750e6d17a72fc25f8a8c686cfc52d638e998237a1 +"eta@npm:^2.0.0": + version: 2.0.0 + resolution: "eta@npm:2.0.0" + checksum: ab8e93af73f0d4917485976aa8fcac68e730c47e9aa54a720c21c2e9087cdcd5f984a50cf5e04d189757612df014a229fa047a437651c9eea31e0b6bf1afe56b languageName: node linkType: hard @@ -6214,6 +6376,13 @@ __metadata: languageName: node linkType: hard +"immutable@npm:^4.0.0": + version: 4.2.2 + resolution: "immutable@npm:4.2.2" + checksum: 4d6437ea9388fe8ceca7eed5c768cf438cda7fa14d2831b87b90aa00cc60d536964d107c255b8a2e5dbf4f44a0e1295afbb9d1f0a65fb4f57b936e71df601862 + languageName: node + linkType: hard + "import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" @@ -6622,6 +6791,13 @@ __metadata: languageName: node linkType: hard +"javascript-stringify@npm:^2.0.1": + version: 2.1.0 + resolution: "javascript-stringify@npm:2.1.0" + checksum: 009981ec84299da88795fc764221ed213e3d52251cc93a396430a7a02ae09f1163a9be36a36808689681a8e6113cf00fe97ec2eea2552df48111f79be59e9358 + languageName: node + linkType: hard + "jest-util@npm:^29.3.1": version: 29.3.1 resolution: "jest-util@npm:29.3.1" @@ -6793,10 +6969,10 @@ __metadata: languageName: node linkType: hard -"klona@npm:^2.0.5": - version: 2.0.5 - resolution: "klona@npm:2.0.5" - checksum: 8c976126ea252b766e648a4866e1bccff9d3b08432474ad80c559f6c7265cf7caede2498d463754d8c88c4759895edd8210c85c0d3155e6aae4968362889466f +"klona@npm:^2.0.4, klona@npm:^2.0.5": + version: 2.0.6 + resolution: "klona@npm:2.0.6" + checksum: ac9ee3732e42b96feb67faae4d27cf49494e8a3bf3fa7115ce242fe04786788e0aff4741a07a45a2462e2079aa983d73d38519c85d65b70ef11447bbc3c58ce7 languageName: node linkType: hard @@ -9214,6 +9390,44 @@ __metadata: languageName: node linkType: hard +"sass-loader@npm:^10.1.1": + version: 10.4.1 + resolution: "sass-loader@npm:10.4.1" + dependencies: + klona: ^2.0.4 + loader-utils: ^2.0.0 + neo-async: ^2.6.2 + schema-utils: ^3.0.0 + semver: ^7.3.2 + peerDependencies: + fibers: ">= 3.1.0" + node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + sass: ^1.3.0 + webpack: ^4.36.0 || ^5.0.0 + peerDependenciesMeta: + fibers: + optional: true + node-sass: + optional: true + sass: + optional: true + checksum: df9a65a62247e95305299ccbdf212cffdcdb69490928aecdf4f3dcf539b5302ed7cbffa663f83c5fc3ce0864decf84257a9ce484f6df4cb4426feeb88445dcd0 + languageName: node + linkType: hard + +"sass@npm:^1.57.1": + version: 1.58.3 + resolution: "sass@npm:1.58.3" + 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: 35a2b98c037ef80fdc93c9b0be846e6ccc7d75596351a37ee79c397e66666d0a754c52c4696e746c0aff32327471e185343ca349e998a58340411adc9d0489a5 + languageName: node + linkType: hard + "sax@npm:^1.2.4": version: 1.2.4 resolution: "sax@npm:1.2.4" @@ -9603,7 +9817,7 @@ __metadata: languageName: node linkType: hard -"source-map-js@npm:^1.0.2": +"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 @@ -9895,6 +10109,16 @@ __metadata: languageName: node linkType: hard +"swc-loader@npm:^0.2.3": + version: 0.2.3 + resolution: "swc-loader@npm:0.2.3" + peerDependencies: + "@swc/core": ^1.2.147 + webpack: ">=2" + checksum: 010d84d399525c0185d36d62c86c55ae017e7a90046bc8a39be4b7e07526924037868049f6037bc966da98151cb2600934b96a66279b742d3c413a718b427251 + languageName: node + linkType: hard + "tapable@npm:^1.0.0": version: 1.1.3 resolution: "tapable@npm:1.1.3" @@ -10092,6 +10316,26 @@ __metadata: languageName: node linkType: hard +"typescript@npm:^4.9.4": + version: 4.9.5 + resolution: "typescript@npm:4.9.5" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: ee000bc26848147ad423b581bd250075662a354d84f0e06eb76d3b892328d8d4440b7487b5a83e851b12b255f55d71835b008a66cbf8f255a11e4400159237db + languageName: node + linkType: hard + +"typescript@patch:typescript@^4.9.4#~builtin": + version: 4.9.5 + resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=a1c5e5" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 2eee5c37cad4390385db5db5a8e81470e42e8f1401b0358d7390095d6f681b410f2c4a0c496c6ff9ebd775423c7785cdace7bcdad76c7bee283df3d9718c0f20 + languageName: node + linkType: hard + "ua-parser-js@npm:^0.7.30": version: 0.7.33 resolution: "ua-parser-js@npm:0.7.33" @@ -10391,6 +10635,15 @@ __metadata: languageName: node linkType: hard +"use-sync-external-store@npm:^1.2.0": + version: 1.2.0 + resolution: "use-sync-external-store@npm:1.2.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 5c639e0f8da3521d605f59ce5be9e094ca772bd44a4ce7322b055a6f58eeed8dda3c94cabd90c7a41fb6fa852210092008afe48f7038792fd47501f33299116a + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -10877,6 +11130,17 @@ __metadata: languageName: node linkType: hard +"yaml-loader@npm:^0.8.0": + version: 0.8.0 + resolution: "yaml-loader@npm:0.8.0" + dependencies: + javascript-stringify: ^2.0.1 + loader-utils: ^2.0.0 + yaml: ^2.0.0 + checksum: d12dd264666b80baec23cea9f81cb677a9102d6f34ab45d8b6c085ace4d05b7285db9ce317db57264c3317af01128ce6e5b754e6866d15ccd75e8141902fb529 + languageName: node + linkType: hard + "yaml@npm:^1.10.0, yaml@npm:^1.10.2, yaml@npm:^1.7.2": version: 1.10.2 resolution: "yaml@npm:1.10.2" @@ -10884,6 +11148,13 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.0.0": + version: 2.2.1 + resolution: "yaml@npm:2.2.1" + checksum: 84f68cbe462d5da4e7ded4a8bded949ffa912bc264472e5a684c3d45b22d8f73a3019963a32164023bdf3d83cfb6f5b58ff7b2b10ef5b717c630f40bd6369a23 + languageName: node + linkType: hard + "yargs-parser@npm:^18.1.2": version: 18.1.3 resolution: "yargs-parser@npm:18.1.3" diff --git a/microsite/blog/2020-03-18-what-is-backstage.md b/microsite/blog/2020-03-18-what-is-backstage.md index 2c2b81d64d..5e3ec4ac90 100644 --- a/microsite/blog/2020-03-18-what-is-backstage.md +++ b/microsite/blog/2020-03-18-what-is-backstage.md @@ -85,4 +85,4 @@ We are envisioning [three phases](https://github.com/backstage/backstage/milesto https://github.com/backstage/backstage/milestones -Want to discuss the project or need support? Join us on [Discord](https://discord.gg/MUpMjP2) or reach out on [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com). +Want to discuss the project or need support? Join us on [Discord](https://discord.gg/backstage-687207715902193673) or reach out on [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com). diff --git a/microsite/blog/2020-04-30-how-to-quickly-set-up-backstage.md b/microsite/blog/2020-04-30-how-to-quickly-set-up-backstage.md index 17f095f1fb..7d5098a721 100644 --- a/microsite/blog/2020-04-30-how-to-quickly-set-up-backstage.md +++ b/microsite/blog/2020-04-30-how-to-quickly-set-up-backstage.md @@ -125,4 +125,4 @@ If you are developing a plugin that might be useful for others, consider releasi ## Ready to get started? -Head over to GitHub and check out the [project](https://github.com/backstage/backstage) or download our [CLI](https://www.npmjs.com/package/@backstage/cli). If you have more questions, join us on [Discord](https://discord.gg/MUpMjP2) or [create an issue](https://github.com/backstage/backstage/issues/new/choose). +Head over to GitHub and check out the [project](https://github.com/backstage/backstage) or download our [CLI](https://www.npmjs.com/package/@backstage/cli). If you have more questions, join us on [Discord](https://discord.gg/backstage-687207715902193673) or [create an issue](https://github.com/backstage/backstage/issues/new/choose). diff --git a/microsite/blog/2020-06-22-backstage-service-catalog-alpha.md b/microsite/blog/2020-06-22-backstage-service-catalog-alpha.md index 7f8fe01e11..0f324cd5be 100644 --- a/microsite/blog/2020-06-22-backstage-service-catalog-alpha.md +++ b/microsite/blog/2020-06-22-backstage-service-catalog-alpha.md @@ -49,6 +49,6 @@ Alpha is our shorthand for "we don’t yet think Backstage is ready for producti As with most alpha releases, you should expect things to change quite a lot until we reach the beta stage (we’re targeting the end of summer). There are obviously many things missing as well, but we wanted to start collecting feedback early and make it easier to see the end-to-end flow. -If you have feedback or questions, please open a [GitHub issue](https://github.com/backstage/backstage/issues), ping us on [Discord chat](https://discord.gg/EBHEGzX) or send us an email at [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com) 🙏 +If you have feedback or questions, please open a [GitHub issue](https://github.com/backstage/backstage/issues), ping us on [Discord chat](https://discord.gg/backstage-687207715902193673) or send us an email at [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com) 🙏 To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://info.backstage.spotify.com/newsletter_subscribe). diff --git a/microsite/blog/2020-08-05-announcing-backstage-software-templates.md b/microsite/blog/2020-08-05-announcing-backstage-software-templates.md index 18bfa64c19..6acefa571c 100644 --- a/microsite/blog/2020-08-05-announcing-backstage-software-templates.md +++ b/microsite/blog/2020-08-05-announcing-backstage-software-templates.md @@ -73,6 +73,6 @@ Backstage ships with four example templates, but since these are likely not the We have learned that one of the keys to getting these standards adopted is to keep an open process. Templates are code. By making it clear to your engineers that you are open to pull requests, and that teams with different needs can add their own templates, you are on the path of striking a good balance between autonomy and standardization. -If you have feedback or questions, please open a [GitHub issue](https://github.com/backstage/backstage/issues), ping us on [Discord chat](https://discord.gg/EBHEGzX) or send us an email at [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com) 🙏 +If you have feedback or questions, please open a [GitHub issue](https://github.com/backstage/backstage/issues), ping us on [Discord chat](https://discord.gg/backstage-687207715902193673) or send us an email at [backstage-interest@spotify.com](mailto:backstage-interest@spotify.com) 🙏 To get regular product updates and news about the Backstage community, sign up for the [Backstage newsletter](https://info.backstage.spotify.com/newsletter_subscribe). diff --git a/microsite/blog/2021-01-12-new-backstage-feature-kubernetes-for-service-owners.md b/microsite/blog/2021-01-12-new-backstage-feature-kubernetes-for-service-owners.md index 8981f276be..7b0686aae7 100644 --- a/microsite/blog/2021-01-12-new-backstage-feature-kubernetes-for-service-owners.md +++ b/microsite/blog/2021-01-12-new-backstage-feature-kubernetes-for-service-owners.md @@ -70,4 +70,4 @@ To contribute or get more information on Kubernetes in Backstage, [join the disc [here]: https://github.com/backstage/backstage/issues?q=is%3Aissue+is%3Aopen+kubernetes+label%3Ak8s-plugin [read the docs]: https://backstage.io/docs/features/kubernetes/overview -[join the discussion on discord]: https://discord.gg/MUpMjP2 +[join the discussion on discord]: https://discord.gg/backstage-687207715902193673 diff --git a/microsite/blog/2021-06-22-spotify-backstage-is-growing.md b/microsite/blog/2021-06-22-spotify-backstage-is-growing.md index a12ddf7443..35285c5e04 100644 --- a/microsite/blog/2021-06-22-spotify-backstage-is-growing.md +++ b/microsite/blog/2021-06-22-spotify-backstage-is-growing.md @@ -49,7 +49,7 @@ We’ve launched a new website at: [backstage.spotify.com](https://backstage.spo You’ll find a high-level introduction to the platform, tips and tricks tested by Spotify to accelerate developer effectiveness, and access to a group of partners that have scaled Backstage for numerous adopters. You can also use the site to book product overviews, demos, and technical deep dives with members of the Spotify team. -We will continue to post important product announcements, technical documentation, feature demos, and community news here on Backstage.io. ([Subscribe to the newsletter](https://info.backstage.spotify.com/newsletter_subscribe) to stay up to date.) And both contributors and adopting companies can continue to find around-the-clock/around-the-world technical support on [GitHub](https://github.com/backstage/backstage) and [Discord](https://discord.gg/MUpMjP2). +We will continue to post important product announcements, technical documentation, feature demos, and community news here on Backstage.io. ([Subscribe to the newsletter](https://info.backstage.spotify.com/newsletter_subscribe) to stay up to date.) And both contributors and adopting companies can continue to find around-the-clock/around-the-world technical support on [GitHub](https://github.com/backstage/backstage) and [Discord](https://discord.gg/backstage-687207715902193673). ## Separate community sessions for adopters and contributors diff --git a/microsite/blog/2021-06-24-announcing-backstage-search-platform.md b/microsite/blog/2021-06-24-announcing-backstage-search-platform.md index 6914077522..118ac1f43c 100644 --- a/microsite/blog/2021-06-24-announcing-backstage-search-platform.md +++ b/microsite/blog/2021-06-24-announcing-backstage-search-platform.md @@ -99,4 +99,4 @@ We’ve built the foundation for the Backstage Search platform, and we can't wai You can check out our [project roadmap](https://backstage.io/docs/features/search/search-overview#project-roadmap) in our search documentation or track the progress of our [Beta milestone](https://github.com/backstage/backstage/milestone/27) and [GA milestone](https://github.com/backstage/backstage/milestone/28). -For any questions, feedback or ideas about the Backstage Search platform, join us in the #search channel on [Discord](https://discord.gg/MUpMjP2)! +For any questions, feedback or ideas about the Backstage Search platform, join us in the #search channel on [Discord](https://discord.gg/backstage-687207715902193673)! diff --git a/microsite/blog/2021-09-16-the-techdocs-beta-has-landed.md b/microsite/blog/2021-09-16-the-techdocs-beta-has-landed.md index f3f79abf44..27df0b3a44 100644 --- a/microsite/blog/2021-09-16-the-techdocs-beta-has-landed.md +++ b/microsite/blog/2021-09-16-the-techdocs-beta-has-landed.md @@ -61,4 +61,4 @@ If you're upgrading from a prior, alpha version of TechDocs, be aware that there - If you've configured TechDocs to publish generated content to a remote storage solution provider like AWS S3, Google Cloud Storage, or Azure Blob Storage, you will need to use the TechDocs CLI to migrate the contents of your storage bucket. [See full migration instructions here](https://backstage.io/docs/features/techdocs/how-to-guides#how-to-migrate-from-techdocs-alpha-to-beta). - In order to take advantage of the stale file deletion functionality, you may need to add some permissions to the account or role used by your TechDocs backend to publish contents to your storage provider. [See "Using Cloud Storage docs"](https://backstage.io/docs/features/techdocs/using-cloud-storage) for updated permissions recommendations. -Thanks again to the whole community for hitting this milestone with us! Catch us in [Discord](https://discord.gg/MUpMjP2) or an [upcoming community session](https://github.com/backstage/community) if you have any questions. +Thanks again to the whole community for hitting this milestone with us! Catch us in [Discord](https://discord.gg/backstage-687207715902193673) or an [upcoming community session](https://github.com/backstage/community) if you have any questions. diff --git a/microsite/blog/2022-03-04-backstage-upgrade-helper.md b/microsite/blog/2022-03-04-backstage-upgrade-helper.md index 80b3b9c0a8..3f4fc6da77 100644 --- a/microsite/blog/2022-03-04-backstage-upgrade-helper.md +++ b/microsite/blog/2022-03-04-backstage-upgrade-helper.md @@ -13,7 +13,7 @@ _TLDR;_ The Spotify team recently announced [Backstage Upgrade Helper](https://b ## Upgrading Backstage was a common pain point -Without a doubt, one of the most exciting things about Backstage is our community. Step into our daily [Discord conversations](https://discord.gg/sBEF5VkG) and the monthly [Community Sessions](https://www.youtube.com/watch?v=0QMQYSTKAx0) and you’ll find a ton of great ideas, problem-solving, and support for one another. +Without a doubt, one of the most exciting things about Backstage is our community. Step into our daily [Discord conversations](https://discord.gg/backstage-687207715902193673) and the monthly [Community Sessions](https://www.youtube.com/watch?v=0QMQYSTKAx0) and you’ll find a ton of great ideas, problem-solving, and support for one another. During one of these discussions, we realized we all shared the same pain point — upgrading a Backstage application. diff --git a/microsite/blog/2022-03-17-backstage-1.0.md b/microsite/blog/2022-03-17-backstage-1.0.md index 02ead0390c..8cc627c127 100644 --- a/microsite/blog/2022-03-17-backstage-1.0.md +++ b/microsite/blog/2022-03-17-backstage-1.0.md @@ -54,6 +54,6 @@ If you want to know more about this first major release, check out the following - [Release notes](https://backstage.io/docs/releases/v1.0.0) and [Changelog](https://github.com/backstage/backstage/releases/tag/v1.0.0). - [Backstage official documentation](https://backstage.io/docs/) and [backstage.spotify.com](https://backstage.spotify.com/). -- [Discord channel](https://discord.gg/EUaBAS58). +- [Discord channel](https://discord.gg/backstage-687207715902193673). - [Backstage repository on GitHub](https://github.com/backstage/backstage). - [List of public adopters](https://github.com/backstage/backstage/blob/master/ADOPTERS.md). diff --git a/microsite/blog/2022-12-19-backstage-wrapped-2022.md b/microsite/blog/2022-12-19-backstage-wrapped-2022.md index 967bc14433..4986b3effd 100644 --- a/microsite/blog/2022-12-19-backstage-wrapped-2022.md +++ b/microsite/blog/2022-12-19-backstage-wrapped-2022.md @@ -20,7 +20,7 @@ Last year we celebrated 75 [public adopters](https://github.com/backstage/backst ![Accelerated growth of Public Backstage Adopters, from January 2021–December 2022.](assets/2022-12-19/public-backstage-adopters-2022.png) -Not only are our adopters growing at an exponential rate, but so too are our contributors. Our [Discord server](https://discord.gg/backstage-687207715902193673) is a perfect example of the worlds of our adopters and contributors melding. On average, at any given hour of the day or night, there are more than 500 people online available to talk and provide support on any Backstage topic. Discord discussions run a full gamut of topics – from technical support questions to best practices for onboarding engineers to Backstage – basically, anything and everything an adopter may be interested to know and learn. At the very beginning of 2022, we “only” had 4k Discord members. Today, we have a growing membership of 8.2k. +Not only are our adopters growing at an exponential rate, but so too are our contributors. Our [Discord server](https://discord.gg/backstage-687207715902193673-687207715902193673) is a perfect example of the worlds of our adopters and contributors melding. On average, at any given hour of the day or night, there are more than 500 people online available to talk and provide support on any Backstage topic. Discord discussions run a full gamut of topics – from technical support questions to best practices for onboarding engineers to Backstage – basically, anything and everything an adopter may be interested to know and learn. At the very beginning of 2022, we “only” had 4k Discord members. Today, we have a growing membership of 8.2k. Isn’t it what we can call a great and vibrant community of enthusiasts? diff --git a/microsite/blog/2023-01-31-incremental-entity-provider.md b/microsite/blog/2023-01-31-incremental-entity-provider.md index c14c3fc15d..fd273af208 100644 --- a/microsite/blog/2023-01-31-incremental-entity-provider.md +++ b/microsite/blog/2023-01-31-incremental-entity-provider.md @@ -4,10 +4,12 @@ author: Paul Cowan & Taras Mankovski authorURL: https://frontside.com/ --- -At the heart of [Backstage](https://backstage.io/) is the [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview), which is a data store that allows an organization to centralize and visualize its many software services and components. Backstage inspects and transforms an organization's disparate software services and parts into a centralized data store. +At the heart of [Backstage](https://backstage.io/) is the [Backstage Software Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview), which is a data store that allows an organization to centralize and visualize its many software services and components. Backstage inspects and transforms an organization's disparate software services and parts into a centralized data store. This blog post introduces the concept of incremental entity providers, which allow Backstage to scale ingestion to even larger datasets. ![catalog pipeline](assets/2023-01-31/catalog-pipeline.png) + + A common use case is for an organization to want to surface ownership and metadata about repositories. Backstage provides a mechanism for discovering and transforming repository information into a standard data structure and persisting it into the Backstage [Catalog](https://backstage.io/docs/features/software-catalog/software-catalog-overview). This process is known as ingestion, where all data is transformed into a standard Backstage data structure known as an entity. Entities in the Catalog’s data store are accessible to the Backstage App via the REST API. Data is transformed into entities via what is known as the ingestion and processing loop, which can be thought of as an [extract, transform and load (ETL) pipeline](https://en.wikipedia.org/wiki/Extract,_transform,_load), where raw data such as GitHub repositories are loaded from GitHub, transformed into entities and outputted to the Catalog. diff --git a/microsite/blog/2023-02-06-whats-ahead-in-2023.md b/microsite/blog/2023-02-06-whats-ahead-in-2023.md index a9f06d9ea0..f989973ca0 100644 --- a/microsite/blog/2023-02-06-whats-ahead-in-2023.md +++ b/microsite/blog/2023-02-06-whats-ahead-in-2023.md @@ -10,6 +10,8 @@ authorURL: https://github.com/leemills83 Okay, everyone. Time to move on from all the 2022 reflections, Top 10 lists, and Wrapped(s), and turn our gaze in the other direction — towards 2023. As the Backstage team moves into the new year, we find ourselves asking those perennial questions: How can we continue to grow and enhance the Backstage community? How can we improve the experience for those adopting Backstage? How can we give the best support to Backstage contributors? + + Well, we don’t have all the answers, but we do have some. So we wanted to share more on three ongoing initiatives aimed at moving the needle forward for these three distinct, yet interrelated, questions. - Grow your influence by climbing the contribution ladder diff --git a/microsite/blog/2023-02-15-backend-system-alpha.md b/microsite/blog/2023-02-15-backend-system-alpha.md new file mode 100644 index 0000000000..9970945f67 --- /dev/null +++ b/microsite/blog/2023-02-15-backend-system-alpha.md @@ -0,0 +1,83 @@ +--- +title: Backstage Backend System Alpha +author: Patrik Oldsberg +authorURL: https://github.com/Rugvip +authorImageURL: https://avatars.githubusercontent.com/u/4984472?v=4 +--- + +![backend system alpha header image](assets/2023-02-15/backend-system-alpha.gif) + +For the past year, the Backstage maintainer team has been spending time to give the [old Backstage backend system](https://backstage.io/docs/plugins/backend-plugin) a much needed revamp. Our goal was not to build something completely new from scratch, but rather to solidify the existing foundations that have grown organically. We wanted to make plugin installation a lot simpler, while maintaining and even improving the ways in which you can customize your backend setups. + +We’re happy to announce that the [v1.11](https://backstage.io/docs/releases/v1.11.0) release includes the public alpha of the [new Backstage backend system](https://backstage.io/docs/backend-system/)! The system has already been available to use for some time, as some of you have already found, but this alpha release marks the point where we are finally ready to encourage widespread adoption by plugin builders. We still don’t recommend that you use this new system in your production setups just yet, more on that later. + + + +## History of the Backstage backend system + +The backend system that we all use today has grown very organically based on all the needs that have been discovered along the journey of the Backstage Open Source project. We started out with a very flexible system that was essentially just a collection of recommended patterns for plugins, along with a couple of common interfaces and utilities. This was largely due to the fact that before it was open sourced, the Backstage backend services at Spotify were all built on top of internal frameworks and practices that we couldn’t bring with us. Back in 2020, we didn’t have a lot of knowledge about what a good backend system for Backstage would look like, so we started off with a highly flexible foundation that would evolve organically over time. + +As Backstage grew across all dimensions of adopter count, community size, code size, and capability, we saw the need to take a step back and reevaluate how Backstage backend plugins are built. About one year ago, the maintainers sat down and started to sketch what a new backend system could look like. + +## Designing the New System + +When we set out on this project, we had a few primary goals. First, we intended to introduce as few new concepts as possible. Our existing system already had a lot of different patterns, and ideally we wanted to only give those patterns names and make them part of the framework. Second, we wanted to keep the backend system recognizable to those familiar with the frontend system. The list of goals goes on, we had a lot of reasons to build this new system, these are a few more important ones: + +- Make it easier to create and maintain backend installations. +- Align how plugins provide points of customization and how those customizations are installed. +- Make it much easier to maintain plugins, in particular keeping the API stable. +- Simplify the process of splitting plugins out into separate deployments with shared environments. +- Improve the local development and testing experience. + +Prioritizing simplicity is often a guiding principle that we use for designs that span multiple ownership roles. We decide on which parts of the system that we think are the most important to have as simple as possible, or, viewed from the opposite end, where in the system we put necessary complexity. In this case, we optimized for keeping the backend setup as simple as possible, followed by modules and plugins, then libraries, and lastly the framework itself. What this guidance means in practice is that when there is complexity that needs to be added to implement a certain feature, we place as much of it as possible within the framework itself, then libraries, plugins and modules, and if absolutely needed, the backend setup. + +To get the Backstage backend system to where we are today, we went through three major stages, starting with some very early high level experimentation. If you’re a fan of Git archaeology, you can see some of our early ideas in [our experiments branch](https://github.com/backstage/backstage/commit/fd3e6b67fef25a04789779700db4c37047d59d1b), as well as the [separate repository](https://github.com/backstage/backend-system-exploration) that we used to explore different ideas together with [Roadie](https://roadie.io/). The output of this work was all presented in an [RFC](https://github.com/backstage/backstage/issues/11611) to gather feedback. + +A few months later as the RFC settled, we resumed work and followed up with an initial implementation. At this point there were still a lot of details in the design to figure out, especially as we started looking at how our existing plugins and services fit into this new system. We identified a lot of aspects that we inevitably didn’t consider in the initial design, and started exploring technical solutions to those problems. There was a lot of zooming in and out, both implementing details and then stepping back and looking at how that affects the broader system and where to go next. This ended up being the most time consuming stage, and we spent several months iterating on this. + +We wrapped up this work just before KubeCon NA 2022, with the full system implemented. The state of the system at this point was presented in our talk on the topic, which you can see just below. Except for a few API tweaks, this is what the system still looks like today. + + + +
    + +The final stage was all about polish, which we picked up at the beginning of this year. By leaving a bit of space between the main implementation, or phase two, and the polish phase, phase three, it was much easier to properly scrutinize our past solutions. We forget a lot of the low level reasoning for changes, and it is easier to step back and reconsider parts of the system. For example, we found that our initial design of the `createServiceFactory` function was unnecessarily complex, and could be made much simpler for most usages. In addition to reviewing all the APIs, we also wrote more documentation to help users, ensured that the local development and testing experience was solid, and double checked that there was a smooth migration path from the old system. + +## Architecture + +Now that you’ve learned about the journey of designing the new system, let’s review the new architecture. This blog includes a brief introduction to the architecture of the new system. If you want to dive deeper, check out our [architecture documentation](https://backstage.io/docs/backend-system/architecture/). + +The backend system has five major building blocks: + +- Backend instances act as dependency injection containers and are the unit of deployment in which you install plugins and modules that you want to use. +- Plugins implement the actual features and main business logic, for example the service catalog. +- Services provide shared utilities for plugins to use, for example logging, database access, and serving HTTP. Services are provided by the backend and can be customized in each backend instance. +- Extension Points serve as an optional API surface for plugins to provide deeper customization, such as installing custom processors in the catalog. It is up to each plugin to define their own extension points. +- Modules extend individual plugins with additional features by interacting with the extension points that the plugins expose. A module might for example implement a single entity provider for the catalog. + +![backend system architecture](assets/2023-02-15/backend-system-architecture.png) + +## Benefits of the New System + +This new system reduced the size of a typical backend installation from hundreds of lines of code to just about two dozen, more than an order of magnitude. This reduction comes from shifting complexity away from the backend installation and into the plugins, services, and the backend system itself. Not only does this make a typical backend setup much easier to maintain, but it also makes it much easier to build plugins and modules, and leaves fewer patterns to be unnecessarily invented. + +As part of this shift, we’ve moved many concepts from being coding patterns to being features built into the framework. This will allow us to further evolve the backend system in much more interesting ways, and still bring along the entire Backstage plugin ecosystem. It also helps align Backstage plugins around a couple of extensibility patterns, rather than each plugin having their own bespoke patterns for how extensions are installed. + +## Alpha, what does it mean? + +With the release of the backend system into alpha, we are confident enough in the design of the system that we encourage plugin owners to add support for the new system in their plugins. This means following the [plugin migration guide](https://backstage.io/docs/backend-system/building-plugins-and-modules/migrating) and exporting a plugin instance. Do not remove support for the old system yet – keep your existing `createRouter` export intact. + +While we encourage migration of plugins, we do not yet recommend migrating your backend installations to the new system. We want to create space to gather and address feedback from the plugin migration experience, and to make changes if necessary. + +If you are worried about the upcoming backend migration, you can [take a peek](https://backstage.io/docs/backend-system/building-backends/migrating#migrating-the-index-file) at our `legacyPlugin` helper. It allows you to forklift over all existing plugin setups to the new backend system, and then migrate plugins one by one. + +## Next Steps + +During the next release we will keep working on migrating the core plugins, as well as addressing any feedback that we receive. We don’t want to rush a stable release though, and won’t encourage broad adoption until we’re confident that we won’t have to follow it up with immediate breaking changes. Yet, we are excited about where we are today, and are looking forward to the future stable release! + +Useful Links: + +- [Architecture Docs](https://backstage.io/docs/backend-system/architecture/) +- [Building Plugins](https://backstage.io/docs/backend-system/building-plugins-and-modules/) +- [Core Services](https://backstage.io/docs/backend-system/core-services/) +- [#backend-system](https://discord.com/channels/687207715902193673/1034089724664610938) channel in Discord diff --git a/microsite/blog/assets/2023-02-15/backend-system-alpha.gif b/microsite/blog/assets/2023-02-15/backend-system-alpha.gif new file mode 100644 index 0000000000..ca91651e9a Binary files /dev/null and b/microsite/blog/assets/2023-02-15/backend-system-alpha.gif differ diff --git a/microsite/blog/assets/2023-02-15/backend-system-architecture.png b/microsite/blog/assets/2023-02-15/backend-system-architecture.png new file mode 100644 index 0000000000..90c1a495fd Binary files /dev/null and b/microsite/blog/assets/2023-02-15/backend-system-architecture.png differ diff --git a/microsite/core/Footer.js b/microsite/core/Footer.js index 327e42f38a..c93b1779cf 100644 --- a/microsite/core/Footer.js +++ b/microsite/core/Footer.js @@ -40,7 +40,9 @@ class Footer extends React.Component {
    Community
    - Support chatroom + + Support chatroom + Contributing diff --git a/microsite/data/plugins/backstage-kubernetes.yaml b/microsite/data/plugins/backstage-kubernetes.yaml index a070ea99b0..603211eb21 100644 --- a/microsite/data/plugins/backstage-kubernetes.yaml +++ b/microsite/data/plugins/backstage-kubernetes.yaml @@ -4,7 +4,7 @@ author: Spotify authorUrl: https://github.com/spotify category: Core Feature description: Monitor all your service's deployments at a glance, even across clusters. -documentation: https://backstage.io/docs/features/kubernetes/overview +documentation: https://backstage.io/docs/features/kubernetes/ iconUrl: img/backstage-k8s.svg npmPackageName: '@backstage/plugin-kubernetes' order: 4 diff --git a/microsite/data/plugins/backstage-search-platform.yaml b/microsite/data/plugins/backstage-search-platform.yaml index 33faaba310..1488b8a283 100644 --- a/microsite/data/plugins/backstage-search-platform.yaml +++ b/microsite/data/plugins/backstage-search-platform.yaml @@ -4,7 +4,7 @@ author: Spotify authorUrl: https://github.com/spotify category: Core Feature description: A composable and extensible search platform built to fit your organization’s needs and find information quickly. -documentation: https://backstage.io/docs/features/search/search-overview +documentation: https://backstage.io/docs/features/search/ iconUrl: img/backstage-search-platform.svg npmPackageName: '@backstage/plugin-search' order: 5 diff --git a/microsite/data/plugins/backstage-software-catalog.yaml b/microsite/data/plugins/backstage-software-catalog.yaml index e633e17e8e..13dac42e0c 100644 --- a/microsite/data/plugins/backstage-software-catalog.yaml +++ b/microsite/data/plugins/backstage-software-catalog.yaml @@ -4,7 +4,7 @@ author: Spotify authorUrl: https://github.com/spotify category: Core Feature description: Manage all your services and software components, all in one place. -documentation: https://backstage.io/docs/features/software-catalog/software-catalog-overview +documentation: https://backstage.io/docs/features/software-catalog/ iconUrl: img/backstage-software-catalog.svg npmPackageName: '@backstage/plugin-catalog' order: 1 diff --git a/microsite/data/plugins/backstage-software-templates.yaml b/microsite/data/plugins/backstage-software-templates.yaml index f111ee30ce..492f26f97a 100644 --- a/microsite/data/plugins/backstage-software-templates.yaml +++ b/microsite/data/plugins/backstage-software-templates.yaml @@ -4,7 +4,7 @@ author: Spotify authorUrl: https://github.com/spotify category: Core Feature description: Create new software components in just a few steps, with your standards built-in (Scaffolder). -documentation: https://backstage.io/docs/features/software-templates/software-templates-index +documentation: https://backstage.io/docs/features/software-templates/ iconUrl: img/backstage-software-templates.svg npmPackageName: '@backstage/plugin-scaffolder' order: 2 diff --git a/microsite/data/plugins/backstage-techdocs.yaml b/microsite/data/plugins/backstage-techdocs.yaml index 8d89ac5060..f49fe98811 100644 --- a/microsite/data/plugins/backstage-techdocs.yaml +++ b/microsite/data/plugins/backstage-techdocs.yaml @@ -4,7 +4,7 @@ author: Spotify authorUrl: https://github.com/spotify category: Core Feature description: A docs-like-code solution to technical documentation. Write your docs right alongside your code. -documentation: https://backstage.io/docs/features/techdocs/techdocs-overview +documentation: https://backstage.io/docs/features/techdocs/ iconUrl: img/backstage-techdocs.svg npmPackageName: '@backstage/plugin-techdocs' order: 3 diff --git a/microsite/data/plugins/kubevela.yaml b/microsite/data/plugins/kubevela.yaml new file mode 100644 index 0000000000..524a046025 --- /dev/null +++ b/microsite/data/plugins/kubevela.yaml @@ -0,0 +1,15 @@ +--- +title: KubeVela +author: Charlie Chiang +authorUrl: https://github.com/charlie0129 +category: App Delivery +description: KubeVela is a modern software delivery platform that makes deploying and operating applications across today's hybrid, multi-cloud environments easier, faster and more reliable. +documentation: https://github.com/kubevela-contrib/backstage-plugin-kubevela +iconUrl: https://kubevela.io/img/logo.svg +npmPackageName: '@oamdev/plugin-kubevela-backend' +tags: + - cd + - delivery + - multi-cluster + - deployment as code +addedDate: '2023-02-12' diff --git a/microsite/data/plugins/stackstorm.yaml b/microsite/data/plugins/stackstorm.yaml new file mode 100644 index 0000000000..2524ca538f --- /dev/null +++ b/microsite/data/plugins/stackstorm.yaml @@ -0,0 +1,14 @@ +--- +title: StackStorm +author: ExpediaGroup +authorUrl: https://github.com/ExpediaGroup +category: Automation +description: Manage StackStorm workflow executions from within Backstage. +documentation: https://github.com/backstage/backstage/tree/master/plugins/stackstorm +iconUrl: img/stackstorm.png +npmPackageName: '@backstage/plugin-stackstorm' +tags: + - stackstorm + - st2 + - automation + - workflow diff --git a/microsite/pages/en/community.js b/microsite/pages/en/community.js index a5fd5353e0..69330e6569 100644 --- a/microsite/pages/en/community.js +++ b/microsite/pages/en/community.js @@ -62,7 +62,9 @@ const Background = props => {
  • Chat and get support on our{' '} - Discord + + Discord +
  • diff --git a/microsite/pages/en/live.js b/microsite/pages/en/live.js index 166e3bf13a..cad5e52bd2 100644 --- a/microsite/pages/en/live.js +++ b/microsite/pages/en/live.js @@ -58,7 +58,9 @@ const Background = props => { Main community channels
    - Chat and get support on our{' '} - Discord + + Discord +
    - Get into contributing with the{' '} Good First Issues diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 6baeb20e8b..adeb5a6609 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -1,6 +1,7 @@ { "releases": { "Release Notes": [ + "releases/v1.11.0", "releases/v1.10.0", "releases/v1.9.0", "releases/v1.8.0", @@ -104,6 +105,7 @@ "features/software-templates/writing-custom-actions", "features/software-templates/writing-custom-field-extensions", "features/software-templates/writing-custom-step-layouts", + "features/software-templates/testing-scaffolder-alpha", "features/software-templates/migrating-from-v1beta2-to-v1beta3" ] }, diff --git a/microsite/static/.nojekyll b/microsite/static/.nojekyll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/microsite/static/CNAME b/microsite/static/CNAME new file mode 100644 index 0000000000..c3be0f8d9b --- /dev/null +++ b/microsite/static/CNAME @@ -0,0 +1 @@ +backstage.io \ No newline at end of file diff --git a/microsite/static/img/stackstorm.png b/microsite/static/img/stackstorm.png new file mode 100644 index 0000000000..f017906e07 Binary files /dev/null and b/microsite/static/img/stackstorm.png differ diff --git a/mkdocs.yml b/mkdocs.yml index 38369f4748..4b5c2cf7a2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -154,6 +154,7 @@ nav: - Included providers: - Auth0: 'auth/auth0/provider.md' - Azure: 'auth/microsoft/provider.md' + - Azure EasyAuth: 'auth/microsoft/azure-easyauth.md' - GitHub: 'auth/github/provider.md' - GitLab: 'auth/gitlab/provider.md' - Google: 'auth/google/provider.md' diff --git a/package.json b/package.json index 286e750f29..9a60fb9d4a 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "build:backend": "yarn workspace backend build", "build:all": "backstage-cli repo build --all", "build:api-reports": "yarn build:api-reports:only --tsc", - "build:api-reports:only": "backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type", + "build:api-reports:only": "backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", "build:api-docs": "LANG=en_EN yarn build:api-reports --docs", "tsc": "tsc", "tsc:full": "backstage-cli repo clean && tsc --skipLibCheck false --incremental false", @@ -47,7 +47,7 @@ "@types/react": "^17", "@types/react-dom": "^17" }, - "version": "1.11.0-next.2", + "version": "1.12.0-next.0", "dependencies": { "@backstage/errors": "workspace:^", "@manypkg/get-packages": "^1.1.3" diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index e785ffe05a..fe9c1ac9ba 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/app-defaults +## 1.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-permission-react@0.4.11-next.0 + +## 1.2.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-permission-react@0.4.10 + ## 1.1.1-next.1 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 8ffdfd60bc..b9116c21ae 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/app-defaults", "description": "Provides the default wiring of a Backstage App", - "version": "1.1.1-next.1", + "version": "1.2.1-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/app-defaults/src/defaults/apis.ts b/packages/app-defaults/src/defaults/apis.ts index 3f5cfc1c58..d3ebddfb84 100644 --- a/packages/app-defaults/src/defaults/apis.ts +++ b/packages/app-defaults/src/defaults/apis.ts @@ -25,6 +25,7 @@ import { GitlabAuth, MicrosoftAuth, BitbucketAuth, + BitbucketServerAuth, OAuthRequestManager, WebStorage, UrlPatternDiscovery, @@ -53,6 +54,7 @@ import { configApiRef, oneloginAuthApiRef, bitbucketAuthApiRef, + bitbucketServerAuthApiRef, atlassianAuthApiRef, } from '@backstage/core-plugin-api'; import { @@ -219,6 +221,19 @@ export const apis = [ environment: configApi.getOptionalString('auth.environment'), }), }), + createApiFactory({ + api: bitbucketServerAuthApiRef, + deps: { + discoveryApi: discoveryApiRef, + oauthRequestApi: oauthRequestApiRef, + }, + factory: ({ discoveryApi, oauthRequestApi }) => + BitbucketServerAuth.create({ + discoveryApi, + oauthRequestApi, + defaultScopes: ['REPO_READ'], + }), + }), createApiFactory({ api: atlassianAuthApiRef, deps: { diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 818d21840d..78633bc1d9 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,142 @@ # example-app +## 0.2.81-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.1.1-next.0 + - @backstage/cli@0.22.4-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/plugin-techdocs@1.6.0-next.0 + - @backstage/plugin-api-docs@0.9.1-next.0 + - @backstage/plugin-org@0.6.6-next.0 + - @backstage/plugin-stackstorm@0.1.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/plugin-cost-insights@0.12.5-next.0 + - @backstage/plugin-scaffolder@1.11.1-next.0 + - @backstage/plugin-jenkins@0.7.15-next.0 + - @backstage/plugin-playlist@0.1.7-next.0 + - @backstage/plugin-explore@0.4.1-next.0 + - @backstage/plugin-catalog-graph@0.2.28-next.0 + - @backstage/plugin-catalog-import@0.9.6-next.0 + - @backstage/app-defaults@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-airbrake@0.3.16-next.0 + - @backstage/plugin-apache-airflow@0.2.9-next.0 + - @backstage/plugin-azure-devops@0.2.7-next.0 + - @backstage/plugin-azure-sites@0.1.5-next.0 + - @backstage/plugin-badges@0.2.40-next.0 + - @backstage/plugin-circleci@0.3.16-next.0 + - @backstage/plugin-cloudbuild@0.3.16-next.0 + - @backstage/plugin-code-coverage@0.2.9-next.0 + - @backstage/plugin-dynatrace@3.0.0-next.0 + - @backstage/plugin-entity-feedback@0.1.1-next.0 + - @backstage/plugin-gcalendar@0.3.12-next.0 + - @backstage/plugin-gcp-projects@0.3.35-next.0 + - @backstage/plugin-github-actions@0.5.16-next.0 + - @backstage/plugin-gocd@0.1.22-next.0 + - @backstage/plugin-graphiql@0.2.48-next.0 + - @backstage/plugin-home@0.4.32-next.0 + - @backstage/plugin-kafka@0.3.16-next.0 + - @backstage/plugin-kubernetes@0.7.9-next.0 + - @backstage/plugin-lighthouse@0.4.1-next.0 + - @backstage/plugin-linguist@0.1.1-next.0 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/plugin-microsoft-calendar@0.1.1-next.0 + - @backstage/plugin-newrelic@0.3.34-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.9-next.0 + - @backstage/plugin-pagerduty@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.11-next.0 + - @backstage/plugin-rollbar@0.4.16-next.0 + - @backstage/plugin-search@1.1.1-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + - @backstage/plugin-sentry@0.5.1-next.0 + - @backstage/plugin-shortcuts@0.3.8-next.0 + - @backstage/plugin-stack-overflow@0.1.12-next.0 + - @backstage/plugin-tech-insights@0.3.8-next.0 + - @backstage/plugin-tech-radar@0.6.2-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.11-next.0 + - @backstage/plugin-todo@0.2.18-next.0 + - @backstage/plugin-user-settings@0.7.1-next.0 + - @internal/plugin-catalog-customized@0.0.8-next.0 + +## 0.2.80 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.1.0 + - @backstage/plugin-scaffolder@1.11.0 + - @backstage/plugin-azure-devops@0.2.6 + - @backstage/cli@0.22.2 + - @backstage/plugin-techdocs@1.5.0 + - @backstage/core-components@0.12.4 + - @backstage/plugin-microsoft-calendar@0.1.0 + - @backstage/plugin-catalog-graph@0.2.27 + - @backstage/plugin-code-coverage@0.2.8 + - @backstage/plugin-azure-sites@0.1.4 + - @backstage/plugin-lighthouse@0.4.0 + - @backstage/plugin-shortcuts@0.3.7 + - @backstage/plugin-home@0.4.31 + - @backstage/plugin-tech-insights@0.3.7 + - @backstage/plugin-search@1.1.0 + - @backstage/plugin-api-docs@0.9.0 + - @backstage/plugin-entity-feedback@0.1.0 + - @backstage/plugin-tech-radar@0.6.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.10 + - @backstage/plugin-dynatrace@2.0.0 + - @backstage/plugin-playlist@0.1.6 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/plugin-kubernetes@0.7.8 + - @backstage/core-plugin-api@1.4.0 + - @backstage/app-defaults@1.2.0 + - @backstage/plugin-user-settings@0.7.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-pagerduty@0.5.8 + - @backstage/plugin-explore@0.4.0 + - @backstage/plugin-linguist@0.1.0 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/plugin-apache-airflow@0.2.8 + - @backstage/plugin-circleci@0.3.15 + - @backstage/plugin-sentry@0.5.0 + - @backstage/plugin-org@0.6.5 + - @backstage/plugin-cost-insights@0.12.4 + - @backstage/plugin-airbrake@0.3.15 + - @internal/plugin-catalog-customized@0.0.7 + - @backstage/config@1.0.6 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-badges@0.2.39 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-catalog-import@0.9.5 + - @backstage/plugin-cloudbuild@0.3.15 + - @backstage/plugin-gcalendar@0.3.11 + - @backstage/plugin-gcp-projects@0.3.34 + - @backstage/plugin-github-actions@0.5.15 + - @backstage/plugin-gocd@0.1.21 + - @backstage/plugin-graphiql@0.2.47 + - @backstage/plugin-jenkins@0.7.14 + - @backstage/plugin-kafka@0.3.15 + - @backstage/plugin-newrelic@0.3.33 + - @backstage/plugin-newrelic-dashboard@0.2.8 + - @backstage/plugin-permission-react@0.4.10 + - @backstage/plugin-rollbar@0.4.15 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-stack-overflow@0.1.11 + - @backstage/plugin-techdocs-react@1.1.3 + - @backstage/plugin-todo@0.2.17 + ## 0.2.80-next.2 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index afb1738207..7aba203895 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.80-next.2", + "version": "0.2.81-next.0", "private": true, "backstage": { "role": "frontend" @@ -42,6 +42,8 @@ "@backstage/plugin-kafka": "workspace:^", "@backstage/plugin-kubernetes": "workspace:^", "@backstage/plugin-lighthouse": "workspace:^", + "@backstage/plugin-linguist": "workspace:^", + "@backstage/plugin-linguist-common": "workspace:^", "@backstage/plugin-microsoft-calendar": "workspace:^", "@backstage/plugin-newrelic": "workspace:^", "@backstage/plugin-newrelic-dashboard": "workspace:^", @@ -58,6 +60,7 @@ "@backstage/plugin-sentry": "workspace:^", "@backstage/plugin-shortcuts": "workspace:^", "@backstage/plugin-stack-overflow": "workspace:^", + "@backstage/plugin-stackstorm": "workspace:^", "@backstage/plugin-tech-insights": "workspace:^", "@backstage/plugin-tech-radar": "workspace:^", "@backstage/plugin-techdocs": "workspace:^", diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index f789328104..4dacbbc007 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -59,9 +59,9 @@ import { GraphiQLPage } from '@backstage/plugin-graphiql'; import { HomepageCompositionRoot } from '@backstage/plugin-home'; import { LighthousePage } from '@backstage/plugin-lighthouse'; import { NewRelicPage } from '@backstage/plugin-newrelic'; +import { NextScaffolderPage } from '@backstage/plugin-scaffolder/alpha'; import { ScaffolderPage, - NextScaffolderPage, scaffolderPlugin, ScaffolderLayouts, } from '@backstage/plugin-scaffolder'; @@ -104,10 +104,11 @@ import * as plugins from './plugins'; import { techDocsPage } from './components/techdocs/TechDocsPage'; import { ApacheAirflowPage } from '@backstage/plugin-apache-airflow'; import { RequirePermission } from '@backstage/plugin-permission-react'; -import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common'; +import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; import { PlaylistIndexPage } from '@backstage/plugin-playlist'; import { TwoColumnLayout } from './components/scaffolder/customScaffolderLayouts'; import { ScoreBoardPage } from '@oriflame/backstage-plugin-score-card'; +import { StackstormPage } from '@backstage/plugin-stackstorm'; const app = createApp({ apis, @@ -281,6 +282,7 @@ const routes = ( } /> } /> } /> + } /> ); diff --git a/packages/app/src/components/catalog/EntityPage.tsx b/packages/app/src/components/catalog/EntityPage.tsx index 36a8b7553f..d07870194b 100644 --- a/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/app/src/components/catalog/EntityPage.tsx @@ -162,6 +162,10 @@ import { LightBox, } from '@backstage/plugin-techdocs-module-addons-contrib'; import { EntityCostInsightsContent } from '@backstage/plugin-cost-insights'; +import { + isLinguistAvailable, + EntityLinguistCard, +} from '@backstage/plugin-linguist'; const customEntityFilterKind = ['Component', 'API', 'System']; @@ -417,6 +421,14 @@ const overviewContent = ( + + + + + + + + diff --git a/packages/app/src/components/scaffolder/customScaffolderExtensions.tsx b/packages/app/src/components/scaffolder/customScaffolderExtensions.tsx index 8a2e7fba53..b15d12979a 100644 --- a/packages/app/src/components/scaffolder/customScaffolderExtensions.tsx +++ b/packages/app/src/components/scaffolder/customScaffolderExtensions.tsx @@ -17,10 +17,11 @@ import React from 'react'; import type { FieldValidation } from '@rjsf/utils'; import { scaffolderPlugin } from '@backstage/plugin-scaffolder'; import { TextField } from '@material-ui/core'; - import { NextFieldExtensionComponentProps, createNextScaffolderFieldExtension, +} from '@backstage/plugin-scaffolder-react/alpha'; +import { createScaffolderFieldExtension, FieldExtensionComponentProps, } from '@backstage/plugin-scaffolder-react'; diff --git a/packages/app/src/identityProviders.ts b/packages/app/src/identityProviders.ts index 5f8c0faf47..66f1460210 100644 --- a/packages/app/src/identityProviders.ts +++ b/packages/app/src/identityProviders.ts @@ -22,6 +22,7 @@ import { microsoftAuthApiRef, oneloginAuthApiRef, bitbucketAuthApiRef, + bitbucketServerAuthApiRef, } from '@backstage/core-plugin-api'; export const providers = [ @@ -67,4 +68,10 @@ export const providers = [ message: 'Sign In using Bitbucket', apiRef: bitbucketAuthApiRef, }, + { + id: 'bitbucket-server-auth-provider', + title: 'Bitbucket Server', + message: 'Sign In using Bitbucket Server', + apiRef: bitbucketServerAuthApiRef, + }, ]; diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index daae24c717..af7828daac 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,55 @@ # @backstage/backend-app-api +## 0.4.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-node@0.7.6-next.0 + +## 0.4.0 + +### Minor Changes + +- 01a075ec1d: **BREAKING**: Renamed `RootHttpRouterConfigureOptions` to `RootHttpRouterConfigureContext`, and removed the unused type `ServiceOrExtensionPoint`. +- 4ae71b7f2e: **BREAKING** Renaming `*Factory` exports to `*ServiceFactory` instead. For example `configFactory` now is exported as `configServiceFactory`. +- d31d8e00b3: **BREAKING** `HttpServerCertificateOptions` when specified with a `key` and `cert` should also have the `type: 'pem'` instead of `type: 'plain'` + +### Patch Changes + +- a18da2f8b5: Fixed an issue were the log redaction didn't properly escape RegExp characters. +- 5febb216fe: Updated to match the new `CacheService` interface. +- e716946103: Updated usage of the lifecycle service. +- f60cca9da1: Updated database factory to pass service deps required for restoring database state during development. +- 610d65e143: Updates to match new `BackendFeature` type. +- 725383f69d: Tweaked messaging in the README. +- b86efa2d04: Updated usage of `ServiceFactory`. +- ab22515647: The shutdown signal handlers are now installed as part of the backend instance rather than the lifecycle service, and explicitly cause the process to exit. +- b729f9f31f: Moved the options of the `config` and `rootHttpRouter` services out to the factories themselves, where they belong +- ed8b5967d7: `HttpRouterFactoryOptions.getPath` is now optional as a default value is always provided in the factory. +- 71a5ec0f06: Updated usages of `LogMeta`. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/backend-tasks@0.4.3 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-node@0.7.5 + ## 0.4.0-next.2 ### Minor Changes diff --git a/packages/backend-app-api/README.md b/packages/backend-app-api/README.md index ee608ceb43..44705cde52 100644 --- a/packages/backend-app-api/README.md +++ b/packages/backend-app-api/README.md @@ -1,6 +1,6 @@ # @backstage/backend-app-api -**This package is HIGHLY EXPERIMENTAL, do not use this for production** +**This package is EXPERIMENTAL, we recommend against using it for production deployments** This package provides the core API used by Backstage backend apps. @@ -17,3 +17,4 @@ yarn add --cwd packages/backend @backstage/backend-app-api - [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md) - [Backstage Documentation](https://github.com/backstage/backstage/blob/master/docs/README.md) +- [Backstage Backend System](https://backstage.io/docs/backend-system/) diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 3bbae1f7fe..099466aef7 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,14 +1,13 @@ { "name": "@backstage/backend-app-api", "description": "Core API used by Backstage backend apps", - "version": "0.4.0-next.2", + "version": "0.4.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "types": "dist/index.d.ts" }, "backstage": { "role": "node-library" @@ -24,7 +23,7 @@ ], "license": "Apache-2.0", "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 1a495ff771..dc07ac0614 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/backend-common +## 0.18.3-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-app-api@0.4.1-next.0 + - @backstage/backend-dev-utils@0.1.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## 0.18.2 + +### Patch Changes + +- 5febb216fe: **BREAKING**: The `CacheClient` interface must now also implement the `withOptions` method. The `.get()` method has also received a type parameter that helps ensure that `undefined` in the event of a cache miss is handled. + + Added a `cacheToPluginCacheManager` helper that converts a `CacheService` into a legacy `PluginCacheManager` instance. + +- 5febb216fe: Updated to match the new `CacheService` interface. +- e716946103: Updated usage of the lifecycle service. +- d31d8e00b3: Updated to work with the new `type: 'pem'` with `createHttpServer` from `@backstage/backend-app-api` +- 0ff03319be: Updated usage of `createBackendPlugin`. +- f60cca9da1: The `DatabaseManager.forPlugin` method now accepts additional service dependencies. There is no need to update existing code to pass these dependencies. +- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. +- Updated dependencies + - @backstage/backend-app-api@0.4.0 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-dev-utils@0.1.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + ## 0.18.2-next.2 ### Patch Changes diff --git a/packages/backend-common/alpha-api-report.md b/packages/backend-common/alpha-api-report.md new file mode 100644 index 0000000000..9d60b68b6b --- /dev/null +++ b/packages/backend-common/alpha-api-report.md @@ -0,0 +1,32 @@ +## API Report File for "@backstage/backend-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Duration } from 'luxon'; + +// @alpha +export interface Context { + readonly abortSignal: AbortSignal; + readonly deadline: Date | undefined; + value(key: string): T | undefined; +} + +// @alpha +export class Contexts { + static root(): Context; + static withAbort( + parentCtx: Context, + source: AbortController | AbortSignal, + ): Context; + static withTimeoutDuration(parentCtx: Context, timeout: Duration): Context; + static withTimeoutMillis(parentCtx: Context, timeout: number): Context; + static withValue( + parentCtx: Context, + key: string, + value: unknown | ((previous: unknown | undefined) => unknown), + ): Context; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index d21ef30a0b..1cde27877b 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -20,7 +20,6 @@ import { Config } from '@backstage/config'; import { ConfigService } from '@backstage/backend-plugin-api'; import cors from 'cors'; import Docker from 'dockerode'; -import { Duration } from 'luxon'; import { ErrorRequestHandler } from 'express'; import express from 'express'; import { GerritIntegration } from '@backstage/integration'; @@ -211,29 +210,6 @@ export interface ContainerRunner { runContainer(opts: RunContainerOptions): Promise; } -// @alpha -export interface Context { - readonly abortSignal: AbortSignal; - readonly deadline: Date | undefined; - value(key: string): T | undefined; -} - -// @alpha -export class Contexts { - static root(): Context; - static withAbort( - parentCtx: Context, - source: AbortController | AbortSignal, - ): Context; - static withTimeoutDuration(parentCtx: Context, timeout: Duration): Context; - static withTimeoutMillis(parentCtx: Context, timeout: number): Context; - static withValue( - parentCtx: Context, - key: string, - value: unknown | ((previous: unknown | undefined) => unknown), - ): Context; -} - // @public export function createDatabaseClient( dbConfig: Config, diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index 9619ef25f8..28c11e39e0 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,14 +1,26 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.18.2-next.2", + "version": "0.18.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "node-library" @@ -24,7 +36,7 @@ ], "license": "Apache-2.0", "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -120,7 +132,7 @@ "better-sqlite3": "^8.0.0", "http-errors": "^2.0.0", "mock-fs": "^5.1.0", - "msw": "^0.49.0", + "msw": "^1.0.0", "mysql2": "^2.2.5", "recursive-readdir": "^2.2.2", "supertest": "^6.1.3" diff --git a/packages/backend-common/src/alpha.ts b/packages/backend-common/src/alpha.ts new file mode 100644 index 0000000000..e0a5b2ddc2 --- /dev/null +++ b/packages/backend-common/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './context'; diff --git a/packages/backend-common/src/index.ts b/packages/backend-common/src/index.ts index 46639a1923..afb12115b2 100644 --- a/packages/backend-common/src/index.ts +++ b/packages/backend-common/src/index.ts @@ -24,7 +24,6 @@ export { legacyPlugin, makeLegacyPlugin } from './legacy'; export type { LegacyCreateRouter } from './legacy'; export * from './cache'; export { loadBackendConfig } from './config'; -export * from './context'; export * from './database'; export * from './discovery'; export * from './hot'; diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index 89f3ee25c6..e56a19d04a 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/backend-defaults +## 0.1.8-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-app-api@0.4.1-next.0 + +## 0.1.7 + +### Patch Changes + +- 725383f69d: Tweaked messaging in the README. +- e412d33025: Use the new `*ServiceFactory` exports from `@backstage/backend-app-api` +- Updated dependencies + - @backstage/backend-app-api@0.4.0 + - @backstage/backend-plugin-api@0.4.0 + ## 0.1.7-next.2 ### Patch Changes diff --git a/packages/backend-defaults/README.md b/packages/backend-defaults/README.md index 3128159f7c..826994da23 100644 --- a/packages/backend-defaults/README.md +++ b/packages/backend-defaults/README.md @@ -1,8 +1,8 @@ # @backstage/backend-defaults -**This package is HIGHLY EXPERIMENTAL, do not use this for production** +**This package is EXPERIMENTAL, we recommend against using it for production deployments** -This package provides the core API used by Backstage backend apps. +This package provides the default implementations and setup for a standard Backstage backend app. ## Installation @@ -17,3 +17,4 @@ yarn add --cwd packages/backend @backstage/backend-defaults - [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md) - [Backstage Documentation](https://github.com/backstage/backstage/blob/master/docs/README.md) +- [Backstage Backend System](https://backstage.io/docs/backend-system/) diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 2d92d15ab8..b5f6018d64 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-defaults", "description": "Backend defaults used by Backstage backend apps", - "version": "0.1.7-next.2", + "version": "0.1.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { @@ -33,6 +33,7 @@ }, "dependencies": { "@backstage/backend-app-api": "workspace:^", + "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^" }, "devDependencies": { diff --git a/packages/backend-defaults/src/index.ts b/packages/backend-defaults/src/index.ts index b6ae2f1333..833878744e 100644 --- a/packages/backend-defaults/src/index.ts +++ b/packages/backend-defaults/src/index.ts @@ -20,5 +20,10 @@ * @packageDocumentation */ +// This import is here as a workaround for a cyclic dependency bug where +// backend-common must be loaded before backend-app-api +// TODO(Rugvip): Remove this once backend-common is no longer used by backend-app-api +import '@backstage/backend-common'; + export type { CreateBackendOptions } from './CreateBackend'; export { createBackend } from './CreateBackend'; diff --git a/packages/backend-dev-utils/CHANGELOG.md b/packages/backend-dev-utils/CHANGELOG.md index 9acf8cf15f..44238676af 100644 --- a/packages/backend-dev-utils/CHANGELOG.md +++ b/packages/backend-dev-utils/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-dev-utils +## 0.1.0 + +### Minor Changes + +- 9d9cdea117: Introduced a new package for backend development utilities. Similar to how `@backstage/dev-utils` is used in the frontend. + +### Patch Changes + +- 725383f69d: Tweaked messaging in the README. + ## 0.1.0-next.0 ### Minor Changes diff --git a/packages/backend-dev-utils/README.md b/packages/backend-dev-utils/README.md index 8acce94cf0..c60f5a4ad7 100644 --- a/packages/backend-dev-utils/README.md +++ b/packages/backend-dev-utils/README.md @@ -1,5 +1,20 @@ -# backend-dev-utils +# @backstage/backend-dev-utils -Welcome to the backend-dev-utils package! +**This package is EXPERIMENTAL, but we encourage use of it to add support for the new backend system in your own plugins** -_This package is experimental._ +This package helps set up local development environments for Backstage backend packages. + +## Installation + +Add the library to your backend plugin or module package: + +```bash +# From your Backstage root directory +yarn add --cwd plugins/-backend @backstage/backend-dev-utils +``` + +## Documentation + +- [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md) +- [Backstage Documentation](https://github.com/backstage/backstage/blob/master/docs/README.md) +- [Backstage Backend System](https://backstage.io/docs/backend-system/) diff --git a/packages/backend-dev-utils/package.json b/packages/backend-dev-utils/package.json index 6e1cf7d3b0..cb1654d499 100644 --- a/packages/backend-dev-utils/package.json +++ b/packages/backend-dev-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-dev-utils", - "version": "0.1.0-next.0", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/packages/backend-next/CHANGELOG.md b/packages/backend-next/CHANGELOG.md index 9e8f7a2d83..2c40502783 100644 --- a/packages/backend-next/CHANGELOG.md +++ b/packages/backend-next/CHANGELOG.md @@ -1,5 +1,26 @@ # example-backend-next +## 0.0.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-todo-backend@0.1.40-next.0 + - @backstage/plugin-scaffolder-backend@1.11.1-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-defaults@0.1.8-next.0 + - @backstage/plugin-app-backend@0.3.43-next.0 + +## 0.0.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/plugin-scaffolder-backend@1.11.0 + - @backstage/plugin-app-backend@0.3.42 + - @backstage/backend-defaults@0.1.7 + ## 0.0.8-next.2 ### Patch Changes diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index 8f007dc7ea..21ba3550b4 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-next", - "version": "0.0.8-next.2", + "version": "0.0.9-next.0", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,7 +28,8 @@ "@backstage/backend-defaults": "workspace:^", "@backstage/plugin-app-backend": "workspace:^", "@backstage/plugin-catalog-backend": "workspace:^", - "@backstage/plugin-scaffolder-backend": "workspace:^" + "@backstage/plugin-scaffolder-backend": "workspace:^", + "@backstage/plugin-todo-backend": "workspace:^" }, "devDependencies": { "@backstage/cli": "workspace:^" diff --git a/packages/backend-next/src/index.ts b/packages/backend-next/src/index.ts index 97b6eaf32b..8e29244ebf 100644 --- a/packages/backend-next/src/index.ts +++ b/packages/backend-next/src/index.ts @@ -14,14 +14,16 @@ * limitations under the License. */ -import { catalogPlugin } from '@backstage/plugin-catalog-backend'; -import { catalogModuleTemplateKind } from '@backstage/plugin-scaffolder-backend'; +import { catalogPlugin } from '@backstage/plugin-catalog-backend/alpha'; +import { catalogModuleTemplateKind } from '@backstage/plugin-scaffolder-backend/alpha'; import { createBackend } from '@backstage/backend-defaults'; -import { appPlugin } from '@backstage/plugin-app-backend'; +import { appPlugin } from '@backstage/plugin-app-backend/alpha'; +import { todoPlugin } from '@backstage/plugin-todo-backend'; const backend = createBackend(); backend.add(catalogPlugin()); backend.add(catalogModuleTemplateKind()); backend.add(appPlugin({ appPackageName: 'example-app' })); +backend.add(todoPlugin()); backend.start(); diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index f5aa2dd9fc..4dc19db6fc 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/backend-plugin-api +## 0.4.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + +## 0.4.0 + +### Minor Changes + +- e716946103: **BREAKING**: Split out the hook for both lifecycle services so that the first parameter of `addShutdownHook` is the hook function, and the second is the options. +- 0ff03319be: **BREAKING**: The plugin ID option passed to `createBackendPlugin` is now `pluginId`, rather than just `id`. This is to make it match `createBackendModule` more closely. +- 71a5ec0f06: **BREAKING**: Switched out `LogMeta` type for `JsonObject`. +- 5febb216fe: **BREAKING**: The `CacheService` has been changed to remove the indirection of `getClient`, instead making the `CacheClient` methods directly available on the `CacheService`. In order to allow for the creation of clients with default options, there is now a new `.withOptions` method that must be implemented as part of the service interface. +- b86efa2d04: Switch `ServiceFactory` to be an opaque type, keeping only the `service` field as public API, but also adding a type parameter for the service scope. +- 610d65e143: Switched `BackendFeature` to be an opaque type. + +### Patch Changes + +- 9c9456fd33: Removed the unused `TypesToServiceRef` type +- 181c03edb5: Aligned opaque type markers to all use a `$type` property with namespacing. +- 725383f69d: Tweaked messaging in the README. +- ae88f61e00: The `register` methods passed to `createBackendPlugin` and `createBackendModule` + now have dedicated `BackendPluginRegistrationPoints` and + `BackendModuleRegistrationPoints` arguments, respectively. This lets us make it + clear on a type level that it's not possible to pass in extension points as + dependencies to plugins (should only ever be done for modules). This has no + practical effect on code that was already well behaved. +- Updated dependencies + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + ## 0.4.0-next.2 ### Minor Changes diff --git a/packages/backend-plugin-api/README.md b/packages/backend-plugin-api/README.md index 364655dd60..02b19a0c40 100644 --- a/packages/backend-plugin-api/README.md +++ b/packages/backend-plugin-api/README.md @@ -1,19 +1,20 @@ # @backstage/backend-plugin-api -**This package is HIGHLY EXPERIMENTAL, do not use this for production** +**This package is EXPERIMENTAL, but we encourage use of it to add support for the new backend system in your own plugins** -This package provides the core API used by Backstage backend plugins. +This package provides the core API used by Backstage backend plugins and modules. ## Installation -Add the library to your backend plugin package: +Add the library to your backend plugin or module package: ```bash # From your Backstage root directory -yarn add --cwd plugin/-backend @backstage/backend-plugin-api +yarn add --cwd plugins/-backend @backstage/backend-plugin-api ``` ## Documentation - [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md) - [Backstage Documentation](https://github.com/backstage/backstage/blob/master/docs/README.md) +- [Backstage Backend System](https://backstage.io/docs/backend-system/) diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 7243f3485c..06acbce628 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,14 +1,13 @@ { "name": "@backstage/backend-plugin-api", "description": "Core API used by Backstage backend plugins", - "version": "0.4.0-next.2", + "version": "0.4.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { "access": "public", "main": "dist/index.cjs.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "types": "dist/index.d.ts" }, "backstage": { "role": "node-library" @@ -24,7 +23,7 @@ ], "license": "Apache-2.0", "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index 1e32f34978..e70ff6146d 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/backend-tasks +## 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 diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index ee7d7d6e67..42d0f35374 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.4.3-next.2", + "version": "0.4.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts new file mode 100644 index 0000000000..5b5d592b7b --- /dev/null +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts @@ -0,0 +1,96 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { TestDatabases } 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'; + +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 = getVoidLogger(); + const databases = TestDatabases.create({ + ids: [ + /* 'MYSQL_8' not supported yet */ + 'POSTGRES_13', + 'POSTGRES_9', + 'SQLITE_3', + ], + }); + + 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, + }); + + const abortController = new AbortController(); + worker.start(abortController.signal); + + 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, + }), + ); + }); + + abortController.abort(); + }, + ); +}); diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts index 81b0345c2c..f69b7d9b88 100644 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts @@ -53,15 +53,33 @@ export class PluginTaskSchedulerJanitor { private async runOnce() { const dbNull = this.knex.raw('null'); + const configClient = this.knex.client.config.client; - const 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']); + 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 diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index bf7b6c6713..8129bb3c0a 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/backend-test-utils +## 0.1.35-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-app-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + +## 0.1.34 + +### Patch Changes + +- baf6e4c96a: Removed unnecessary `@backstage/cli` dependency. +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 1835311713: Added explicit return type signature for `mockServices.config()`. +- e716946103: Updated usage of the lifecycle service. +- 7e7557a2be: Updated the `mockServices.rootLogger` options to accept a single level option instead. +- 610d65e143: Updates to match new `BackendFeature` type. +- e412d33025: Use the new `*ServiceFactory` exports from `@backstage/backend-app-api` +- b86efa2d04: Updated usage of `ServiceFactory`. +- 17b573e4be: The new backend system testing utilities have now been marked as stable API. +- f1adb2e36b: Removed the `ref` from all `mockServices`. +- d0901c9ba4: All mock service factories and mock service implementations are now available via the new experimental `mockServices` export. +- 71a5ec0f06: Updated usages of `LogMeta`. +- Updated dependencies + - @backstage/backend-app-api@0.4.0 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + ## 0.1.34-next.2 ### Patch Changes diff --git a/packages/backend-test-utils/README.md b/packages/backend-test-utils/README.md index 38756fa5d7..7ccf4e2798 100644 --- a/packages/backend-test-utils/README.md +++ b/packages/backend-test-utils/README.md @@ -7,7 +7,7 @@ Test helpers library for Backstage backends. Add the library as a `devDependency` to your backend package: ```sh -# From the Backstage root directory, go to your backend package, or to a backend plugin +# From your Backstage root directory, go to your backend package, or to a backend plugin cd plugins/my-plugin-backend yarn add --dev @backstage/backend-test-utils ``` diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 0b3d7dd843..c13d1bb859 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -28,7 +28,7 @@ import { UrlReaderService } from '@backstage/backend-plugin-api'; // @public (undocumented) export function isDockerDisabledForTests(): boolean; -// @alpha (undocumented) +// @public (undocumented) export namespace mockServices { // (undocumented) export namespace cache { @@ -126,7 +126,7 @@ export function setupRequestMockHandlers(worker: { resetHandlers: () => void; }): void; -// @alpha (undocumented) +// @public (undocumented) export function startTestBackend< TServices extends any[], TExtensionPoints extends any[], @@ -134,12 +134,12 @@ export function startTestBackend< options: TestBackendOptions, ): Promise; -// @alpha (undocumented) +// @public (undocumented) export interface TestBackend extends Backend { readonly server: ExtendedHttpServer; } -// @alpha (undocumented) +// @public (undocumented) export interface TestBackendOptions< TServices extends any[], TExtensionPoints extends any[], diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 08e00e1c5e..73f0e9762d 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,14 +1,22 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.1.34-next.2", + "version": "0.1.35-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "node-library" @@ -25,7 +33,7 @@ ], "license": "Apache-2.0", "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -43,7 +51,7 @@ "better-sqlite3": "^8.0.0", "express": "^4.17.1", "knex": "^2.0.0", - "msw": "^0.49.0", + "msw": "^1.0.0", "mysql2": "^2.2.5", "pg": "^8.3.0", "testcontainers": "^8.1.2", @@ -55,7 +63,6 @@ "supertest": "^6.1.3" }, "files": [ - "dist", - "alpha" + "dist" ] } diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/next/services/mockServices.ts index 2e97cc63fb..8a3125214c 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/next/services/mockServices.ts @@ -58,7 +58,7 @@ function simpleFactory< } /** - * @alpha + * @public */ export namespace mockServices { export function config(options?: config.Options): ConfigService { diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts index bbda9854d4..66bbb62193 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts @@ -36,7 +36,7 @@ import { mockServices } from '../services'; import { ConfigReader } from '@backstage/config'; import express from 'express'; -/** @alpha */ +/** @public */ export interface TestBackendOptions< TServices extends any[], TExtensionPoints extends any[], @@ -60,7 +60,7 @@ export interface TestBackendOptions< features?: BackendFeature[]; } -/** @alpha */ +/** @public */ export interface TestBackend extends Backend { /** * Provides access to the underling HTTP server for use with utilities @@ -89,7 +89,7 @@ const defaultServiceFactories = [ const backendInstancesToCleanUp = new Array(); -/** @alpha */ +/** @public */ export async function startTestBackend< TServices extends any[], TExtensionPoints extends any[], diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 7053244da9..a9551d3c47 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,107 @@ # example-backend +## 0.2.81-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-todo-backend@0.1.40-next.0 + - @backstage/plugin-scaffolder-backend@1.11.1-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/plugin-tech-insights-backend@0.5.9-next.0 + - @backstage/plugin-linguist-backend@0.2.0-next.0 + - @backstage/plugin-adr-backend@0.3.1-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/plugin-techdocs-backend@1.5.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-events-backend@0.2.4-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/plugin-app-backend@0.3.43-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/plugin-proxy-backend@0.2.37-next.0 + - @backstage/plugin-auth-backend@0.18.1-next.0 + - @backstage/plugin-badges-backend@0.1.37-next.0 + - @backstage/plugin-code-coverage-backend@0.2.9-next.0 + - @backstage/plugin-entity-feedback-backend@0.1.1-next.0 + - @backstage/plugin-jenkins-backend@0.1.33-next.0 + - @backstage/plugin-kubernetes-backend@0.9.4-next.0 + - @backstage/plugin-lighthouse-backend@0.1.1-next.0 + - @backstage/plugin-playlist-backend@0.2.6-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.11-next.0 + - example-app@0.2.81-next.0 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-azure-devops-backend@0.3.22-next.0 + - @backstage/plugin-azure-sites-backend@0.1.5-next.0 + - @backstage/plugin-explore-backend@0.0.5-next.0 + - @backstage/plugin-graphql-backend@0.1.33-next.0 + - @backstage/plugin-kafka-backend@0.2.36-next.0 + - @backstage/plugin-permission-backend@0.5.18-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + - @backstage/plugin-rollbar-backend@0.1.40-next.0 + - @backstage/plugin-search-backend@1.2.4-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.1.4-next.0 + - @backstage/plugin-search-backend-module-pg@0.5.4-next.0 + - @backstage/plugin-search-backend-node@1.1.4-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.27-next.0 + - @backstage/plugin-tech-insights-node@0.4.1-next.0 + +## 0.2.80 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/plugin-playlist-backend@0.2.5 + - @backstage/plugin-search-backend-module-elasticsearch@1.1.3 + - @backstage/backend-common@0.18.2 + - @backstage/plugin-kubernetes-backend@0.9.3 + - @backstage/plugin-lighthouse-backend@0.1.0 + - @backstage/plugin-code-coverage-backend@0.2.8 + - @backstage/plugin-azure-devops-backend@0.3.21 + - @backstage/plugin-azure-sites-backend@0.1.4 + - @backstage/plugin-adr-backend@0.3.0 + - @backstage/plugin-tech-insights-backend@0.5.8 + - @backstage/plugin-tech-insights-node@0.4.0 + - @backstage/plugin-entity-feedback-backend@0.1.0 + - @backstage/plugin-search-backend@1.2.3 + - @backstage/plugin-techdocs-backend@1.5.3 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.10 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.26 + - @backstage/plugin-scaffolder-backend@1.11.0 + - @backstage/plugin-events-backend@0.2.3 + - @backstage/plugin-kafka-backend@0.2.35 + - @backstage/plugin-proxy-backend@0.2.36 + - @backstage/plugin-app-backend@0.3.42 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-auth-backend@0.18.0 + - @backstage/plugin-linguist-backend@0.1.0 + - @backstage/plugin-events-node@0.2.3 + - example-app@0.2.80 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-badges-backend@0.1.36 + - @backstage/plugin-explore-backend@0.0.4 + - @backstage/plugin-graphql-backend@0.1.32 + - @backstage/plugin-jenkins-backend@0.1.32 + - @backstage/plugin-permission-backend@0.5.17 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + - @backstage/plugin-rollbar-backend@0.1.39 + - @backstage/plugin-search-backend-module-pg@0.5.3 + - @backstage/plugin-search-backend-node@1.1.3 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-todo-backend@0.1.39 + ## 0.2.80-next.2 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 34a7498927..2e742b365d 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.80-next.2", + "version": "0.2.81-next.0", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -51,6 +51,7 @@ "@backstage/plugin-kafka-backend": "workspace:^", "@backstage/plugin-kubernetes-backend": "workspace:^", "@backstage/plugin-lighthouse-backend": "workspace:^", + "@backstage/plugin-linguist-backend": "workspace:^", "@backstage/plugin-permission-backend": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 495dc435c1..011be941cf 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -64,6 +64,7 @@ import permission from './plugins/permission'; import playlist from './plugins/playlist'; import adr from './plugins/adr'; import lighthouse from './plugins/lighthouse'; +import linguist from './plugins/linguist'; import { PluginEnvironment } from './types'; import { ServerPermissionClient } from '@backstage/plugin-permission-node'; import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; @@ -158,6 +159,7 @@ async function main() { const eventBasedEntityProviders = await catalogEventBasedProviders( catalogEnv, ); + const linguistEnv = useHotMemoize(module, () => createEnv('linguist')); const apiRouter = Router(); apiRouter.use( @@ -185,6 +187,7 @@ async function main() { apiRouter.use('/explore', await explore(exploreEnv)); apiRouter.use('/entity-feedback', await entityFeedback(entityFeedbackEnv)); apiRouter.use('/adr', await adr(adrEnv)); + apiRouter.use('/linguist', await linguist(linguistEnv)); apiRouter.use(notFoundHandler()); await lighthouse(lighthouseEnv); diff --git a/packages/backend/src/plugins/auth.ts b/packages/backend/src/plugins/auth.ts index 8beda6f3fb..0d92315f92 100644 --- a/packages/backend/src/plugins/auth.ts +++ b/packages/backend/src/plugins/auth.ts @@ -114,6 +114,13 @@ export default async function createPlugin( }, }), + bitbucketServer: providers.bitbucketServer.create({ + signIn: { + resolver: + providers.bitbucketServer.resolvers.emailMatchingUserEntityProfileEmail(), + }, + }), + // This is an example of how to configure the OAuth2Proxy provider as well // as how to sign a user in without a matching user entity in the catalog. // You can try it out using `` diff --git a/packages/backend/src/plugins/linguist.ts b/packages/backend/src/plugins/linguist.ts new file mode 100644 index 0000000000..2c8713a7e3 --- /dev/null +++ b/packages/backend/src/plugins/linguist.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; +import { createRouter } from '@backstage/plugin-linguist-backend'; +import { Router } from 'express'; +import type { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + const schedule: TaskScheduleDefinition = { + frequency: { minutes: 2 }, + timeout: { minutes: 15 }, + initialDelay: { seconds: 15 }, + }; + + return createRouter( + { + schedule: schedule, + age: { days: 30 }, + batchSize: 2, + useSourceLocation: false, + }, + { ...env }, + ); +} diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index 1602dfbb79..99b07f3c5c 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/catalog-client +## 1.4.0-next.0 + +### Minor Changes + +- 8c030b1826: Add `queryEntities` method to `CatalogApi`. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/errors@1.1.4 + +## 1.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/errors@1.1.4 + ## 1.3.1-next.1 ### Patch Changes diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index a81314308b..22feceabec 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -58,6 +58,10 @@ export interface CatalogApi { locationRef: string, options?: CatalogRequestOptions, ): Promise; + queryEntities( + request?: QueryEntitiesRequest, + options?: CatalogRequestOptions, + ): Promise; refreshEntity( entityRef: string, options?: CatalogRequestOptions, @@ -124,6 +128,10 @@ export class CatalogClient implements CatalogApi { locationRef: string, options?: CatalogRequestOptions, ): Promise; + queryEntities( + request?: QueryEntitiesRequest, + options?: CatalogRequestOptions, + ): Promise; refreshEntity( entityRef: string, options?: CatalogRequestOptions, @@ -219,10 +227,7 @@ export interface GetEntityAncestorsResponse { // @public export interface GetEntityFacetsRequest { facets: string[]; - filter?: - | Record[] - | Record - | undefined; + filter?: EntityFilterQuery; } // @public @@ -244,6 +249,40 @@ type Location_2 = { }; export { Location_2 as Location }; +// @public +export type QueryEntitiesCursorRequest = { + fields?: string[]; + limit?: number; + cursor: string; +}; + +// @public +export type QueryEntitiesInitialRequest = { + fields?: string[]; + limit?: number; + filter?: EntityFilterQuery; + orderFields?: EntityOrderQuery; + fullTextFilter?: { + term: string; + fields?: string[]; + }; +}; + +// @public +export type QueryEntitiesRequest = + | QueryEntitiesInitialRequest + | QueryEntitiesCursorRequest; + +// @public +export type QueryEntitiesResponse = { + items: Entity[]; + totalItems: number; + pageInfo: { + nextCursor?: string; + prevCursor?: string; + }; +}; + // @public export type ValidateEntityResponse = | { diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index ac233e293a..91e852c3b0 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-client", "description": "An isomorphic client for the catalog backend", - "version": "1.3.1-next.1", + "version": "1.4.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -38,7 +38,7 @@ }, "devDependencies": { "@backstage/cli": "workspace:^", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/packages/catalog-client/src/CatalogClient.test.ts b/packages/catalog-client/src/CatalogClient.test.ts index 2e9d2a0679..c235ff1592 100644 --- a/packages/catalog-client/src/CatalogClient.test.ts +++ b/packages/catalog-client/src/CatalogClient.test.ts @@ -18,7 +18,11 @@ import { Entity } from '@backstage/catalog-model'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { CatalogClient } from './CatalogClient'; -import { CATALOG_FILTER_EXISTS, GetEntitiesResponse } from './types/api'; +import { + CATALOG_FILTER_EXISTS, + GetEntitiesResponse, + QueryEntitiesResponse, +} from './types/api'; import { DiscoveryApi } from './types/discovery'; const server = setupServer(); @@ -249,6 +253,185 @@ describe('CatalogClient', () => { }); }); + describe('queryEntities', () => { + const defaultResponse: QueryEntitiesResponse = { + items: [ + { + apiVersion: '1', + kind: 'Component', + metadata: { + name: 'Test2', + namespace: 'test1', + }, + }, + { + apiVersion: '1', + kind: 'Component', + metadata: { + name: 'Test1', + namespace: 'test1', + }, + }, + ], + pageInfo: { + nextCursor: 'next', + prevCursor: 'prev', + }, + totalItems: 10, + }; + + beforeEach(() => { + server.use( + rest.get(`${mockBaseUrl}/entities/by-query`, (_, res, ctx) => { + return res(ctx.json(defaultResponse)); + }), + ); + }); + + it('should fetch entities from correct endpoint', async () => { + const response = await client.queryEntities({}, { token }); + expect(response?.items).toEqual(defaultResponse.items); + expect(response?.totalItems).toEqual(defaultResponse.totalItems); + expect(response?.pageInfo.nextCursor).toBeDefined(); + expect(response?.pageInfo.prevCursor).toBeDefined(); + }); + + it('builds multiple entity search filters properly', async () => { + const mockedEndpoint = jest + .fn() + .mockImplementation((_req, res, ctx) => + res(ctx.json({ items: [], totalItems: 0 })), + ); + + server.use(rest.get(`${mockBaseUrl}/entities/by-query`, mockedEndpoint)); + + const response = await client.queryEntities( + { + filter: [ + { + a: '1', + b: ['2', '3'], + ö: '=', + }, + { + a: '2', + }, + { + c: CATALOG_FILTER_EXISTS, + }, + ], + }, + { token }, + ); + + expect(response).toEqual({ items: [], totalItems: 0 }); + expect(mockedEndpoint).toHaveBeenCalledTimes(1); + expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( + '?filter=a=1,b=2,b=3,%C3%B6=%3D&filter=a=2&filter=c', + ); + }); + + it('should send query params correctly on initial request', async () => { + const mockedEndpoint = jest + .fn() + .mockImplementation((_req, res, ctx) => + res(ctx.json({ items: [], totalItems: 0 })), + ); + + server.use(rest.get(`${mockBaseUrl}/entities/by-query`, mockedEndpoint)); + + await client.queryEntities({ + fields: ['a', 'b'], + limit: 100, + fullTextFilter: { + term: 'query', + }, + orderFields: [ + { field: 'metadata.name', order: 'asc' }, + { field: 'metadata.uid', order: 'desc' }, + ], + }); + expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( + '?limit=100&sortField=metadata.name,asc&sortField=metadata.uid,desc&fields=a,b&fullTextFilterTerm=query', + ); + }); + + it('should ignore initial query params if cursor is passed', async () => { + const mockedEndpoint = jest + .fn() + .mockImplementation((_req, res, ctx) => + res(ctx.json({ items: [], totalItems: 0 })), + ); + + server.use(rest.get(`${mockBaseUrl}/entities/by-query`, mockedEndpoint)); + + await client.queryEntities({ + fields: ['a', 'b'], + limit: 100, + fullTextFilter: { + term: 'query', + }, + orderFields: [{ field: 'metadata.name', order: 'asc' }], + cursor: 'cursor', + }); + expect(mockedEndpoint.mock.calls[0][0].url.search).toBe( + '?cursor=cursor&limit=100&fields=a,b', + ); + }); + + it('should return paginated functions if next and prev cursors are present', async () => { + const mockedEndpoint = jest.fn().mockImplementation((_req, res, ctx) => + res( + ctx.json({ + items: [ + { + apiVersion: 'v1', + kind: 'CustomKind', + metadata: { + namespace: 'default', + name: 'e1', + }, + }, + { + apiVersion: 'v1', + kind: 'CustomKind', + metadata: { + namespace: 'default', + name: 'e2', + }, + }, + ], + pageInfo: { + nextCursor: 'nextcursor', + prevCursor: 'prevcursor', + }, + totalItems: 100, + } as QueryEntitiesResponse), + ), + ); + + server.use(rest.get(`${mockBaseUrl}/entities/by-query`, mockedEndpoint)); + + const response = await client.queryEntities({ + limit: 2, + }); + expect(mockedEndpoint.mock.calls[0][0].url.search).toBe('?limit=2'); + + expect(response?.pageInfo.nextCursor).toBeDefined(); + expect(response?.pageInfo.prevCursor).toBeDefined(); + + await client.queryEntities({ cursor: response!.pageInfo.nextCursor! }); + expect(mockedEndpoint.mock.calls[1][0].url.search).toBe( + '?cursor=nextcursor', + ); + + await client.queryEntities({ cursor: response!.pageInfo.prevCursor! }); + expect(mockedEndpoint.mock.calls[2][0].url.search).toBe( + '?cursor=prevcursor', + ); + }); + }); + describe('getEntityByRef', () => { const existingEntity: Entity = { apiVersion: 'v1', diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index af4262b842..4984d394d4 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -39,9 +39,13 @@ import { ValidateEntityResponse, GetEntitiesByRefsRequest, GetEntitiesByRefsResponse, + QueryEntitiesRequest, + QueryEntitiesResponse, + EntityFilterQuery, } from './types/api'; import { DiscoveryApi } from './types/discovery'; import { FetchApi } from './types/fetch'; +import { isQueryEntitiesInitialRequest } from './utils'; /** * A frontend and backend compatible client for communicating with the Backstage @@ -107,30 +111,7 @@ export class CatalogClient implements CatalogApi { limit, after, } = request ?? {}; - const params: string[] = []; - - // filter param can occur multiple times, for example - // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component' - // the "outer array" defined by `filter` occurrences corresponds to "anyOf" filters - // the "inner array" defined within a `filter` param corresponds to "allOf" filters - for (const filterItem of [filter].flat()) { - const filterParts: string[] = []; - for (const [key, value] of Object.entries(filterItem)) { - for (const v of [value].flat()) { - if (v === CATALOG_FILTER_EXISTS) { - filterParts.push(encodeURIComponent(key)); - } else if (typeof v === 'string') { - filterParts.push( - `${encodeURIComponent(key)}=${encodeURIComponent(v)}`, - ); - } - } - } - - if (filterParts.length) { - params.push(`filter=${filterParts.join(',')}`); - } - } + const params = this.getParams(filter); if (fields.length) { params.push(`fields=${fields.map(encodeURIComponent).join(',')}`); @@ -223,6 +204,64 @@ export class CatalogClient implements CatalogApi { return { items }; } + /** + * {@inheritdoc CatalogApi.queryEntities} + */ + async queryEntities( + request: QueryEntitiesRequest = {}, + options?: CatalogRequestOptions, + ) { + const params: string[] = []; + + if (isQueryEntitiesInitialRequest(request)) { + const { + fields = [], + filter, + limit, + orderFields, + fullTextFilter, + } = request; + params.push(...this.getParams(filter)); + + if (limit !== undefined) { + params.push(`limit=${limit}`); + } + if (orderFields !== undefined) { + (Array.isArray(orderFields) ? orderFields : [orderFields]).forEach( + ({ field, order }) => params.push(`sortField=${field},${order}`), + ); + } + if (fields.length) { + params.push(`fields=${fields.map(encodeURIComponent).join(',')}`); + } + + const normalizedFullTextFilterTerm = fullTextFilter?.term?.trim(); + if (normalizedFullTextFilterTerm) { + params.push(`fullTextFilterTerm=${normalizedFullTextFilterTerm}`); + } + if (fullTextFilter?.fields?.length) { + params.push(`fullTextFilterFields=${fullTextFilter.fields.join(',')}`); + } + } else { + const { fields = [], limit, cursor } = request; + + params.push(`cursor=${cursor}`); + if (limit !== undefined) { + params.push(`limit=${limit}`); + } + if (fields.length) { + params.push(`fields=${fields.map(encodeURIComponent).join(',')}`); + } + } + + const query = params.length ? `?${params.join('&')}` : ''; + return this.requestRequired( + 'GET', + `/entities/by-query${query}`, + options, + ); + } + /** * {@inheritdoc CatalogApi.getEntityByRef} */ @@ -290,30 +329,7 @@ export class CatalogClient implements CatalogApi { options?: CatalogRequestOptions, ): Promise { const { filter = [], facets } = request; - const params: string[] = []; - - // filter param can occur multiple times, for example - // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component' - // the "outer array" defined by `filter` occurrences corresponds to "anyOf" filters - // the "inner array" defined within a `filter` param corresponds to "allOf" filters - for (const filterItem of [filter].flat()) { - const filterParts: string[] = []; - for (const [key, value] of Object.entries(filterItem)) { - for (const v of [value].flat()) { - if (v === CATALOG_FILTER_EXISTS) { - filterParts.push(encodeURIComponent(key)); - } else if (typeof v === 'string') { - filterParts.push( - `${encodeURIComponent(key)}=${encodeURIComponent(v)}`, - ); - } - } - } - - if (filterParts.length) { - params.push(`filter=${filterParts.join(',')}`); - } - } + const params = this.getParams(filter); for (const facet of facets) { params.push(`facet=${encodeURIComponent(facet)}`); @@ -466,11 +482,11 @@ export class CatalogClient implements CatalogApi { } } - private async requestRequired( + private async requestRequired( method: string, path: string, options?: CatalogRequestOptions, - ): Promise { + ): Promise { const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`; const headers: Record = options?.token ? { Authorization: `Bearer ${options.token}` } @@ -481,7 +497,7 @@ export class CatalogClient implements CatalogApi { throw await ResponseError.fromResponse(response); } - return await response.json(); + return response.json(); } private async requestOptional( @@ -504,4 +520,31 @@ export class CatalogClient implements CatalogApi { return await response.json(); } + + private getParams(filter: EntityFilterQuery = []) { + const params: string[] = []; + // filter param can occur multiple times, for example + // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component' + // the "outer array" defined by `filter` occurrences corresponds to "anyOf" filters + // the "inner array" defined within a `filter` param corresponds to "allOf" filters + for (const filterItem of [filter].flat()) { + const filterParts: string[] = []; + for (const [key, value] of Object.entries(filterItem)) { + for (const v of [value].flat()) { + if (v === CATALOG_FILTER_EXISTS) { + filterParts.push(encodeURIComponent(key)); + } else if (typeof v === 'string') { + filterParts.push( + `${encodeURIComponent(key)}=${encodeURIComponent(v)}`, + ); + } + } + } + + if (filterParts.length) { + params.push(`filter=${filterParts.join(',')}`); + } + } + return params; + } } diff --git a/packages/catalog-client/src/types/api.ts b/packages/catalog-client/src/types/api.ts index d662a9d106..ee6579efca 100644 --- a/packages/catalog-client/src/types/api.ts +++ b/packages/catalog-client/src/types/api.ts @@ -287,10 +287,7 @@ export interface GetEntityFacetsRequest { * (exported from this package), which means that you assert on the existence * of that key, no matter what its value is. */ - filter?: - | Record[] - | Record - | undefined; + filter?: EntityFilterQuery; /** * Dot separated paths for the facets to extract from each entity. * @@ -380,6 +377,67 @@ export type ValidateEntityResponse = | { valid: true } | { valid: false; errors: SerializedError[] }; +/** + * The request type for {@link CatalogClient.queryEntities}. + * + * @public + */ +export type QueryEntitiesRequest = + | QueryEntitiesInitialRequest + | QueryEntitiesCursorRequest; + +/** + * A request type for {@link CatalogClient.queryEntities}. + * The method takes this type in an initial pagination request, + * when requesting the first batch of entities. + * + * The properties filter, sortField, query and sortFieldOrder, are going + * to be immutable for the entire lifecycle of the following requests. + * + * @public + */ +export type QueryEntitiesInitialRequest = { + fields?: string[]; + limit?: number; + filter?: EntityFilterQuery; + orderFields?: EntityOrderQuery; + fullTextFilter?: { + term: string; + fields?: string[]; + }; +}; + +/** + * A request type for {@link CatalogClient.queryEntities}. + * The method takes this type in a pagination request, following + * the initial request. + * + * @public + */ +export type QueryEntitiesCursorRequest = { + fields?: string[]; + limit?: number; + cursor: string; +}; + +/** + * The response type for {@link CatalogClient.queryEntities}. + * + * @public + */ +export type QueryEntitiesResponse = { + /* The list of entities for the current request */ + items: Entity[]; + /* The number of entities among all the requests */ + totalItems: number; + pageInfo: { + /* The cursor for the next batch of entities */ + nextCursor?: string; + /* The cursor for the previous batch of entities */ + prevCursor?: string; + }; +}; + /** * A client for interacting with the Backstage software catalog through its API. * @@ -414,6 +472,49 @@ export interface CatalogApi { options?: CatalogRequestOptions, ): Promise; + /** + * Gets paginated entities from the catalog. + * + * @remarks + * + * @example + * + * ``` + * const response = await catalogClient.queryEntities({ + * filter: [{ kind: 'group' }], + * limit: 20, + * fullTextFilter: { + * term: 'A', + * } + * orderFields: { field: 'metadata.name' order: 'asc' }, + * }); + * ``` + * + * this will match all entities of type group having a name starting + * with 'A', ordered by name ascending. + * + * The response will contain a maximum of 20 entities. In case + * more than 20 entities exist, the response will contain a nextCursor + * property that can be used to fetch the next batch of entities. + * + * ``` + * const secondBatchResponse = await catalogClient + * .queryEntities({ cursor: response.nextCursor }); + * ``` + * + * secondBatchResponse will contain the next batch of (maximum) 20 entities, + * together with a prevCursor property, useful to fetch the previous batch. + * + * @public + * + * @param request - Request parameters + * @param options - Additional options + */ + queryEntities( + request?: QueryEntitiesRequest, + options?: CatalogRequestOptions, + ): Promise; + /** * Gets entity ancestor information, i.e. the hierarchy of parent entities * whose processing resulted in a given entity appearing in the catalog. diff --git a/packages/catalog-client/src/types/index.ts b/packages/catalog-client/src/types/index.ts index 81b985eb42..9bf35886c8 100644 --- a/packages/catalog-client/src/types/index.ts +++ b/packages/catalog-client/src/types/index.ts @@ -33,5 +33,9 @@ export type { GetEntityFacetsResponse, Location, ValidateEntityResponse, + QueryEntitiesCursorRequest, + QueryEntitiesInitialRequest, + QueryEntitiesRequest, + QueryEntitiesResponse, } from './api'; export { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from './status'; diff --git a/packages/catalog-client/src/utils.ts b/packages/catalog-client/src/utils.ts new file mode 100644 index 0000000000..de21cea0d4 --- /dev/null +++ b/packages/catalog-client/src/utils.ts @@ -0,0 +1,33 @@ +/* + * 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 { + QueryEntitiesCursorRequest, + QueryEntitiesInitialRequest, + QueryEntitiesRequest, +} from './types/api'; + +export function isQueryEntitiesInitialRequest( + request: QueryEntitiesInitialRequest, +): request is QueryEntitiesInitialRequest { + return !(request as QueryEntitiesCursorRequest).cursor; +} + +export function isQueryEntitiesCursorRequest( + request: QueryEntitiesRequest, +): request is QueryEntitiesCursorRequest { + return !isQueryEntitiesInitialRequest(request); +} diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index 1f14aba820..8d6659c20b 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/catalog-model +## 1.2.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## 1.2.0 + +### Minor Changes + +- d51668882d: Adds the tRPC API type to the catalog. + +### Patch Changes + +- aece6c57d2: Add additional validation for location references. +- 2518ef5b8a: Add deprecation tag to kubernetes constants in catalog, constants are now defined in plugin-kubernetes-common +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + ## 1.2.0-next.1 ### Minor Changes diff --git a/packages/catalog-model/alpha-api-report.md b/packages/catalog-model/alpha-api-report.md new file mode 100644 index 0000000000..5b962a7403 --- /dev/null +++ b/packages/catalog-model/alpha-api-report.md @@ -0,0 +1,31 @@ +## API Report File for "@backstage/catalog-model" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Entity } from '@backstage/catalog-model'; +import { SerializedError } from '@backstage/errors'; + +// @alpha +export interface AlphaEntity extends Entity { + status?: EntityStatus; +} + +// @alpha +export type EntityStatus = { + items?: EntityStatusItem[]; +}; + +// @alpha +export type EntityStatusItem = { + type: string; + level: EntityStatusLevel; + message: string; + error?: SerializedError; +}; + +// @alpha +export type EntityStatusLevel = 'info' | 'warning' | 'error'; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/catalog-model/api-report.md b/packages/catalog-model/api-report.md index 15eec90f09..b8eb20c590 100644 --- a/packages/catalog-model/api-report.md +++ b/packages/catalog-model/api-report.md @@ -4,12 +4,6 @@ ```ts import { JsonObject } from '@backstage/types'; -import { SerializedError } from '@backstage/errors'; - -// @alpha -export interface AlphaEntity extends Entity { - status?: EntityStatus; -} // @public export const ANNOTATION_EDIT_URL = 'backstage.io/edit-url'; @@ -209,22 +203,6 @@ export function entitySchemaValidator( schema?: unknown, ): (data: unknown) => T; -// @alpha -export type EntityStatus = { - items?: EntityStatusItem[]; -}; - -// @alpha -export type EntityStatusItem = { - type: string; - level: EntityStatusLevel; - message: string; - error?: SerializedError; -}; - -// @alpha -export type EntityStatusLevel = 'info' | 'warning' | 'error'; - // @public export class FieldFormatEntityPolicy implements EntityPolicy { constructor(validators?: Validators); diff --git a/packages/catalog-model/examples/components/artist-lookup-component.yaml b/packages/catalog-model/examples/components/artist-lookup-component.yaml index c0022762b4..a3a3780c84 100644 --- a/packages/catalog-model/examples/components/artist-lookup-component.yaml +++ b/packages/catalog-model/examples/components/artist-lookup-component.yaml @@ -28,6 +28,8 @@ metadata: - url: https://example.com/alert title: Alerts icon: alert + annotations: + backstage.io/linguist: 'https://github.com/backstage/backstage/tree/master/plugins/playlist' spec: type: service lifecycle: experimental diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index 117035a82e..c75984643b 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,16 +1,27 @@ { "name": "@backstage/catalog-model", "description": "Types and validators that help describe the model of a Backstage Catalog", - "version": "1.2.0-next.1", + "version": "1.2.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "module": "dist/index.esm.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "common-library" @@ -25,7 +36,7 @@ "backstage" ], "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -48,7 +59,6 @@ "yaml": "^2.0.0" }, "files": [ - "dist", - "alpha" + "dist" ] } diff --git a/packages/catalog-model/src/alpha.ts b/packages/catalog-model/src/alpha.ts new file mode 100644 index 0000000000..1d29c97464 --- /dev/null +++ b/packages/catalog-model/src/alpha.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type { + EntityStatus, + EntityStatusItem, + EntityStatusLevel, +} from './entity/EntityStatus'; +export type { AlphaEntity } from './entity/AlphaEntity'; diff --git a/packages/catalog-model/src/entity/AlphaEntity.ts b/packages/catalog-model/src/entity/AlphaEntity.ts new file mode 100644 index 0000000000..6f5c9d4fa7 --- /dev/null +++ b/packages/catalog-model/src/entity/AlphaEntity.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// TODO(Rugvip): Figure out best way to allow this import +// eslint-disable-next-line import/no-extraneous-dependencies +import { Entity } from '@backstage/catalog-model'; +import { EntityStatus } from './EntityStatus'; + +/** + * A version of the `Entity` type that contains unstable alpha fields. + * + * @remarks + * + * Available via the `@backstage/catalog-model/alpha` import. + * + * @alpha + */ +export interface AlphaEntity extends Entity { + /** + * The current status of the entity, as claimed by various sources. + * + * The keys are implementation defined and the values can be any JSON object + * with semantics that match that implementation. + */ + status?: EntityStatus; +} diff --git a/packages/catalog-model/src/entity/Entity.ts b/packages/catalog-model/src/entity/Entity.ts index 80c9adaffb..8d36fe0134 100644 --- a/packages/catalog-model/src/entity/Entity.ts +++ b/packages/catalog-model/src/entity/Entity.ts @@ -15,7 +15,6 @@ */ import { JsonObject } from '@backstage/types'; -import { EntityStatus } from './EntityStatus'; /** * The parts of the format that's common to all versions/kinds of entity. @@ -54,25 +53,6 @@ export type Entity = { relations?: EntityRelation[]; }; -/** - * A version of the {@link Entity} type that contains unstable alpha fields. - * - * @remarks - * - * Available via the `@backstage/catalog-model/alpha` import. - * - * @alpha - */ -export interface AlphaEntity extends Entity { - /** - * The current status of the entity, as claimed by various sources. - * - * The keys are implementation defined and the values can be any JSON object - * with semantics that match that implementation. - */ - status?: EntityStatus; -} - /** * Metadata fields common to all versions/kinds of entity. * diff --git a/packages/catalog-model/src/entity/index.ts b/packages/catalog-model/src/entity/index.ts index 87f414cc9c..269d56ec86 100644 --- a/packages/catalog-model/src/entity/index.ts +++ b/packages/catalog-model/src/entity/index.ts @@ -16,19 +16,8 @@ export * from './conditions'; export * from './constants'; -export type { - AlphaEntity, - Entity, - EntityLink, - EntityMeta, - EntityRelation, -} from './Entity'; +export type { Entity, EntityLink, EntityMeta, EntityRelation } from './Entity'; export type { EntityEnvelope } from './EntityEnvelope'; -export type { - EntityStatus, - EntityStatusItem, - EntityStatusLevel, -} from './EntityStatus'; export * from './policies'; export { getCompoundEntityRef, diff --git a/packages/catalog-model/src/location/helpers.test.ts b/packages/catalog-model/src/location/helpers.test.ts index 91a2137611..28267dcf37 100644 --- a/packages/catalog-model/src/location/helpers.test.ts +++ b/packages/catalog-model/src/location/helpers.test.ts @@ -50,6 +50,9 @@ describe('parseLocationRef', () => { expect(() => parseLocationRef('https://bleh')).toThrow( "Invalid location ref 'https://bleh', please prefix it with 'url:', e.g. 'url:https://bleh'", ); + expect(() => parseLocationRef('url:javascript:alert()')).toThrow( + "Invalid location ref 'url:javascript:alert()', target is a javascript: URL", + ); }); }); @@ -70,6 +73,12 @@ describe('stringifyLocationRef', () => { expect(() => stringifyLocationRef({ type: 'hello', target: '' })).toThrow( 'Unable to stringify location ref, empty target', ); + expect(() => + // eslint-disable-next-line no-script-url + stringifyLocationRef({ type: 'url', target: 'javascript:alert()' }), + ).toThrow( + "Invalid location ref 'url:javascript:alert()', target is a javascript: URL", + ); }); }); diff --git a/packages/catalog-model/src/location/helpers.ts b/packages/catalog-model/src/location/helpers.ts index 6f9800c5a2..a2f4d84f6f 100644 --- a/packages/catalog-model/src/location/helpers.ts +++ b/packages/catalog-model/src/location/helpers.ts @@ -17,6 +17,11 @@ import { Entity, stringifyEntityRef } from '../entity'; import { ANNOTATION_LOCATION, ANNOTATION_SOURCE_LOCATION } from './annotation'; +// See https://github.com/facebook/react/blob/f0cf832e1d0c8544c36aa8b310960885a11a847c/packages/react-dom-bindings/src/shared/sanitizeURL.js +const scriptProtocolPattern = + // eslint-disable-next-line no-control-regex + /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; + /** * Parses a string form location reference. * @@ -56,6 +61,12 @@ export function parseLocationRef(ref: string): { ); } + if (scriptProtocolPattern.test(target)) { + throw new TypeError( + `Invalid location ref '${ref}', target is a javascript: URL`, + ); + } + return { type, target }; } @@ -78,6 +89,12 @@ export function stringifyLocationRef(ref: { throw new TypeError(`Unable to stringify location ref, empty target`); } + if (scriptProtocolPattern.test(target)) { + throw new TypeError( + `Invalid location ref '${type}:${target}', target is a javascript: URL`, + ); + } + return `${type}:${target}`; } diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 09e7f44eb4..c42f76c774 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/cli +## 0.22.4-next.0 + +### Patch Changes + +- b4cd145b57: Added a new `migrate package-exports` command that synchronizes package exports fields in all `package.json`s. +- 8bf24946c6: Adjust express dependencies to be the same as the rest of the project +- 17271841de: Updated frontend plugin template to use some more recent features +- Updated dependencies + - @backstage/eslint-plugin@0.1.2-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/release-manifests@0.0.8 + - @backstage/types@1.0.2 + +## 0.22.2 + +### Patch Changes + +- 561df21ea3: The `backstage-cli repo test` command now sets a default Jest `--workerIdleMemoryLimit` of 1GB. If needed to ensure that tests are not run in band, `--maxWorkers=2` is set as well. This is the recommended workaround for dealing with Jest workers leaking memory and eventually hitting the heap limit. +- 2815981057: Show module name causing error during build +- dd8a9afe66: Replaced several monorepo lint rules with new rules from `@backstage/eslint-plugin`. See the [README](https://github.com/import-js/eslint-plugin-import/blob/main/packages/eslint-plugin/README.md) for a full list of rules. +- a9c50af76b: Fixed Webpack loader patterns so that they properly match the file suffix only. +- 66cf22fdc4: Updated dependency `esbuild` to `^0.17.0`. +- 6d3abfded1: Switch to inline source maps for test transpilation, simplifying editor setups. +- 90616df9a8: Added an experimental mode for the `package start` command for backend packages. Enabled by setting `EXPERIMENTAL_BACKEND_START`. +- Updated dependencies + - @backstage/eslint-plugin@0.1.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/errors@1.1.4 + - @backstage/release-manifests@0.0.8 + - @backstage/types@1.0.2 + ## 0.22.2-next.1 ### Patch Changes diff --git a/packages/cli/cli-report.md b/packages/cli/cli-report.md index fa9a2aca8d..bad849d283 100644 --- a/packages/cli/cli-report.md +++ b/packages/cli/cli-report.md @@ -127,11 +127,21 @@ Options: Commands: package-roles package-scripts + package-exports package-lint-configs react-router-deps help [command] ``` +### `backstage-cli migrate package-exports` + +``` +Usage: backstage-cli migrate package-exports [options] + +Options: + -h, --help +``` + ### `backstage-cli migrate package-lint-configs` ``` diff --git a/packages/cli/package.json b/packages/cli/package.json index a3020de1da..0260a1c59b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.22.2-next.1", + "version": "0.22.4-next.0", "publishConfig": { "access": "public" }, @@ -155,9 +155,9 @@ "@types/tar": "^6.1.1", "@types/terser-webpack-plugin": "^5.0.4", "@types/yarnpkg__lockfile": "^1.1.4", - "del": "^6.0.0", + "del": "^7.0.0", "mock-fs": "^5.1.0", - "msw": "^0.49.0", + "msw": "^1.0.0", "nodemon": "^2.0.2", "ts-node": "^10.0.0" }, diff --git a/packages/cli/src/commands/build/buildBackend.ts b/packages/cli/src/commands/build/buildBackend.ts index d7c4f72dbe..7e61f9ae85 100644 --- a/packages/cli/src/commands/build/buildBackend.ts +++ b/packages/cli/src/commands/build/buildBackend.ts @@ -37,6 +37,7 @@ export async function buildBackend(options: BuildBackendOptions) { // We build the target package without generating type declarations. await buildPackage({ targetDir: options.targetDir, + packageJson: pkg, outputs: new Set([Output.cjs]), }); diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 628e46df85..ddec5c6a4a 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -116,7 +116,7 @@ export function registerScriptCommand(program: Command) { ) .option( '--experimental-type-build', - 'Enable experimental type build. Does not apply to app or backend packages.', + 'Enable experimental type build. Does not apply to app or backend packages. [DEPRECATED]', ) .option( '--skip-build-dependencies', @@ -191,6 +191,13 @@ export function registerMigrateCommand(program: Command) { lazy(() => import('./migrate/packageScripts').then(m => m.command)), ); + command + .command('package-exports') + .description('Synchronize package subpath export definitions') + .action( + lazy(() => import('./migrate/packageExports').then(m => m.command)), + ); + command .command('package-lint-configs') .description( diff --git a/packages/cli/src/commands/migrate/packageExports.ts b/packages/cli/src/commands/migrate/packageExports.ts new file mode 100644 index 0000000000..ff01f939f9 --- /dev/null +++ b/packages/cli/src/commands/migrate/packageExports.ts @@ -0,0 +1,121 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES 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 { ExtendedPackageJSON, PackageGraph } from '../../lib/monorepo'; + +function trimRelative(path: string): string { + if (path.startsWith('./')) { + return path.slice(2); + } + return path; +} + +export async function command() { + const packages = await PackageGraph.listTargetPackages(); + + await Promise.all( + packages.map(async ({ dir, packageJson }) => { + let changed = false; + let newPackageJson = packageJson; + + let { exports: exp } = newPackageJson; + if (!exp) { + return; + } + if (Array.isArray(exp)) { + throw new Error('Unexpected array in package.json exports field'); + } + + // If exports is a string we rewrite it to an object to add package.json + if (typeof exp === 'string') { + changed = true; + exp = { '.': exp }; + newPackageJson.exports = exp; + } else if (typeof exp !== 'object') { + return; + } + + if (!exp['./package.json']) { + changed = true; + exp['./package.json'] = './package.json'; + } + + const existingTypesVersions = JSON.stringify(packageJson.typesVersions); + + const typeEntries: Record = {}; + for (const [path, value] of Object.entries(exp)) { + // Main entry point does not need to be listed + if (path === '.') { + continue; + } + const newPath = trimRelative(path); + + if (typeof value === 'string') { + typeEntries[newPath] = [trimRelative(value)]; + } else if ( + value && + typeof value === 'object' && + !Array.isArray(value) + ) { + if (typeof value.types === 'string') { + typeEntries[newPath] = [trimRelative(value.types)]; + } else if (typeof value.default === 'string') { + typeEntries[newPath] = [trimRelative(value.default)]; + } + } + } + + const typesVersions = { '*': typeEntries }; + if (existingTypesVersions !== JSON.stringify(typesVersions)) { + console.log(`Synchronizing exports in ${packageJson.name}`); + const newPkgEntries = Object.entries(newPackageJson).filter( + ([name]) => name !== 'typesVersions', + ); + newPkgEntries.splice( + newPkgEntries.findIndex(([name]) => name === 'exports') + 1, + 0, + ['typesVersions', typesVersions], + ); + + newPackageJson = Object.fromEntries( + newPkgEntries, + ) as ExtendedPackageJSON; + changed = true; + } + + // Remove the legacy fields from publishConfig, which are no longer needed + const publishConfig = newPackageJson.publishConfig as + | Record + | undefined; + if (publishConfig) { + for (const field of ['main', 'module', 'browser', 'types']) { + if (publishConfig[field]) { + delete publishConfig[field]; + changed = true; + } + } + } + + if (changed) { + await fs.writeJson(resolvePath(dir, 'package.json'), newPackageJson, { + spaces: 2, + }); + } + }), + ); +} diff --git a/packages/cli/src/commands/pack.ts b/packages/cli/src/commands/pack.ts index 6c88ac055f..9c101e97fe 100644 --- a/packages/cli/src/commands/pack.ts +++ b/packages/cli/src/commands/pack.ts @@ -14,77 +14,16 @@ * limitations under the License. */ -import fs from 'fs-extra'; +import { + productionPack, + revertProductionPack, +} from '../lib/packager/productionPack'; import { paths } from '../lib/paths'; -import { join as joinPath } from 'path'; - -const SKIPPED_KEYS = ['access', 'registry', 'tag', 'alphaTypes', 'betaTypes']; - -const PKG_PATH = 'package.json'; -const PKG_BACKUP_PATH = 'package.json-prepack'; - -function resolveEntrypoint(pkg: any, name: string) { - const targetEntry = pkg.publishConfig[name] || pkg[name]; - return targetEntry && joinPath('..', targetEntry); -} - -// Writes e.g. alpha/package.json -async function writeReleaseStageEntrypoint(pkg: any, stage: 'alpha' | 'beta') { - await fs.ensureDir(paths.resolveTarget(stage)); - await fs.writeJson( - paths.resolveTarget(stage, PKG_PATH), - { - name: pkg.name, - version: pkg.version, - main: resolveEntrypoint(pkg, 'main'), - module: resolveEntrypoint(pkg, 'module'), - browser: resolveEntrypoint(pkg, 'browser'), - types: joinPath('..', pkg.publishConfig[`${stage}Types`]), - }, - { encoding: 'utf8', spaces: 2 }, - ); -} export const pre = async () => { - const pkgPath = paths.resolveTarget(PKG_PATH); - - const pkgContent = await fs.readFile(pkgPath, 'utf8'); - const pkg = JSON.parse(pkgContent); - await fs.writeFile(PKG_BACKUP_PATH, pkgContent); - - const publishConfig = pkg.publishConfig ?? {}; - for (const key of Object.keys(publishConfig)) { - if (!SKIPPED_KEYS.includes(key)) { - pkg[key] = publishConfig[key]; - } - } - await fs.writeJson(pkgPath, pkg, { encoding: 'utf8', spaces: 2 }); - - if (publishConfig.alphaTypes) { - await writeReleaseStageEntrypoint(pkg, 'alpha'); - } - if (publishConfig.betaTypes) { - await writeReleaseStageEntrypoint(pkg, 'beta'); - } + await productionPack({ packageDir: paths.targetDir }); }; export const post = async () => { - // postpack isn't called by yarn right now, so it needs to be called manually - try { - await fs.move(PKG_BACKUP_PATH, PKG_PATH, { overwrite: true }); - - // Check if we're shipping types for other release stages, clean up in that case - const pkg = await fs.readJson(PKG_PATH); - if (pkg.publishConfig?.alphaTypes) { - await fs.remove(paths.resolveTarget('alpha')); - } - if (pkg.publishConfig?.betaTypes) { - await fs.remove(paths.resolveTarget('beta')); - } - } catch (error) { - console.warn( - `Failed to restore package.json during postpack, ${error}. ` + - 'Your package will be fine but you may have ended up with some garbage in the repo.', - ); - } + await revertProductionPack(paths.targetDir); }; diff --git a/packages/cli/src/commands/repo/build.ts b/packages/cli/src/commands/repo/build.ts index a6bf87da82..d5602a4008 100644 --- a/packages/cli/src/commands/repo/build.ts +++ b/packages/cli/src/commands/repo/build.ts @@ -130,6 +130,7 @@ export async function command(opts: OptionValues, cmd: Command): Promise { return { targetDir: pkg.dir, + packageJson: pkg.packageJson, outputs, logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `, minify: buildOptions.minify, diff --git a/packages/cli/src/lib/builder/config.test.ts b/packages/cli/src/lib/builder/config.test.ts index a2e99da73b..733c35fb55 100644 --- a/packages/cli/src/lib/builder/config.test.ts +++ b/packages/cli/src/lib/builder/config.test.ts @@ -24,6 +24,11 @@ describe('makeRollupConfigs', () => { const [config] = await makeRollupConfigs({ outputs: new Set([Output.cjs]), + packageJson: { + name: 'test', + version: '0.0.0', + main: './src/index.ts', + }, }); const external = config.external as Exclude< ExternalOption, diff --git a/packages/cli/src/lib/builder/config.ts b/packages/cli/src/lib/builder/config.ts index 1cfaf15bfc..ecd755d05b 100644 --- a/packages/cli/src/lib/builder/config.ts +++ b/packages/cli/src/lib/builder/config.ts @@ -31,6 +31,10 @@ import { forwardFileImports } from './plugins'; import { BuildOptions, Output } from './types'; import { paths } from '../paths'; import { svgrTemplate } from '../svgrTemplate'; +import { ExtendedPackageJSON } from '../monorepo'; +import { readEntryPoints } from '../monorepo/entryPoints'; + +const SCRIPT_EXTS = ['.js', '.jsx', '.ts', '.tsx']; function isFileImport(source: string) { if (source.startsWith('.')) { @@ -50,6 +54,13 @@ export async function makeRollupConfigs( ): Promise { const configs = new Array(); const targetDir = options.targetDir ?? paths.targetDir; + + let targetPkg = options.packageJson; + if (!targetPkg) { + const packagePath = resolvePath(targetDir, 'package.json'); + targetPkg = (await fs.readJson(packagePath)) as ExtendedPackageJSON; + } + const onwarn = ({ code, message }: RollupWarning) => { if (code === 'EMPTY_BUNDLE') { return; // We don't care about this one @@ -62,111 +73,118 @@ export async function makeRollupConfigs( }; const distDir = resolvePath(targetDir, 'dist'); + const entryPoints = readEntryPoints(targetPkg); - if (options.outputs.has(Output.cjs) || options.outputs.has(Output.esm)) { - const output = new Array(); - const mainFields = ['module', 'main']; - - if (options.outputs.has(Output.cjs)) { - output.push({ - dir: distDir, - entryFileNames: 'index.cjs.js', - chunkFileNames: 'cjs/[name]-[hash].cjs.js', - format: 'commonjs', - sourcemap: true, - }); - } - if (options.outputs.has(Output.esm)) { - output.push({ - dir: distDir, - entryFileNames: 'index.esm.js', - chunkFileNames: 'esm/[name]-[hash].esm.js', - format: 'module', - sourcemap: true, - }); - // Assume we're building for the browser if ESM output is included - mainFields.unshift('browser'); + for (const { path, name, ext } of entryPoints) { + if (!SCRIPT_EXTS.includes(ext)) { + continue; } - configs.push({ - input: resolvePath(targetDir, 'src/index.ts'), - output, - onwarn, - preserveEntrySignatures: 'strict', - // All module imports are always marked as external - external: (source, importer, isResolved) => - Boolean(importer && !isResolved && !isFileImport(source)), - plugins: [ - resolve({ mainFields }), - commonjs({ - include: /node_modules/, - exclude: [/\/[^/]+\.(?:stories|test)\.[^/]+$/], - }), - postcss(), - forwardFileImports({ - exclude: /\.icon\.svg$/, - include: [ - /\.svg$/, - /\.png$/, - /\.gif$/, - /\.jpg$/, - /\.jpeg$/, - /\.eot$/, - /\.woff$/, - /\.woff2$/, - /\.ttf$/, - ], - }), - json(), - yaml(), - svgr({ - include: /\.icon\.svg$/, - template: svgrTemplate, - }), - esbuild({ - target: 'es2019', - minify: options.minify, - }), - ], - }); - } + if (options.outputs.has(Output.cjs) || options.outputs.has(Output.esm)) { + const output = new Array(); + const mainFields = ['module', 'main']; - if (options.outputs.has(Output.types) && !options.useApiExtractor) { - const typesInput = paths.resolveTargetRoot( - 'dist-types', - relativePath(paths.targetRoot, targetDir), - 'src/index.d.ts', - ); + if (options.outputs.has(Output.cjs)) { + output.push({ + dir: distDir, + entryFileNames: `${name}.cjs.js`, + chunkFileNames: `cjs/${name}/[name]-[hash].cjs.js`, + format: 'commonjs', + sourcemap: true, + }); + } + if (options.outputs.has(Output.esm)) { + output.push({ + dir: distDir, + entryFileNames: `${name}.esm.js`, + chunkFileNames: `esm/${name}/[name]-[hash].esm.js`, + format: 'module', + sourcemap: true, + }); + // Assume we're building for the browser if ESM output is included + mainFields.unshift('browser'); + } - const declarationsExist = await fs.pathExists(typesInput); - if (!declarationsExist) { - const path = relativePath(targetDir, typesInput); - throw new Error( - `No declaration files found at ${path}, be sure to run ${chalk.bgRed.white( - 'yarn tsc', - )} to generate .d.ts files before packaging`, + configs.push({ + input: resolvePath(targetDir, path), + output, + onwarn, + preserveEntrySignatures: 'strict', + // All module imports are always marked as external + external: (source, importer, isResolved) => + Boolean(importer && !isResolved && !isFileImport(source)), + plugins: [ + resolve({ mainFields }), + commonjs({ + include: /node_modules/, + exclude: [/\/[^/]+\.(?:stories|test)\.[^/]+$/], + }), + postcss(), + forwardFileImports({ + exclude: /\.icon\.svg$/, + include: [ + /\.svg$/, + /\.png$/, + /\.gif$/, + /\.jpg$/, + /\.jpeg$/, + /\.eot$/, + /\.woff$/, + /\.woff2$/, + /\.ttf$/, + ], + }), + json(), + yaml(), + svgr({ + include: /\.icon\.svg$/, + template: svgrTemplate, + }), + esbuild({ + target: 'es2019', + minify: options.minify, + }), + ], + }); + } + + if (options.outputs.has(Output.types) && !options.useApiExtractor) { + const typesInput = paths.resolveTargetRoot( + 'dist-types', + relativePath(paths.targetRoot, targetDir), + path.replace(/\.ts$/, '.d.ts'), ); - } - configs.push({ - input: typesInput, - output: { - file: resolvePath(distDir, 'index.d.ts'), - format: 'es', - }, - external: [ - /\.css$/, - /\.scss$/, - /\.sass$/, - /\.svg$/, - /\.eot$/, - /\.woff$/, - /\.woff2$/, - /\.ttf$/, - ], - onwarn, - plugins: [dts()], - }); + const declarationsExist = await fs.pathExists(typesInput); + if (!declarationsExist) { + const declarationPath = relativePath(targetDir, typesInput); + throw new Error( + `No declaration files found at ${declarationPath}, be sure to run ${chalk.bgRed.white( + 'yarn tsc', + )} to generate .d.ts files before packaging`, + ); + } + + configs.push({ + input: typesInput, + output: { + file: resolvePath(distDir, `${name}.d.ts`), + format: 'es', + }, + external: [ + /\.css$/, + /\.scss$/, + /\.sass$/, + /\.svg$/, + /\.eot$/, + /\.woff$/, + /\.woff2$/, + /\.ttf$/, + ], + onwarn, + plugins: [dts()], + }); + } } return configs; diff --git a/packages/cli/src/lib/builder/types.ts b/packages/cli/src/lib/builder/types.ts index f43d84cd92..de7e9b10eb 100644 --- a/packages/cli/src/lib/builder/types.ts +++ b/packages/cli/src/lib/builder/types.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { ExtendedPackageJSON } from '../monorepo'; + export enum Output { esm, cjs, @@ -23,6 +25,7 @@ export enum Output { export type BuildOptions = { logPrefix?: string; targetDir?: string; + packageJson?: ExtendedPackageJSON; outputs: Set; minify?: boolean; useApiExtractor?: boolean; diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index ce216f5c59..a6d757028f 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -15,7 +15,7 @@ */ import fs from 'fs-extra'; -import { resolve as resolvePath } from 'path'; +import { resolve as resolvePath, join as joinPath } from 'path'; import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'; import HtmlWebpackPlugin from 'html-webpack-plugin'; import ModuleScopePlugin from 'react-dev-utils/ModuleScopePlugin'; @@ -36,6 +36,8 @@ import { runPlain } from '../run'; import ESLintPlugin from 'eslint-webpack-plugin'; import pickBy from 'lodash/pickBy'; import yn from 'yn'; +import { readEntryPoints } from '../monorepo/entryPoints'; +import { ExtendedPackage } from '../monorepo'; const BUILD_CACHE_ENV_VAR = 'BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE'; @@ -232,7 +234,10 @@ export async function createBackendConfig( // Find all local monorepo packages and their node_modules, and mark them as external. const { packages } = await getPackages(cliPaths.targetDir); - const localPackageNames = packages.map(p => p.packageJson.name); + const localPackageEntryPoints = packages.flatMap(p => { + const entryPoints = readEntryPoints((p as ExtendedPackage).packageJson); + return entryPoints.map(e => joinPath(p.packageJson.name, e.mount)); + }); const moduleDirs = packages.map(p => resolvePath(p.dir, 'node_modules')); // See frontend config const externalPkgs = packages.filter(p => !isChildPath(paths.root, p.dir)); @@ -261,7 +266,7 @@ export async function createBackendConfig( nodeExternalsWithResolve({ modulesDir: paths.rootNodeModules, additionalModuleDirs: moduleDirs, - allowlist: ['webpack/hot/poll?100', ...localPackageNames], + allowlist: ['webpack/hot/poll?100', ...localPackageEntryPoints], }), ], target: 'node' as const, diff --git a/packages/cli/src/lib/monorepo/PackageGraph.ts b/packages/cli/src/lib/monorepo/PackageGraph.ts index a1fc95e669..bb203c01a5 100644 --- a/packages/cli/src/lib/monorepo/PackageGraph.ts +++ b/packages/cli/src/lib/monorepo/PackageGraph.ts @@ -20,10 +20,15 @@ import { paths } from '../paths'; import { PackageRole } from '../role'; import { listChangedFiles, readFileAtRef } from '../git'; import { Lockfile } from '../versioning'; +import { JsonValue } from '@backstage/types'; type PackageJSON = Package['packageJson']; export interface ExtendedPackageJSON extends PackageJSON { + main?: string; + module?: string; + types?: string; + scripts?: { [key: string]: string; }; @@ -34,6 +39,19 @@ export interface ExtendedPackageJSON extends PackageJSON { backstage?: { role?: PackageRole; }; + + exports?: JsonValue; + typesVersions?: Record>; + + files?: string[]; + + publishConfig?: { + access?: 'public' | 'restricted'; + directory?: string; + registry?: string; + alphaTypes?: string; + betaTypes?: string; + }; } export type ExtendedPackage = { diff --git a/packages/cli/src/lib/monorepo/entryPoints.ts b/packages/cli/src/lib/monorepo/entryPoints.ts new file mode 100644 index 0000000000..1e1fd7ed27 --- /dev/null +++ b/packages/cli/src/lib/monorepo/entryPoints.ts @@ -0,0 +1,77 @@ +/* + * 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 { extname } from 'path'; +import { ExtendedPackageJSON } from './PackageGraph'; + +export interface EntryPoint { + mount: string; + path: string; + name: string; + ext: string; +} + +// Unless explicitly specified in exports, the index entrypoint is always +// assumed to be at src/index.ts for backwards compatibility. +const defaultIndex = { + mount: '.', + path: 'src/index.ts', + name: 'index', + ext: '.ts', +}; + +function parseEntryPoint(mount: string, path: string): EntryPoint { + let name = mount; + if (name === '.') { + name = 'index'; + } else if (name.startsWith('./')) { + name = name.slice(2); + } + if (name.includes('/')) { + throw new Error(`Mount point '${mount}' may not contain multiple slashes`); + } + + return { mount, path, name, ext: extname(path) }; +} + +export function readEntryPoints(pkg: ExtendedPackageJSON): Array { + const exp = pkg.exports; + if (typeof exp === 'string') { + return [defaultIndex]; + } else if (exp && typeof exp === 'object' && !Array.isArray(exp)) { + const entryPoints = new Array<{ + mount: string; + path: string; + name: string; + ext: string; + }>(); + + for (const mount of Object.keys(exp)) { + const path = exp[mount]; + if (typeof path !== 'string') { + throw new Error( + `Exports field value must be a string, got '${JSON.stringify(path)}'`, + ); + } + + entryPoints.push(parseEntryPoint(mount, path)); + } + + return entryPoints; + } + + return [defaultIndex]; +} diff --git a/packages/cli/src/lib/packager/copyPackageDist.ts b/packages/cli/src/lib/packager/copyPackageDist.ts deleted file mode 100644 index b704148542..0000000000 --- a/packages/cli/src/lib/packager/copyPackageDist.ts +++ /dev/null @@ -1,93 +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 fs from 'fs-extra'; -import npmPackList from 'npm-packlist'; -import { join as joinPath, resolve as resolvePath } from 'path'; - -const SKIPPED_KEYS = ['access', 'registry', 'tag', 'alphaTypes', 'betaTypes']; - -function resolveEntrypoint(pkg: any, name: string) { - const targetEntry = pkg.publishConfig[name] || pkg[name]; - return targetEntry && joinPath('..', targetEntry); -} - -// Writes e.g. alpha/package.json -async function writeReleaseStageEntrypoint( - pkg: any, - stage: 'alpha' | 'beta', - targetDir: string, -) { - await fs.ensureDir(resolvePath(targetDir, stage)); - await fs.writeJson( - resolvePath(targetDir, stage, 'package.json'), - { - name: pkg.name, - version: pkg.version, - main: resolveEntrypoint(pkg, 'main'), - module: resolveEntrypoint(pkg, 'module'), - browser: resolveEntrypoint(pkg, 'browser'), - types: joinPath('..', pkg.publishConfig[`${stage}Types`]), - }, - { encoding: 'utf8', spaces: 2 }, - ); -} - -export async function copyPackageDist(packageDir: string, targetDir: string) { - const pkgPath = resolvePath(packageDir, 'package.json'); - const pkgContent = await fs.readFile(pkgPath, 'utf8'); - const pkg = JSON.parse(pkgContent); - - const publishConfig = pkg.publishConfig ?? {}; - for (const key of Object.keys(publishConfig)) { - if (!SKIPPED_KEYS.includes(key)) { - pkg[key] = publishConfig[key]; - } - } - - // We remove the dependencies from package.json of packages that are marked - // as bundled, so that yarn doesn't try to install them. - if (pkg.bundled) { - delete pkg.dependencies; - delete pkg.devDependencies; - delete pkg.peerDependencies; - delete pkg.optionalDependencies; - } - - // Lists all dist files, respecting .npmignore, files field in package.json, etc. - const filePaths = await npmPackList({ - path: packageDir, - // This makes sure we use the update package.json when listing files - packageJsonCache: new Map([[resolvePath(packageDir, 'package.json'), pkg]]), - }); - - await fs.ensureDir(targetDir); - for (const filePath of filePaths.sort()) { - const target = resolvePath(targetDir, filePath); - if (filePath === 'package.json') { - await fs.writeJson(target, pkg, { encoding: 'utf8', spaces: 2 }); - } else { - await fs.copy(resolvePath(packageDir, filePath), target); - } - } - - if (publishConfig.alphaTypes) { - await writeReleaseStageEntrypoint(pkg, 'alpha', targetDir); - } - if (publishConfig.betaTypes) { - await writeReleaseStageEntrypoint(pkg, 'beta', targetDir); - } -} diff --git a/packages/cli/src/lib/packager/createDistWorkspace.ts b/packages/cli/src/lib/packager/createDistWorkspace.ts index 5451a873f7..2d2967fc44 100644 --- a/packages/cli/src/lib/packager/createDistWorkspace.ts +++ b/packages/cli/src/lib/packager/createDistWorkspace.ts @@ -37,7 +37,7 @@ import { getOutputsForRole, Output, } from '../builder'; -import { copyPackageDist } from './copyPackageDist'; +import { productionPack } from './productionPack'; import { getRoleInfo } from '../role'; import { runParallelWorkers } from '../parallel'; @@ -178,6 +178,7 @@ export async function createDistWorkspace( if (outputs.size > 0) { standardBuilds.push({ targetDir: pkg.dir, + packageJson: pkg.packageJson, outputs: outputs, logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `, // No need to detect these for the backend builds, we assume no minification or types @@ -257,7 +258,10 @@ async function moveToDistWorkspace( const outputDir = relativePath(paths.targetRoot, target.dir); const absoluteOutputPath = resolvePath(workspaceDir, outputDir); - await copyPackageDist(target.dir, absoluteOutputPath); + await productionPack({ + packageDir: target.dir, + targetDir: absoluteOutputPath, + }); }), ); diff --git a/packages/cli/src/lib/packager/productionPack.ts b/packages/cli/src/lib/packager/productionPack.ts new file mode 100644 index 0000000000..b91112216a --- /dev/null +++ b/packages/cli/src/lib/packager/productionPack.ts @@ -0,0 +1,259 @@ +/* + * 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 fs from 'fs-extra'; +import npmPackList from 'npm-packlist'; +import { join as joinPath, resolve as resolvePath } from 'path'; +import { ExtendedPackageJSON } from '../monorepo'; +import { readEntryPoints } from '../monorepo/entryPoints'; + +const PKG_PATH = 'package.json'; +const PKG_BACKUP_PATH = 'package.json-prepack'; + +const SKIPPED_KEYS = ['access', 'registry', 'tag', 'alphaTypes', 'betaTypes']; +const SCRIPT_EXTS = ['.js', '.jsx', '.ts', '.tsx']; + +interface ProductionPackOptions { + packageDir: string; + targetDir?: string; +} + +export async function productionPack(options: ProductionPackOptions) { + const { packageDir, targetDir } = options; + const pkgPath = resolvePath(packageDir, PKG_PATH); + const pkgContent = await fs.readFile(pkgPath, 'utf8'); + const pkg = JSON.parse(pkgContent) as ExtendedPackageJSON; + + // If we're making the update in-line, back up the package.json + if (!targetDir) { + await fs.writeFile(PKG_BACKUP_PATH, pkgContent); + } + + const hasStageEntry = + !!pkg.publishConfig?.alphaTypes || !!pkg.publishConfig?.betaTypes; + if (pkg.exports && hasStageEntry) { + throw new Error( + 'Combining both exports and alpha/beta types is not supported', + ); + } + + // This mutates pkg to fill in index exports, so call it before applying publishConfig + const writeCompatibilityEntryPoints = await prepareExportsEntryPoints( + pkg, + packageDir, + ); + + // TODO(Rugvip): Once exports are rolled out more broadly we should deprecate and remove this behavior + const publishConfig = pkg.publishConfig ?? {}; + for (const key of Object.keys(publishConfig)) { + if (!SKIPPED_KEYS.includes(key)) { + (pkg as any)[key] = publishConfig[key as keyof typeof publishConfig]; + } + } + + // For published packages we rely on compatibility entry points rather than this + delete pkg.typesVersions; + + // We remove the dependencies from package.json of packages that are marked + // as bundled, so that yarn doesn't try to install them. + if (pkg.bundled) { + delete pkg.dependencies; + delete pkg.devDependencies; + delete pkg.peerDependencies; + delete pkg.optionalDependencies; + } + + if (targetDir) { + // Lists all dist files, respecting .npmignore, files field in package.json, etc. + const filePaths = await npmPackList({ + path: packageDir, + // This makes sure we use the updated package.json when listing files + packageJsonCache: new Map([ + [resolvePath(packageDir, PKG_PATH), pkg], + ]) as any, // Seems like this parameter type is wrong, + }); + + await fs.ensureDir(targetDir); + for (const filePath of filePaths.sort()) { + const target = resolvePath(targetDir, filePath); + if (filePath === PKG_PATH) { + await fs.writeJson(target, pkg, { encoding: 'utf8', spaces: 2 }); + } else { + await fs.copy(resolvePath(packageDir, filePath), target); + } + } + } else { + await fs.writeJson(pkgPath, pkg, { encoding: 'utf8', spaces: 2 }); + } + + if (publishConfig.alphaTypes) { + await writeReleaseStageEntrypoint(pkg, 'alpha', targetDir ?? packageDir); + } + if (publishConfig.betaTypes) { + await writeReleaseStageEntrypoint(pkg, 'beta', targetDir ?? packageDir); + } + if (writeCompatibilityEntryPoints) { + await writeCompatibilityEntryPoints(targetDir ?? packageDir); + } +} + +// Reverts the changes made by productionPack when called without a targetDir. +export async function revertProductionPack(packageDir: string) { + // postpack isn't called by yarn right now, so it needs to be called manually + try { + await fs.move(PKG_BACKUP_PATH, PKG_PATH, { overwrite: true }); + + // Check if we're shipping types for other release stages, clean up in that case + const pkg = await fs.readJson(PKG_PATH); + if (pkg.publishConfig?.alphaTypes) { + await fs.remove(resolvePath(packageDir, 'alpha')); + } + if (pkg.publishConfig?.betaTypes) { + await fs.remove(resolvePath(packageDir, 'beta')); + } + + // Remove any extra entrypoint backwards compatibility directories + const entryPoints = readEntryPoints(pkg); + for (const entryPoint of entryPoints) { + if (entryPoint.mount !== '.' && SCRIPT_EXTS.includes(entryPoint.ext)) { + await fs.remove(resolvePath(packageDir, entryPoint.name)); + } + } + } catch (error) { + console.warn( + `Failed to restore package.json, ${error}. ` + + 'Your package will be fine but you may have ended up with some garbage in the repo.', + ); + } +} + +function resolveEntrypoint(pkg: any, name: string) { + const targetEntry = pkg.publishConfig[name] || pkg[name]; + return targetEntry && joinPath('..', targetEntry); +} + +// Writes e.g. alpha/package.json +async function writeReleaseStageEntrypoint( + pkg: ExtendedPackageJSON, + stage: 'alpha' | 'beta', + targetDir: string, +) { + await fs.ensureDir(resolvePath(targetDir, stage)); + await fs.writeJson( + resolvePath(targetDir, stage, PKG_PATH), + { + name: pkg.name, + version: pkg.version, + main: resolveEntrypoint(pkg, 'main'), + module: resolveEntrypoint(pkg, 'module'), + browser: resolveEntrypoint(pkg, 'browser'), + types: joinPath('..', pkg.publishConfig![`${stage}Types`]!), + }, + { encoding: 'utf8', spaces: 2 }, + ); +} + +const EXPORT_MAP = { + import: '.esm.js', + require: '.cjs.js', + types: '.d.ts', +}; + +/** + * Rewrites the exports field in package.json to point to dist files, as + * well as returning a function that creates backwards compatibility + * entry points for importers that don't support exports. + */ +async function prepareExportsEntryPoints( + pkg: ExtendedPackageJSON, + packageDir: string, +) { + const distPath = resolvePath(packageDir, 'dist'); + if (!(await fs.pathExists(distPath))) { + return undefined; + } + const distFiles = await fs.readdir(distPath); + const outputExports = {} as Record>; + + const compatibilityWriters = new Array< + (targetDir: string) => Promise + >(); + + const entryPoints = readEntryPoints(pkg); + for (const entryPoint of entryPoints) { + if (!SCRIPT_EXTS.includes(entryPoint.ext)) { + continue; + } + const exp = {} as Record; + for (const [key, ext] of Object.entries(EXPORT_MAP)) { + const name = `${entryPoint.name}${ext}`; + if (distFiles.includes(name)) { + exp[key] = `./${joinPath(`dist`, name)}`; + } + } + exp.default = exp.require ?? exp.import; + + // This creates a directory with a lone package.json for backwards compatibility + if (entryPoint.mount === '.') { + if (exp.default) { + pkg.main = exp.default; + } + if (exp.import) { + pkg.module = exp.import; + } + if (exp.types) { + pkg.types = exp.types; + } + } else { + // This is deferred until after we have created the target directory + compatibilityWriters.push(async targetDir => { + const entryPointDir = resolvePath(targetDir, entryPoint.name); + await fs.ensureDir(entryPointDir); + await fs.writeJson( + resolvePath(entryPointDir, PKG_PATH), + { + name: pkg.name, + version: pkg.version, + ...(exp.default ? { main: joinPath('..', exp.default) } : {}), + ...(exp.import ? { module: joinPath('..', exp.import) } : {}), + ...(exp.types ? { types: joinPath('..', exp.types) } : {}), + }, + { encoding: 'utf8', spaces: 2 }, + ); + }); + if (Array.isArray(pkg.files) && !pkg.files.includes(entryPoint.name)) { + pkg.files.push(entryPoint.name); + } + } + + if (Object.keys(exp).length > 0) { + outputExports[entryPoint.mount] = exp; + } + } + + if (pkg.exports) { + pkg.exports = outputExports; + // We treat package.json as a fixed export that is always available in the published package + pkg.exports['./package.json'] = './package.json'; + } + + if (compatibilityWriters.length > 0) { + return async (targetDir: string) => { + await Promise.all(compatibilityWriters.map(writer => writer(targetDir))); + }; + } + return undefined; +} diff --git a/packages/cli/templates/default-backend-plugin/package.json.hbs b/packages/cli/templates/default-backend-plugin/package.json.hbs index 3a9091e87f..2b860260ac 100644 --- a/packages/cli/templates/default-backend-plugin/package.json.hbs +++ b/packages/cli/templates/default-backend-plugin/package.json.hbs @@ -30,8 +30,8 @@ "dependencies": { "@backstage/backend-common": "{{versionQuery '@backstage/backend-common'}}", "@backstage/config": "{{versionQuery '@backstage/config'}}", - "@types/express": "{{versionQuery '@types/express' '4.17.13'}}", - "express": "{{versionQuery 'express' '4.18.1'}}", + "@types/express": "{{versionQuery '@types/express' '4.17.6'}}", + "express": "{{versionQuery 'express' '4.17.1'}}", "express-promise-router": "{{versionQuery 'express-promise-router' '4.1.0'}}", "winston": "{{versionQuery 'winston' '3.2.1'}}", "node-fetch": "{{versionQuery 'node-fetch' '2.6.7'}}", @@ -41,7 +41,7 @@ "@backstage/cli": "{{versionQuery '@backstage/cli'}}", "@types/supertest": "{{versionQuery '@types/supertest' '2.0.12'}}", "supertest": "{{versionQuery 'supertest' '6.2.4'}}", - "msw": "{{versionQuery 'msw' '0.49.0'}}" + "msw": "{{versionQuery 'msw' '1.0.0'}}" }, "files": [ "dist" diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs index d319b16449..de42f3cdef 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -48,7 +48,7 @@ "@testing-library/react": "{{versionQuery '@testing-library/react' '12.1.3'}}", "@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '14.0.0'}}", "@types/node": "{{versionQuery '@types/node' '16.11.26'}}", - "msw": "{{versionQuery 'msw' '0.49.0'}}", + "msw": "{{versionQuery 'msw' '1.0.0'}}", "cross-fetch": "{{versionQuery 'cross-fetch' '3.1.5'}}" }, "files": [ diff --git a/packages/cli/templates/default-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs b/packages/cli/templates/default-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs index 159fcd70c5..03b25dfb4f 100644 --- a/packages/cli/templates/default-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs +++ b/packages/cli/templates/default-plugin/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs @@ -1,7 +1,7 @@ import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; -import { Table, TableColumn, Progress } from '@backstage/core-components'; -import Alert from '@material-ui/lab/Alert'; +import { Table, TableColumn, Progress, ResponseErrorPanel } from '@backstage/core-components'; +import { fetchApiRef, useApi } from '@backstage/core-plugin-api'; import useAsync from 'react-use/lib/useAsync'; const useStyles = makeStyles({ @@ -74,6 +74,7 @@ export const DenseTable = ({ users }: DenseTableProps) => { }; export const ExampleFetchComponent = () => { + const { fetch } = useApi(fetchApiRef); const { value, loading, error } = useAsync(async (): Promise => { const response = await fetch('https://randomuser.me/api/?results=20'); const data = await response.json(); @@ -83,7 +84,7 @@ export const ExampleFetchComponent = () => { if (loading) { return ; } else if (error) { - return {error.message}; + return ; } return ; diff --git a/packages/codemods/CHANGELOG.md b/packages/codemods/CHANGELOG.md index 5dc610d5c1..c3387fce64 100644 --- a/packages/codemods/CHANGELOG.md +++ b/packages/codemods/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/codemods +## 0.1.43 + +### Patch Changes + +- 02f1316e57: Moved `commander` to being a regular dependency. +- Updated dependencies + - @backstage/cli-common@0.1.11 + ## 0.1.43-next.0 ### Patch Changes diff --git a/packages/codemods/package.json b/packages/codemods/package.json index 7c6af890b0..17649d49cf 100644 --- a/packages/codemods/package.json +++ b/packages/codemods/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/codemods", "description": "A collection of codemods for Backstage projects", - "version": "0.1.43-next.0", + "version": "0.1.43", "publishConfig": { "access": "public", "main": "dist/index.cjs.js" diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index c78eb632da..657c6630eb 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -56,7 +56,7 @@ "@types/node": "^16.11.26", "@types/yup": "^0.29.13", "mock-fs": "^5.1.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 1d682dbc4a..4575040798 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/core-app-api +## 1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.5.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- dff4d8ddb1: Fixed an issue where an explicit port the frontend base URL could break the app. +- Updated dependencies + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + ## 1.4.1-next.0 ### Patch Changes diff --git a/packages/core-app-api/api-report.md b/packages/core-app-api/api-report.md index 133ac22e5b..37f7a98de0 100644 --- a/packages/core-app-api/api-report.md +++ b/packages/core-app-api/api-report.md @@ -22,6 +22,7 @@ import { BackstageIdentityApi } from '@backstage/core-plugin-api'; import { BackstageIdentityResponse } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { bitbucketAuthApiRef } from '@backstage/core-plugin-api'; +import { bitbucketServerAuthApiRef } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; import { Config } from '@backstage/config'; import { ConfigReader } from '@backstage/config'; @@ -280,6 +281,25 @@ export class BitbucketAuth { static create(options: OAuthApiCreateOptions): typeof bitbucketAuthApiRef.T; } +// @public +export class BitbucketServerAuth { + // (undocumented) + static create( + options: OAuthApiCreateOptions, + ): typeof bitbucketServerAuthApiRef.T; +} + +// @public +export type BitbucketServerSession = { + providerInfo: { + accessToken: string; + scopes: Set; + expiresAt?: Date; + }; + profile: ProfileInfo; + backstageIdentity: BackstageIdentityResponse; +}; + // @public export type BitbucketSession = { providerInfo: { diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 391771bd5c..c43b27009b 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.4.1-next.0", + "version": "1.5.1-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -57,7 +57,7 @@ "@types/node": "^16.11.26", "@types/zen-observable": "^0.8.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0", + "msw": "^1.0.0", "react-router-beta": "npm:react-router@6.0.0-beta.0", "react-router-dom-beta": "npm:react-router-dom@6.0.0-beta.0", "react-router-dom-stable": "npm:react-router-dom@^6.3.0", diff --git a/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.test.ts b/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.test.ts new file mode 100644 index 0000000000..32e7755a00 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.test.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi'; +import { UrlPatternDiscovery } from '../../DiscoveryApi'; +import BitbucketServerAuth from './BitbucketServerAuth'; + +const getSession = jest.fn(); + +jest.mock('../../../../lib/AuthSessionManager', () => ({ + ...(jest.requireActual('../../../../lib/AuthSessionManager') as any), + RefreshingAuthSessionManager: class { + getSession = getSession; + }, +})); + +describe('BitbucketServerAuth', () => { + afterEach(() => { + jest.resetAllMocks(); + }); + + it.each([ + ['PUBLIC_REPOS', ['PUBLIC_REPOS']], + ['PROJECT_ADMIN REPO_READ', ['PROJECT_ADMIN', 'REPO_READ']], + [ + 'PROJECT_ADMIN REPO_READ ACCOUNT_WRITE', + ['PROJECT_ADMIN', 'REPO_READ', 'ACCOUNT_WRITE'], + ], + ])(`should normalize scopes correctly - %p`, (scope, scopes) => { + const bitbucketServerAuth = BitbucketServerAuth.create({ + oauthRequestApi: new MockOAuthApi(), + discoveryApi: UrlPatternDiscovery.compile('http://example.com'), + }); + + bitbucketServerAuth.getAccessToken(scope); + expect(getSession).toHaveBeenCalledWith({ scopes: new Set(scopes) }); + }); +}); diff --git a/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.ts b/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.ts new file mode 100644 index 0000000000..dc50eff6ab --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/BitbucketServerAuth.ts @@ -0,0 +1,66 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + BackstageIdentityResponse, + bitbucketServerAuthApiRef, + ProfileInfo, +} from '@backstage/core-plugin-api'; + +import { OAuthApiCreateOptions } from '../types'; +import { OAuth2 } from '../oauth2'; + +export type BitbucketServerAuthResponse = { + providerInfo: { + accessToken: string; + scope: string; + expiresInSeconds: number; + }; + profile: ProfileInfo; + backstageIdentity: BackstageIdentityResponse; +}; + +const DEFAULT_PROVIDER = { + id: 'bitbucketServer', + title: 'Bitbucket Server', + icon: () => null, +}; + +/** + * Implements the OAuth flow to Bitbucket Server. + * @public + */ +export default class BitbucketServerAuth { + static create( + options: OAuthApiCreateOptions, + ): typeof bitbucketServerAuthApiRef.T { + const { + discoveryApi, + environment = 'development', + provider = DEFAULT_PROVIDER, + oauthRequestApi, + defaultScopes = ['PROJECT_ADMIN'], + } = options; + + return OAuth2.create({ + discoveryApi, + oauthRequestApi, + provider, + environment, + defaultScopes, + }); + } +} diff --git a/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/index.ts b/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/index.ts new file mode 100644 index 0000000000..5fcb8f72f2 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './types'; +export { default as BitbucketServerAuth } from './BitbucketServerAuth'; diff --git a/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/types.ts b/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/types.ts new file mode 100644 index 0000000000..1041aa8110 --- /dev/null +++ b/packages/core-app-api/src/apis/implementations/auth/bitbucketServer/types.ts @@ -0,0 +1,35 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + ProfileInfo, + BackstageIdentityResponse, +} from '@backstage/core-plugin-api'; + +/** + * Session information for Bitbucket Server auth. + * + * @public + */ +export type BitbucketServerSession = { + providerInfo: { + accessToken: string; + scopes: Set; + expiresAt?: Date; + }; + profile: ProfileInfo; + backstageIdentity: BackstageIdentityResponse; +}; diff --git a/packages/core-app-api/src/apis/implementations/auth/index.ts b/packages/core-app-api/src/apis/implementations/auth/index.ts index c4cf520db5..b54e0424da 100644 --- a/packages/core-app-api/src/apis/implementations/auth/index.ts +++ b/packages/core-app-api/src/apis/implementations/auth/index.ts @@ -23,5 +23,6 @@ export * from './saml'; export * from './microsoft'; export * from './onelogin'; export * from './bitbucket'; +export * from './bitbucketServer'; export * from './atlassian'; export type { OAuthApiCreateOptions, AuthApiCreateOptions } from './types'; diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 30c4e92173..5ad035fbfd 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/core-components +## 0.12.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/version-bridge@1.0.3 + +## 0.12.4 + +### Patch Changes + +- 68ce7d0417: Added aria labels on the support button and sidebar +- 5637ebed92: Added a global override for `window.open` that helps prevent security vulnerabilities. +- 910015f5b7: The Button component has been deprecated in favor of the LinkButton component +- 20840b36b4: Adds new type, TableOptions, extending Material Table Options. +- e81a6e0ab5: Updated Link URL validation to be more strict. +- 85b04f659a: Internal refactor to not use deprecated `substr` +- 66e2aab4c4: Navigation items in mobile sidebar now have aria label. +- Updated dependencies + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/version-bridge@1.0.3 + ## 0.12.4-next.1 ### Patch Changes diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 721c208406..6439be23a7 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -131,7 +131,7 @@ export type BreadcrumbsStyledBoxClassKey = 'root'; export function BrokenImageIcon(props: IconComponentProps): JSX.Element; // @public @deprecated (undocumented) -export const Button: (props: ButtonProps) => JSX.Element; +export const Button: (props: LinkButtonProps) => JSX.Element; // @public @deprecated (undocumented) export type ButtonProps = LinkButtonProps; @@ -631,7 +631,7 @@ export function LinearGauge(props: Props_11): JSX.Element | null; export const Link: (props: LinkProps) => JSX.Element; // @public -export const LinkButton: (props: ButtonProps) => JSX.Element; +export const LinkButton: (props: LinkButtonProps) => JSX.Element; // @public export type LinkButtonProps = ButtonProps_2 & diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 7eedac93ac..aa47734d8b 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.12.4-next.1", + "version": "0.12.5-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -98,7 +98,7 @@ "@types/react-window": "^1.8.5", "@types/zen-observable": "^0.8.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/packages/core-components/src/components/Link/Link.test.tsx b/packages/core-components/src/components/Link/Link.test.tsx index 3538b79052..682c4bea8a 100644 --- a/packages/core-components/src/components/Link/Link.test.tsx +++ b/packages/core-components/src/components/Link/Link.test.tsx @@ -173,4 +173,24 @@ describe('', () => { }); }); }); + + it('throws an error when attempting to link to script code', () => { + expect(() => + // eslint-disable-next-line no-script-url + render(wrapInTestApp(Script)), + ).toThrowErrorMatchingInlineSnapshot( + `"Link component rejected javascript: URL as a security precaution"`, + ); + }); +}); + +describe('window.open', () => { + it('throws an error when attempting to open script code', () => { + expect(() => + // eslint-disable-next-line no-script-url + window.open("javascript:alert('hello')"), + ).toThrowErrorMatchingInlineSnapshot( + `"Rejected window.open() with a javascript: URL as a security precaution"`, + ); + }); }); diff --git a/packages/core-components/src/components/Link/Link.tsx b/packages/core-components/src/components/Link/Link.tsx index 440fcb811f..be91753ea3 100644 --- a/packages/core-components/src/components/Link/Link.tsx +++ b/packages/core-components/src/components/Link/Link.tsx @@ -55,6 +55,32 @@ const useStyles = makeStyles( export const isExternalUri = (uri: string) => /^([a-z+.-]+):/.test(uri); +// See https://github.com/facebook/react/blob/f0cf832e1d0c8544c36aa8b310960885a11a847c/packages/react-dom-bindings/src/shared/sanitizeURL.js +const scriptProtocolPattern = + // eslint-disable-next-line no-control-regex + /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; + +// We install this globally in order to prevent javascript: URL XSS attacks via window.open +const originalWindowOpen = window.open as typeof window.open & { + __backstage?: true; +}; +if (originalWindowOpen && !originalWindowOpen.__backstage) { + const newOpen = function open( + this: Window, + ...args: Parameters + ) { + const url = String(args[0]); + if (scriptProtocolPattern.test(url)) { + throw new Error( + 'Rejected window.open() with a javascript: URL as a security precaution', + ); + } + return originalWindowOpen.apply(this, args); + }; + newOpen.__backstage = true; + window.open = newOpen; +} + export type LinkProps = Omit & Omit & { to: string; @@ -144,6 +170,12 @@ export const Link = React.forwardRef( const external = isExternalUri(to); const newWindow = external && !!/^https?:/.exec(to); + if (scriptProtocolPattern.test(to)) { + throw new Error( + 'Link component rejected javascript: URL as a security precaution', + ); + } + const handleClick = (event: React.MouseEvent) => { onClick?.(event); if (!noTrack) { diff --git a/packages/core-components/src/components/LinkButton/LinkButton.tsx b/packages/core-components/src/components/LinkButton/LinkButton.tsx index a6ba4d67a7..7da25bcb41 100644 --- a/packages/core-components/src/components/LinkButton/LinkButton.tsx +++ b/packages/core-components/src/components/LinkButton/LinkButton.tsx @@ -44,9 +44,11 @@ const LinkWrapper = React.forwardRef((props, ref) => ( * @public * @remarks */ -export const LinkButton = React.forwardRef((props, ref) => ( - -)) as (props: ButtonProps) => JSX.Element; +export const LinkButton = React.forwardRef( + (props, ref) => ( + + ), +) as (props: LinkButtonProps) => JSX.Element; /** * @public diff --git a/packages/core-components/src/layout/ErrorBoundary/ErrorBoundary.tsx b/packages/core-components/src/layout/ErrorBoundary/ErrorBoundary.tsx index 9157b57fe2..037e170640 100644 --- a/packages/core-components/src/layout/ErrorBoundary/ErrorBoundary.tsx +++ b/packages/core-components/src/layout/ErrorBoundary/ErrorBoundary.tsx @@ -16,7 +16,7 @@ import Typography from '@material-ui/core/Typography'; import React, { ComponentClass, Component, ErrorInfo } from 'react'; -import { Button } from '../../components/LinkButton'; +import { LinkButton } from '../../components/LinkButton'; import { ErrorPanel } from '../../components/ErrorPanel'; type SlackChannel = { @@ -49,9 +49,9 @@ const SlackLink = (props: { slackChannel?: string | SlackChannel }) => { } return ( - + ); }; diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index aac062c01b..48e0a8906a 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -104,7 +104,7 @@ export function HeaderTabs(props: HeaderTabsProps) { textColor="inherit" variant="scrollable" scrollButtons="auto" - aria-label="scrollable auto tabs example" + aria-label="tabs" onChange={handleChange} value={selectedTab} > diff --git a/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx b/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx index f7df3d43cc..1ba3dec3fd 100644 --- a/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx +++ b/packages/core-components/src/layout/ItemCard/ItemCard.stories.tsx @@ -22,7 +22,7 @@ import CardMedia from '@material-ui/core/CardMedia'; import Typography from '@material-ui/core/Typography'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; -import { Button } from '../../components'; +import { LinkButton } from '../../components'; import { ItemCardGrid } from './ItemCardGrid'; import { ItemCardHeader } from './ItemCardHeader'; @@ -63,9 +63,9 @@ export const Default = () => ( .join(' ')} - + ))} @@ -99,9 +99,9 @@ export const Styling = () => { .join(' ')} - + ))} diff --git a/packages/core-components/src/layout/ItemCard/ItemCard.tsx b/packages/core-components/src/layout/ItemCard/ItemCard.tsx index fedcf7de8f..0b1ee34c0c 100644 --- a/packages/core-components/src/layout/ItemCard/ItemCard.tsx +++ b/packages/core-components/src/layout/ItemCard/ItemCard.tsx @@ -21,7 +21,7 @@ import CardContent from '@material-ui/core/CardContent'; import CardMedia from '@material-ui/core/CardMedia'; import Chip from '@material-ui/core/Chip'; import React, { ReactNode } from 'react'; -import { Button } from '../../components'; +import { LinkButton } from '../../components'; import { ItemCardHeader } from './ItemCardHeader'; type ItemCardProps = { @@ -80,14 +80,14 @@ export function ItemCard(props: ItemCardProps) { {!href && ( - + )} {href && ( - + )} diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index 88208e4430..e2da5bc048 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/core-plugin-api +## 1.4.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + +## 1.4.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + ## 1.3.0 ### Minor Changes diff --git a/packages/core-plugin-api/alpha-api-report.md b/packages/core-plugin-api/alpha-api-report.md new file mode 100644 index 0000000000..379e186df8 --- /dev/null +++ b/packages/core-plugin-api/alpha-api-report.md @@ -0,0 +1,26 @@ +## API Report File for "@backstage/core-plugin-api" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { ReactNode } from 'react'; + +// @alpha +export interface PluginOptionsProviderProps { + // (undocumented) + children: ReactNode; + // (undocumented) + plugin?: BackstagePlugin; +} + +// @alpha +export const PluginProvider: (props: PluginOptionsProviderProps) => JSX.Element; + +// @alpha +export function usePluginOptions< + TPluginOptions extends {} = {}, +>(): TPluginOptions; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index dc7aa9eb5f..4887f0b7f2 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -241,6 +241,11 @@ export const bitbucketAuthApiRef: ApiRef< OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi >; +// @public +export const bitbucketServerAuthApiRef: ApiRef< + OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi +>; + // @public export type BootErrorPageProps = { step: 'load-config' | 'load-chunk'; @@ -644,17 +649,6 @@ export type PluginFeatureFlagConfig = { name: string; }; -// @alpha -export interface PluginOptionsProviderProps { - // (undocumented) - children: ReactNode; - // (undocumented) - plugin?: BackstagePlugin; -} - -// @alpha -export const PluginProvider: (props: PluginOptionsProviderProps) => JSX.Element; - // @public export type ProfileInfo = { email?: string; @@ -755,11 +749,6 @@ export function useElementFilter( dependencies?: any[], ): T; -// @alpha -export function usePluginOptions< - TPluginOptions extends {} = {}, ->(): TPluginOptions; - // @public export function useRouteRef( routeRef: ExternalRouteRef, diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index 490ef25fbe..1da87fa457 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -1,12 +1,24 @@ { "name": "@backstage/core-plugin-api", "description": "Core API used by Backstage plugins", - "version": "1.3.0", + "version": "1.4.1-next.0", "publishConfig": { - "access": "public", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "web-library" @@ -24,7 +36,7 @@ "main": "src/index.ts", "types": "src/index.ts", "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -57,10 +69,9 @@ "@types/prop-types": "^15.7.3", "@types/zen-observable": "^0.8.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ - "dist", - "alpha" + "dist" ] } diff --git a/packages/core-plugin-api/src/alpha.ts b/packages/core-plugin-api/src/alpha.ts new file mode 100644 index 0000000000..09983a48e9 --- /dev/null +++ b/packages/core-plugin-api/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './plugin-options'; diff --git a/packages/core-plugin-api/src/apis/definitions/auth.ts b/packages/core-plugin-api/src/apis/definitions/auth.ts index 163ae74806..43597639b6 100644 --- a/packages/core-plugin-api/src/apis/definitions/auth.ts +++ b/packages/core-plugin-api/src/apis/definitions/auth.ts @@ -412,6 +412,21 @@ export const bitbucketAuthApiRef: ApiRef< id: 'core.auth.bitbucket', }); +/** + * Provides authentication towards Bitbucket Server APIs. + * + * @public + * @remarks + * + * See {@link https://confluence.atlassian.com/bitbucketserver/bitbucket-oauth-2-0-provider-api-1108483661.html#BitbucketOAuth2.0providerAPI-scopes} + * for a full list of supported scopes. + */ +export const bitbucketServerAuthApiRef: ApiRef< + OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi +> = createApiRef({ + id: 'core.auth.bitbucket-server', +}); + /** * Provides authentication towards Atlassian APIs. * diff --git a/packages/core-plugin-api/src/index.ts b/packages/core-plugin-api/src/index.ts index e8edd38ff3..30fc35b62a 100644 --- a/packages/core-plugin-api/src/index.ts +++ b/packages/core-plugin-api/src/index.ts @@ -22,7 +22,6 @@ export * from './analytics'; export * from './apis'; -export * from './plugin-options'; export * from './app'; export * from './extensions'; export * from './icons'; diff --git a/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx b/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx index 4fdacc1ace..8b3f7c109c 100644 --- a/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx +++ b/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx @@ -19,7 +19,7 @@ import { createVersionedValueMap, useVersionedContext, } from '@backstage/version-bridge'; -import { BackstagePlugin } from '../plugin'; +import { BackstagePlugin } from '@backstage/core-plugin-api'; import React, { ReactNode } from 'react'; const contextKey: string = 'plugin-context'; diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index 198d4d92a9..149c474022 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/create-app +## 0.4.38-next.0 + +### Patch Changes + +- Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.11 + +## 0.4.37 + +### Patch Changes + +- 12a7b316ee: Bumped create-app version. +- 86a8dfd7b0: Added a check to ensure that Yarn v1 is used when creating new projects. +- 0eaa579f89: Update `SearchPage` template to use `SearchResult` extensions. +- 02f1316e57: Updated `packages/app/cypress/.eslintrc.json` to remove the unnecessary `import/no-extraneous-dependencies` rule. +- Updated dependencies + - @backstage/cli-common@0.1.11 + ## 0.4.37-next.2 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index cfdccc5a2b..6ca80a519c 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "A CLI that helps you create your own Backstage app", - "version": "0.4.37-next.2", + "version": "0.4.38-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 6996180db5..ae7c5a3282 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/dev-utils +## 1.0.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/test-utils@1.2.6-next.0 + - @backstage/app-defaults@1.2.1-next.0 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + +## 1.0.12 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/app-defaults@1.2.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/integration-react@1.1.10 + - @backstage/test-utils@1.2.5 + ## 1.0.12-next.2 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 773dc3cac0..2680401145 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "1.0.12-next.2", + "version": "1.0.13-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/packages/e2e-test/CHANGELOG.md b/packages/e2e-test/CHANGELOG.md index d872d34664..c3345a5815 100644 --- a/packages/e2e-test/CHANGELOG.md +++ b/packages/e2e-test/CHANGELOG.md @@ -1,5 +1,14 @@ # e2e-test +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.4.38-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/errors@1.1.4 + ## 0.2.0 ### Minor Changes diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index ee447a1736..969c68feb3 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.0", + "version": "0.2.1-next.0", "private": true, "backstage": { "role": "cli" @@ -28,6 +28,7 @@ "bin": "bin/e2e-test", "dependencies": { "@backstage/cli-common": "workspace:^", + "@backstage/create-app": "workspace:^", "@backstage/errors": "workspace:^", "chalk": "^4.0.0", "commander": "^9.1.0", diff --git a/packages/e2e-test/src/commands/run.ts b/packages/e2e-test/src/commands/run.ts index 254198ebb4..b3fb8d9a3c 100644 --- a/packages/e2e-test/src/commands/run.ts +++ b/packages/e2e-test/src/commands/run.ts @@ -490,6 +490,17 @@ async function testBackendStart(appDir: string, ...args: string[]) { !l.includes('Update this package.json to use a subpath') && !l.includes( '(Use `node --trace-deprecation ...` to show where the warning was created)', + ) && + // These 4 are all for the AWS SDK v2 deprecation + !l.includes( + 'The AWS SDK for JavaScript (v2) will be put into maintenance mode', + ) && + !l.includes( + 'Please migrate your code to use AWS SDK for JavaScript', + ) && + !l.includes('check the migration guide at https://a.co/7PzMCcy') && + !l.includes( + '(Use `node --trace-warnings ...` to show where the warning was created)', ), ).length !== 0 ); diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index 35e3c8f0ea..7e5a3efbae 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/eslint-plugin +## 0.1.2-next.0 + +### Patch Changes + +- a061c466d6: Fixing a bug that we should check internal dependencies too + +## 0.1.0 + +### Minor Changes + +- 179d301518: Added a new ESLint plugin with common rules for Backstage projects. See the [README](https://github.com/import-js/eslint-plugin-import/blob/main/packages/eslint-plugin/README.md) for more details. + ## 0.1.0-next.0 ### Minor Changes diff --git a/packages/eslint-plugin/lib/visitImports.js b/packages/eslint-plugin/lib/visitImports.js index 43401bf5f9..1a344c1101 100644 --- a/packages/eslint-plugin/lib/visitImports.js +++ b/packages/eslint-plugin/lib/visitImports.js @@ -34,6 +34,7 @@ const getPackages = require('./getPackages'); * @property {'value' | 'type'} kind * @property {string} path * @property {import('./getPackages').ExtendedPackage} package + * @property {string} packageName */ /** @@ -160,6 +161,7 @@ module.exports = function visitImports(context, visitor) { kind: info.kind, path: subPath, package: pkg, + packageName, }); } diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 0aea11d370..fcc038cdbf 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/eslint-plugin", "description": "Backstage ESLint plugin", - "version": "0.1.0-next.0", + "version": "0.1.2-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/eslint-plugin/rules/no-undeclared-imports.js b/packages/eslint-plugin/rules/no-undeclared-imports.js index 42624beb5c..b1e11d1b97 100644 --- a/packages/eslint-plugin/rules/no-undeclared-imports.js +++ b/packages/eslint-plugin/rules/no-undeclared-imports.js @@ -151,11 +151,18 @@ module.exports = { } return visitImports(context, (node, imp) => { - if (imp.type !== 'external') { + // We leave checking of type imports to the repo-tools check, + // and we skip builtins and local imports + if ( + imp.kind === 'type' || + imp.type === 'builtin' || + imp.type === 'local' + ) { return; } - // We leave checking of type imports to the repo-tools check - if (imp.kind === 'type') { + + // We skip imports for the package itself + if (imp.packageName === localPkg.packageJson.name) { return; } diff --git a/packages/eslint-plugin/src/__fixtures__/monorepo/packages/node_modules/@internal/foo/index.js b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/node_modules/@internal/foo/index.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/eslint-plugin/src/__fixtures__/monorepo/packages/node_modules/@internal/foo/package.json b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/node_modules/@internal/foo/package.json new file mode 100644 index 0000000000..c15a2c1718 --- /dev/null +++ b/packages/eslint-plugin/src/__fixtures__/monorepo/packages/node_modules/@internal/foo/package.json @@ -0,0 +1,17 @@ +{ + "name": "@internal/foo", + "main": "index.js", + "dependencies": { + "@internal/bar": "1.0.0" + }, + "devDependencies": { + "lodash": "*" + }, + "peerDependencies": { + "react": "*" + }, + "files": [ + "dist", + "type-utils" + ] +} diff --git a/packages/eslint-plugin/src/no-undeclared-imports.test.ts b/packages/eslint-plugin/src/no-undeclared-imports.test.ts index 1b5cbee853..78844899ba 100644 --- a/packages/eslint-plugin/src/no-undeclared-imports.test.ts +++ b/packages/eslint-plugin/src/no-undeclared-imports.test.ts @@ -236,5 +236,16 @@ ruleTester.run(RULE, rule, { ), ], }, + { + code: `import '@internal/foo'`, + filename: joinPath(FIXTURE, 'packages/bar/src/index.ts'), + errors: [ + ERR_UNDECLARED( + '@internal/foo', + 'dependencies', + joinPath('packages', 'bar'), + ), + ], + }, ], }); diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index 8813458f86..700b410bf6 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/integration-react +## 1.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + +## 1.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + ## 1.1.10-next.1 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index b287f88f87..ab163f9b1a 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration-react", "description": "Frontend package for managing integrations towards external systems", - "version": "1.1.10-next.1", + "version": "1.1.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -45,7 +45,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/packages/integration/package.json b/packages/integration/package.json index 90f82dae35..3ad53b1e08 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -46,7 +46,7 @@ "@backstage/config-loader": "workspace:^", "@backstage/test-utils": "workspace:^", "@types/luxon": "^3.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json index 4abeb9dc6a..96c5aec484 100644 --- a/packages/release-manifests/package.json +++ b/packages/release-manifests/package.json @@ -38,7 +38,7 @@ "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@types/node": "^16.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/packages/repo-tools/CHANGELOG.md b/packages/repo-tools/CHANGELOG.md index 2875d54fef..d4d300f450 100644 --- a/packages/repo-tools/CHANGELOG.md +++ b/packages/repo-tools/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/repo-tools +## 0.1.3-next.0 + +### Patch Changes + +- 32a4a05838: Tweaked type dependency check to trim wildcard type imports. +- 6ba8faf22a: The API report generation process is now able to detect and generate reports for additional entry points declared in the package `"exports"` field. +- Updated dependencies + - @backstage/cli-common@0.1.11 + - @backstage/errors@1.1.4 + +## 0.1.2 + +### Patch Changes + +- ff63acf30a: Packages without a declared `backstage.role` are now ignored. +- Updated dependencies + - @backstage/cli-common@0.1.11 + - @backstage/errors@1.1.4 + ## 0.1.2-next.0 ### Patch Changes diff --git a/packages/repo-tools/cli-report.md b/packages/repo-tools/cli-report.md index 3378d20ea7..0e1b2d2a4c 100644 --- a/packages/repo-tools/cli-report.md +++ b/packages/repo-tools/cli-report.md @@ -29,6 +29,7 @@ Options: -a, --allow-warnings --allow-all-warnings -o, --omit-messages + --validate-release-tags -h, --help ``` diff --git a/packages/repo-tools/package.json b/packages/repo-tools/package.json index 5ea26060c4..2ceeeb0dd8 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.1.2-next.0", + "version": "0.1.3-next.0", "publishConfig": { "access": "public" }, @@ -45,6 +45,7 @@ }, "devDependencies": { "@backstage/cli": "workspace:^", + "@backstage/types": "workspace:^", "@types/is-glob": "^4.0.2", "@types/mock-fs": "^4.13.0", "mock-fs": "^5.1.0" diff --git a/packages/repo-tools/src/commands/api-reports/api-extractor.ts b/packages/repo-tools/src/commands/api-reports/api-extractor.ts index 39df70c21a..1fe7602617 100644 --- a/packages/repo-tools/src/commands/api-reports/api-extractor.ts +++ b/packages/repo-tools/src/commands/api-reports/api-extractor.ts @@ -62,6 +62,7 @@ import { IMarkdownEmitterContext } from '@microsoft/api-documenter/lib/markdown/ import { AstDeclaration } from '@microsoft/api-extractor/lib/analyzer/AstDeclaration'; import { paths as cliPaths } from '../../lib/paths'; import minimatch from 'minimatch'; +import { getPackageExportNames } from '../../lib/entryPoints'; const tmpDir = cliPaths.resolveTargetRoot( './node_modules/.cache/api-extractor', @@ -237,10 +238,9 @@ export async function createTemporaryTsConfig(includedPackageDirs: string[]) { return path; } -export async function countApiReportWarnings(projectFolder: string) { - const path = resolvePath(projectFolder, 'api-report.md'); +export async function countApiReportWarnings(reportPath: string) { try { - const content = await fs.readFile(path, 'utf8'); + const content = await fs.readFile(reportPath, 'utf8'); const lines = content.split('\n'); const lineWarnings = lines.filter(line => @@ -300,6 +300,32 @@ function logApiReportInstructions() { console.log(''); } +async function findPackageEntryPoints(packageDirs: string[]): Promise< + Array<{ + packageDir: string; + name: string; + usesExperimentalTypeBuild?: boolean; + }> +> { + return Promise.all( + packageDirs.map(async packageDir => { + const pkg = await fs.readJson( + cliPaths.resolveTargetRoot(packageDir, 'package.json'), + ); + + return ( + getPackageExportNames(pkg)?.map(name => ({ packageDir, name })) ?? { + packageDir, + name: 'index', + usesExperimentalTypeBuild: pkg.scripts?.build?.includes( + '--experimental-type-build', + ), + } + ); + }), + ).then(results => results.flat()); +} + interface ApiExtractionOptions { packageDirs: string[]; outputDir: string; @@ -307,6 +333,7 @@ interface ApiExtractionOptions { tsconfigFilePath: string; allowWarnings?: boolean | string[]; omitMessages?: string[]; + validateReleaseTags?: boolean; } export async function runApiExtraction({ @@ -316,12 +343,15 @@ export async function runApiExtraction({ tsconfigFilePath, allowWarnings = false, omitMessages = [], + validateReleaseTags = false, }: ApiExtractionOptions) { await fs.remove(outputDir); - const entryPoints = packageDirs.map(packageDir => { + const packageEntryPoints = await findPackageEntryPoints(packageDirs); + + const entryPoints = packageEntryPoints.map(({ packageDir, name }) => { return cliPaths.resolveTargetRoot( - `./dist-types/${packageDir}/src/index.d.ts`, + `./dist-types/${packageDir}/src/${name}.d.ts`, ); }); @@ -337,7 +367,11 @@ export async function runApiExtraction({ } const warnings = new Array(); - for (const packageDir of packageDirs) { + for (const { + packageDir, + name, + usesExperimentalTypeBuild, + } of packageEntryPoints) { console.log(`## Processing ${packageDir}`); const noBail = Array.isArray(allowWarnings) ? allowWarnings.some(aw => aw === packageDir || minimatch(packageDir, aw)) @@ -349,11 +383,15 @@ export async function runApiExtraction({ packageDir, ); - const warningCountBefore = await countApiReportWarnings(projectFolder); + const prefix = name === 'index' ? '' : `${name}-`; + const reportFileName = `${prefix}api-report.md`; + const reportPath = resolvePath(projectFolder, reportFileName); + + const warningCountBefore = await countApiReportWarnings(reportPath); const extractorConfig = ExtractorConfig.prepare({ configObject: { - mainEntryPointFilePath: resolvePath(packageFolder, 'src/index.d.ts'), + mainEntryPointFilePath: resolvePath(packageFolder, `src/${name}.d.ts`), bundledPackages: [], compiler: { @@ -362,16 +400,21 @@ export async function runApiExtraction({ apiReport: { enabled: true, - reportFileName: 'api-report.md', + reportFileName, reportFolder: projectFolder, - reportTempFolder: resolvePath(outputDir, ''), + reportTempFolder: resolvePath( + outputDir, + `${prefix}`, + ), }, docModel: { - enabled: true, + // TODO(Rugvip): This skips docs for non-index entry points. We can try to work around it, but + // most likely it makes sense to wait for API Extractor to natively support exports. + enabled: name === 'index', apiJsonFilePath: resolvePath( outputDir, - '.api.json', + `${prefix}.api.json`, ), }, @@ -461,6 +504,35 @@ export async function runApiExtraction({ compilerState, }); + // This release tag validation makes sure that the release tag of known entry points match expectations. + // The root index entrypoint is only allowed @public exports, while /alpha and /beta only allow @alpha and @beta. + if (validateReleaseTags && !usesExperimentalTypeBuild) { + if (['index', 'alpha', 'beta'].includes(name)) { + const report = await fs.readFile( + extractorConfig.reportFilePath, + 'utf8', + ); + const lines = report.split(/\r?\n/); + const expectedTag = name === 'index' ? 'public' : name; + for (let i = 0; i < lines.length; i += 1) { + const line = lines[i]; + const match = line.match(/^\/\/ @(alpha|beta|public)/); + if (match && match[1] !== expectedTag) { + // Because of limitations in the type script rollup logic we need to allow public exports from the other release stages + // TODO(Rugvip): Try to work around the need for this exception + if (expectedTag !== 'public' && match[1] === 'public') { + continue; + } + throw new Error( + `Unexpected release tag ${match[1]} in ${ + extractorConfig.reportFilePath + } at line ${i + 1}`, + ); + } + } + } + } + if (!extractorResult.succeeded) { if (shouldLogInstructions) { logApiReportInstructions(); @@ -488,7 +560,7 @@ export async function runApiExtraction({ ); } - const warningCountAfter = await countApiReportWarnings(projectFolder); + const warningCountAfter = await countApiReportWarnings(reportPath); if (noBail) { console.log(`Skipping warnings check for ${packageDir}`); } diff --git a/packages/repo-tools/src/commands/api-reports/api-reports.ts b/packages/repo-tools/src/commands/api-reports/api-reports.ts index 66436644d2..a917975750 100644 --- a/packages/repo-tools/src/commands/api-reports/api-reports.ts +++ b/packages/repo-tools/src/commands/api-reports/api-reports.ts @@ -33,6 +33,7 @@ type Options = { allowWarnings?: string; allowAllWarnings?: boolean; omitMessages?: string; + validateReleaseTags?: boolean; } & OptionValues; export const buildApiReports = async (paths: string[] = [], opts: Options) => { @@ -90,6 +91,7 @@ export const buildApiReports = async (paths: string[] = [], opts: Options) => { tsconfigFilePath, allowWarnings: allowAllWarnings || allowWarnings, omitMessages: Array.isArray(omitMessages) ? omitMessages : [], + validateReleaseTags: opts.validateReleaseTags, }); } if (cliPackageDirs.length > 0) { diff --git a/packages/repo-tools/src/commands/index.ts b/packages/repo-tools/src/commands/index.ts index f7a16b6d4e..f283e9c743 100644 --- a/packages/repo-tools/src/commands/index.ts +++ b/packages/repo-tools/src/commands/index.ts @@ -37,6 +37,10 @@ export function registerCommands(program: Command) { '-o, --omit-messages ', 'select some message code to be omited on the API Extractor (comma separated values i.e ae-cyclic-inherit-doc,ae-missing-getter )', ) + .option( + '--validate-release-tags', + 'Turn on release tag validation for the public, beta, and alpha APIs', + ) .description('Generate an API report for selected packages') .action( lazy(() => diff --git a/packages/repo-tools/src/commands/type-deps/type-deps.ts b/packages/repo-tools/src/commands/type-deps/type-deps.ts index 4f8e5e5529..17164cea39 100644 --- a/packages/repo-tools/src/commands/type-deps/type-deps.ts +++ b/packages/repo-tools/src/commands/type-deps/type-deps.ts @@ -20,6 +20,7 @@ import { resolve as resolvePath } from 'path'; // eslint-disable-next-line @backstage/no-undeclared-imports import chalk from 'chalk'; import { getPackages, Package } from '@manypkg/get-packages'; +import { getPackageExportNames } from '../../lib/entryPoints'; export default async () => { const { packages } = await getPackages(resolvePath('.')); @@ -96,16 +97,23 @@ function findAllDeps(declSrc: string) { * missing or incorrect in package.json */ function checkTypes(pkg: Package) { - const typeDecl = fs.readFileSync( - resolvePath(pkg.dir, 'dist/index.d.ts'), - 'utf8', - ); - const allDeps = findAllDeps(typeDecl); + const entryPointNames = getPackageExportNames(pkg.packageJson) ?? ['index']; + + const allDeps = entryPointNames.flatMap(name => { + const typeDecl = fs.readFileSync( + resolvePath(pkg.dir, `dist/${name}.d.ts`), + 'utf8', + ); + return findAllDeps(typeDecl); + }); const deps = Array.from(new Set(allDeps)); const errors = []; const typeDeps = []; - for (const dep of deps) { + for (let dep of deps) { + if (dep.endsWith('/*')) { + dep = dep.slice(0, -2); + } try { const typeDep = findTypesPackage(dep, pkg); if (typeDep) { diff --git a/packages/repo-tools/src/lib/entryPoints.ts b/packages/repo-tools/src/lib/entryPoints.ts new file mode 100644 index 0000000000..4a412d410b --- /dev/null +++ b/packages/repo-tools/src/lib/entryPoints.ts @@ -0,0 +1,39 @@ +/* + * 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 { extname } from 'path'; +import type { JsonObject } from '@backstage/types'; + +export function getPackageExportNames(pkg: JsonObject): string[] | undefined { + if (pkg.exports && typeof pkg.exports !== 'string') { + return Object.entries(pkg.exports).flatMap(([mount, path]) => { + const ext = extname(String(path)); + if (!['.ts', '.tsx', '.cts', '.mts'].includes(ext)) { + return []; // Ignore non-TS entry points + } + let name = mount; + if (name.startsWith('./')) { + name = name.slice(2); + } + if (!name || name === '.') { + return ['index']; + } + return [name]; + }); + } + + return undefined; +} diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index 55d39a6ee5..e3b49ff2f2 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.80-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.22.4-next.0 + - @backstage/plugin-techdocs@1.6.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/test-utils@1.2.6-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + - @backstage/app-defaults@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + +## 0.2.79 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/cli@0.22.2 + - @backstage/plugin-techdocs@1.5.0 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/app-defaults@1.2.0 + - @backstage/config@1.0.6 + - @backstage/integration-react@1.1.10 + - @backstage/test-utils@1.2.5 + - @backstage/plugin-techdocs-react@1.1.3 + ## 0.2.79-next.2 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index acee2e8cb3..2d8c47c1f0 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.79-next.2", + "version": "0.2.80-next.0", "private": true, "backstage": { "role": "frontend" diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 54bf7d2e8c..1e995b5f23 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,38 @@ # @techdocs/cli +## 1.3.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + - @backstage/plugin-techdocs-node@1.5.1-next.0 + +## 1.3.2 + +### Patch Changes + +- dd1e37649f: Deprecated getMkDocsYml in favor of getMkdocsYml (lowercase 'd') +- dcacf94912: Fix proxying to mkdocs + + The domain localhost may point to both 127.0.0.1 and ::1, ipv4 and ipv6 + and when node tries to lookup localhost it might prefer ipv6 while mkdocs + is only listening on ipv4. This tells node-proxy to target the ipv4 address + instead of relying on localhost hostname lookup. + +- 339d9a5b5c: Added support for using a default `mkdocs.yml` configuration file when none is provided +- 6e0b6a0d50: Fixed publish command missing awsBucketRootPath option. + Fixed publish command having the gcsBucketRootPath option misconfigured, previously returning a boolean vs a string. +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-techdocs-node@1.5.0 + - @backstage/catalog-model@1.2.0 + - @backstage/cli-common@0.1.11 + - @backstage/config@1.0.6 + ## 1.3.2-next.2 ### Patch Changes diff --git a/packages/techdocs-cli/cypress/e2e/mkdocs_serve.cy.js b/packages/techdocs-cli/cypress/e2e/mkdocs_serve.cy.js index d9da6caeca..d5417e615f 100644 --- a/packages/techdocs-cli/cypress/e2e/mkdocs_serve.cy.js +++ b/packages/techdocs-cli/cypress/e2e/mkdocs_serve.cy.js @@ -16,7 +16,7 @@ /// describe('TechDocs Live Preview - MkDocs Serve', () => { it('successfully serves documentation', () => { - cy.visit(Cypress.env('mkDocsBaseUrl')); + cy.visit(Cypress.env('mkdocsBaseUrl')); cy.contains('hello mock docs'); }); @@ -41,7 +41,7 @@ describe('TechDocs Live Preview - MkDocs Serve', () => { }); it('matchImage - MkDocs Page', () => { - cy.visit(Cypress.env('mkDocsBaseUrl')).then(() => { + cy.visit(Cypress.env('mkdocsBaseUrl')).then(() => { cy.document().matchImage(); }); }); diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 092bd687bc..0a3bbed06f 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.3.2-next.2", + "version": "1.3.3-next.0", "publishConfig": { "access": "public" }, diff --git a/packages/techdocs-cli/src/commands/generate/generate.ts b/packages/techdocs-cli/src/commands/generate/generate.ts index 8445dd9ec6..5d80beb38a 100644 --- a/packages/techdocs-cli/src/commands/generate/generate.ts +++ b/packages/techdocs-cli/src/commands/generate/generate.ts @@ -21,7 +21,7 @@ import Docker from 'dockerode'; import { TechdocsGenerator, ParsedLocationAnnotation, - getMkDocsYml, + getMkdocsYml, } from '@backstage/plugin-techdocs-node'; import { ContainerRunner, @@ -31,8 +31,8 @@ import { ConfigReader } from '@backstage/config'; import { convertTechDocsRefToLocationAnnotation, createLogger, + getLogStream, } from '../../lib/utility'; -import { stdout } from 'process'; export default async function generate(opts: OptionValues) { // Use techdocs-node package to generate docs. Keep consistency between Backstage and CI generating docs. @@ -55,7 +55,7 @@ export default async function generate(opts: OptionValues) { await fs.ensureDir(outputDir); - const { path: mkDocsYmlPath, configIsTemporary } = await getMkDocsYml( + const { path: mkdocsYmlPath, configIsTemporary } = await getMkdocsYml( sourceDir, ); @@ -110,13 +110,13 @@ export default async function generate(opts: OptionValues) { : {}), logger, etag: opts.etag, - ...(process.env.LOG_LEVEL === 'debug' ? { logStream: stdout } : {}), + logStream: getLogStream(logger), siteOptions: { name: opts.siteName }, }); if (configIsTemporary) { process.on('exit', async () => { - fs.rmSync(mkDocsYmlPath, {}); + fs.rmSync(mkdocsYmlPath, {}); }); } diff --git a/packages/techdocs-cli/src/commands/serve/mkdocs.ts b/packages/techdocs-cli/src/commands/serve/mkdocs.ts index 1a471cf1a6..c061d4474f 100644 --- a/packages/techdocs-cli/src/commands/serve/mkdocs.ts +++ b/packages/techdocs-cli/src/commands/serve/mkdocs.ts @@ -19,7 +19,7 @@ import openBrowser from 'react-dev-utils/openBrowser'; import { createLogger } from '../../lib/utility'; import { runMkdocsServer } from '../../lib/mkdocsServer'; import { LogFunc, waitForSignal } from '../../lib/run'; -import { getMkDocsYml } from '@backstage/plugin-techdocs-node'; +import { getMkdocsYml } from '@backstage/plugin-techdocs-node'; import fs from 'fs-extra'; export default async function serveMkdocs(opts: OptionValues) { @@ -29,7 +29,7 @@ export default async function serveMkdocs(opts: OptionValues) { const localAddr = `http://127.0.0.1:${opts.port}`; const expectedDevAddr = opts.docker ? dockerAddr : localAddr; - const { path: mkDocsYmlPath, configIsTemporary } = await getMkDocsYml( + const { path: mkdocsYmlPath, configIsTemporary } = await getMkdocsYml( './', opts.siteName, ); @@ -81,7 +81,7 @@ export default async function serveMkdocs(opts: OptionValues) { if (configIsTemporary) { process.on('exit', async () => { - fs.rmSync(mkDocsYmlPath, {}); + fs.rmSync(mkdocsYmlPath, {}); }); } } diff --git a/packages/techdocs-cli/src/commands/serve/serve.ts b/packages/techdocs-cli/src/commands/serve/serve.ts index 48e48d4f66..9e2e521546 100644 --- a/packages/techdocs-cli/src/commands/serve/serve.ts +++ b/packages/techdocs-cli/src/commands/serve/serve.ts @@ -22,7 +22,7 @@ import HTTPServer from '../../lib/httpServer'; import { runMkdocsServer } from '../../lib/mkdocsServer'; import { LogFunc, waitForSignal } from '../../lib/run'; import { createLogger } from '../../lib/utility'; -import { getMkDocsYml } from '@backstage/plugin-techdocs-node'; +import { getMkdocsYml } from '@backstage/plugin-techdocs-node'; import fs from 'fs-extra'; function findPreviewBundlePath(): string { @@ -66,7 +66,7 @@ export default async function serve(opts: OptionValues) { ? mkdocsDockerAddr : mkdocsLocalAddr; - const { path: mkDocsYmlPath, configIsTemporary } = await getMkDocsYml( + const { path: mkdocsYmlPath, configIsTemporary } = await getMkdocsYml( './', opts.siteName, ); @@ -127,7 +127,7 @@ export default async function serve(opts: OptionValues) { const httpServer = new HTTPServer( previewAppPath, port, - opts.mkdocsPort, + mkdocsExpectedDevAddr, opts.verbose, ); @@ -150,7 +150,7 @@ export default async function serve(opts: OptionValues) { if (configIsTemporary) { process.on('exit', async () => { - fs.rmSync(mkDocsYmlPath, {}); + fs.rmSync(mkdocsYmlPath, {}); }); } } diff --git a/packages/techdocs-cli/src/lib/httpServer.ts b/packages/techdocs-cli/src/lib/httpServer.ts index c4bd5b823a..08987f3f1d 100644 --- a/packages/techdocs-cli/src/lib/httpServer.ts +++ b/packages/techdocs-cli/src/lib/httpServer.ts @@ -23,26 +23,26 @@ export default class HTTPServer { private readonly proxyEndpoint: string; private readonly backstageBundleDir: string; private readonly backstagePort: number; - private readonly mkdocsPort: number; + private readonly mkdocsTargetAddress: string; private readonly verbose: boolean; constructor( backstageBundleDir: string, backstagePort: number, - mkdocsPort: number, + mkdocsTargetAddress: string, verbose: boolean, ) { this.proxyEndpoint = '/api/techdocs/'; this.backstageBundleDir = backstageBundleDir; this.backstagePort = backstagePort; - this.mkdocsPort = mkdocsPort; + this.mkdocsTargetAddress = mkdocsTargetAddress; this.verbose = verbose; } // Create a Proxy for mkdocs server private createProxy() { const proxy = httpProxy.createProxyServer({ - target: `http://localhost:${this.mkdocsPort}`, + target: this.mkdocsTargetAddress, }); return (request: http.IncomingMessage): [httpProxy, string] => { diff --git a/packages/techdocs-cli/src/lib/utility.ts b/packages/techdocs-cli/src/lib/utility.ts index 3f91f3c82d..00927fd1df 100644 --- a/packages/techdocs-cli/src/lib/utility.ts +++ b/packages/techdocs-cli/src/lib/utility.ts @@ -18,6 +18,8 @@ import { ParsedLocationAnnotation, } from '@backstage/plugin-techdocs-node'; import * as winston from 'winston'; +import { Writable } from 'stream'; +import { stdout } from 'process'; export const convertTechDocsRefToLocationAnnotation = ( techdocsRef: string, @@ -52,3 +54,17 @@ export const createLogger = ({ return logger; }; + +export const getLogStream = (logger: winston.Logger): Writable => { + if (process.env.LOG_LEVEL === 'debug') { + return stdout; + } + + return new Writable({ + defaultEncoding: 'utf8', + write(chunk, _encoding, next) { + logger.verbose(chunk.toString().trim()); + next(); + }, + }); +}; diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 72ef042554..2a2ff57694 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/test-utils +## 1.2.6-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.11-next.0 + +## 1.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.10 + ## 1.2.5-next.0 ### Patch Changes diff --git a/packages/test-utils/alpha-api-report.md b/packages/test-utils/alpha-api-report.md new file mode 100644 index 0000000000..3e0c4aa6c2 --- /dev/null +++ b/packages/test-utils/alpha-api-report.md @@ -0,0 +1,14 @@ +## API Report File for "@backstage/test-utils" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { PropsWithChildren } from 'react'; + +// @alpha +export const MockPluginProvider: ({ + children, +}: PropsWithChildren<{}>) => JSX.Element; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/test-utils/api-report.md b/packages/test-utils/api-report.md index e11072f5a6..37650ff18a 100644 --- a/packages/test-utils/api-report.md +++ b/packages/test-utils/api-report.md @@ -26,7 +26,6 @@ import { JsonValue } from '@backstage/types'; import { MatcherFunction } from '@testing-library/react'; import { Observable } from '@backstage/types'; import { PermissionApi } from '@backstage/plugin-permission-react'; -import { PropsWithChildren } from 'react'; import { ReactElement } from 'react'; import { ReactNode } from 'react'; import { RenderOptions } from '@testing-library/react'; @@ -167,11 +166,6 @@ export class MockPermissionApi implements PermissionApi { ): Promise; } -// @alpha -export const MockPluginProvider: ({ - children, -}: PropsWithChildren<{}>) => JSX.Element; - // @public export class MockStorageApi implements StorageApi { // (undocumented) diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 396bbcc4ed..ef57be6a57 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,12 +1,24 @@ { "name": "@backstage/test-utils", "description": "Utilities to test Backstage plugins and apps.", - "version": "1.2.5-next.0", + "version": "1.2.6-next.0", "publishConfig": { - "access": "public", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "web-library" @@ -24,7 +36,7 @@ "main": "src/index.ts", "types": "src/index.ts", "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -57,10 +69,9 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/node": "^16.11.26", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ - "dist", - "alpha" + "dist" ] } diff --git a/packages/test-utils/src/alpha.ts b/packages/test-utils/src/alpha.ts new file mode 100644 index 0000000000..0b2a6a8d1c --- /dev/null +++ b/packages/test-utils/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './testUtils/MockPluginProvider'; diff --git a/packages/test-utils/src/testUtils/providers.tsx b/packages/test-utils/src/testUtils/MockPluginProvider.tsx similarity index 89% rename from packages/test-utils/src/testUtils/providers.tsx rename to packages/test-utils/src/testUtils/MockPluginProvider.tsx index 8bc4b5122d..25442ae267 100644 --- a/packages/test-utils/src/testUtils/providers.tsx +++ b/packages/test-utils/src/testUtils/MockPluginProvider.tsx @@ -15,7 +15,8 @@ */ import React, { PropsWithChildren } from 'react'; -import { createPlugin, PluginProvider } from '@backstage/core-plugin-api'; +import { PluginProvider } from '@backstage/core-plugin-api/alpha'; +import { createPlugin } from '@backstage/core-plugin-api'; /** * Mock for PluginProvider to use in unit tests diff --git a/packages/test-utils/src/testUtils/TestApiProvider.tsx b/packages/test-utils/src/testUtils/TestApiProvider.tsx index 35fa302415..c212b94bea 100644 --- a/packages/test-utils/src/testUtils/TestApiProvider.tsx +++ b/packages/test-utils/src/testUtils/TestApiProvider.tsx @@ -91,6 +91,10 @@ export class TestApiRegistry implements ApiHolder { * It lets you provide any number of API implementations, without necessarily * having to fully implement each of the APIs. * + * @remarks + * todo: remove this remark tag and ship in the api-reference. There's some odd formatting going on when this is made into a markdown doc, that there's no line break between + * the emmited

    for To the following

    so what happens is that when parsing in docusaurus, it thinks that the code block is mdx rather than a code + * snippet. Just ommiting this from the report for now until we can work out how to fix laterr. * A migration from `ApiRegistry` and `ApiProvider` might look like this, from: * * ```tsx @@ -100,7 +104,7 @@ export class TestApiRegistry implements ApiHolder { * [identityApiRef, mockIdentityApi as unknown as IdentityApi] * ])} * > - * {...} + * ... * * ) * ``` @@ -110,7 +114,7 @@ export class TestApiRegistry implements ApiHolder { * ```tsx * renderInTestApp( * - * {...} + * ... * * ) * ``` diff --git a/packages/test-utils/src/testUtils/index.tsx b/packages/test-utils/src/testUtils/index.tsx index 8fc1395eb8..1510af106e 100644 --- a/packages/test-utils/src/testUtils/index.tsx +++ b/packages/test-utils/src/testUtils/index.tsx @@ -25,7 +25,6 @@ export { export type { TestAppOptions } from './appWrappers'; export * from './msw'; export * from './logCollector'; -export * from './providers'; export * from './testingLibrary'; export { TestApiProvider, TestApiRegistry } from './TestApiProvider'; export type { TestApiProviderProps } from './TestApiProvider'; diff --git a/packages/theme/CHANGELOG.md b/packages/theme/CHANGELOG.md index dcdcf2a6ae..a0ad669076 100644 --- a/packages/theme/CHANGELOG.md +++ b/packages/theme/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/theme +## 0.2.17 + +### Patch Changes + +- b7705e176c: Use same table header color as @backstage/core-components Table to meet accessibility color contrast requirements. This change affects material-ui tables. + ## 0.2.16 ### Patch Changes diff --git a/packages/theme/package.json b/packages/theme/package.json index f311aa7c1f..70f7cb2277 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/theme", "description": "material-ui theme for use with Backstage.", - "version": "0.2.16", + "version": "0.2.17", "publishConfig": { "access": "public", "main": "dist/index.esm.js", diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md index 11f11a19b9..9bd8a9576a 100644 --- a/plugins/adr-backend/CHANGELOG.md +++ b/plugins/adr-backend/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-adr-backend +## 0.3.1-next.0 + +### Patch Changes + +- 8bf24946c6: Adjust express dependencies to be the same as the rest of the project +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/plugin-adr-common@0.2.7-next.0 + - @backstage/plugin-search-common@1.2.1 + +## 0.3.0 + +### Minor Changes + +- 0a32911d8a: Display title, status and date in ADR navigation, sourced from ADR content and reverse order. + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/plugin-adr-common@0.2.6 + - @backstage/plugin-search-common@1.2.1 + ## 0.2.7-next.2 ### Patch Changes diff --git a/plugins/adr-backend/README.md b/plugins/adr-backend/README.md index b751a3b56d..29fead7c84 100644 --- a/plugins/adr-backend/README.md +++ b/plugins/adr-backend/README.md @@ -19,9 +19,8 @@ Here's how to get the backend up and running: 1. First we need to add the `@backstage/plugin-adr-backend` package to your backend: ```sh -# From the Backstage root directory -cd packages/backend -yarn add @backstage/plugin-adr-backend +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-adr-backend ``` 2. Then we will create a new file named `packages/backend/src/plugins/adr.ts`, and add the diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index 33679a00dc..719b3808a7 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr-backend", - "version": "0.2.7-next.2", + "version": "0.3.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -36,9 +36,9 @@ "@backstage/integration": "workspace:^", "@backstage/plugin-adr-common": "workspace:^", "@backstage/plugin-search-common": "workspace:^", - "@types/express": "^4.17.15", - "express": "^4.18.2", - "express-promise-router": "^4.1.1", + "@types/express": "^4.17.6", + "express": "^4.17.1", + "express-promise-router": "^4.1.0", "luxon": "^3.0.0", "marked": "^4.0.14", "node-fetch": "^2.6.5", @@ -49,7 +49,7 @@ "@backstage/cli": "workspace:^", "@types/marked": "^4.0.0", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/adr-backend/src/search/createMadrParser.ts b/plugins/adr-backend/src/search/createMadrParser.ts index 6b77ec2fa7..1bc3c852e9 100644 --- a/plugins/adr-backend/src/search/createMadrParser.ts +++ b/plugins/adr-backend/src/search/createMadrParser.ts @@ -14,12 +14,11 @@ * limitations under the License. */ -import { DateTime } from 'luxon'; -import { marked } from 'marked'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { MADR_DATE_FORMAT } from '@backstage/plugin-adr-common'; import { AdrParser } from './types'; +import { madrParser } from './madrParser'; const applyArgsToFormat = ( format: string, @@ -65,43 +64,12 @@ export const createMadrParser = ( const dateFormat = options.dateFormat ?? MADR_DATE_FORMAT; return async ({ entity, content, path }) => { - const tokens = marked.lexer(content); - if (!tokens.length) { - throw new Error('ADR has no content'); - } - - // First h1 header should contain ADR title - const adrTitle = ( - tokens.find( - t => t.type === 'heading' && t.depth === 1, - ) as marked.Tokens.Heading - )?.text; - - // First list should contain status & date metadata (if defined) - const listTokens = ( - tokens.find(t => t.type === 'list') as marked.Tokens.List - )?.items; - const adrStatus = listTokens - .find(t => /^status:/i.test(t.text)) - ?.text.replace(/^status:/i, '') - .trim() - .toLocaleLowerCase('en-US'); - const adrDateTime = DateTime.fromFormat( - listTokens - .find(t => /^date:/i.test(t.text)) - ?.text.replace(/^date:/i, '') - .trim() ?? '', - dateFormat, - ); - const adrDate = adrDateTime.isValid - ? adrDateTime.toFormat(MADR_DATE_FORMAT) - : undefined; - + const madr = madrParser(content, dateFormat); return { - title: adrTitle ?? path.replace(/\.md$/, ''), + title: madr.title ?? path.replace(/\.md$/, ''), text: content, - status: adrStatus, - date: adrDate, + status: madr.status, + date: madr.date, entityRef: stringifyEntityRef(entity), entityTitle: entity.metadata.title, location: applyArgsToFormat(locationTemplate, { diff --git a/plugins/adr-backend/src/search/madrParser.ts b/plugins/adr-backend/src/search/madrParser.ts new file mode 100644 index 0000000000..30672028fe --- /dev/null +++ b/plugins/adr-backend/src/search/madrParser.ts @@ -0,0 +1,59 @@ +/* + * 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 { DateTime } from 'luxon'; +import { marked } from 'marked'; +import { MADR_DATE_FORMAT } from '@backstage/plugin-adr-common'; + +export const madrParser = (content: string, dateFormat = MADR_DATE_FORMAT) => { + const tokens = marked.lexer(content); + if (!tokens.length) { + throw new Error('ADR has no content'); + } + + // First h1 header should contain ADR title + const adrTitle = ( + tokens.find( + t => t.type === 'heading' && t.depth === 1, + ) as marked.Tokens.Heading + )?.text; + + // First list should contain status & date metadata (if defined) + const listTokens = (tokens.find(t => t.type === 'list') as marked.Tokens.List) + ?.items; + const adrStatus = listTokens + ?.find(t => /^status:/i.test(t.text)) + ?.text.replace(/^status:/i, '') + .trim() + .toLocaleLowerCase('en-US'); + + const adrDateTime = DateTime.fromFormat( + listTokens + ?.find(t => /^date:/i.test(t.text)) + ?.text.replace(/^date:/i, '') + .trim() ?? '', + dateFormat, + ); + const adrDate = adrDateTime?.isValid + ? adrDateTime.toFormat(MADR_DATE_FORMAT) + : undefined; + + return { + title: adrTitle, + status: adrStatus, + date: adrDate, + }; +}; diff --git a/plugins/adr-backend/src/service/router.test.ts b/plugins/adr-backend/src/service/router.test.ts index f12b29c70a..6836343882 100644 --- a/plugins/adr-backend/src/service/router.test.ts +++ b/plugins/adr-backend/src/service/router.test.ts @@ -158,8 +158,8 @@ describe('createRouter', () => { data: [ { type: 'file', - name: 'testFile001.txt', - path: 'folder/testFile001.txt', + name: 'testFile002.txt', + path: 'testFile002.txt', }, { type: 'file', @@ -168,8 +168,8 @@ describe('createRouter', () => { }, { type: 'file', - name: 'testFile002.txt', - path: 'testFile002.txt', + name: 'testFile001.txt', + path: 'folder/testFile001.txt', }, ], }; diff --git a/plugins/adr-backend/src/service/router.ts b/plugins/adr-backend/src/service/router.ts index e6603ab346..ed02a76e13 100644 --- a/plugins/adr-backend/src/service/router.ts +++ b/plugins/adr-backend/src/service/router.ts @@ -19,6 +19,7 @@ import { NotModifiedError, stringifyError } from '@backstage/errors'; import { Logger } from 'winston'; import express from 'express'; import Router from 'express-promise-router'; +import { madrParser } from '../search/madrParser'; /** @public */ export type AdrRouterOptions = { @@ -59,13 +60,20 @@ export async function createRouter( etag: cachedTree?.etag, }); const files = await treeGetResponse.files(); - const data = files.map(file => { - return { - type: 'file', - name: file.path.substring(file.path.lastIndexOf('/') + 1), - path: file.path, - }; - }); + const data = await Promise.all( + files + .map(async file => { + const fileContent = await file.content(); + const adrInfo = madrParser(fileContent.toString()); + return { + type: 'file', + name: file.path.substring(file.path.lastIndexOf('/') + 1), + path: file.path, + ...adrInfo, + }; + }) + .reverse(), + ); await cacheClient.set(urlToProcess, { data, diff --git a/plugins/adr-common/CHANGELOG.md b/plugins/adr-common/CHANGELOG.md index 7ed77717a1..b04b7a0c64 100644 --- a/plugins/adr-common/CHANGELOG.md +++ b/plugins/adr-common/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-adr-common +## 0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/integration@1.4.2 + - @backstage/plugin-search-common@1.2.1 + +## 0.2.6 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/integration@1.4.2 + - @backstage/plugin-search-common@1.2.1 + ## 0.2.6-next.1 ### Patch Changes diff --git a/plugins/adr-common/package.json b/plugins/adr-common/package.json index 7bae7294bb..b2557c5407 100644 --- a/plugins/adr-common/package.json +++ b/plugins/adr-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-adr-common", "description": "Common functionalities for the adr plugin", - "version": "0.2.6-next.1", + "version": "0.2.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/adr/CHANGELOG.md b/plugins/adr/CHANGELOG.md index cea1b59deb..c22c566b6c 100644 --- a/plugins/adr/CHANGELOG.md +++ b/plugins/adr/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-adr +## 0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-adr-common@0.2.7-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 0.4.0 + +### Minor Changes + +- 0a32911d8a: Display title, status and date in ADR navigation, sourced from ADR content and reverse order. +- ec34b535c0: The `AdrSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- ec34b535c0: Support displaying an icon on `AdrSearchResultListItem` +- 496cf6aff0: Render the common `` component when the `backstage.io/adr-location` annotation is missing from the component +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-adr-common@0.2.6 + - @backstage/plugin-search-common@1.2.1 + ## 0.4.0-next.2 ### Minor Changes diff --git a/plugins/adr/README.md b/plugins/adr/README.md index b9cc5d84ba..a669762dad 100644 --- a/plugins/adr/README.md +++ b/plugins/adr/README.md @@ -4,6 +4,8 @@ Welcome to the ADR plugin! This plugin allows you to browse ADRs associated with your entities as well as a way to discover ADRs across others entities via Backstage Search. Use this to learn from the past experience of other projects to guide your own architecture decisions. +![ADR tab](./docs/adr-tab.png) + ## Setup 1. Install this plugin: diff --git a/plugins/adr/api-report.md b/plugins/adr/api-report.md index 4ced4e9416..1d07edc4ce 100644 --- a/plugins/adr/api-report.md +++ b/plugins/adr/api-report.md @@ -52,6 +52,9 @@ export type AdrFileInfo = { type: string; path: string; name: string; + title?: string; + status?: string; + date?: string; }; // @public diff --git a/plugins/adr/docs/adr-tab.png b/plugins/adr/docs/adr-tab.png new file mode 100644 index 0000000000..d9dd728221 Binary files /dev/null and b/plugins/adr/docs/adr-tab.png differ diff --git a/plugins/adr/package.json b/plugins/adr/package.json index 085729f86f..3910fbdef9 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr", - "version": "0.4.0-next.2", + "version": "0.4.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -54,7 +54,7 @@ "@types/git-url-parse": "^9.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/adr/src/api/types.ts b/plugins/adr/src/api/types.ts index e4632e171a..0af35cc6df 100644 --- a/plugins/adr/src/api/types.ts +++ b/plugins/adr/src/api/types.ts @@ -30,6 +30,15 @@ export type AdrFileInfo = { /** The name of the ADR file. */ name: string; + + /** The title of the ADR. */ + title?: string; + + /** The status of the ADR. */ + status?: string; + + /** The date of the ADR. */ + date?: string; }; /** diff --git a/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx b/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx index d1db286943..eb5b4aed21 100644 --- a/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx +++ b/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx @@ -35,6 +35,7 @@ import { } from '@backstage/plugin-adr-common'; import { useEntity } from '@backstage/plugin-catalog-react'; import { + Chip, Grid, List, ListItem, @@ -67,7 +68,9 @@ export const EntityAdrContent = (props: { const classes = useStyles(); const { entity } = useEntity(); const rootLink = useRouteRef(rootRouteRef); - const [adrList, setAdrList] = useState([]); + const [adrList, setAdrList] = useState< + { name: string; title?: string; status?: string; date?: string }[] + >([]); const [searchParams, setSearchParams] = useSearchParams(); const scmIntegrations = useApi(scmIntegrationsApiRef); const adrApi = useApi(adrApiRef); @@ -79,10 +82,10 @@ export const EntityAdrContent = (props: { }, [entity, scmIntegrations]); const selectedAdr = - adrList.find(adr => adr === searchParams.get('record')) ?? ''; + adrList.find(adr => adr.name === searchParams.get('record'))?.name ?? ''; useEffect(() => { if (adrList.length && !selectedAdr) { - searchParams.set('record', adrList[0]); + searchParams.set('record', adrList[0].name); setSearchParams(searchParams, { replace: true }); } }); @@ -100,11 +103,22 @@ export const EntityAdrContent = (props: { ? filePathFilterFn(item.name) : madrFilePathFilter(item.name)), ) - .map(({ name }: { name: string }) => name); + .map(({ name, title, status, date }) => ({ name, title, status, date })); setAdrList(adrs); }, [filePathFilterFn, value]); + const getChipColor = (status: string) => { + switch (status) { + case 'accepted': + return 'primary'; + case 'rejected' || 'deprecated': + return 'secondary'; + default: + return 'default'; + } + }; + return ( @@ -133,13 +147,24 @@ export const EntityAdrContent = (props: { key={idx} button component={Link} - to={`${rootLink()}?record=${adr}`} - selected={selectedAdr === adr} + to={`${rootLink()}?record=${adr.name}`} + selected={selectedAdr === adr.name} > + {adr.status && ( + + )} ))} diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md index 16ad4db685..821f2df769 100644 --- a/plugins/airbrake-backend/CHANGELOG.md +++ b/plugins/airbrake-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-airbrake-backend +## 0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + +## 0.2.15 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + ## 0.2.15-next.2 ### Patch Changes diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index 4d8cde9678..6f79200b0e 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake-backend", - "version": "0.2.15-next.2", + "version": "0.2.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,7 +35,7 @@ "@backstage/cli": "workspace:^", "@types/http-proxy-middleware": "^0.19.3", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md index 0d7ccc3e7e..493a4ecd34 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-airbrake +## 0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/test-utils@1.2.6-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/dev-utils@1.0.13-next.0 + - @backstage/theme@0.2.17 + +## 0.3.15 + +### Patch Changes + +- 41377156d0: Adds a boolean helper function to airbrake plugin for use on the EntityPage to show/hide airbrake tab depending on whether the entity's `catalog-info.yaml` has an airbrake id set in the metadata +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/dev-utils@1.0.12 + - @backstage/test-utils@1.2.5 + ## 0.3.15-next.2 ### Patch Changes diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index c16cccd171..22d961419c 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.3.15-next.2", + "version": "0.3.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -48,7 +48,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md index 02c249120e..d3629f0406 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-allure +## 0.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.1.31 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.1.31-next.2 ### Patch Changes diff --git a/plugins/allure/README.md b/plugins/allure/README.md index b9a8435a34..3a1137fc39 100644 --- a/plugins/allure/README.md +++ b/plugins/allure/README.md @@ -4,16 +4,9 @@ Welcome to the Backstage Allure plugin. This plugin add an entity service page t ## Install -Run the below command from the `app` package directory. - ```shell -yarn add @backstage/plugin-allure -``` - -alternatively, you can execute below command from the root directory of your Backstage app. - -```shell -yarn workspace app add @backstage/plugin-allure +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-allure ``` ## Configure diff --git a/plugins/allure/package.json b/plugins/allure/package.json index cdd0b6c71f..98296190b7 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-allure", "description": "A Backstage plugin that integrates with Allure", - "version": "0.1.31-next.2", + "version": "0.1.32-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -47,7 +47,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md index 61cd39fcb8..02bed18551 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-analytics-module-ga +## 0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.1.26 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + ## 0.1.26-next.1 ### Patch Changes diff --git a/plugins/analytics-module-ga/README.md b/plugins/analytics-module-ga/README.md index c2d79aa45d..d6e2642e2b 100644 --- a/plugins/analytics-module-ga/README.md +++ b/plugins/analytics-module-ga/README.md @@ -9,7 +9,12 @@ This plugin contains no other functionality. ## Installation 1. Install the plugin package in your Backstage app: - `cd packages/app && yarn add @backstage/plugin-analytics-module-ga` + +```sh +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-analytics-module-ga +``` + 2. Wire up the API implementation to your App: ```tsx diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index e98aa30b4b..2cf706b25e 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga", - "version": "0.1.26-next.1", + "version": "0.1.27-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -45,7 +45,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md index 1434589d01..50ceff31ac 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-apache-airflow +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + +## 0.2.8 + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- 4bdd6bcb3c: Prefer Link over plain anchors +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/core-plugin-api@1.4.0 + ## 0.2.8-next.1 ### Patch Changes diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index 45116f3171..b249948e90 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.2.8-next.1", + "version": "0.2.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -43,7 +43,7 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx b/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx index 2660e9380e..2cd136c7fa 100644 --- a/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx +++ b/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx @@ -15,6 +15,7 @@ */ import { + Link, Progress, StatusError, StatusOK, @@ -144,13 +145,14 @@ export const DenseTable = ({ dags, rowClick }: DenseTableProps) => { { title: 'Link', field: 'dagUrl', - render: (row: Partial) => ( -
    - - - - - ), + render: (row: Partial) => + !row.dagUrl ? null : ( + + + + + + ), width: '5%', disableClick: true, hidden: hiddenColumns.some(field => field === 'dagUrl'), diff --git a/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md b/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md index 4e030b2264..f1c0b0499b 100644 --- a/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md +++ b/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/plugin-api-docs-module-protoc-gen-doc +## 0.1.1 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend + ## 0.1.0 ### Minor Changes diff --git a/plugins/api-docs-module-protoc-gen-doc/README.md b/plugins/api-docs-module-protoc-gen-doc/README.md index 4d90cd74c2..a921fafc0b 100644 --- a/plugins/api-docs-module-protoc-gen-doc/README.md +++ b/plugins/api-docs-module-protoc-gen-doc/README.md @@ -6,8 +6,9 @@ This package contains ApiDefinitionWidgets for the following projects: ## Setup -``` -yarn add @backstage/plugin-api-docs-module-protoc-gen-doc +```sh +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-api-docs-module-protoc-gen-doc ``` ## Add the GrpcDocsApiWidget to your apis diff --git a/plugins/api-docs-module-protoc-gen-doc/package.json b/plugins/api-docs-module-protoc-gen-doc/package.json index 072304d2cf..0fa001ff0e 100644 --- a/plugins/api-docs-module-protoc-gen-doc/package.json +++ b/plugins/api-docs-module-protoc-gen-doc/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs-module-protoc-gen-doc", "description": "Additional functionalities for the api-docs plugin that renders the output of the protoc-gen-doc", - "version": "0.1.0", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index 39796b3231..8f6878bb97 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-api-docs +## 0.9.1-next.0 + +### Patch Changes + +- 095e755d9b: Add ApiDefinitionDialog component for fast access to the API definition in ProvidedApiCards and ConsumedApiCards. +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.9.0 + +### Minor Changes + +- 9ed53218a5: Adds a new tRPC API definition widget which users can utilize to integrate their tRPC API definitions into Backstage. + +### Patch Changes + +- 60996f8aba: Updating the readme with better `csp` instructions +- 6856ab98f4: Updated dependency `@asyncapi/react-component` to `1.0.0-next.47`. +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.9.0-next.2 ### Minor Changes diff --git a/plugins/api-docs/api-report.md b/plugins/api-docs/api-report.md index a4f61872f2..c00f9f8e00 100644 --- a/plugins/api-docs/api-report.md +++ b/plugins/api-docs/api-report.md @@ -20,6 +20,13 @@ import { UserListFilterKind } from '@backstage/plugin-catalog-react'; // @public (undocumented) export const ApiDefinitionCard: () => JSX.Element; +// @public +export function ApiDefinitionDialog(props: { + open: boolean; + entity: ApiEntity; + onClose: () => void; +}): JSX.Element; + // @public (undocumented) export type ApiDefinitionWidget = { type: string; diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index ee3e88fe11..7660e62320 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs", "description": "A Backstage plugin that helps represent API entities in the frontend", - "version": "0.9.0-next.2", + "version": "0.9.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -65,7 +65,7 @@ "@types/node": "^16.11.26", "@types/swagger-ui-react": "^4.1.1", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/api-docs/src/components/ApiDefinitionDialog/ApiDefinitionDialog.tsx b/plugins/api-docs/src/components/ApiDefinitionDialog/ApiDefinitionDialog.tsx new file mode 100644 index 0000000000..2f82a0cc5a --- /dev/null +++ b/plugins/api-docs/src/components/ApiDefinitionDialog/ApiDefinitionDialog.tsx @@ -0,0 +1,176 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ApiEntity } from '@backstage/catalog-model'; +import { useApi } from '@backstage/core-plugin-api'; +import { BackstageTheme } from '@backstage/theme'; +import { + Box, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + makeStyles, + Tab, + Tabs, + Typography, +} from '@material-ui/core'; +import React, { useEffect } from 'react'; +import { apiDocsConfigRef } from '../../config'; +import { PlainApiDefinitionWidget } from '../PlainApiDefinitionWidget'; + +const useStyles = makeStyles(theme => ({ + fullHeightDialog: { + height: 'calc(100% - 64px)', + }, + root: { + display: 'flex', + flexGrow: 1, + width: '100%', + height: '100%', + }, + tabs: { + borderRight: `1px solid ${theme.palette.divider}`, + flexShrink: 0, + }, + tabContents: { + flexGrow: 1, + overflowX: 'auto', + }, + title: { + color: theme.palette.text.primary, + wordBreak: 'break-word', + fontSize: theme.typography.h3.fontSize, + marginBottom: 0, + }, + type: { + textTransform: 'uppercase', + fontSize: 11, + opacity: 0.8, + marginBottom: theme.spacing(1), + color: theme.palette.text.primary, + }, +})); + +function TabPanel(props: { + children?: React.ReactNode; + index: number; + value: number; +}) { + const { children, value, index, ...other } = props; + const classes = useStyles(); + return ( + + ); +} + +function a11yProps(index: number) { + return { + id: `vertical-tab-${index}`, + 'aria-controls': `vertical-tabpanel-${index}`, + }; +} + +/** + * A dialog that lets users inspect the API definition. + * + * @public + */ +export function ApiDefinitionDialog(props: { + open: boolean; + entity: ApiEntity; + onClose: () => void; +}) { + const { open, entity, onClose } = props; + const [activeTab, setActiveTab] = React.useState(0); + const classes = useStyles(); + + useEffect(() => { + setActiveTab(0); + }, [open]); + + const config = useApi(apiDocsConfigRef); + const definitionWidget = config.getApiDefinitionWidget(entity); + + let tabIndex = 0; + let tabPanelIndex = 0; + + return ( + + + + API - {definitionWidget?.title ?? 'Raw'} + + + {entity.metadata.title ?? entity.metadata.name} + + + + setActiveTab(newValue)} + aria-label="API definition options" + className={classes.tabs} + > + {definitionWidget ? ( + + ) : null} + + + + {definitionWidget ? ( + + {definitionWidget.component(entity.spec.definition)} + + ) : null} + + + + + + + + + ); +} diff --git a/plugins/api-docs/src/components/ApiDefinitionDialog/index.ts b/plugins/api-docs/src/components/ApiDefinitionDialog/index.ts new file mode 100644 index 0000000000..28e3388bcc --- /dev/null +++ b/plugins/api-docs/src/components/ApiDefinitionDialog/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { ApiDefinitionDialog } from './ApiDefinitionDialog'; diff --git a/plugins/api-docs/src/components/ApisCards/presets.tsx b/plugins/api-docs/src/components/ApisCards/presets.tsx index 4a0a0f429e..b1ef39c113 100644 --- a/plugins/api-docs/src/components/ApisCards/presets.tsx +++ b/plugins/api-docs/src/components/ApisCards/presets.tsx @@ -15,10 +15,13 @@ */ import { ApiEntity } from '@backstage/catalog-model'; -import { EntityTable } from '@backstage/plugin-catalog-react'; -import React from 'react'; -import { ApiTypeTitle } from '../ApiDefinitionCard'; import { TableColumn } from '@backstage/core-components'; +import { EntityTable } from '@backstage/plugin-catalog-react'; +import ExtensionIcon from '@material-ui/icons/Extension'; +import { ToggleButton } from '@material-ui/lab'; +import React, { useState } from 'react'; +import { ApiTypeTitle } from '../ApiDefinitionCard'; +import { ApiDefinitionDialog } from '../ApiDefinitionDialog'; export function createSpecApiTypeColumn(): TableColumn { return { @@ -28,9 +31,29 @@ export function createSpecApiTypeColumn(): TableColumn { }; } -// TODO: This could be moved to plugin-catalog-react if we wouldn't have a -// special createSpecApiTypeColumn. But this is required to use ApiTypeTitle to -// resolve the display name of an entity. Is the display name really worth it? +const ApiDefinitionButton = ({ apiEntity }: { apiEntity: ApiEntity }) => { + const [dialogOpen, setDialogOpen] = useState(false); + + return ( + <> + setDialogOpen(!dialogOpen)}> + + + setDialogOpen(false)} + /> + + ); +}; + +function createApiDefinitionColumn(): TableColumn { + return { + title: 'API Definition', + render: entity => , + }; +} export const apiEntityColumns: TableColumn[] = [ EntityTable.columns.createEntityRefColumn({ defaultKind: 'API' }), @@ -39,4 +62,5 @@ export const apiEntityColumns: TableColumn[] = [ createSpecApiTypeColumn(), EntityTable.columns.createSpecLifecycleColumn(), EntityTable.columns.createMetadataDescriptionColumn(), + createApiDefinitionColumn(), ]; diff --git a/plugins/api-docs/src/components/index.ts b/plugins/api-docs/src/components/index.ts index 7e7b206c54..12297a91a1 100644 --- a/plugins/api-docs/src/components/index.ts +++ b/plugins/api-docs/src/components/index.ts @@ -16,6 +16,7 @@ export * from './ApiExplorerPage'; export * from './ApiDefinitionCard'; +export * from './ApiDefinitionDialog'; export * from './ApisCards'; export * from './AsyncApiDefinitionWidget'; export * from './ComponentsCards'; diff --git a/plugins/apollo-explorer/CHANGELOG.md b/plugins/apollo-explorer/CHANGELOG.md index 8903d504a9..b3d1d90f53 100644 --- a/plugins/apollo-explorer/CHANGELOG.md +++ b/plugins/apollo-explorer/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-apollo-explorer +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.1.8 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + ## 0.1.8-next.1 ### Patch Changes diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json index 7917f5a417..8251dac9b9 100644 --- a/plugins/apollo-explorer/package.json +++ b/plugins/apollo-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apollo-explorer", - "version": "0.1.8-next.1", + "version": "0.1.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -45,7 +45,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index 617d74217b..ef9392a626 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-app-backend +## 0.3.43-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/types@1.0.2 + +## 0.3.42 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/config-loader@1.1.8 + - @backstage/types@1.0.2 + ## 0.3.42-next.2 ### Patch Changes diff --git a/plugins/app-backend/alpha-api-report.md b/plugins/app-backend/alpha-api-report.md new file mode 100644 index 0000000000..20a2902557 --- /dev/null +++ b/plugins/app-backend/alpha-api-report.md @@ -0,0 +1,21 @@ +## API Report File for "@backstage/plugin-app-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import express from 'express'; + +// @alpha +export const appPlugin: (options: AppPluginOptions) => BackendFeature; + +// @alpha (undocumented) +export type AppPluginOptions = { + appPackageName?: string; + staticFallbackHandler?: express.Handler; + disableConfigInjection?: boolean; + disableStaticFallbackCache?: boolean; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/app-backend/api-report.md b/plugins/app-backend/api-report.md index b52132ef51..0383129823 100644 --- a/plugins/app-backend/api-report.md +++ b/plugins/app-backend/api-report.md @@ -3,23 +3,11 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import express from 'express'; import { Logger } from 'winston'; import { PluginDatabaseManager } from '@backstage/backend-common'; -// @alpha -export const appPlugin: (options: AppPluginOptions) => BackendFeature; - -// @alpha (undocumented) -export type AppPluginOptions = { - appPackageName?: string; - staticFallbackHandler?: express.Handler; - disableConfigInjection?: boolean; - disableStaticFallbackCache?: boolean; -}; - // @public (undocumented) export function createRouter(options: RouterOptions): Promise; diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index ff9cd8fe5f..203faaa517 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-app-backend", "description": "A Backstage backend plugin that serves the Backstage frontend app", - "version": "0.3.42-next.2", + "version": "0.3.43-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin" @@ -25,7 +37,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -57,13 +69,12 @@ "@backstage/types": "workspace:^", "@types/supertest": "^2.0.8", "mock-fs": "^5.1.0", - "msw": "^0.49.0", + "msw": "^1.0.0", "node-fetch": "^2.6.7", "supertest": "^6.1.3" }, "files": [ "dist", - "alpha", "migrations/**/*.{js,d.ts}", "static" ] diff --git a/plugins/app-backend/src/alpha.ts b/plugins/app-backend/src/alpha.ts new file mode 100644 index 0000000000..cc8276b853 --- /dev/null +++ b/plugins/app-backend/src/alpha.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { appPlugin } from './service/appPlugin'; +export type { AppPluginOptions } from './service/appPlugin'; diff --git a/plugins/app-backend/src/index.ts b/plugins/app-backend/src/index.ts index 167dc041fc..c91416eac1 100644 --- a/plugins/app-backend/src/index.ts +++ b/plugins/app-backend/src/index.ts @@ -21,5 +21,3 @@ */ export * from './service/router'; -export { appPlugin } from './service/appPlugin'; -export type { AppPluginOptions } from './service/appPlugin'; diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index f76848cb94..5e2b975fc1 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-auth-backend +## 0.18.1-next.0 + +### Patch Changes + +- 529de8c421: Added authentication provider for Azure Easy Authentication. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + +## 0.18.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + ## 0.17.5-next.2 ### Patch Changes diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index f6b19189cd..63aa060875 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -132,6 +132,19 @@ export type BitbucketPassportProfile = Profile & { }; }; +// @public (undocumented) +export type BitbucketServerOAuthResult = { + fullProfile: Profile; + params: { + scope: string; + access_token?: string; + token_type?: string; + expires_in?: number; + }; + accessToken: string; + refreshToken?: string; +}; + // @public export class CatalogIdentityClient { constructor(options: { catalogApi: CatalogApi; tokenManager: TokenManager }); @@ -480,6 +493,23 @@ export const providers: Readonly<{ userIdMatchingUserEntityAnnotation(): SignInResolver; }>; }>; + bitbucketServer: Readonly<{ + create: ( + options?: + | { + authHandler?: AuthHandler | undefined; + signIn?: + | { + resolver: SignInResolver; + } + | undefined; + } + | undefined, + ) => AuthProviderFactory; + resolvers: Readonly<{ + emailMatchingUserEntityProfileEmail: () => SignInResolver; + }>; + }>; cfAccess: Readonly<{ create: (options: { authHandler?: AuthHandler | undefined; diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 7a855e62a8..a65377276e 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend", "description": "A Backstage backend plugin that handles authentication", - "version": "0.17.5-next.2", + "version": "0.18.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -78,6 +78,7 @@ "devDependencies": { "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", + "@backstage/test-utils": "workspace:^", "@types/body-parser": "^1.19.0", "@types/cookie-parser": "^1.4.2", "@types/express-session": "^1.17.2", @@ -85,11 +86,11 @@ "@types/passport-auth0": "^1.0.5", "@types/passport-github2": "^1.2.4", "@types/passport-google-oauth20": "^2.0.3", - "@types/passport-microsoft": "^0.0.0", + "@types/passport-microsoft": "^1.0.0", "@types/passport-saml": "^1.1.3", "@types/passport-strategy": "^0.2.35", "@types/xml2js": "^0.4.7", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/auth-backend/src/providers/azure-easyauth/index.ts b/plugins/auth-backend/src/providers/azure-easyauth/index.ts new file mode 100644 index 0000000000..698092d73f --- /dev/null +++ b/plugins/auth-backend/src/providers/azure-easyauth/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { easyAuth } from './provider'; +export type { EasyAuthResponse } from './provider'; diff --git a/plugins/auth-backend/src/providers/azure-easyauth/provider.test.ts b/plugins/auth-backend/src/providers/azure-easyauth/provider.test.ts new file mode 100644 index 0000000000..b521ddeb10 --- /dev/null +++ b/plugins/auth-backend/src/providers/azure-easyauth/provider.test.ts @@ -0,0 +1,292 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AuthHandler, AuthResolverContext } from '../types'; +import { makeProfileInfo } from '../../lib/passport'; +import { + easyAuth, + ACCESS_TOKEN_HEADER, + EasyAuthAuthProvider, + EasyAuthResult, + ID_TOKEN_HEADER, +} from './provider'; +import { Request, Response } from 'express'; +import { SignJWT, JWTPayload, errors as JoseErrors } from 'jose'; +import { randomBytes } from 'crypto'; + +const jwtSecret = randomBytes(48); + +async function buildJwt(claims: JWTPayload) { + return await new SignJWT(claims) + .setProtectedHeader({ alg: 'HS256' }) + .sign(jwtSecret); +} + +const backstageIdentityTokenClaims = { + sub: 'user:default/alice', + ent: ['user:default/alice'], +}; + +describe('EasyAuthAuthProvider', () => { + const authHandler: AuthHandler = async ({ fullProfile }) => ({ + profile: makeProfileInfo(fullProfile), + }); + const resolverContext: AuthResolverContext = {} as AuthResolverContext; + async function signInResolver() { + return { + id: 'user.name', + token: await buildJwt(backstageIdentityTokenClaims), + }; + } + + const provider = new EasyAuthAuthProvider({ + authHandler, + signInResolver, + resolverContext, + }); + + function mockRequest(headers?: Record) { + return { + header: (name: string) => headers?.[name], + } as unknown as Request; + } + + describe('should succeed when', () => { + it('id_token is valid and identity is resolved successfully', async () => { + const claims = { + ver: '2.0', + oid: 'c43063d4-0650-4f3e-ba6b-307473d24dfd', + name: 'Alice Bob', + email: 'alice@bob.com', + preferred_username: 'Another name', + }; + const response = { + end: jest.fn(), + header: () => jest.fn(), + json: jest.fn(), + status: jest.fn(), + } as unknown as Response; + + const request = mockRequest({ + [ID_TOKEN_HEADER]: await buildJwt(claims), + }); + await provider.refresh(request, response); + + expect(response.json).toHaveBeenCalledWith({ + backstageIdentity: { + id: 'user.name', + token: await buildJwt(backstageIdentityTokenClaims), + identity: { + ownershipEntityRefs: ['user:default/alice'], + type: 'user', + userEntityRef: 'user:default/alice', + }, + }, + profile: { + displayName: claims.name, + email: claims.email, + picture: undefined, + }, + providerInfo: { + accessToken: undefined, + }, + }); + }); + + it('valid id_token and access_token provided', async () => { + const claims = { + ver: '2.0', + oid: 'c43063d4-0650-4f3e-ba6b-307473d24dfd', + name: 'Alice Bob', + email: 'alice@bob.com', + preferred_username: 'Another name', + }; + const response = { + end: jest.fn(), + header: () => jest.fn(), + json: jest.fn(), + status: jest.fn(), + } as unknown as Response; + + const request = mockRequest({ + [ID_TOKEN_HEADER]: await buildJwt(claims), + [ACCESS_TOKEN_HEADER]: 'ACCESS_TOKEN', + }); + await provider.refresh(request, response); + + expect(response.json).toHaveBeenCalledWith( + expect.objectContaining({ + providerInfo: { + accessToken: 'ACCESS_TOKEN', + }, + }), + ); + }); + }); + + describe('should fail when', () => { + const response = {} as Response; + + it('Access token is missing', async () => { + const request = mockRequest(); + + await expect(provider.refresh(request, response)).rejects.toThrow( + 'Missing x-ms-token-aad-id-token header', + ); + }); + + it('id token is invalid', async () => { + const request = mockRequest({ + [ID_TOKEN_HEADER]: 'not-a-jwt', + }); + + await expect(provider.refresh(request, response)).rejects.toThrow( + JoseErrors.JWTInvalid, + ); + }); + + it('id token is v1', async () => { + const request = mockRequest({ + [ID_TOKEN_HEADER]: await buildJwt({ ver: '1.0' }), + }); + + await expect(provider.refresh(request, response)).rejects.toThrow( + 'id_token is not version 2.0', + ); + }); + + it('SignInResolver rejects', async () => { + const request = mockRequest({ + [ID_TOKEN_HEADER]: await buildJwt({ ver: '2.0' }), + }); + + const rejectProvider = new EasyAuthAuthProvider({ + authHandler, + signInResolver: async () => { + throw new Error('REJECTED!!'); + }, + resolverContext, + }); + + await expect(rejectProvider.refresh(request, response)).rejects.toThrow( + 'REJECTED!!', + ); + }); + + it('AuthHanlder rejects', async () => { + const request = mockRequest({ + [ID_TOKEN_HEADER]: await buildJwt({ ver: '2.0' }), + }); + + const rejectProvider = new EasyAuthAuthProvider({ + authHandler: async () => { + throw new Error('OBJECTION!!'); + }, + signInResolver, + resolverContext, + }); + + await expect(rejectProvider.refresh(request, response)).rejects.toThrow( + 'OBJECTION!!', + ); + }); + }); +}); + +describe('easyAuth factory', () => { + const env = process.env; + beforeEach(() => { + jest.resetModules(); + process.env = { ...env }; + }); + + afterEach(() => { + process.env = env; + }); + + it('should fail when run outside of Azure App Services', async () => { + const factory = easyAuth.create({ + signIn: { + resolver: jest.fn(), + }, + }); + + expect(() => factory({} as any)).toThrow( + 'Backstage is not running on Azure App Services', + ); + }); + + it('should fail when Azure App Services Auth is not enabled', async () => { + process.env.WEBSITE_SKU = 'Standard'; + process.env.WEBSITE_AUTH_ENABLED = 'False'; + + const factory = easyAuth.create({ + signIn: { + resolver: jest.fn(), + }, + }); + + expect(() => factory({} as any)).toThrow( + 'Azure App Services does not have authentication enabled', + ); + }); + + it('should fail when Azure App Services Auth is not AAD', async () => { + process.env.WEBSITE_SKU = 'Standard'; + process.env.WEBSITE_AUTH_ENABLED = 'True'; + process.env.WEBSITE_AUTH_DEFAULT_PROVIDER = 'Facebook'; + + const factory = easyAuth.create({ + signIn: { + resolver: jest.fn(), + }, + }); + + expect(() => factory({} as any)).toThrow( + 'Authentication provider is not Azure Active Directory', + ); + }); + + it('should fail when Token Store not enabled', async () => { + process.env.WEBSITE_SKU = 'Standard'; + process.env.WEBSITE_AUTH_ENABLED = 'True'; + process.env.WEBSITE_AUTH_DEFAULT_PROVIDER = 'AzureActiveDirectory'; + process.env.WEBSITE_AUTH_TOKEN_STORE = 'False'; + + const factory = easyAuth.create({ + signIn: { + resolver: jest.fn(), + }, + }); + + expect(() => factory({} as any)).toThrow('Token Store is not enabled'); + }); + + it('should return EasyAuthAuthProvider when running in Azure App Services with AAD Auth', async () => { + process.env.WEBSITE_SKU = 'Standard'; + process.env.WEBSITE_AUTH_ENABLED = 'True'; + process.env.WEBSITE_AUTH_DEFAULT_PROVIDER = 'AzureActiveDirectory'; + process.env.WEBSITE_AUTH_TOKEN_STORE = 'True'; + + const factory = easyAuth.create({ + signIn: { + resolver: jest.fn(), + }, + }); + + expect(factory({} as any)).toBeInstanceOf(EasyAuthAuthProvider); + }); +}); diff --git a/plugins/auth-backend/src/providers/azure-easyauth/provider.ts b/plugins/auth-backend/src/providers/azure-easyauth/provider.ts new file mode 100644 index 0000000000..405ca9ed59 --- /dev/null +++ b/plugins/auth-backend/src/providers/azure-easyauth/provider.ts @@ -0,0 +1,192 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + AuthHandler, + AuthProviderRouteHandlers, + AuthResolverContext, + AuthResponse, + SignInResolver, +} from '../types'; +import { Request, Response } from 'express'; +import { makeProfileInfo } from '../../lib/passport'; +import { AuthenticationError } from '@backstage/errors'; +import { prepareBackstageIdentityResponse } from '../prepareBackstageIdentityResponse'; +import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; +import { Profile } from 'passport'; +import { decodeJwt } from 'jose'; + +export const ID_TOKEN_HEADER = 'x-ms-token-aad-id-token'; +export const ACCESS_TOKEN_HEADER = 'x-ms-token-aad-access-token'; + +type Options = { + authHandler: AuthHandler; + signInResolver: SignInResolver; + resolverContext: AuthResolverContext; +}; + +export type EasyAuthResult = { + fullProfile: Profile; + accessToken?: string; +}; + +export type EasyAuthResponse = AuthResponse<{}>; + +export class EasyAuthAuthProvider implements AuthProviderRouteHandlers { + private readonly resolverContext: AuthResolverContext; + private readonly authHandler: AuthHandler; + private readonly signInResolver: SignInResolver; + + constructor(options: Options) { + this.authHandler = options.authHandler; + this.signInResolver = options.signInResolver; + this.resolverContext = options.resolverContext; + } + + frameHandler(): Promise { + return Promise.resolve(undefined); + } + + async refresh(req: Request, res: Response): Promise { + const result = await this.getResult(req); + const response = await this.handleResult(result); + res.json(response); + } + + start(): Promise { + return Promise.resolve(undefined); + } + + private async getResult(req: Request): Promise { + const idToken = req.header(ID_TOKEN_HEADER); + const accessToken = req.header(ACCESS_TOKEN_HEADER); + if (idToken === undefined) { + throw new AuthenticationError(`Missing ${ID_TOKEN_HEADER} header`); + } + + return { + fullProfile: this.idTokenToProfile(idToken), + accessToken: accessToken, + }; + } + + private idTokenToProfile(idToken: string) { + const claims = decodeJwt(idToken); + + if (claims.ver !== '2.0') { + throw new Error('id_token is not version 2.0 '); + } + + return { + id: claims.oid, + displayName: claims.name, + provider: 'easyauth', + emails: [{ value: claims.email }], + username: claims.preferred_username, + } as Profile; + } + + private async handleResult( + result: EasyAuthResult, + ): Promise { + const { profile } = await this.authHandler(result, this.resolverContext); + + const backstageIdentity = await this.signInResolver( + { + result, + profile, + }, + this.resolverContext, + ); + + return { + providerInfo: { + accessToken: result.accessToken, + }, + backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity), + profile, + }; + } +} + +/** + * Auth provider integration for Azure EasyAuth + * + * @public + */ +export const easyAuth = 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 ({ resolverContext }) => { + validateAppServiceConfiguration(process.env); + + if (options?.signIn.resolver === undefined) { + throw new Error( + 'SignInResolver is required to use this authentication provider', + ); + } + + const authHandler = + options.authHandler ?? + (async ({ fullProfile }) => ({ + profile: makeProfileInfo(fullProfile), + })); + + return new EasyAuthAuthProvider({ + signInResolver: options.signIn.resolver, + authHandler, + resolverContext, + }); + }; + }, +}); + +function validateAppServiceConfiguration(env: NodeJS.ProcessEnv) { + // Based on https://github.com/AzureAD/microsoft-identity-web/blob/f7403779d1a91f4a3fec0ed0993bd82f50f299e1/src/Microsoft.Identity.Web/AppServicesAuth/AppServicesAuthenticationInformation.cs#L38-L59 + // + // It's critical to validate we're really running in a correctly configured Azure App Services, + // As we rely on App Services to manage & validate the ID and Access Token headers + // Without that, this users can be trivially impersonated. + if (env.WEBSITE_SKU === undefined) { + throw new Error('Backstage is not running on Azure App Services'); + } + if (env.WEBSITE_AUTH_ENABLED?.toLowerCase() !== 'true') { + throw new Error('Azure App Services does not have authentication enabled'); + } + if ( + env.WEBSITE_AUTH_DEFAULT_PROVIDER?.toLowerCase() !== 'azureactivedirectory' + ) { + throw new Error('Authentication provider is not Azure Active Directory'); + } + if (process.env.WEBSITE_AUTH_TOKEN_STORE?.toLowerCase() !== 'true') { + throw new Error('Token Store is not enabled'); + } +} diff --git a/plugins/auth-backend/src/providers/bitbucketServer/index.ts b/plugins/auth-backend/src/providers/bitbucketServer/index.ts new file mode 100644 index 0000000000..cef12cd50d --- /dev/null +++ b/plugins/auth-backend/src/providers/bitbucketServer/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { bitbucketServer } from './provider'; +export type { BitbucketServerOAuthResult } from './provider'; diff --git a/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts b/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts new file mode 100644 index 0000000000..fc48cdbe8b --- /dev/null +++ b/plugins/auth-backend/src/providers/bitbucketServer/provider.test.ts @@ -0,0 +1,390 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as helpers from '../../lib/passport/PassportStrategyHelper'; +import { makeProfileInfo } from '../../lib/passport'; +import { AuthResolverContext } from '../types'; +import { + bitbucketServer, + BitbucketServerAuthProvider, + BitbucketServerOAuthResult, +} from './provider'; +import { setupServer } from 'msw/node'; +import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { rest } from 'msw'; + +jest.mock('../../lib/passport/PassportStrategyHelper', () => { + return { + ...jest.requireActual('../../lib/passport/PassportStrategyHelper'), + executeFrameHandlerStrategy: jest.fn(), + executeRefreshTokenStrategy: jest.fn(), + executeFetchUserProfileStrategy: jest.fn(), + }; +}); + +const mockFrameHandler = jest.spyOn( + helpers, + 'executeFrameHandlerStrategy', +) as unknown as jest.MockedFunction< + () => Promise<{ + result: BitbucketServerOAuthResult; + privateInfo: { refreshToken?: string }; + }> +>; + +const passportProfile = { + id: '123', + username: 'john.doe', + provider: 'bitubcketServer', + displayName: 'John Doe', + emails: [{ value: 'john@doe.com' }], + photos: [{ value: 'https://bitbucket.org/user/123/avatar' }], +}; + +const mockHost = 'bitbucket.org'; +const mockBaseUrl = `https://${mockHost}`; + +const whoAmIHandler = (options?: { fail?: boolean; value?: string }) => + rest.get( + `${mockBaseUrl}/plugins/servlet/applinks/whoami`, + (_req, res, ctx) => { + if (options?.fail) { + res.networkError('error'); + } + return res( + ctx.status(200), + ctx.set('X-Ausername', options?.value ?? passportProfile.username), + ); + }, + ); + +const getUserHandler = (options?: { + fail?: boolean; + status?: number; + avatarUrl?: string; + noDisplayName?: boolean; + noUserName?: boolean; +}) => + rest.get( + `${mockBaseUrl}/rest/api/latest/users/${passportProfile.username}`, + (_req, res, ctx) => { + if (options?.fail) { + res.networkError('error'); + } + return res( + ctx.status(options?.status ?? 200), + ctx.json({ + name: options?.noUserName ? undefined : 'john.doe', + emailAddress: 'john@doe.com', + id: 123, + displayName: options?.noDisplayName ? undefined : 'John Doe', + active: true, + slug: 'john.doe', + type: 'NORMAL', + links: { + self: [ + { + href: 'https://bitbucket.org/users/john.doe', + }, + ], + }, + avatarUrl: options?.avatarUrl ?? '/user/123/avatar', + }), + ); + }, + ); + +describe('BitbucketServerAuthProvider', () => { + const provider = new BitbucketServerAuthProvider({ + resolverContext: { + signInWithCatalogUser: jest.fn(info => { + return { + token: `token-for-user:${info.filter['spec.profile.email']}`, + }; + }), + } as unknown as AuthResolverContext, + signInResolver: + bitbucketServer.resolvers.emailMatchingUserEntityProfileEmail(), + authHandler: async ({ fullProfile }) => ({ + profile: makeProfileInfo(fullProfile), + }), + callbackUrl: 'mock', + clientId: 'mock', + clientSecret: 'mock', + host: mockHost, + authorizationUrl: 'mock', + tokenUrl: 'mock', + }); + + describe('when transforming to type OAuthResponse', () => { + const server = setupServer(); + setupRequestMockHandlers(server); + + it('should map to a valid response', async () => { + server.use(whoAmIHandler(), getUserHandler()); + + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + + const expected = { + backstageIdentity: { + token: 'token-for-user:john@doe.com', + }, + providerInfo: { + accessToken: '19xasczxcm9n7gacn9jdgm19me', + scope: 'REPO_READ', + }, + profile: { + email: 'john@doe.com', + displayName: 'John Doe', + picture: 'https://bitbucket.org/user/123/avatar', + }, + }; + + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: {}, + }); + const { response } = await provider.handler({} as any); + expect(response).toEqual(expected); + }); + + it('should throw if whoami fails', async () => { + server.use(whoAmIHandler({ fail: true }), getUserHandler()); + + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: {}, + }); + + await expect(provider.handler({} as any)).rejects.toThrow( + `Failed to retrieve the username of the logged in user`, + ); + }); + + it('should throw if whoami returns an invalid response', async () => { + server.use(whoAmIHandler({ value: '' }), getUserHandler()); + + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: {}, + }); + + await expect(provider.handler({} as any)).rejects.toThrow( + `Failed to retrieve the username of the logged in user`, + ); + }); + + it('should throw if get user fails', async () => { + server.use(whoAmIHandler(), getUserHandler({ fail: true })); + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: {}, + }); + + await expect(provider.handler({} as any)).rejects.toThrow( + `Failed to retrieve the user '${passportProfile.username}'`, + ); + }); + + it('should throw if get user is not ok', async () => { + server.use(whoAmIHandler(), getUserHandler({ status: 500 })); + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: {}, + }); + + await expect(provider.handler({} as any)).rejects.toThrow( + `Failed to retrieve the user '${passportProfile.username}'`, + ); + }); + + it('should not set an avatar url if not given', async () => { + server.use(whoAmIHandler(), getUserHandler({ avatarUrl: '' })); + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + + const expected = { + backstageIdentity: { + token: 'token-for-user:john@doe.com', + }, + providerInfo: { + accessToken: '19xasczxcm9n7gacn9jdgm19me', + scope: 'REPO_READ', + }, + profile: { + email: 'john@doe.com', + displayName: 'John Doe', + }, + }; + + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: {}, + }); + const { response } = await provider.handler({} as any); + expect(response).toEqual(expected); + }); + + it('should fallback to the username if no displayName is given', async () => { + server.use(whoAmIHandler(), getUserHandler({ noDisplayName: true })); + + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + + const expected = { + backstageIdentity: { + token: 'token-for-user:john@doe.com', + }, + providerInfo: { + accessToken: '19xasczxcm9n7gacn9jdgm19me', + scope: 'REPO_READ', + }, + profile: { + email: 'john@doe.com', + displayName: 'john.doe', + picture: 'https://bitbucket.org/user/123/avatar', + }, + }; + + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: {}, + }); + const { response } = await provider.handler({} as any); + expect(response).toEqual(expected); + }); + + it('should fallback to the user id if no name is given', async () => { + server.use( + whoAmIHandler(), + getUserHandler({ noDisplayName: true, noUserName: true }), + ); + + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + + const expected = { + backstageIdentity: { + token: 'token-for-user:john@doe.com', + }, + providerInfo: { + accessToken: '19xasczxcm9n7gacn9jdgm19me', + scope: 'REPO_READ', + }, + profile: { + email: 'john@doe.com', + displayName: '123', + picture: 'https://bitbucket.org/user/123/avatar', + }, + }; + + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: {}, + }); + const { response } = await provider.handler({} as any); + expect(response).toEqual(expected); + }); + }); + + describe('when authenticating', () => { + const server = setupServer(); + setupRequestMockHandlers(server); + + it('should forward the refresh token', async () => { + server.use(whoAmIHandler(), getUserHandler()); + + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: { refreshToken: 'refresh-token' }, + }); + + const response = await provider.handler({} as any); + + const expected = { + response: { + backstageIdentity: { + token: 'token-for-user:john@doe.com', + }, + providerInfo: { + accessToken: '19xasczxcm9n7gacn9jdgm19me', + scope: 'REPO_READ', + }, + profile: { + email: 'john@doe.com', + displayName: 'John Doe', + picture: 'https://bitbucket.org/user/123/avatar', + }, + }, + refreshToken: 'refresh-token', + }; + + expect(response).toEqual(expected); + }); + + it('should forward a new refresh token on refresh', async () => { + server.use(whoAmIHandler(), getUserHandler()); + + const accessToken = '19xasczxcm9n7gacn9jdgm19me'; + const params = { scope: 'REPO_READ' }; + const mockRefreshToken = jest.spyOn( + helpers, + 'executeRefreshTokenStrategy', + ) as unknown as jest.MockedFunction<() => Promise<{}>>; + mockRefreshToken.mockResolvedValueOnce({ + accessToken, + refreshToken: 'dont-forget-to-send-refresh', + params, + }); + mockFrameHandler.mockResolvedValueOnce({ + result: { fullProfile: passportProfile, accessToken, params }, + privateInfo: { refreshToken: 'refresh-token' }, + }); + + const expected = { + response: { + backstageIdentity: { + token: 'token-for-user:john@doe.com', + }, + providerInfo: { + accessToken: '19xasczxcm9n7gacn9jdgm19me', + scope: 'REPO_READ', + }, + profile: { + email: 'john@doe.com', + displayName: 'John Doe', + picture: 'https://bitbucket.org/user/123/avatar', + }, + }, + refreshToken: 'dont-forget-to-send-refresh', + }; + const response = await provider.refresh({ scope: 'REPO_WRITE' } as any); + + expect(response).toEqual(expected); + }); + }); +}); diff --git a/plugins/auth-backend/src/providers/bitbucketServer/provider.ts b/plugins/auth-backend/src/providers/bitbucketServer/provider.ts new file mode 100644 index 0000000000..fb8dd3d5b8 --- /dev/null +++ b/plugins/auth-backend/src/providers/bitbucketServer/provider.ts @@ -0,0 +1,305 @@ +/* + * 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 { + encodeState, + OAuthAdapter, + OAuthEnvironmentHandler, + OAuthHandlers, + OAuthProviderOptions, + OAuthRefreshRequest, + OAuthResponse, + OAuthStartRequest, +} from '../../lib/oauth'; +import { Strategy as OAuth2Strategy, VerifyCallback } from 'passport-oauth2'; +import { + executeFetchUserProfileStrategy, + executeFrameHandlerStrategy, + executeRedirectStrategy, + executeRefreshTokenStrategy, + makeProfileInfo, +} from '../../lib/passport'; +import { + AuthHandler, + AuthResolverContext, + OAuthStartResponse, + SignInResolver, +} from '../types'; +import express from 'express'; +import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; +import { Profile as PassportProfile } from 'passport'; +import { commonByEmailResolver } from '../resolvers'; +import fetch from 'node-fetch'; + +type PrivateInfo = { + refreshToken: string; +}; + +/** @public */ +export type BitbucketServerOAuthResult = { + fullProfile: PassportProfile; + params: { + scope: string; + access_token?: string; + token_type?: string; + expires_in?: number; + }; + accessToken: string; + refreshToken?: string; +}; + +export type BitbucketServerAuthProviderOptions = OAuthProviderOptions & { + host: string; + authorizationUrl: string; + tokenUrl: string; + authHandler: AuthHandler; + signInResolver?: SignInResolver; + resolverContext: AuthResolverContext; +}; + +export class BitbucketServerAuthProvider implements OAuthHandlers { + private readonly signInResolver?: SignInResolver; + private readonly authHandler: AuthHandler; + private readonly resolverContext: AuthResolverContext; + private readonly strategy: OAuth2Strategy; + private readonly host: string; + + constructor(options: BitbucketServerAuthProviderOptions) { + this.signInResolver = options.signInResolver; + this.authHandler = options.authHandler; + this.resolverContext = options.resolverContext; + this.strategy = new OAuth2Strategy( + { + authorizationURL: options.authorizationUrl, + tokenURL: options.tokenUrl, + clientID: options.clientId, + clientSecret: options.clientSecret, + callbackURL: options.callbackUrl, + }, + ( + accessToken: string, + refreshToken: string, + params: any, + fullProfile: PassportProfile, + done: VerifyCallback, + ) => { + done(undefined, { fullProfile, params, accessToken }, { refreshToken }); + }, + ); + this.host = options.host; + } + + async start(req: OAuthStartRequest): Promise { + return await executeRedirectStrategy(req, this.strategy, { + accessType: 'offline', + prompt: 'consent', + scope: req.scope, + state: encodeState(req.state), + }); + } + + async handler( + req: express.Request, + ): Promise<{ response: OAuthResponse; refreshToken?: string }> { + const { result, privateInfo } = await executeFrameHandlerStrategy< + BitbucketServerOAuthResult, + PrivateInfo + >(req, this.strategy); + + return { + response: await this.handleResult(result), + refreshToken: privateInfo.refreshToken, + }; + } + + async refresh( + req: OAuthRefreshRequest, + ): Promise<{ response: OAuthResponse; refreshToken?: string }> { + const { accessToken, refreshToken, params } = + await executeRefreshTokenStrategy( + this.strategy, + req.refreshToken, + req.scope, + ); + const fullProfile = await executeFetchUserProfileStrategy( + this.strategy, + accessToken, + ); + return { + response: await this.handleResult({ + fullProfile, + params, + accessToken, + }), + refreshToken, + }; + } + + private async handleResult( + result: BitbucketServerOAuthResult, + ): Promise { + // The OAuth2 strategy does not return a user profile -> let's fetch it before calling the auth handler + result.fullProfile = await this.fetchProfile(result); + const { profile } = await this.authHandler(result, this.resolverContext); + + let backstageIdentity = undefined; + if (this.signInResolver) { + backstageIdentity = await this.signInResolver( + { result, profile }, + this.resolverContext, + ); + } + + return { + providerInfo: { + accessToken: result.accessToken, + scope: result.params.scope, + expiresInSeconds: result.params.expires_in, + }, + profile, + backstageIdentity, + }; + } + + private async fetchProfile( + result: BitbucketServerOAuthResult, + ): Promise { + // Get current user name + let whoAmIResponse; + try { + whoAmIResponse = await fetch( + `https://${this.host}/plugins/servlet/applinks/whoami`, + { + headers: { + Authorization: `Bearer ${result.accessToken}`, + }, + }, + ); + } catch (e) { + throw new Error(`Failed to retrieve the username of the logged in user`); + } + + // A response.ok check here would be worthless as the Bitbucket API always returns 200 OK for this call + const username = whoAmIResponse.headers.get('X-Ausername'); + if (!username) { + throw new Error(`Failed to retrieve the username of the logged in user`); + } + + let userResponse; + try { + userResponse = await fetch( + `https://${this.host}/rest/api/latest/users/${username}?avatarSize=256`, + { + headers: { + Authorization: `Bearer ${result.accessToken}`, + }, + }, + ); + } catch (e) { + throw new Error(`Failed to retrieve the user '${username}'`); + } + + if (!userResponse.ok) { + throw new Error(`Failed to retrieve the user '${username}'`); + } + + const user = (await userResponse.json()) as any; + + const passportProfile = { + provider: 'bitbucketServer', + id: user.id.toString(), + displayName: user.displayName, + username: user.name, + emails: [ + { + value: user.emailAddress, + }, + ], + } as PassportProfile; + + if (user.avatarUrl) { + passportProfile.photos = [ + { value: `https://${this.host}${user.avatarUrl}` }, + ]; + } + + return passportProfile; + } +} + +export const bitbucketServer = 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 => { + const clientId = envConfig.getString('clientId'); + const clientSecret = envConfig.getString('clientSecret'); + const host = envConfig.getString('host'); + const customCallbackUrl = envConfig.getOptionalString('callbackUrl'); + const callbackUrl = + customCallbackUrl || + `${globalConfig.baseUrl}/${providerId}/handler/frame`; + const authorizationUrl = `https://${host}/rest/oauth2/latest/authorize`; + const tokenUrl = `https://${host}/rest/oauth2/latest/token`; + + const authHandler: AuthHandler = + options?.authHandler + ? options.authHandler + : async ({ fullProfile }) => ({ + profile: makeProfileInfo(fullProfile), + }); + + const provider = new BitbucketServerAuthProvider({ + callbackUrl, + clientId, + clientSecret, + host, + authorizationUrl, + tokenUrl, + authHandler, + signInResolver: options?.signIn?.resolver, + resolverContext, + }); + + return OAuthAdapter.fromConfig(globalConfig, provider, { + providerId, + callbackUrl, + }); + }); + }, + resolvers: { + /** + * Looks up the user by matching their email to the entity email. + */ + emailMatchingUserEntityProfileEmail: + (): SignInResolver => commonByEmailResolver, + }, +}); diff --git a/plugins/auth-backend/src/providers/index.ts b/plugins/auth-backend/src/providers/index.ts index 67d3a62990..a922065fd8 100644 --- a/plugins/auth-backend/src/providers/index.ts +++ b/plugins/auth-backend/src/providers/index.ts @@ -19,6 +19,7 @@ export type { BitbucketOAuthResult, BitbucketPassportProfile, } from './bitbucket'; +export type { BitbucketServerOAuthResult } from './bitbucketServer'; export type { CloudflareAccessClaims, CloudflareAccessGroup, diff --git a/plugins/auth-backend/src/providers/providers.ts b/plugins/auth-backend/src/providers/providers.ts index b2795c25f0..aa630b7481 100644 --- a/plugins/auth-backend/src/providers/providers.ts +++ b/plugins/auth-backend/src/providers/providers.ts @@ -31,6 +31,7 @@ import { okta } from './okta'; import { onelogin } from './onelogin'; import { saml } from './saml'; import { AuthProviderFactory } from './types'; +import { bitbucketServer } from './bitbucketServer'; /** * All built-in auth provider integrations. @@ -42,6 +43,7 @@ export const providers = Object.freeze({ auth0, awsAlb, bitbucket, + bitbucketServer, cfAccess, gcpIap, github, @@ -76,5 +78,6 @@ export const defaultAuthProviderFactories: { onelogin: onelogin.create(), awsalb: awsAlb.create(), bitbucket: bitbucket.create(), + bitbucketServer: bitbucketServer.create(), atlassian: atlassian.create(), }; diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 7f9e0f8a33..9f0609bd7a 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-auth-node +## 0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## 0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + ## 0.2.11-next.2 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index fe7adb300d..fcb0ed8e48 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.2.11-next.2", + "version": "0.2.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,7 +35,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "lodash": "^4.17.21", - "msw": "^0.49.0", + "msw": "^1.0.0", "uuid": "^8.0.0" }, "files": [ diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index 7488628b80..2f28ddd584 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-azure-devops-backend +## 0.3.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-azure-devops-common@0.3.0 + +## 0.3.21 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- cc926a59bd: Fixed a bug where the azure devops host in URLs on the readme card was being URL encoded, breaking hosts with ports. +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-azure-devops-common@0.3.0 + ## 0.3.21-next.2 ### Patch Changes diff --git a/plugins/azure-devops-backend/README.md b/plugins/azure-devops-backend/README.md index 301ae5b2b9..ba2a847c0a 100644 --- a/plugins/azure-devops-backend/README.md +++ b/plugins/azure-devops-backend/README.md @@ -30,9 +30,8 @@ Here's how to get the backend up and running: 1. First we need to add the `@backstage/plugin-azure-devops-backend` package to your backend: ```sh - # From the Backstage root directory - cd packages/backend - yarn add @backstage/plugin-azure-devops-backend + # From your Backstage root directory + yarn add --cwd packages/backend @backstage/plugin-azure-devops-backend ``` 2. Then we will create a new file named `packages/backend/src/plugins/azure-devops.ts`, and add the diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index 2103acf8fc..a8baac3673 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-backend", - "version": "0.3.21-next.2", + "version": "0.3.22-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -37,7 +37,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index cb4be6f908..3df7331474 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-azure-devops +## 0.2.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-azure-devops-common@0.3.0 + +## 0.2.6 + +### Patch Changes + +- 347b16ecea: Fixed `AssignedToCurrentUsersTeams` & `CreatedByCurrentUsersTeams` filter in `AzurePullRequestsPage` component. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/plugin-azure-devops-common@0.3.0 + ## 0.2.6-next.2 ### Patch Changes diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index bfb09aff1d..4174675f03 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.2.6-next.2", + "version": "0.2.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -56,7 +56,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/azure-sites-backend/CHANGELOG.md b/plugins/azure-sites-backend/CHANGELOG.md index e3680abddb..32fba35d47 100644 --- a/plugins/azure-sites-backend/CHANGELOG.md +++ b/plugins/azure-sites-backend/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-azure-sites-backend +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-azure-sites-common@0.1.0 + +## 0.1.4 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-azure-sites-common@0.1.0 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/azure-sites-backend/README.md b/plugins/azure-sites-backend/README.md index 5f19267499..0d44b9a4e4 100644 --- a/plugins/azure-sites-backend/README.md +++ b/plugins/azure-sites-backend/README.md @@ -36,7 +36,7 @@ Here's how to get the backend plugin up and running: 1. First we need to add the `@backstage/plugin-azure-sites-backend` package to your backend: ```sh - # From the Backstage root directory + # From your Backstage root directory yarn add --cwd packages/backend @backstage/plugin-azure-sites-backend ``` diff --git a/plugins/azure-sites-backend/package.json b/plugins/azure-sites-backend/package.json index c053435161..50618bb0ad 100644 --- a/plugins/azure-sites-backend/package.json +++ b/plugins/azure-sites-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites-backend", - "version": "0.1.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -48,7 +48,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/azure-sites/CHANGELOG.md b/plugins/azure-sites/CHANGELOG.md index 8c44d24ff3..e755c154ce 100644 --- a/plugins/azure-sites/CHANGELOG.md +++ b/plugins/azure-sites/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-azure-sites +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-azure-sites-common@0.1.0 + +## 0.1.4 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 98a00a09d5: Fixed `AzureSites` plugin start and stop issue #15904 + Fixed `AzureSites` UI load issue #15907 +- 4bdd6bcb3c: Prefer Link over plain anchors +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-azure-sites-common@0.1.0 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/azure-sites/README.md b/plugins/azure-sites/README.md index f240dab140..57bf84ccc5 100644 --- a/plugins/azure-sites/README.md +++ b/plugins/azure-sites/README.md @@ -44,10 +44,11 @@ azure.com/microsoft-web-sites: func-testapp ### Install the component -1. Install the plugin in the `packages/app` directory +1. Install the plugin ```sh -yarn add @backstage/plugin-azure-sites +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-azure-sites ``` 2. Add widget component to your Backstage instance: diff --git a/plugins/azure-sites/package.json b/plugins/azure-sites/package.json index 3cfe1ea9c3..7d37bf287a 100644 --- a/plugins/azure-sites/package.json +++ b/plugins/azure-sites/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-sites", - "version": "0.1.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -57,7 +57,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/azure-sites/src/components/AzureSitesOverviewTableComponent/AzureSitesOverviewTable.tsx b/plugins/azure-sites/src/components/AzureSitesOverviewTableComponent/AzureSitesOverviewTable.tsx index dc059b2f15..5b67fe844a 100644 --- a/plugins/azure-sites/src/components/AzureSitesOverviewTableComponent/AzureSitesOverviewTable.tsx +++ b/plugins/azure-sites/src/components/AzureSitesOverviewTableComponent/AzureSitesOverviewTable.tsx @@ -164,9 +164,8 @@ const ActionButtons = ({ )} diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index ca5bbb859d..c71299528e 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-badges-backend +## 0.1.37-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## 0.1.36 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + ## 0.1.36-next.2 ### Patch Changes diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index 25beed0238..af9ff60372 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges-backend", "description": "A Backstage backend plugin that generates README badges for your entities", - "version": "0.1.36-next.2", + "version": "0.1.37-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index cefd2f8ccd..c92817a9e3 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-badges +## 0.2.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.2.39 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + ## 0.2.39-next.2 ### Patch Changes diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 4c8edbd09f..a5a610c041 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges", "description": "A Backstage plugin that generates README badges for your entities", - "version": "0.2.39-next.2", + "version": "0.2.40-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -54,7 +54,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md index 5a7107312e..1ae72cadfb 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-bazaar-backend +## 0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + +## 0.2.5 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + ## 0.2.5-next.2 ### Patch Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 5fba3fcbb3..e8ea2a19f7 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.2.5-next.2", + "version": "0.2.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md index d3b9cc6a71..49a5570245 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-bazaar +## 0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/cli@0.22.4-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/cli@0.22.2 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + ## 0.2.4-next.2 ### Patch Changes diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index 7558aaf2ec..ae3703cbbc 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.2.4-next.2", + "version": "0.2.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index d42d00e4f3..da9ebadcca 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -33,7 +33,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@openapitools/openapi-generator-cli": "^2.4.26", - "msw": "^0.49.0", + "msw": "^1.0.0", "ts-morph": "^17.0.0" }, "files": [ diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index 65cef85765..2c74da08aa 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-bitrise +## 0.1.43-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.1.42 + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.1.42-next.2 ### Patch Changes diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 13cc29fd06..3366b34d9a 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitrise", "description": "A Backstage plugin that integrates towards Bitrise", - "version": "0.1.42-next.2", + "version": "0.1.43-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -51,7 +51,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "@types/recharts": "^1.8.15", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index d0eeb5702c..085b505782 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.1.17-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- bf611cf019: Fix missing `dependencies` in `package.json` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-kubernetes-common@0.6.1-next.0 + +## 0.1.15 + +### Patch Changes + +- 671c6af700: Update to import `LocationSpec` from the correct package. +- 8e025f1347: Added support for `externalId` when assuming role in `AwsS3EntityProvider` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + ## 0.1.15-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/alpha-api-report.md b/plugins/catalog-backend-module-aws/alpha-api-report.md new file mode 100644 index 0000000000..8781975085 --- /dev/null +++ b/plugins/catalog-backend-module-aws/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-aws" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const awsS3EntityProviderCatalogModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend-module-aws/api-report.md b/plugins/catalog-backend-module-aws/api-report.md index 1725692cb1..5086ec1ea7 100644 --- a/plugins/catalog-backend-module-aws/api-report.md +++ b/plugins/catalog-backend-module-aws/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorParser } from '@backstage/plugin-catalog-backend'; @@ -88,7 +87,4 @@ export class AwsS3EntityProvider implements EntityProvider { // (undocumented) refresh(logger: Logger): Promise; } - -// @alpha -export const awsS3EntityProviderCatalogModule: () => BackendFeature; ``` diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 0c9d9af8bb..ea75932dc8 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", "description": "A Backstage catalog backend module that helps integrate towards AWS", - "version": "0.1.15-next.2", + "version": "0.1.17-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" @@ -25,7 +37,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -41,7 +53,9 @@ "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-catalog-backend": "workspace:^", + "@backstage/plugin-catalog-common": "workspace:^", "@backstage/plugin-catalog-node": "workspace:^", + "@backstage/plugin-kubernetes-common": "workspace:^", "@backstage/types": "workspace:^", "aws-sdk": "^2.840.0", "lodash": "^4.17.21", @@ -58,7 +72,6 @@ "yaml": "^2.0.0" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/catalog-backend-module-aws/src/alpha.ts b/plugins/catalog-backend-module-aws/src/alpha.ts new file mode 100644 index 0000000000..3ae30df0cb --- /dev/null +++ b/plugins/catalog-backend-module-aws/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { awsS3EntityProviderCatalogModule } from './service/AwsS3EntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-aws/src/index.ts b/plugins/catalog-backend-module-aws/src/index.ts index 804fd97e91..212308edaa 100644 --- a/plugins/catalog-backend-module-aws/src/index.ts +++ b/plugins/catalog-backend-module-aws/src/index.ts @@ -22,5 +22,4 @@ export * from './processors'; export * from './providers'; -export { awsS3EntityProviderCatalogModule } from './service/AwsS3EntityProviderCatalogModule'; export * from './types'; diff --git a/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.test.ts index c0d36ad3c2..868a9535b4 100644 --- a/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.test.ts @@ -22,7 +22,7 @@ import { } from '@backstage/backend-tasks'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; import { awsS3EntityProviderCatalogModule } from './AwsS3EntityProviderCatalogModule'; import { AwsS3EntityProvider } from '../providers'; diff --git a/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.ts b/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.ts index cbc137ab40..5d4170ec1c 100644 --- a/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-aws/src/service/AwsS3EntityProviderCatalogModule.ts @@ -19,7 +19,7 @@ import { coreServices, createBackendModule, } from '@backstage/backend-plugin-api'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { AwsS3EntityProvider } from '../providers'; /** diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index 05e48690d7..3dbd990f57 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,66 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.14-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## 0.1.13 + +### Patch Changes + +- 2890f47517: This will add the ability to use Azure DevOps with multi project with a single value which is a new feature as previously this had to be done manually for each project that you wanted to add. + + Right now you would have to fill in multiple values in the config to use multiple projects: + + ``` + yourFirstProviderId: # identifies your dataset / provider independent of config changes + organization: myorg + project: 'firstProject' # this will match the firstProject project + repository: '*' # this will match all repos + path: /catalog-info.yaml + yourSecondProviderId: # identifies your dataset / provider independent of config changes + organization: myorg + project: 'secondProject' # this will match the secondProject project + repository: '*' # this will match all repos + path: /catalog-info.yaml + ``` + + With this change you can actually have all projects available where your PAT determines which you have access to, so that includes multiple projects: + + ``` + yourFirstProviderId: # identifies your dataset / provider independent of config changes + organization: myorg + project: '*' # this will match all projects where your PAT has access to + repository: '*' # this will match all repos + path: /catalog-info.yaml + ``` + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + ## 0.1.13-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/alpha-api-report.md b/plugins/catalog-backend-module-azure/alpha-api-report.md new file mode 100644 index 0000000000..486aac7775 --- /dev/null +++ b/plugins/catalog-backend-module-azure/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-azure" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const azureDevOpsEntityProviderCatalogModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend-module-azure/api-report.md b/plugins/catalog-backend-module-azure/api-report.md index 5ffae14b6b..8fb7edeb53 100644 --- a/plugins/catalog-backend-module-azure/api-report.md +++ b/plugins/catalog-backend-module-azure/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; @@ -56,7 +55,4 @@ export class AzureDevOpsEntityProvider implements EntityProvider { // (undocumented) refresh(logger: Logger): Promise; } - -// @alpha -export const azureDevOpsEntityProviderCatalogModule: () => BackendFeature; ``` diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 9552fe1e98..1594e88955 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", "description": "A Backstage catalog backend module that helps integrate towards Azure", - "version": "0.1.13-next.2", + "version": "0.1.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" @@ -25,7 +37,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -53,10 +65,9 @@ "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", "luxon": "^3.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/catalog-backend-module-azure/src/alpha.ts b/plugins/catalog-backend-module-azure/src/alpha.ts new file mode 100644 index 0000000000..cc3c4a83af --- /dev/null +++ b/plugins/catalog-backend-module-azure/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { azureDevOpsEntityProviderCatalogModule } from './service/AzureDevOpsEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-azure/src/index.ts b/plugins/catalog-backend-module-azure/src/index.ts index aa3a94fda2..a71c40ee6c 100644 --- a/plugins/catalog-backend-module-azure/src/index.ts +++ b/plugins/catalog-backend-module-azure/src/index.ts @@ -22,4 +22,3 @@ export { AzureDevOpsDiscoveryProcessor } from './processors'; export { AzureDevOpsEntityProvider } from './providers'; -export { azureDevOpsEntityProviderCatalogModule } from './service/AzureDevOpsEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.test.ts index a11e6b14f2..a8e526e871 100644 --- a/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.test.ts @@ -22,7 +22,7 @@ import { } from '@backstage/backend-tasks'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; import { azureDevOpsEntityProviderCatalogModule } from './AzureDevOpsEntityProviderCatalogModule'; import { AzureDevOpsEntityProvider } from '../providers'; diff --git a/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.ts index bd59cec29b..3fc1ddf3a4 100644 --- a/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-azure/src/service/AzureDevOpsEntityProviderCatalogModule.ts @@ -19,7 +19,7 @@ import { createBackendModule, coreServices, } from '@backstage/backend-plugin-api'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { AzureDevOpsEntityProvider } from '../providers'; /** diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 261a192dfa..c506ddc588 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.1.10-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.3 + +## 0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.3 + - @backstage/plugin-catalog-common@1.0.11 + ## 0.1.9-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/alpha-api-report.md b/plugins/catalog-backend-module-bitbucket-cloud/alpha-api-report.md new file mode 100644 index 0000000000..77b4b77410 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-cloud/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-bitbucket-cloud" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha (undocumented) +export const bitbucketCloudEntityProviderCatalogModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend-module-bitbucket-cloud/api-report.md b/plugins/catalog-backend-module-bitbucket-cloud/api-report.md index 7ad6b3b3e0..456ea62dd3 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/api-report.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { EntityProvider } from '@backstage/plugin-catalog-backend'; @@ -46,7 +45,4 @@ export class BitbucketCloudEntityProvider // (undocumented) supportsEventTopics(): string[]; } - -// @alpha (undocumented) -export const bitbucketCloudEntityProviderCatalogModule: () => BackendFeature; ``` diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index 78e1e15653..470ab9b813 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", - "version": "0.1.9-next.2", + "version": "0.1.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" @@ -25,7 +37,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -53,10 +65,9 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "luxon": "^3.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/alpha.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/alpha.ts new file mode 100644 index 0000000000..e949dcb894 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { bitbucketCloudEntityProviderCatalogModule } from './service/BitbucketCloudEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/index.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/index.ts index c1f04b8877..1c15ad4e8f 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/index.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/index.ts @@ -21,4 +21,3 @@ */ export { BitbucketCloudEntityProvider } from './BitbucketCloudEntityProvider'; -export { bitbucketCloudEntityProviderCatalogModule } from './service/BitbucketCloudEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts index 1b18ab0ed9..630c18b134 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.test.ts @@ -20,8 +20,8 @@ import { TaskScheduleDefinition, } from '@backstage/backend-tasks'; import { startTestBackend, mockServices } from '@backstage/backend-test-utils'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { Duration } from 'luxon'; import { bitbucketCloudEntityProviderCatalogModule } from './BitbucketCloudEntityProviderCatalogModule'; import { BitbucketCloudEntityProvider } from '../BitbucketCloudEntityProvider'; diff --git a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts index d17656a473..a95d99ceef 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-bitbucket-cloud/src/service/BitbucketCloudEntityProviderCatalogModule.ts @@ -22,8 +22,8 @@ import { import { catalogProcessingExtensionPoint, catalogServiceRef, -} from '@backstage/plugin-catalog-node'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +} from '@backstage/plugin-catalog-node/alpha'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { BitbucketCloudEntityProvider } from '../BitbucketCloudEntityProvider'; /** diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md index b3b825bbc6..938f731df3 100644 --- a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-catalog-backend-module-bitbucket-server +## 0.1.8-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + ## 0.1.7-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-server/alpha-api-report.md b/plugins/catalog-backend-module-bitbucket-server/alpha-api-report.md new file mode 100644 index 0000000000..3177828f51 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-bitbucket-server" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha (undocumented) +export const bitbucketServerEntityProviderCatalogModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend-module-bitbucket-server/api-report.md b/plugins/catalog-backend-module-bitbucket-server/api-report.md index 213f5d2573..6c840883af 100644 --- a/plugins/catalog-backend-module-bitbucket-server/api-report.md +++ b/plugins/catalog-backend-module-bitbucket-server/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { BitbucketServerIntegrationConfig } from '@backstage/integration'; import { Config } from '@backstage/config'; import { Entity } from '@backstage/catalog-model'; @@ -68,9 +67,6 @@ export class BitbucketServerEntityProvider implements EntityProvider { refresh(logger: Logger): Promise; } -// @alpha (undocumented) -export const bitbucketServerEntityProviderCatalogModule: () => BackendFeature; - // @public (undocumented) export type BitbucketServerListOptions = { [key: string]: number | undefined; diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json index edd1fbf0e6..d96e7c91f9 100644 --- a/plugins/catalog-backend-module-bitbucket-server/package.json +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -1,14 +1,26 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", - "version": "0.1.7-next.2", + "version": "0.1.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" @@ -24,7 +36,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -50,10 +62,9 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "luxon": "^3.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/catalog-backend-module-bitbucket-server/src/alpha.ts b/plugins/catalog-backend-module-bitbucket-server/src/alpha.ts new file mode 100644 index 0000000000..d6227c29f1 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { bitbucketServerEntityProviderCatalogModule } from './service/BitbucketServerEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-bitbucket-server/src/index.ts b/plugins/catalog-backend-module-bitbucket-server/src/index.ts index f139078cfb..34ac3a9966 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/index.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/index.ts @@ -29,4 +29,3 @@ export type { } from './lib'; export { BitbucketServerEntityProvider } from './providers'; export type { BitbucketServerLocationParser } from './providers'; -export { bitbucketServerEntityProviderCatalogModule } from './service/BitbucketServerEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.test.ts index 474431dc7a..bdd7209364 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.test.ts @@ -22,7 +22,7 @@ import { TaskScheduleDefinition, } from '@backstage/backend-tasks'; import { startTestBackend } from '@backstage/backend-test-utils'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { bitbucketServerEntityProviderCatalogModule } from './BitbucketServerEntityProviderCatalogModule'; import { Duration } from 'luxon'; import { BitbucketServerEntityProvider } from '../providers'; diff --git a/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.ts index 46712d29dd..deab47c9e9 100644 --- a/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/service/BitbucketServerEntityProviderCatalogModule.ts @@ -19,7 +19,7 @@ import { coreServices, createBackendModule, } from '@backstage/backend-plugin-api'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { BitbucketServerEntityProvider } from '../providers'; /** diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md index b07c7a92bb..d082563115 100644 --- a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-catalog-backend-module-bitbucket +## 0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.3 + +## 0.2.9 + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-bitbucket-cloud-common@0.2.3 + ## 0.2.9-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index 7df64bbc87..4f10b4c567 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket", - "version": "0.2.9-next.2", + "version": "0.2.10-next.0", "deprecated": true, "main": "src/index.ts", "types": "src/index.ts", @@ -49,7 +49,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 9efd73aac5..80a5989141 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.11-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## 0.1.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + ## 0.1.10-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/alpha-api-report.md b/plugins/catalog-backend-module-gerrit/alpha-api-report.md new file mode 100644 index 0000000000..03f5d099b9 --- /dev/null +++ b/plugins/catalog-backend-module-gerrit/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-gerrit" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha (undocumented) +export const gerritEntityProviderCatalogModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend-module-gerrit/api-report.md b/plugins/catalog-backend-module-gerrit/api-report.md index 870937f7ec..1dee786da1 100644 --- a/plugins/catalog-backend-module-gerrit/api-report.md +++ b/plugins/catalog-backend-module-gerrit/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { EntityProvider } from '@backstage/plugin-catalog-backend'; import { EntityProviderConnection } from '@backstage/plugin-catalog-backend'; @@ -30,8 +29,5 @@ export class GerritEntityProvider implements EntityProvider { refresh(logger: Logger): Promise; } -// @alpha (undocumented) -export const gerritEntityProviderCatalogModule: () => BackendFeature; - // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index 4e8d389c9c..b5482affb1 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,14 +1,26 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.1.10-next.2", + "version": "0.1.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" @@ -21,7 +33,7 @@ }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -48,7 +60,7 @@ "@backstage/cli": "workspace:^", "@types/fs-extra": "^9.0.1", "luxon": "^3.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/catalog-backend-module-gerrit/src/alpha.ts b/plugins/catalog-backend-module-gerrit/src/alpha.ts new file mode 100644 index 0000000000..8b03d9312a --- /dev/null +++ b/plugins/catalog-backend-module-gerrit/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { gerritEntityProviderCatalogModule } from './service/GerritEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-gerrit/src/index.ts b/plugins/catalog-backend-module-gerrit/src/index.ts index 38ede69926..133772d4b1 100644 --- a/plugins/catalog-backend-module-gerrit/src/index.ts +++ b/plugins/catalog-backend-module-gerrit/src/index.ts @@ -15,4 +15,3 @@ */ export { GerritEntityProvider } from './providers/GerritEntityProvider'; -export { gerritEntityProviderCatalogModule } from './service/GerritEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.test.ts index 9d61cabdb9..51c1749c66 100644 --- a/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.test.ts @@ -22,7 +22,7 @@ import { } from '@backstage/backend-tasks'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; import { gerritEntityProviderCatalogModule } from './GerritEntityProviderCatalogModule'; import { GerritEntityProvider } from '../providers/GerritEntityProvider'; diff --git a/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.ts index 8c61038c8f..782c724094 100644 --- a/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-gerrit/src/service/GerritEntityProviderCatalogModule.ts @@ -19,7 +19,7 @@ import { coreServices, createBackendModule, } from '@backstage/backend-plugin-api'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { GerritEntityProvider } from '../providers/GerritEntityProvider'; /** diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index 089cd237e2..e4b14ca727 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-catalog-backend-module-github +## 0.2.6-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## 0.2.5 + +### Patch Changes + +- 66158754b4: Add support for filtering out forks +- 80afd5ff8b: Use github team slug and login annotations rather than entity name to infer location annotations +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + ## 0.2.5-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/alpha-api-report.md b/plugins/catalog-backend-module-github/alpha-api-report.md new file mode 100644 index 0000000000..eb13ec4558 --- /dev/null +++ b/plugins/catalog-backend-module-github/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-github" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const githubEntityProviderCatalogModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend-module-github/api-report.md b/plugins/catalog-backend-module-github/api-report.md index a66ec712c7..e2b73d267b 100644 --- a/plugins/catalog-backend-module-github/api-report.md +++ b/plugins/catalog-backend-module-github/api-report.md @@ -4,7 +4,6 @@ ```ts import { AnalyzeOptions } from '@backstage/plugin-catalog-backend'; -import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; @@ -100,9 +99,6 @@ export class GithubEntityProvider implements EntityProvider, EventSubscriber { supportsEventTopics(): string[]; } -// @alpha -export const githubEntityProviderCatalogModule: () => BackendFeature; - // @public (undocumented) export class GithubLocationAnalyzer implements ScmLocationAnalyzer { constructor(options: GithubLocationAnalyzerOptions); diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 36cd96274a..5a528a8e05 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-catalog-backend-module-github", "description": "A Backstage catalog backend module that helps integrate towards GitHub", - "version": "0.2.5-next.2", + "version": "0.2.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" @@ -24,7 +36,7 @@ "backstage" ], "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -60,11 +72,10 @@ "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", "luxon": "^3.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", - "alpha", "config.d.ts" ], "configSchema": "config.d.ts" diff --git a/plugins/catalog-backend-module-github/src/alpha.ts b/plugins/catalog-backend-module-github/src/alpha.ts new file mode 100644 index 0000000000..1b83eead82 --- /dev/null +++ b/plugins/catalog-backend-module-github/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { githubEntityProviderCatalogModule } from './service/GithubEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-github/src/index.ts b/plugins/catalog-backend-module-github/src/index.ts index b005780758..17c769419f 100644 --- a/plugins/catalog-backend-module-github/src/index.ts +++ b/plugins/catalog-backend-module-github/src/index.ts @@ -28,7 +28,6 @@ export { GithubOrgReaderProcessor } from './processors/GithubOrgReaderProcessor' export { GithubEntityProvider } from './providers/GithubEntityProvider'; export { GithubOrgEntityProvider } from './providers/GithubOrgEntityProvider'; export type { GithubOrgEntityProviderOptions } from './providers/GithubOrgEntityProvider'; -export { githubEntityProviderCatalogModule } from './service/GithubEntityProviderCatalogModule'; export { type GithubMultiOrgConfig, type GithubTeam, diff --git a/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.test.ts index d8ebc8d0ad..7c08e8947d 100644 --- a/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.test.ts @@ -22,7 +22,7 @@ import { } from '@backstage/backend-tasks'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; import { githubEntityProviderCatalogModule } from './GithubEntityProviderCatalogModule'; import { GithubEntityProvider } from '../providers/GithubEntityProvider'; diff --git a/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.ts index d9dc0a12aa..246f700248 100644 --- a/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-github/src/service/GithubEntityProviderCatalogModule.ts @@ -19,11 +19,11 @@ import { coreServices, } from '@backstage/backend-plugin-api'; import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { GithubEntityProvider } from '../providers/GithubEntityProvider'; /** - * Registers the {@link GithubEntityProvider} with the catalog processing extension point. + * Registers the `GithubEntityProvider` with the catalog processing extension point. * * @alpha */ diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 1f5fc26f38..67bb23d79e 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.1.14-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## 0.1.13 + +### Patch Changes + +- 49948f644f: The config now consistently uses the term 'instance' to refer to a single GitLab API host. +- 85b04f659a: Internal refactor to not use deprecated `substr` +- 52c5685ceb: Implement Group and User Catalog Provider +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + ## 0.1.13-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/alpha-api-report.md b/plugins/catalog-backend-module-gitlab/alpha-api-report.md new file mode 100644 index 0000000000..8912b4a7b2 --- /dev/null +++ b/plugins/catalog-backend-module-gitlab/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-gitlab" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const gitlabDiscoveryEntityProviderCatalogModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend-module-gitlab/api-report.md b/plugins/catalog-backend-module-gitlab/api-report.md index 0195975d4b..68ea45169f 100644 --- a/plugins/catalog-backend-module-gitlab/api-report.md +++ b/plugins/catalog-backend-module-gitlab/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; @@ -33,9 +32,6 @@ export class GitlabDiscoveryEntityProvider implements EntityProvider { refresh(logger: Logger): Promise; } -// @alpha -export const gitlabDiscoveryEntityProviderCatalogModule: () => BackendFeature; - // @public export class GitLabDiscoveryProcessor implements CatalogProcessor { // (undocumented) diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 6668e2f45d..be78589199 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", "description": "A Backstage catalog backend module that helps integrate towards GitLab", - "version": "0.1.13-next.2", + "version": "0.1.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" @@ -25,7 +37,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -54,10 +66,9 @@ "@types/lodash": "^4.14.151", "@types/uuid": "^8.0.0", "luxon": "^3.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/catalog-backend-module-gitlab/src/alpha.ts b/plugins/catalog-backend-module-gitlab/src/alpha.ts new file mode 100644 index 0000000000..883ffc13c4 --- /dev/null +++ b/plugins/catalog-backend-module-gitlab/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { gitlabDiscoveryEntityProviderCatalogModule } from './service/GitlabDiscoveryEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-gitlab/src/index.ts b/plugins/catalog-backend-module-gitlab/src/index.ts index 30efac4924..2dd19c041d 100644 --- a/plugins/catalog-backend-module-gitlab/src/index.ts +++ b/plugins/catalog-backend-module-gitlab/src/index.ts @@ -25,4 +25,3 @@ export { GitlabDiscoveryEntityProvider, GitlabOrgDiscoveryEntityProvider, } from './providers'; -export { gitlabDiscoveryEntityProviderCatalogModule } from './service/GitlabDiscoveryEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.test.ts index ca8d86f555..efb86e4223 100644 --- a/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.test.ts @@ -22,7 +22,7 @@ import { } from '@backstage/backend-tasks'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; import { gitlabDiscoveryEntityProviderCatalogModule } from './GitlabDiscoveryEntityProviderCatalogModule'; import { GitlabDiscoveryEntityProvider } from '../providers'; diff --git a/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.ts index bb4fb656a8..0adf5b18f2 100644 --- a/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-gitlab/src/service/GitlabDiscoveryEntityProviderCatalogModule.ts @@ -19,7 +19,7 @@ import { coreServices, } from '@backstage/backend-plugin-api'; import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { GitlabDiscoveryEntityProvider } from '../providers'; /** diff --git a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md index 1953885783..88ae72e1a8 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md +++ b/plugins/catalog-backend-module-incremental-ingestion/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/plugin-catalog-backend-module-incremental-ingestion +## 0.2.2-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- bf611cf019: Fix missing `dependencies` in `package.json` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-defaults@0.1.8-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-permission-common@0.7.3 + +## 0.2.0 + +### Minor Changes + +- 1ba120faa3: Added new mechanism to handle deltas in incremental providers + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 407dc01fc9: Removing extra imports for `run` script as `TestBackend` auto loads the default factories +- b7e36660d5: Return `EventSubscriber` from `addIncrementalEntityProvider` to hook up to `EventsBackend` +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- 77c41b6924: Updated README to include newer API options for incremental entity providers +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-permission-common@0.7.3 + ## 0.2.0-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-incremental-ingestion/README.md b/plugins/catalog-backend-module-incremental-ingestion/README.md index aa23b8dfc1..7fe36eeec7 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/README.md +++ b/plugins/catalog-backend-module-incremental-ingestion/README.md @@ -41,7 +41,7 @@ The Incremental Entity Provider backend is designed for data sources that provid ## Installation -1. Install `@backstage/plugin-catalog-backend-module-incremental-ingestion` with `yarn workspace backend add @backstage/plugin-catalog-backend-module-incremental-ingestion` +1. Install `@backstage/plugin-catalog-backend-module-incremental-ingestion` with `yarn add --cwd packages/backend @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 diff --git a/plugins/catalog-backend-module-incremental-ingestion/alpha-api-report.md b/plugins/catalog-backend-module-incremental-ingestion/alpha-api-report.md new file mode 100644 index 0000000000..ec9c59a4c4 --- /dev/null +++ b/plugins/catalog-backend-module-incremental-ingestion/alpha-api-report.md @@ -0,0 +1,19 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-incremental-ingestion" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { IncrementalEntityProvider } from '@backstage/plugin-catalog-backend-module-incremental-ingestion'; +import { IncrementalEntityProviderOptions } from '@backstage/plugin-catalog-backend-module-incremental-ingestion'; + +// @alpha +export const incrementalIngestionEntityProviderCatalogModule: (options: { + providers: { + provider: IncrementalEntityProvider; + options: IncrementalEntityProviderOptions; + }[]; +}) => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend-module-incremental-ingestion/api-report.md b/plugins/catalog-backend-module-incremental-ingestion/api-report.md index fe9ef24777..167c07f70f 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/api-report.md +++ b/plugins/catalog-backend-module-incremental-ingestion/api-report.md @@ -5,7 +5,6 @@ ```ts /// -import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogBuilder } from '@backstage/plugin-catalog-backend'; import type { Config } from '@backstage/config'; import type { DeferredEntity } from '@backstage/plugin-catalog-backend'; @@ -80,14 +79,6 @@ export interface IncrementalEntityProviderOptions { restLength: DurationObjectUnits; } -// @alpha -export const incrementalIngestionEntityProviderCatalogModule: (options: { - providers: { - provider: IncrementalEntityProvider; - options: IncrementalEntityProviderOptions; - }[]; -}) => BackendFeature; - // @public (undocumented) export type PluginEnvironment = { logger: Logger; diff --git a/plugins/catalog-backend-module-incremental-ingestion/package.json b/plugins/catalog-backend-module-incremental-ingestion/package.json index f6ea81996e..e3f6be3a88 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/package.json +++ b/plugins/catalog-backend-module-incremental-ingestion/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-catalog-backend-module-incremental-ingestion", "description": "An entity provider for streaming large asset sources into the catalog", - "version": "0.2.0-next.2", + "version": "0.2.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" @@ -25,7 +37,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -55,12 +67,12 @@ }, "devDependencies": { "@backstage/backend-app-api": "workspace:^", + "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-catalog-backend": "workspace:^" }, "files": [ - "alpha", "dist", "migrations/**/*.{js,d.ts}" ] diff --git a/plugins/catalog-backend-module-incremental-ingestion/src/alpha.ts b/plugins/catalog-backend-module-incremental-ingestion/src/alpha.ts new file mode 100644 index 0000000000..c277a0a680 --- /dev/null +++ b/plugins/catalog-backend-module-incremental-ingestion/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './module'; diff --git a/plugins/catalog-backend-module-incremental-ingestion/src/index.ts b/plugins/catalog-backend-module-incremental-ingestion/src/index.ts index 976c91a1ce..ff1ee1faa1 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/src/index.ts +++ b/plugins/catalog-backend-module-incremental-ingestion/src/index.ts @@ -20,7 +20,6 @@ * @packageDocumentation */ -export * from './module'; export * from './service'; export { type EntityIteratorResult, diff --git a/plugins/catalog-backend-module-incremental-ingestion/src/module/incrementalIngestionEntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-incremental-ingestion/src/module/incrementalIngestionEntityProviderCatalogModule.test.ts index 06cbcb010e..dbadf573a4 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/src/module/incrementalIngestionEntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-incremental-ingestion/src/module/incrementalIngestionEntityProviderCatalogModule.test.ts @@ -18,7 +18,7 @@ import { getVoidLogger } from '@backstage/backend-common'; import { coreServices } from '@backstage/backend-plugin-api'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { IncrementalEntityProvider } from '../types'; import { incrementalIngestionEntityProviderCatalogModule } from './incrementalIngestionEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-incremental-ingestion/src/module/incrementalIngestionEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-incremental-ingestion/src/module/incrementalIngestionEntityProviderCatalogModule.ts index b173b2d2ef..261768c142 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/src/module/incrementalIngestionEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-incremental-ingestion/src/module/incrementalIngestionEntityProviderCatalogModule.ts @@ -18,11 +18,11 @@ import { coreServices, createBackendModule, } from '@backstage/backend-plugin-api'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { IncrementalEntityProvider, IncrementalEntityProviderOptions, -} from '../types'; +} from '@backstage/plugin-catalog-backend-module-incremental-ingestion'; import { WrapperProviders } from './WrapperProviders'; /** diff --git a/plugins/catalog-backend-module-incremental-ingestion/src/run.ts b/plugins/catalog-backend-module-incremental-ingestion/src/run.ts index e9cc7dbb2a..f1b6bd1529 100644 --- a/plugins/catalog-backend-module-incremental-ingestion/src/run.ts +++ b/plugins/catalog-backend-module-incremental-ingestion/src/run.ts @@ -13,14 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { coreServices } from '@backstage/backend-plugin-api'; -import { startTestBackend } from '@backstage/backend-test-utils'; -import { ConfigReader } from '@backstage/config'; -import { catalogPlugin } from '@backstage/plugin-catalog-backend'; + +// Think this file will probably go away once we move to backend system +// And restructure into the /dev folder +// eslint-disable-next-line @backstage/no-undeclared-imports +import { createBackend } from '@backstage/backend-defaults'; import { - IncrementalEntityProvider, - incrementalIngestionEntityProviderCatalogModule, -} from '.'; + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { ConfigReader } from '@backstage/config'; +import { catalogPlugin } from '@backstage/plugin-catalog-backend/alpha'; +import { IncrementalEntityProvider } from '.'; +import { incrementalIngestionEntityProviderCatalogModule } from './alpha'; const provider: IncrementalEntityProvider = { getProviderName: () => 'test-provider', @@ -46,25 +51,33 @@ async function main() { }, }; - await startTestBackend({ - services: [[coreServices.config, new ConfigReader(config)]], - extensionPoints: [], - features: [ - catalogPlugin(), - incrementalIngestionEntityProviderCatalogModule({ - providers: [ - { - provider: provider, - options: { - burstInterval: { seconds: 1 }, - burstLength: { seconds: 10 }, - restLength: { seconds: 10 }, - }, - }, - ], + const backend = createBackend({ + services: [ + createServiceFactory({ + service: coreServices.config, + deps: {}, + factory: () => new ConfigReader(config), }), ], }); + + backend.add(catalogPlugin()); + backend.add( + incrementalIngestionEntityProviderCatalogModule({ + providers: [ + { + provider: provider, + options: { + burstInterval: { seconds: 1 }, + burstLength: { seconds: 10 }, + restLength: { seconds: 10 }, + }, + }, + ], + }), + ); + + await backend.start(); } main().catch(error => { diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 50245d20ae..e2c358d1a4 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## 0.5.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/catalog-model@1.2.0 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + ## 0.5.9-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index 6a5e1426f7..dfca9332c0 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", "description": "A Backstage catalog backend module that helps integrate towards LDAP", - "version": "0.5.9-next.2", + "version": "0.5.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index 0ee67c7a3c..c7c64da5a0 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.5.2-next.0 + +### Patch Changes + +- a4ebd51352: Revert using `baseUrl` for MS Graph provider as it breaks token retrieval +- 928a12a9b3: Internal refactor of `/alpha` exports. +- 2c234a8932: properly support custom graph api URL +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + +## 0.5.0 + +### Minor Changes + +- fb568e2683: Improve performance when loading users via group membership. + Users data is now loaded from a paged query, rather than having to make an extra call per user to load each user's profiles. + + Note, there are still additional per user calls made to load user avatars + +### Patch Changes + +- 4c86436fdf: Fix MS Graph provider to use target URL for fetching access token +- 0daa328c3a: Extract default transformers to their own file +- 28f9883440: Fixed a bug reading the `user.select` field expected from the `app-config.yaml` configuration +- c5b119ad9c: Increased default page size to 999 (from 100) to reduce the number of calls made to the Microsoft Graph API. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + ## 0.5.0-next.2 ### Minor Changes diff --git a/plugins/catalog-backend-module-msgraph/alpha-api-report.md b/plugins/catalog-backend-module-msgraph/alpha-api-report.md new file mode 100644 index 0000000000..ed30b83bc8 --- /dev/null +++ b/plugins/catalog-backend-module-msgraph/alpha-api-report.md @@ -0,0 +1,24 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-msgraph" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { GroupTransformer } from '@backstage/plugin-catalog-backend-module-msgraph'; +import { OrganizationTransformer } from '@backstage/plugin-catalog-backend-module-msgraph'; +import { UserTransformer } from '@backstage/plugin-catalog-backend-module-msgraph'; + +// @alpha +export const microsoftGraphOrgEntityProviderCatalogModule: () => BackendFeature; + +// @alpha +export interface MicrosoftGraphOrgEntityProviderCatalogModuleOptions { + groupTransformer?: GroupTransformer | Record; + organizationTransformer?: + | OrganizationTransformer + | Record; + userTransformer?: UserTransformer | Record; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend-module-msgraph/api-report.md b/plugins/catalog-backend-module-msgraph/api-report.md index 09770614b4..10a4f405c0 100644 --- a/plugins/catalog-backend-module-msgraph/api-report.md +++ b/plugins/catalog-backend-module-msgraph/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; @@ -139,18 +138,6 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider { read(options?: { logger?: Logger }): Promise; } -// @alpha -export const microsoftGraphOrgEntityProviderCatalogModule: () => BackendFeature; - -// @alpha -export interface MicrosoftGraphOrgEntityProviderCatalogModuleOptions { - groupTransformer?: GroupTransformer | Record; - organizationTransformer?: - | OrganizationTransformer - | Record; - userTransformer?: UserTransformer | Record; -} - // @public @deprecated export interface MicrosoftGraphOrgEntityProviderLegacyOptions { groupTransformer?: GroupTransformer; diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index 7ae0af0bea..29909d4c50 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", - "version": "0.5.0-next.2", + "version": "0.5.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" @@ -25,7 +37,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -56,10 +68,9 @@ "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", "luxon": "^3.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/catalog-backend-module-msgraph/src/alpha.ts b/plugins/catalog-backend-module-msgraph/src/alpha.ts new file mode 100644 index 0000000000..137808d881 --- /dev/null +++ b/plugins/catalog-backend-module-msgraph/src/alpha.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { microsoftGraphOrgEntityProviderCatalogModule } from './service/MicrosoftGraphOrgEntityProviderCatalogModule'; +export type { MicrosoftGraphOrgEntityProviderCatalogModuleOptions } from './service/MicrosoftGraphOrgEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-msgraph/src/index.ts b/plugins/catalog-backend-module-msgraph/src/index.ts index b80a0b3863..f98cb907ec 100644 --- a/plugins/catalog-backend-module-msgraph/src/index.ts +++ b/plugins/catalog-backend-module-msgraph/src/index.ts @@ -22,5 +22,3 @@ export * from './microsoftGraph'; export * from './processors'; -export { microsoftGraphOrgEntityProviderCatalogModule } from './service/MicrosoftGraphOrgEntityProviderCatalogModule'; -export type { MicrosoftGraphOrgEntityProviderCatalogModuleOptions } from './service/MicrosoftGraphOrgEntityProviderCatalogModule'; diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts index f7d98f12c6..6d63537b54 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.test.ts @@ -53,7 +53,7 @@ describe('MicrosoftGraphClient', () => { expect(await response.json()).toEqual({ value: 'example' }); expect(tokenCredential.getToken).toHaveBeenCalledTimes(1); expect(tokenCredential.getToken).toHaveBeenCalledWith( - 'https://example.com/.default', + 'https://other.example.com/.default', ); }); diff --git a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts index 7a685b258d..4acf7c726e 100644 --- a/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts +++ b/plugins/catalog-backend-module-msgraph/src/microsoftGraph/client.ts @@ -218,8 +218,9 @@ export class MicrosoftGraphClient { headers?: Record, ): Promise { // Make sure that we always have a valid access token (might be cached) + const urlObj = new URL(url); const token = await this.tokenCredential.getToken( - `${this.baseUrl}/.default`, + `${urlObj.protocol}//${urlObj.hostname}/.default`, ); if (!token) { diff --git a/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.test.ts b/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.test.ts index 27ae5b9dd8..3763553162 100644 --- a/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.test.ts +++ b/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.test.ts @@ -22,7 +22,7 @@ import { } from '@backstage/backend-tasks'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { Duration } from 'luxon'; import { microsoftGraphOrgEntityProviderCatalogModule } from './MicrosoftGraphOrgEntityProviderCatalogModule'; import { MicrosoftGraphOrgEntityProvider } from '../processors'; diff --git a/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.ts b/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.ts index fc63867a23..11be567045 100644 --- a/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.ts +++ b/plugins/catalog-backend-module-msgraph/src/service/MicrosoftGraphOrgEntityProviderCatalogModule.ts @@ -19,12 +19,12 @@ import { createBackendModule, } from '@backstage/backend-plugin-api'; import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { GroupTransformer, OrganizationTransformer, UserTransformer, -} from '../microsoftGraph'; +} from '@backstage/plugin-catalog-backend-module-msgraph'; import { MicrosoftGraphOrgEntityProvider } from '../processors'; /** diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index 496221964e..a1d43e6954 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + +## 0.1.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/config@1.0.6 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + ## 0.1.8-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 8f08f4b183..3407eeb0e6 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", - "version": "0.1.8-next.2", + "version": "0.1.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index 329f641c78..0b55db0239 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,62 @@ # @backstage/plugin-catalog-backend +## 1.8.0-next.0 + +### Minor Changes + +- 7f4ea3d360: Add /entities/by-query endpoint returning paginated entities. + + The endpoint supports cursor base pagination and server side sorting of the entities + +### Patch Changes + +- ac8929f2f3: Fix export of `defaultCatalogCollatorEntityTransformer`. +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + - @backstage/plugin-search-common@1.2.1 + +## 1.7.2 + +### Patch Changes + +- 071354eb7d: Add additional validation as security precations for output entities. +- b977c2e69f: Minor improvements to the descriptions provided with permission rules schemas +- 2380506364: The process of adding or modifying fields in the software-catalog search index has been simplified. For more details, see [how to customize fields in the Software Catalog index](https://backstage.io/docs/features/search/how-to-guides#how-to-customize-fields-in-the-software-catalog-index). +- 9573651919: The previous migration that adds the `search.original_value` column may leave some of the entities not updated. Add a migration script to trigger a reprocessing of the entities. +- 9f71a2fd20: Location rule target patterns now also match hidden files, i.e. path components with a leading dot. +- e716946103: Updated usage of the lifecycle service. +- 1aec041c34: Fixed an issue where entities sometimes were not properly deleted during a full mutation. +- 0ff03319be: Updated usage of `createBackendPlugin`. +- fc73f6aae5: Switched the order of reprocessing statements retroactively in migrations. This only improves the experience for those who at a later time perform a large upgrade of an old Backstage installation. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + - @backstage/plugin-scaffolder-common@1.2.5 + - @backstage/plugin-search-common@1.2.1 + ## 1.7.2-next.2 ### Patch Changes diff --git a/plugins/catalog-backend/alpha-api-report.md b/plugins/catalog-backend/alpha-api-report.md new file mode 100644 index 0000000000..df2fa3d2e9 --- /dev/null +++ b/plugins/catalog-backend/alpha-api-report.md @@ -0,0 +1,156 @@ +## API Report File for "@backstage/plugin-catalog-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common'; +import { Conditions } from '@backstage/plugin-permission-node'; +import { Entity } from '@backstage/catalog-model'; +import { PermissionCondition } from '@backstage/plugin-permission-common'; +import { PermissionCriteria } from '@backstage/plugin-permission-common'; +import { PermissionRule } from '@backstage/plugin-permission-node'; +import { PermissionRuleParams } from '@backstage/plugin-permission-common'; +import { ResourcePermission } from '@backstage/plugin-permission-common'; + +// @alpha +export const catalogConditions: Conditions<{ + hasAnnotation: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + value?: string | undefined; + annotation: string; + } + >; + hasLabel: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + label: string; + } + >; + hasMetadata: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + value?: string | undefined; + key: string; + } + >; + hasSpec: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + value?: string | undefined; + key: string; + } + >; + isEntityKind: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + kinds: string[]; + } + >; + isEntityOwner: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + claims: string[]; + } + >; +}>; + +// @alpha +export type CatalogPermissionRule< + TParams extends PermissionRuleParams = PermissionRuleParams, +> = PermissionRule; + +// @alpha +export const catalogPlugin: () => BackendFeature; + +// @alpha +export const createCatalogConditionalDecision: ( + permission: ResourcePermission<'catalog-entity'>, + conditions: PermissionCriteria< + PermissionCondition<'catalog-entity', PermissionRuleParams> + >, +) => ConditionalPolicyDecision; + +// @alpha +export const createCatalogPermissionRule: < + TParams extends PermissionRuleParams = undefined, +>( + rule: PermissionRule, +) => PermissionRule; + +// @public +export type EntitiesSearchFilter = { + key: string; + values?: string[]; +}; + +// @alpha +export const permissionRules: { + hasAnnotation: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + value?: string | undefined; + annotation: string; + } + >; + hasLabel: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + label: string; + } + >; + hasMetadata: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + value?: string | undefined; + key: string; + } + >; + hasSpec: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + value?: string | undefined; + key: string; + } + >; + isEntityKind: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + kinds: string[]; + } + >; + isEntityOwner: PermissionRule< + Entity, + EntitiesSearchFilter, + 'catalog-entity', + { + claims: string[]; + } + >; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index f15f6b9ba9..00c13a31ea 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -10,7 +10,6 @@ import { AnalyzeLocationExistingEntity as AnalyzeLocationExistingEntity_2 } from import { AnalyzeLocationGenerateEntity as AnalyzeLocationGenerateEntity_2 } from '@backstage/plugin-catalog-common'; import { AnalyzeLocationRequest as AnalyzeLocationRequest_2 } from '@backstage/plugin-catalog-common'; import { AnalyzeLocationResponse as AnalyzeLocationResponse_2 } from '@backstage/plugin-catalog-common'; -import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; @@ -23,8 +22,6 @@ import { CatalogProcessorParser } from '@backstage/plugin-catalog-node'; import { CatalogProcessorRefreshKeysResult } from '@backstage/plugin-catalog-node'; import { CatalogProcessorRelationResult } from '@backstage/plugin-catalog-node'; import { CatalogProcessorResult } from '@backstage/plugin-catalog-node'; -import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common'; -import { Conditions } from '@backstage/plugin-permission-node'; import { Config } from '@backstage/config'; import { DeferredEntity } from '@backstage/plugin-catalog-node'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; @@ -41,8 +38,6 @@ import { LocationSpec as LocationSpec_2 } from '@backstage/plugin-catalog-common import { Logger } from 'winston'; import { Permission } from '@backstage/plugin-permission-common'; import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; -import { PermissionCondition } from '@backstage/plugin-permission-common'; -import { PermissionCriteria } from '@backstage/plugin-permission-common'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; import { PermissionRule } from '@backstage/plugin-permission-node'; import { PermissionRuleParams } from '@backstage/plugin-permission-common'; @@ -50,7 +45,6 @@ import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { processingResult } from '@backstage/plugin-catalog-node'; import { Readable } from 'stream'; -import { ResourcePermission } from '@backstage/plugin-permission-common'; import { Router } from 'express'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { TokenManager } from '@backstage/backend-common'; @@ -128,10 +122,9 @@ export class CatalogBuilder { addLocationAnalyzers( ...analyzers: Array> ): CatalogBuilder; - // @alpha addPermissionRules( ...permissionRules: Array< - CatalogPermissionRule | Array + CatalogPermissionRuleInput | Array > ): this; addProcessor( @@ -172,61 +165,6 @@ export type CatalogCollatorEntityTransformer = ( entity: Entity, ) => Omit; -// @alpha -export const catalogConditions: Conditions<{ - hasAnnotation: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - value?: string | undefined; - annotation: string; - } - >; - hasLabel: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - label: string; - } - >; - hasMetadata: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - value?: string | undefined; - key: string; - } - >; - hasSpec: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - value?: string | undefined; - key: string; - } - >; - isEntityKind: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - kinds: string[]; - } - >; - isEntityOwner: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - claims: string[]; - } - >; -}>; - // @public (undocumented) export type CatalogEnvironment = { logger: Logger; @@ -236,14 +174,11 @@ export type CatalogEnvironment = { permissions: PermissionEvaluator | PermissionAuthorizer; }; -// @alpha -export type CatalogPermissionRule< +// @public +export type CatalogPermissionRuleInput< TParams extends PermissionRuleParams = PermissionRuleParams, > = PermissionRule; -// @alpha -export const catalogPlugin: () => BackendFeature; - // @public export interface CatalogProcessingEngine { // (undocumented) @@ -293,21 +228,6 @@ export class CodeOwnersProcessor implements CatalogProcessor { preProcessEntity(entity: Entity, location: LocationSpec_2): Promise; } -// @alpha -export const createCatalogConditionalDecision: ( - permission: ResourcePermission<'catalog-entity'>, - conditions: PermissionCriteria< - PermissionCondition<'catalog-entity', PermissionRuleParams> - >, -) => ConditionalPolicyDecision; - -// @alpha -export const createCatalogPermissionRule: < - TParams extends PermissionRuleParams = undefined, ->( - rule: PermissionRule, -) => PermissionRule; - // @public export function createRandomProcessingInterval(options: { minSeconds: number; @@ -466,61 +386,6 @@ export function parseEntityYaml( location: LocationSpec_2, ): Iterable; -// @alpha -export const permissionRules: { - hasAnnotation: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - value?: string | undefined; - annotation: string; - } - >; - hasLabel: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - label: string; - } - >; - hasMetadata: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - value?: string | undefined; - key: string; - } - >; - hasSpec: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - value?: string | undefined; - key: string; - } - >; - isEntityKind: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - kinds: string[]; - } - >; - isEntityOwner: PermissionRule< - Entity, - EntitiesSearchFilter, - 'catalog-entity', - { - claims: string[]; - } - >; -}; - // @public export class PlaceholderProcessor implements CatalogProcessor { constructor(options: PlaceholderProcessorOptions); diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index cebd91932b..5d1be38754 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-catalog-backend", "description": "The Backstage backend plugin that provides the Backstage catalog", - "version": "1.7.2-next.2", + "version": "1.8.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin" @@ -25,7 +37,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -82,13 +94,12 @@ "@types/uuid": "^8.0.0", "better-sqlite3": "^8.0.0", "luxon": "^3.0.0", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3", "wait-for-expect": "^3.0.2" }, "files": [ "dist", - "alpha", "migrations/**/*.{js,d.ts}", "config.d.ts" ], diff --git a/plugins/catalog-backend/src/alpha.ts b/plugins/catalog-backend/src/alpha.ts new file mode 100644 index 0000000000..aa1309aecd --- /dev/null +++ b/plugins/catalog-backend/src/alpha.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// TODO(Rugvip): Re-exported for alpha types as the API report will otherwise +// produce warnings due to the indirect dependency. We be nice to avoid. +import type { EntitiesSearchFilter } from './catalog/types'; + +export type { /** @alpha */ EntitiesSearchFilter }; + +export * from './permissions'; +export { catalogPlugin } from './service/CatalogPlugin'; diff --git a/plugins/catalog-backend/src/catalog/types.ts b/plugins/catalog-backend/src/catalog/types.ts index faf7451acd..62c8fad605 100644 --- a/plugins/catalog-backend/src/catalog/types.ts +++ b/plugins/catalog-backend/src/catalog/types.ts @@ -174,6 +174,13 @@ export interface EntitiesCatalog { */ entitiesBatch(request: EntitiesBatchRequest): Promise; + /** + * Fetch entities and scroll back and forth between entities. + * + * @param request + */ + queryEntities(request: QueryEntitiesRequest): Promise; + /** * Removes a single entity. * @@ -202,3 +209,103 @@ export interface EntitiesCatalog { */ facets(request: EntityFacetsRequest): Promise; } + +/** + * The request shape for {@link EntitiesCatalog.queryEntities}. + */ +export type QueryEntitiesRequest = + | QueryEntitiesInitialRequest + | QueryEntitiesCursorRequest; + +/** + * The initial request for {@link EntitiesCatalog.queryEntities}. + * The request take immutable properties that are going to be bound + * for the current and the next pagination requests. + */ +export interface QueryEntitiesInitialRequest { + authorizationToken?: string; + fields?: (entity: Entity) => Entity; + limit?: number; + filter?: EntityFilter; + orderFields?: EntityOrder[]; + fullTextFilter?: { + term: string; + fields?: string[]; + }; +} + +/** + * Request for {@link EntitiesCatalog.queryEntities} used to + * move forward or backward on the data. + */ +export interface QueryEntitiesCursorRequest { + authorizationToken?: string; + fields?: (entity: Entity) => Entity; + limit?: number; + cursor: Cursor; +} + +/** + * The response shape for {@link EntitiesCatalog.queryEntities}. + */ +export interface QueryEntitiesResponse { + /** + * The entities for the current pagination request + */ + items: Entity[]; + + pageInfo: { + /** + * The cursor of the next pagination request. + */ + nextCursor?: Cursor; + /** + * The cursor of the previous pagination request. + */ + prevCursor?: Cursor; + }; + /** + * the total number of entities matching the current filters. + */ + totalItems: number; +} + +/** + * The Cursor used internally by the catalog. + */ +export type Cursor = { + /** + * An array of fields used for sorting the data. + * For example, [ { field: 'metadata.name', order: 'asc' } ] + */ + orderFields: EntityOrder[]; + /** + * The values of the fields of a specific item used for paginating the data. + */ + orderFieldValues: Array; + /** + * A filter to be applied to the full list of entities. + */ + filter?: EntityFilter; + /** + * true if the cursor is a previous cursor. + */ + isPrevious: boolean; + /** + * Used for performing full text filtering on the given fields. + */ + fullTextFilter?: { + term: string; + fields?: string[]; + }; + /** + * The value of the fields of the first returned item used for paginating the data. + * The catalog uses this field internally to understand if the beginning + * of the list has been reached when performing cursor based pagination. + */ + firstSortFieldValues?: Array; + /** + * The number of items that match the provided filters + */ + totalItems?: number; +}; diff --git a/plugins/catalog-backend/src/index.ts b/plugins/catalog-backend/src/index.ts index 000dd94e8b..e52336f036 100644 --- a/plugins/catalog-backend/src/index.ts +++ b/plugins/catalog-backend/src/index.ts @@ -42,7 +42,6 @@ export { processingResult } from '@backstage/plugin-catalog-node'; export * from './catalog'; export * from './ingestion'; export * from './modules'; -export * from './permissions'; export * from './processing'; export * from './search'; export * from './service'; diff --git a/plugins/catalog-backend/src/ingestion/CatalogRules.test.ts b/plugins/catalog-backend/src/ingestion/CatalogRules.test.ts index 34e89fad29..592b1dda21 100644 --- a/plugins/catalog-backend/src/ingestion/CatalogRules.test.ts +++ b/plugins/catalog-backend/src/ingestion/CatalogRules.test.ts @@ -35,6 +35,10 @@ const entity = { }; const location: Record = { + v: { + type: 'url', + target: 'https://github.com/b/c/blob/master/.folder/v.yaml', + }, w: { type: 'url', target: 'https://github.com/b/c/blob/master/w.yaml', @@ -263,4 +267,20 @@ describe('DefaultCatalogRulesEnforcer', () => { expect(enforcer.isAllowed(entity.component, location.z)).toBe(false); }); }); + + it('should allow locations with a hidden folder', () => { + const enforcer = DefaultCatalogRulesEnforcer.fromConfig( + new ConfigReader({ + catalog: { + rules: [ + { + allow: ['Component'], + locations: [{ type: 'url', pattern: 'https://github.com/b/**' }], + }, + ], + }, + }), + ); + expect(enforcer.isAllowed(entity.component, location.v)).toBe(true); + }); }); diff --git a/plugins/catalog-backend/src/ingestion/CatalogRules.ts b/plugins/catalog-backend/src/ingestion/CatalogRules.ts index 677649d4b2..21b2d05a46 100644 --- a/plugins/catalog-backend/src/ingestion/CatalogRules.ts +++ b/plugins/catalog-backend/src/ingestion/CatalogRules.ts @@ -186,7 +186,10 @@ export class DefaultCatalogRulesEnforcer implements CatalogRulesEnforcer { } if ( matcher.pattern && - !minimatch(location?.target, matcher.pattern, { nocase: true }) + !minimatch(location?.target, matcher.pattern, { + nocase: true, + dot: true, + }) ) { continue; } diff --git a/plugins/catalog-backend/src/integration.test.ts b/plugins/catalog-backend/src/integration.test.ts index 4ba046834b..b13e6ef9de 100644 --- a/plugins/catalog-backend/src/integration.test.ts +++ b/plugins/catalog-backend/src/integration.test.ts @@ -52,9 +52,14 @@ import { } from '@backstage/plugin-catalog-node'; import { RefreshStateItem } from './database/types'; import { DefaultProviderDatabase } from './database/DefaultProviderDatabase'; +import { InputError } from '@backstage/errors'; const voidLogger = getVoidLogger(); +type ProgressTrackerWithErrorReports = ProgressTracker & { + reportError(unprocessedEntity: Entity, errors: Error[]): void; +}; + class TestProvider implements EntityProvider { #connection?: EntityProviderConnection; @@ -74,10 +79,10 @@ class TestProvider implements EntityProvider { } } -class ProxyProgressTracker implements ProgressTracker { - #inner: ProgressTracker; +class ProxyProgressTracker implements ProgressTrackerWithErrorReports { + #inner: ProgressTrackerWithErrorReports; - constructor(inner: ProgressTracker) { + constructor(inner: ProgressTrackerWithErrorReports) { this.#inner = inner; } @@ -85,12 +90,16 @@ class ProxyProgressTracker implements ProgressTracker { return this.#inner.processStart(item, voidLogger); } - setTracker(tracker: ProgressTracker) { + setTracker(tracker: ProgressTrackerWithErrorReports) { this.#inner = tracker; } + + reportError(unprocessedEntity: Entity, errors: Error[]): void { + this.#inner.reportError(unprocessedEntity, errors); + } } -class NoopProgressTracker implements ProgressTracker { +class NoopProgressTracker implements ProgressTrackerWithErrorReports { static emptyTracking = { markFailed() {}, markProcessorsCompleted() {}, @@ -102,18 +111,20 @@ class NoopProgressTracker implements ProgressTracker { processStart() { return NoopProgressTracker.emptyTracking; } + + reportError() {} } -class WaitingProgressTracker implements ProgressTracker { - #resolve: (errors: Record) => void; - #promise: Promise>; +class WaitingProgressTracker implements ProgressTrackerWithErrorReports { + #resolve: (errors: Record) => void; + #promise: Promise>; #counts = new Map(); - #errors = new Map(); + #errors = new Map(); #inFlight = new Array>(); constructor(private readonly entityRefs?: Set) { - let resolve: (errors: Record) => void; - this.#promise = new Promise>(_resolve => { + let resolve: (errors: Record) => void; + this.#promise = new Promise>(_resolve => { resolve = _resolve; }); this.#resolve = resolve!; @@ -143,7 +154,7 @@ class WaitingProgressTracker implements ProgressTracker { }; return { markFailed: (error: Error) => { - this.#errors.set(item.entityRef, error); + this.#errors.set(item.entityRef, [error]); onDone(); resolve(); }, @@ -154,7 +165,6 @@ class WaitingProgressTracker implements ProgressTracker { resolve(); }, markSuccessfulWithErrors: () => { - this.#errors.delete(item.entityRef); onDone(); resolve(); }, @@ -165,7 +175,11 @@ class WaitingProgressTracker implements ProgressTracker { }; } - async wait(): Promise> { + reportError(unprocessedEntity: Entity, errors: Error[]): void { + this.#errors.set(stringifyEntityRef(unprocessedEntity), errors); + } + + async wait(): Promise> { return this.#promise; } @@ -191,10 +205,6 @@ class TestHarness { location: LocationSpec, emit: CatalogProcessorEmit, ): Promise; - onProcessingError?(event: { - unprocessedEntity: Entity; - errors: Error[]; - }): void; }) { const config = new ConfigReader( options?.config ?? { @@ -258,7 +268,11 @@ class TestHarness { legacySingleProcessorValidation: false, }); const stitcher = new Stitcher(db, logger); - const catalog = new DefaultEntitiesCatalog(db, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: db, + logger, + stitcher, + }); const proxyProgressTracker = new ProxyProgressTracker( new NoopProgressTracker(), ); @@ -271,13 +285,7 @@ class TestHarness { () => createHash('sha1'), 50, event => { - if (options?.onProcessingError) { - options.onProcessingError(event); - } else { - throw new Error( - `Catalog processing error, ${event.errors.join(', ')}`, - ); - } + proxyProgressTracker.reportError(event.unprocessedEntity, event.errors); }, proxyProgressTracker, ); @@ -388,7 +396,13 @@ describe('Catalog Backend Integration', () => { triggerError = true; - await expect(harness.process()).resolves.toEqual({}); + await expect(harness.process()).resolves.toEqual({ + 'component:default/test': [ + new InputError( + 'Processor Object threw an error while preprocessing; caused by Error: NOPE', + ), + ], + }); await expect(harness.getOutputEntities()).resolves.toEqual({ 'component:default/test': { @@ -685,4 +699,69 @@ describe('Catalog Backend Integration', () => { .annotations!['backstage.io/orphan'], ).toBeUndefined(); }); + + it('should reject insecure URLs', async () => { + const harness = await TestHarness.create(); + + await harness.setInputEntities([ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test', + annotations: { + 'backstage.io/managed-by-location': 'url:.', + 'backstage.io/managed-by-origin-location': 'url:.', + 'backstage.io/view-url': ' javascript:bad()', + 'backstage.io/edit-url': ' javascript:alert()', + }, + }, + }, + ]); + + await expect(harness.process()).resolves.toEqual({}); + + await expect(harness.getOutputEntities()).resolves.toEqual({ + 'component:default/test': { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: expect.objectContaining({ + name: 'test', + annotations: expect.objectContaining({ + 'backstage.io/view-url': + 'https://backstage.io/annotation-rejected-for-security-reasons', + 'backstage.io/edit-url': + 'https://backstage.io/annotation-rejected-for-security-reasons', + }), + }), + relations: [], + }, + }); + }); + + it('should reject insecure location URLs', async () => { + const harness = await TestHarness.create(); + + await harness.setInputEntities([ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test', + annotations: { + 'backstage.io/managed-by-location': 'url:javascript:bad()', + 'backstage.io/managed-by-origin-location': 'url:javascript:alert()', + }, + }, + }, + ]); + + await expect(harness.process()).resolves.toEqual({ + 'component:default/test': [ + new TypeError( + "Invalid location ref 'url:javascript:bad()', target is a javascript: URL", + ), + ], + }); + }); }); diff --git a/plugins/catalog-backend/src/permissions/conditionExports.ts b/plugins/catalog-backend/src/permissions/conditionExports.ts index 1c1ba70631..c9406cdc0e 100644 --- a/plugins/catalog-backend/src/permissions/conditionExports.ts +++ b/plugins/catalog-backend/src/permissions/conditionExports.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; import { createConditionExports } from '@backstage/plugin-permission-node'; import { permissionRules } from './rules'; diff --git a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts index fd51a1a060..73f40da8c8 100644 --- a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts +++ b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts @@ -15,7 +15,7 @@ */ import { get } from 'lodash'; -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; import { createCatalogPermissionRule } from './util'; import { z } from 'zod'; diff --git a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts index ae9b1c3963..315d7fa8d0 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; import { z } from 'zod'; import { createCatalogPermissionRule } from './util'; diff --git a/plugins/catalog-backend/src/permissions/rules/hasLabel.ts b/plugins/catalog-backend/src/permissions/rules/hasLabel.ts index 16c5917585..2d6289dd26 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasLabel.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasLabel.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; import { z } from 'zod'; import { createCatalogPermissionRule } from './util'; diff --git a/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts b/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts index 94aaa63567..8ebad5521c 100644 --- a/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts +++ b/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; import { z } from 'zod'; import { EntitiesSearchFilter } from '../../catalog/types'; import { createCatalogPermissionRule } from './util'; diff --git a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts index d0cc1d9280..86493315dc 100644 --- a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts +++ b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts @@ -15,7 +15,7 @@ */ import { RELATION_OWNED_BY } from '@backstage/catalog-model'; -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; import { z } from 'zod'; import { createCatalogPermissionRule } from './util'; diff --git a/plugins/catalog-backend/src/permissions/rules/util.ts b/plugins/catalog-backend/src/permissions/rules/util.ts index ea25e115d2..466f5ce70b 100644 --- a/plugins/catalog-backend/src/permissions/rules/util.ts +++ b/plugins/catalog-backend/src/permissions/rules/util.ts @@ -15,7 +15,7 @@ */ import { Entity } from '@backstage/catalog-model'; -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; import { PermissionRuleParams } from '@backstage/plugin-permission-common'; import { makeCreatePermissionRule, diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts index 70ec0ee948..42c6930422 100644 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts +++ b/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts @@ -29,10 +29,8 @@ import { CatalogClient, GetEntitiesRequest, } from '@backstage/catalog-client'; -import { - catalogEntityReadPermission, - CatalogEntityDocument, -} from '@backstage/plugin-catalog-common'; +import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha'; +import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; import { Permission } from '@backstage/plugin-permission-common'; /** diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollatorFactory.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollatorFactory.ts index 1c03836e51..ed81d39bbb 100644 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollatorFactory.ts +++ b/plugins/catalog-backend/src/search/DefaultCatalogCollatorFactory.ts @@ -25,10 +25,8 @@ import { GetEntitiesRequest, } from '@backstage/catalog-client'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; -import { - catalogEntityReadPermission, - CatalogEntityDocument, -} from '@backstage/plugin-catalog-common'; +import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha'; +import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; import { Permission } from '@backstage/plugin-permission-common'; import { Readable } from 'stream'; import { CatalogCollatorEntityTransformer } from './CatalogCollatorEntityTransformer'; diff --git a/plugins/catalog-backend/src/search/index.ts b/plugins/catalog-backend/src/search/index.ts index c2a23e5132..3603ab2e60 100644 --- a/plugins/catalog-backend/src/search/index.ts +++ b/plugins/catalog-backend/src/search/index.ts @@ -17,7 +17,7 @@ export { DefaultCatalogCollatorFactory } from './DefaultCatalogCollatorFactory'; export type { DefaultCatalogCollatorFactoryOptions } from './DefaultCatalogCollatorFactory'; export type { CatalogCollatorEntityTransformer } from './CatalogCollatorEntityTransformer'; -export type { defaultCatalogCollatorEntityTransformer } from './defaultCatalogCollatorEntityTransformer'; +export { defaultCatalogCollatorEntityTransformer } from './defaultCatalogCollatorEntityTransformer'; /** * todo(backstage/techdocs-core): stop exporting this in a future release. diff --git a/plugins/catalog-backend/src/service/AuthorizedEntitiesCatalog.test.ts b/plugins/catalog-backend/src/service/AuthorizedEntitiesCatalog.test.ts index 829e41c21e..2ee47dae19 100644 --- a/plugins/catalog-backend/src/service/AuthorizedEntitiesCatalog.test.ts +++ b/plugins/catalog-backend/src/service/AuthorizedEntitiesCatalog.test.ts @@ -20,6 +20,8 @@ import { createConditionTransformer } from '@backstage/plugin-permission-node'; import { isEntityKind } from '../permissions/rules/isEntityKind'; import { CatalogPermissionRule } from '../permissions/rules'; import { AuthorizedEntitiesCatalog } from './AuthorizedEntitiesCatalog'; +import { Cursor, EntityFilter, QueryEntitiesResponse } from '../catalog/types'; +import { Entity } from '@backstage/catalog-model'; describe('AuthorizedEntitiesCatalog', () => { const fakeCatalog = { @@ -30,6 +32,7 @@ describe('AuthorizedEntitiesCatalog', () => { facets: jest.fn(), refresh: jest.fn(), listAncestors: jest.fn(), + queryEntities: jest.fn(), }; const fakePermissionApi = { authorize: jest.fn(), @@ -156,6 +159,153 @@ describe('AuthorizedEntitiesCatalog', () => { }); }); + describe('queryEntities', () => { + it('returns empty response on DENY', async () => { + fakePermissionApi.authorizeConditional.mockResolvedValue([ + { result: AuthorizeResult.DENY }, + ]); + const catalog = createCatalog(); + + await expect( + catalog.queryEntities({ + authorizationToken: 'abcd', + filter: { key: 'kind', values: ['b'] }, + }), + ).resolves.toEqual({ + items: [], + pageInfo: {}, + totalItems: 0, + }); + + expect(fakeCatalog.queryEntities).not.toHaveBeenCalled(); + }); + + it('calls underlying catalog method on ALLOW', async () => { + fakePermissionApi.authorizeConditional.mockResolvedValue([ + { result: AuthorizeResult.ALLOW }, + ]); + const catalog = createCatalog(); + + await catalog.queryEntities({ + authorizationToken: 'abcd', + filter: { key: 'kind', values: ['b'] }, + }); + + expect(fakeCatalog.queryEntities).toHaveBeenCalledWith({ + authorizationToken: 'abcd', + filter: { key: 'kind', values: ['b'] }, + }); + }); + + it('calls underlying catalog method with correct filter on CONDITIONAL', async () => { + fakePermissionApi.authorizeConditional.mockResolvedValue([ + { + result: AuthorizeResult.CONDITIONAL, + conditions: { + rule: 'IS_ENTITY_KIND', + params: { kinds: ['b'] }, + }, + }, + ]); + + const requestFilter: EntityFilter = { key: 'name', values: ['name'] }; + + const entities = [ + { + kind: 'component', + namespace: 'default', + name: 'a', + } as unknown as Entity, + { + kind: 'component', + namespace: 'default', + name: 'b1', + } as unknown as Entity, + ]; + + fakeCatalog.queryEntities.mockResolvedValue({ + items: entities, + pageInfo: { + nextCursor: { + isPrevious: false, + orderFieldValues: ['xxx', null], + filter: { allOf: [{ key: 'kind', values: ['b'] }, requestFilter] }, + }, + prevCursor: { + isPrevious: true, + orderFieldValues: ['a', null], + filter: { allOf: [{ key: 'kind', values: ['b'] }, requestFilter] }, + }, + }, + totalItems: 4, + } as QueryEntitiesResponse); + const catalog = createCatalog(isEntityKind); + + let response = await catalog.queryEntities({ + authorizationToken: 'abcd', + filter: { key: 'name', values: ['name'] }, + }); + + expect(fakeCatalog.queryEntities).toHaveBeenCalledWith({ + authorizationToken: 'abcd', + filter: { allOf: [{ key: 'kind', values: ['b'] }, requestFilter] }, + }); + + expect(response).toEqual({ + items: entities, + totalItems: 4, + pageInfo: { + nextCursor: { + isPrevious: false, + filter: requestFilter, + orderFieldValues: ['xxx', null], + }, + prevCursor: { + isPrevious: true, + filter: requestFilter, + orderFieldValues: ['a', null], + }, + }, + }); + + const cursor: Cursor = { + filter: requestFilter, + orderFields: [{ field: 'name', order: 'asc' }], + isPrevious: false, + orderFieldValues: ['a', null], + }; + response = await catalog.queryEntities({ + authorizationToken: 'abcd', + cursor, + }); + + expect(fakeCatalog.queryEntities).toHaveBeenNthCalledWith(2, { + authorizationToken: 'abcd', + cursor: { + ...cursor, + filter: { allOf: [{ key: 'kind', values: ['b'] }, requestFilter] }, + }, + }); + + expect(response).toEqual({ + items: entities, + totalItems: 4, + pageInfo: { + nextCursor: { + isPrevious: false, + filter: requestFilter, + orderFieldValues: ['xxx', null], + }, + prevCursor: { + isPrevious: true, + filter: requestFilter, + orderFieldValues: ['a', null], + }, + }, + }); + }); + }); + describe('removeEntityByUid', () => { it('throws error on DENY', async () => { fakeCatalog.entities.mockResolvedValue({ diff --git a/plugins/catalog-backend/src/service/AuthorizedEntitiesCatalog.ts b/plugins/catalog-backend/src/service/AuthorizedEntitiesCatalog.ts index c62e9f9a84..0ce1ee87e7 100644 --- a/plugins/catalog-backend/src/service/AuthorizedEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/service/AuthorizedEntitiesCatalog.ts @@ -18,7 +18,7 @@ import { NotAllowedError } from '@backstage/errors'; import { catalogEntityDeletePermission, catalogEntityReadPermission, -} from '@backstage/plugin-catalog-common'; +} from '@backstage/plugin-catalog-common/alpha'; import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { AuthorizeResult, @@ -26,6 +26,7 @@ import { } from '@backstage/plugin-permission-common'; import { ConditionTransformer } from '@backstage/plugin-permission-node'; import { + Cursor, EntitiesBatchRequest, EntitiesBatchResponse, EntitiesCatalog, @@ -35,8 +36,11 @@ import { EntityFacetsRequest, EntityFacetsResponse, EntityFilter, + QueryEntitiesRequest, + QueryEntitiesResponse, } from '../catalog/types'; import { basicEntityFilter } from './request/basicEntityFilter'; +import { isQueryEntitiesCursorRequest } from './util'; export class AuthorizedEntitiesCatalog implements EntitiesCatalog { constructor( @@ -106,6 +110,80 @@ export class AuthorizedEntitiesCatalog implements EntitiesCatalog { return this.entitiesCatalog.entitiesBatch(request); } + async queryEntities( + request: QueryEntitiesRequest, + ): Promise { + const authorizeDecision = ( + await this.permissionApi.authorizeConditional( + [{ permission: catalogEntityReadPermission }], + { token: request.authorizationToken }, + ) + )[0]; + + if (authorizeDecision.result === AuthorizeResult.DENY) { + return { + items: [], + pageInfo: {}, + totalItems: 0, + }; + } + + if (authorizeDecision.result === AuthorizeResult.CONDITIONAL) { + const permissionFilter: EntityFilter = this.transformConditions( + authorizeDecision.conditions, + ); + + let permissionedRequest: QueryEntitiesRequest; + let requestFilter: EntityFilter | undefined; + + if (isQueryEntitiesCursorRequest(request)) { + requestFilter = request.cursor.filter; + + permissionedRequest = { + ...request, + cursor: { + ...request.cursor, + filter: request.cursor.filter + ? { allOf: [permissionFilter, request.cursor.filter] } + : permissionFilter, + }, + }; + } else { + permissionedRequest = { + ...request, + filter: request.filter + ? { allOf: [permissionFilter, request.filter] } + : permissionFilter, + }; + requestFilter = request.filter; + } + + const response = await this.entitiesCatalog.queryEntities( + permissionedRequest, + ); + + const prevCursor: Cursor | undefined = response.pageInfo.prevCursor && { + ...response.pageInfo.prevCursor, + filter: requestFilter, + }; + + const nextCursor: Cursor | undefined = response.pageInfo.nextCursor && { + ...response.pageInfo.nextCursor, + filter: requestFilter, + }; + + return { + ...response, + pageInfo: { + prevCursor, + nextCursor, + }, + }; + } + + return this.entitiesCatalog.queryEntities(request); + } + async removeEntityByUid( uid: string, options?: { authorizationToken?: string }, diff --git a/plugins/catalog-backend/src/service/AuthorizedLocationService.ts b/plugins/catalog-backend/src/service/AuthorizedLocationService.ts index a73597649e..68bb1553a8 100644 --- a/plugins/catalog-backend/src/service/AuthorizedLocationService.ts +++ b/plugins/catalog-backend/src/service/AuthorizedLocationService.ts @@ -21,7 +21,7 @@ import { catalogLocationCreatePermission, catalogLocationDeletePermission, catalogLocationReadPermission, -} from '@backstage/plugin-catalog-common'; +} from '@backstage/plugin-catalog-common/alpha'; import { AuthorizeResult, PermissionEvaluator, diff --git a/plugins/catalog-backend/src/service/AuthorizedRefreshService.ts b/plugins/catalog-backend/src/service/AuthorizedRefreshService.ts index 8634fbf86d..cbc728750a 100644 --- a/plugins/catalog-backend/src/service/AuthorizedRefreshService.ts +++ b/plugins/catalog-backend/src/service/AuthorizedRefreshService.ts @@ -15,7 +15,7 @@ */ import { NotAllowedError } from '@backstage/errors'; -import { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common'; +import { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common/alpha'; import { AuthorizeResult, PermissionEvaluator, diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts index 48bf6a08ef..7da5d69767 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts @@ -76,10 +76,10 @@ import { DefaultCatalogRulesEnforcer } from '../ingestion/CatalogRules'; import { Config } from '@backstage/config'; import { Logger } from 'winston'; import { connectEntityProviders } from '../processing/connectEntityProviders'; -import { - CatalogPermissionRule, - permissionRules as catalogPermissionRules, -} from '../permissions/rules'; +import { PermissionRuleParams } from '@backstage/plugin-permission-common'; +import { EntitiesSearchFilter } from '../catalog/types'; +import { permissionRules as catalogPermissionRules } from '../permissions/rules'; +import { PermissionRule } from '@backstage/plugin-permission-node'; import { PermissionAuthorizer, PermissionEvaluator, @@ -94,11 +94,20 @@ import { basicEntityFilter } from './request/basicEntityFilter'; import { catalogPermissions, RESOURCE_TYPE_CATALOG_ENTITY, -} from '@backstage/plugin-catalog-common'; +} from '@backstage/plugin-catalog-common/alpha'; import { AuthorizedLocationService } from './AuthorizedLocationService'; import { DefaultProviderDatabase } from '../database/DefaultProviderDatabase'; import { DefaultCatalogDatabase } from '../database/DefaultCatalogDatabase'; +/** + * This is a duplicate of the alpha `CatalogPermissionRule` type, for use in the stable API. + * + * @public + */ +export type CatalogPermissionRuleInput< + TParams extends PermissionRuleParams = PermissionRuleParams, +> = PermissionRule; + /** @public */ export type CatalogEnvironment = { logger: Logger; @@ -154,7 +163,7 @@ export class CatalogBuilder { maxSeconds: 150, }); private locationAnalyzer: LocationAnalyzer | undefined = undefined; - private readonly permissionRules: CatalogPermissionRule[]; + private readonly permissionRules: CatalogPermissionRuleInput[]; private allowedLocationType: string[]; private legacySingleProcessorValidation = false; @@ -379,11 +388,10 @@ export class CatalogBuilder { * {@link @backstage/plugin-permission-node#PermissionRule}. * * @param permissionRules - Additional permission rules - * @alpha */ addPermissionRules( ...permissionRules: Array< - CatalogPermissionRule | Array + CatalogPermissionRuleInput | Array > ) { this.permissionRules.push(...permissionRules.flat()); @@ -453,10 +461,11 @@ export class CatalogBuilder { legacySingleProcessorValidation: this.legacySingleProcessorValidation, }); const stitcher = new Stitcher(dbClient, logger); - const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog( - dbClient, + const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog({ + database: dbClient, + logger, stitcher, - ); + }); let permissionEvaluator: PermissionEvaluator; if ('authorizeConditional' in permissions) { diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index 5abb630668..a6b164001c 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -19,9 +19,11 @@ import { } from '@backstage/backend-plugin-api'; import { CatalogBuilder } from './CatalogBuilder'; import { - CatalogProcessor, CatalogProcessingExtensionPoint, catalogProcessingExtensionPoint, +} from '@backstage/plugin-catalog-node/alpha'; +import { + CatalogProcessor, EntityProvider, } from '@backstage/plugin-catalog-node'; import { loggerToWinstonLogger } from '@backstage/backend-common'; diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts index 6735709662..740f5b2558 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.test.ts @@ -14,10 +14,15 @@ * limitations under the License. */ +import { getVoidLogger } from '@backstage/backend-common'; import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { Knex } from 'knex'; -import { v4 as uuid } from 'uuid'; +import { v4 as uuid, v4 } from 'uuid'; +import { + QueryEntitiesCursorRequest, + QueryEntitiesInitialRequest, +} from '../catalog/types'; import { applyDatabaseMigrations } from '../database/migrations'; import { DbFinalEntitiesRow, @@ -31,6 +36,12 @@ import { DefaultEntitiesCatalog } from './DefaultEntitiesCatalog'; import { EntitiesRequest } from '../catalog/types'; describe('DefaultEntitiesCatalog', () => { + let knex: Knex; + + afterEach(async () => { + await knex.destroy(); + }); + const databases = TestDatabases.create({ ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], }); @@ -38,13 +49,11 @@ describe('DefaultEntitiesCatalog', () => { const stitcher: Stitcher = { stitch } as any; async function createDatabase(databaseId: TestDatabaseId) { - const knex = await databases.init(databaseId); + knex = await databases.init(databaseId); await applyDatabaseMigrations(knex); - return { knex }; } async function addEntity( - knex: Knex, entity: Entity, parents: { source?: string; entity?: Entity }[], ) { @@ -81,8 +90,8 @@ describe('DefaultEntitiesCatalog', () => { return id; } - async function addEntityToSearch(knex: Knex, entity: Entity) { - const id = uuid(); + async function addEntityToSearch(entity: Entity) { + const id = entity.metadata.uid || v4(); const entityRef = stringifyEntityRef(entity); const entityJson = JSON.stringify(entity); @@ -120,7 +129,7 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'should return the ancestry with one parent, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); const grandparent: Entity = { apiVersion: 'a', @@ -141,11 +150,15 @@ describe('DefaultEntitiesCatalog', () => { spec: {}, }; - await addEntity(knex, grandparent, [{ source: 's' }]); - await addEntity(knex, parent, [{ entity: grandparent }]); - await addEntity(knex, root, [{ entity: parent }]); + await addEntity(grandparent, [{ source: 's' }]); + await addEntity(parent, [{ entity: grandparent }]); + await addEntity(root, [{ entity: parent }]); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); const result = await catalog.entityAncestry('k:default/root'); expect(result.rootEntityRef).toEqual('k:default/root'); @@ -174,8 +187,12 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'should throw error if the entity does not exist, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + await createDatabase(databaseId); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); await expect(() => catalog.entityAncestry('k:default/root'), ).rejects.toThrow('No such entity k:default/root'); @@ -186,7 +203,7 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'should return the ancestry with multiple parents, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); const grandparent: Entity = { apiVersion: 'a', @@ -213,12 +230,16 @@ describe('DefaultEntitiesCatalog', () => { spec: {}, }; - await addEntity(knex, grandparent, [{ source: 's' }]); - await addEntity(knex, parent1, [{ entity: grandparent }]); - await addEntity(knex, parent2, [{ entity: grandparent }]); - await addEntity(knex, root, [{ entity: parent1 }, { entity: parent2 }]); + await addEntity(grandparent, [{ source: 's' }]); + await addEntity(parent1, [{ entity: grandparent }]); + await addEntity(parent2, [{ entity: grandparent }]); + await addEntity(root, [{ entity: parent1 }, { entity: parent2 }]); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); const result = await catalog.entityAncestry('k:default/root'); expect(result.rootEntityRef).toEqual('k:default/root'); @@ -257,7 +278,7 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'should return correct entity for simple filter, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); const entity1: Entity = { apiVersion: 'a', kind: 'k', @@ -272,9 +293,13 @@ describe('DefaultEntitiesCatalog', () => { test: 'test value', }, }; - await addEntityToSearch(knex, entity1); - await addEntityToSearch(knex, entity2); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + await addEntityToSearch(entity1); + await addEntityToSearch(entity2); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); const testFilter = { key: 'spec.test', @@ -291,7 +316,7 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'should return correct entity for negation filter, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); const entity1: Entity = { apiVersion: 'a', kind: 'k', @@ -306,9 +331,13 @@ describe('DefaultEntitiesCatalog', () => { test: 'test value', }, }; - await addEntityToSearch(knex, entity1); - await addEntityToSearch(knex, entity2); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + await addEntityToSearch(entity1); + await addEntityToSearch(entity2); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); const testFilter = { not: { @@ -327,7 +356,7 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'should return correct entities for nested filter, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); const entity1: Entity = { apiVersion: 'a', kind: 'k', @@ -352,11 +381,15 @@ describe('DefaultEntitiesCatalog', () => { metadata: { name: 'four', org: 'b', color: 'blue' }, spec: {}, }; - await addEntityToSearch(knex, entity1); - await addEntityToSearch(knex, entity2); - await addEntityToSearch(knex, entity3); - await addEntityToSearch(knex, entity4); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + await addEntityToSearch(entity1); + await addEntityToSearch(entity2); + await addEntityToSearch(entity3); + await addEntityToSearch(entity4); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); const testFilter1 = { key: 'metadata.org', @@ -397,7 +430,7 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'should return correct entities for complex negation filter, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); const entity1: Entity = { apiVersion: 'a', kind: 'k', @@ -410,9 +443,13 @@ describe('DefaultEntitiesCatalog', () => { metadata: { name: 'two', org: 'b', desc: 'description' }, spec: {}, }; - await addEntityToSearch(knex, entity1); - await addEntityToSearch(knex, entity2); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + await addEntityToSearch(entity1); + await addEntityToSearch(entity2); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); const testFilter1 = { key: 'metadata.org', @@ -440,7 +477,7 @@ describe('DefaultEntitiesCatalog', () => { 'should return no matches for an empty values array, %p', // NOTE: An empty values array is not a sensible input in a realistic scenario. async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); const entity1: Entity = { apiVersion: 'a', kind: 'k', @@ -453,9 +490,13 @@ describe('DefaultEntitiesCatalog', () => { metadata: { name: 'two' }, spec: {}, }; - await addEntityToSearch(knex, entity1); - await addEntityToSearch(knex, entity2); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + await addEntityToSearch(entity1); + await addEntityToSearch(entity2); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); const testFilter = { key: 'kind', @@ -472,9 +513,8 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'should return both target and targetRef for entities', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); await addEntity( - knex, { apiVersion: 'a', kind: 'k', @@ -485,7 +525,6 @@ describe('DefaultEntitiesCatalog', () => { [], ); await addEntity( - knex, { apiVersion: 'a', kind: 'k', @@ -500,7 +539,11 @@ describe('DefaultEntitiesCatalog', () => { }, [], ); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); const { entities } = await catalog.entities(); @@ -529,7 +572,7 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'can order and combine with filtering, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); const entity1: Entity = { apiVersion: 'a', @@ -555,12 +598,16 @@ describe('DefaultEntitiesCatalog', () => { metadata: { name: 'n4' }, spec: { a: 'baz', b: 'only' }, }; - await addEntityToSearch(knex, entity1); - await addEntityToSearch(knex, entity2); - await addEntityToSearch(knex, entity3); - await addEntityToSearch(knex, entity4); + await addEntityToSearch(entity1); + await addEntityToSearch(entity2); + await addEntityToSearch(entity3); + await addEntityToSearch(entity4); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); function f(request: EntitiesRequest): Promise { return catalog @@ -623,10 +670,9 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'queries for entities by ref, including duplicates, and gracefully returns null for missing entities, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); await addEntity( - knex, { apiVersion: 'a', kind: 'k', @@ -637,7 +683,6 @@ describe('DefaultEntitiesCatalog', () => { [], ); await addEntity( - knex, { apiVersion: 'a', kind: 'k', @@ -648,7 +693,11 @@ describe('DefaultEntitiesCatalog', () => { [], ); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); const { items } = await catalog.entitiesBatch({ entityRefs: [ @@ -674,11 +723,581 @@ describe('DefaultEntitiesCatalog', () => { ); }); + describe('queryEntities', () => { + it.each(databases.eachSupportedId())( + 'should return paginated entities and scroll the items accordingly, %p', + async databaseId => { + await createDatabase(databaseId); + + const names = ['B', 'F', 'A', 'G', 'D', 'C', 'E']; + const entities: Entity[] = names.map(name => entityFrom(name)); + + const notFoundEntities: Entity[] = [ + { + apiVersion: 'a', + kind: 'k', + metadata: { name: 'something' }, + spec: {}, + }, + { + apiVersion: 'a', + kind: 'k', + metadata: { name: 'something else' }, + spec: {}, + }, + ]; + + await Promise.all( + entities.concat(notFoundEntities).map(e => addEntityToSearch(e)), + ); + + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); + + const filter = { + key: 'spec.should_include_this', + }; + + const limit = 2; + + // initial request + const request1: QueryEntitiesInitialRequest = { + filter, + limit, + orderFields: [{ field: 'metadata.name', order: 'asc' }], + }; + const response1 = await catalog.queryEntities(request1); + expect(response1.items).toEqual([entityFrom('A'), entityFrom('B')]); + expect(response1.pageInfo.nextCursor).toBeDefined(); + expect(response1.pageInfo.prevCursor).toBeUndefined(); + expect(response1.totalItems).toBe(names.length); + + // second request (forward) + const request2: QueryEntitiesCursorRequest = { + cursor: response1.pageInfo.nextCursor!, + limit, + }; + const response2 = await catalog.queryEntities(request2); + expect(response2.items).toEqual([entityFrom('C'), entityFrom('D')]); + expect(response2.pageInfo.nextCursor).toBeDefined(); + expect(response2.pageInfo.prevCursor).toBeDefined(); + expect(response2.totalItems).toBe(names.length); + + // third request (forward) + const request3: QueryEntitiesCursorRequest = { + cursor: response2.pageInfo.nextCursor!, + limit, + }; + const response3 = await catalog.queryEntities(request3); + expect(response3.items).toEqual([entityFrom('E'), entityFrom('F')]); + expect(response3.pageInfo.nextCursor).toBeDefined(); + expect(response3.pageInfo.prevCursor).toBeDefined(); + expect(response3.totalItems).toBe(names.length); + + // fourth request (backwards) + const request4: QueryEntitiesCursorRequest = { + cursor: response3.pageInfo.prevCursor!, + limit, + }; + const response4 = await catalog.queryEntities(request4); + expect(response4.items).toEqual([entityFrom('C'), entityFrom('D')]); + expect(response4.pageInfo.nextCursor).toBeDefined(); + expect(response4.pageInfo.prevCursor).toBeDefined(); + expect(response4.totalItems).toBe(names.length); + + // fifth request (backwards) + const request5: QueryEntitiesCursorRequest = { + cursor: response4.pageInfo.prevCursor!, + limit, + }; + const response5 = await catalog.queryEntities(request5); + expect(response5.items).toEqual([entityFrom('A'), entityFrom('B')]); + expect(response5.pageInfo.nextCursor).toBeDefined(); + expect(response5.pageInfo.prevCursor).toBeUndefined(); + expect(response5.totalItems).toBe(names.length); + + // sixth request (forward) + const request6: QueryEntitiesCursorRequest = { + cursor: response5.pageInfo.nextCursor!, + limit, + }; + const response6 = await catalog.queryEntities(request6); + expect(response6.items).toEqual([entityFrom('C'), entityFrom('D')]); + expect(response6.pageInfo.nextCursor).toBeDefined(); + expect(response6.pageInfo.prevCursor).toBeDefined(); + expect(response6.totalItems).toBe(names.length); + + // seventh request (forward) + const request7: QueryEntitiesCursorRequest = { + cursor: response6.pageInfo.nextCursor!, + limit, + }; + const response7 = await catalog.queryEntities(request7); + expect(response7.items).toEqual([entityFrom('E'), entityFrom('F')]); + expect(response7.pageInfo.nextCursor).toBeDefined(); + expect(response7.pageInfo.prevCursor).toBeDefined(); + expect(response7.totalItems).toBe(names.length); + + // seventh.2 request (forward with a different limit) + const request7bis: QueryEntitiesCursorRequest = { + cursor: response6.pageInfo.nextCursor!, + limit: limit + 1, + }; + const response7bis = await catalog.queryEntities(request7bis); + expect(response7bis.items).toEqual([ + entityFrom('E'), + entityFrom('F'), + entityFrom('G'), + ]); + expect(response7bis.pageInfo.nextCursor).toBeUndefined(); + expect(response7bis.pageInfo.prevCursor).toBeDefined(); + expect(response7bis.totalItems).toBe(names.length); + + // last request (forward) + const request8: QueryEntitiesCursorRequest = { + cursor: response7.pageInfo.nextCursor!, + limit, + }; + const response8 = await catalog.queryEntities(request8); + expect(response8.items).toEqual([entityFrom('G')]); + expect(response8.pageInfo.nextCursor).toBeUndefined(); + expect(response8.pageInfo.prevCursor).toBeDefined(); + expect(response8.totalItems).toBe(names.length); + }, + ); + + it.each(databases.eachSupportedId())( + 'should return paginated entities ordered in descending order and scroll the items accordingly, %p', + async databaseId => { + await createDatabase(databaseId); + + const names = ['B', 'F', 'A', 'G', 'D', 'C', 'E']; + const entities: Entity[] = names.map(name => entityFrom(name)); + + const notFoundEntities: Entity[] = [ + { + apiVersion: 'a', + kind: 'k', + metadata: { name: 'something' }, + spec: {}, + }, + { + apiVersion: 'a', + kind: 'k', + metadata: { name: 'something else' }, + spec: {}, + }, + ]; + + await Promise.all( + entities.concat(notFoundEntities).map(e => addEntityToSearch(e)), + ); + + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); + + const filter = { + key: 'spec.should_include_this', + }; + + const limit = 2; + + // initial request + const request1: QueryEntitiesInitialRequest = { + filter, + limit, + orderFields: [{ field: 'metadata.name', order: 'desc' }], + }; + const response1 = await catalog.queryEntities(request1); + expect(response1.items).toEqual([entityFrom('G'), entityFrom('F')]); + expect(response1.pageInfo.nextCursor).toBeDefined(); + expect(response1.pageInfo.prevCursor).toBeUndefined(); + expect(response1.totalItems).toBe(names.length); + + // second request (forward) + const request2: QueryEntitiesCursorRequest = { + cursor: response1.pageInfo.nextCursor!, + limit, + }; + const response2 = await catalog.queryEntities(request2); + expect(response2.items).toEqual([entityFrom('E'), entityFrom('D')]); + expect(response2.pageInfo.nextCursor).toBeDefined(); + expect(response2.pageInfo.prevCursor).toBeDefined(); + expect(response2.totalItems).toBe(names.length); + + // third request (forward) + const request3: QueryEntitiesCursorRequest = { + cursor: response2.pageInfo.nextCursor!, + limit, + }; + const response3 = await catalog.queryEntities(request3); + expect(response3.items).toEqual([entityFrom('C'), entityFrom('B')]); + expect(response3.pageInfo.nextCursor).toBeDefined(); + expect(response3.pageInfo.prevCursor).toBeDefined(); + expect(response3.totalItems).toBe(names.length); + + // fourth request (backwards) + const request4: QueryEntitiesCursorRequest = { + cursor: response3.pageInfo.prevCursor!, + limit, + }; + const response4 = await catalog.queryEntities(request4); + + expect(response4.items).toEqual([entityFrom('E'), entityFrom('D')]); + expect(response4.pageInfo.nextCursor).toBeDefined(); + expect(response4.pageInfo.prevCursor).toBeDefined(); + expect(response4.totalItems).toBe(names.length); + + // fifth request (backwards) + const request5: QueryEntitiesCursorRequest = { + cursor: response4.pageInfo.prevCursor!, + limit, + }; + const response5 = await catalog.queryEntities(request5); + expect(response5.items).toEqual([entityFrom('G'), entityFrom('F')]); + expect(response5.pageInfo.nextCursor).toBeDefined(); + expect(response5.pageInfo.prevCursor).toBeUndefined(); + expect(response5.totalItems).toBe(names.length); + + // sixth request (forward) + const request6: QueryEntitiesCursorRequest = { + cursor: response5.pageInfo.nextCursor!, + limit, + }; + const response6 = await catalog.queryEntities(request6); + expect(response6.items).toEqual([entityFrom('E'), entityFrom('D')]); + expect(response6.pageInfo.nextCursor).toBeDefined(); + expect(response6.pageInfo.prevCursor).toBeDefined(); + expect(response6.totalItems).toBe(names.length); + + // seventh request (forward) + const request7: QueryEntitiesCursorRequest = { + cursor: response6.pageInfo.nextCursor!, + limit, + }; + const response7 = await catalog.queryEntities(request7); + expect(response7.items).toEqual([entityFrom('C'), entityFrom('B')]); + expect(response7.pageInfo.nextCursor).toBeDefined(); + expect(response7.pageInfo.prevCursor).toBeDefined(); + expect(response7.totalItems).toBe(names.length); + + // seventh.2 request (forward with a different limit) + const request7bis: QueryEntitiesCursorRequest = { + cursor: response6.pageInfo.nextCursor!, + limit: limit + 1, + }; + const response7bis = await catalog.queryEntities(request7bis); + expect(response7bis.items).toEqual([ + entityFrom('C'), + entityFrom('B'), + entityFrom('A'), + ]); + expect(response7bis.pageInfo.nextCursor).toBeUndefined(); + expect(response7bis.pageInfo.prevCursor).toBeDefined(); + expect(response7bis.totalItems).toBe(names.length); + + // last request (forward) + const request8: QueryEntitiesCursorRequest = { + cursor: response7.pageInfo.nextCursor!, + limit, + }; + const response8 = await catalog.queryEntities(request8); + expect(response8.items).toEqual([entityFrom('A')]); + expect(response8.pageInfo.nextCursor).toBeUndefined(); + expect(response8.pageInfo.prevCursor).toBeDefined(); + expect(response8.totalItems).toBe(names.length); + }, + ); + + it.each(databases.eachSupportedId())( + 'should filter the results when query is provided, %p', + async databaseId => { + await createDatabase(databaseId); + + const names = ['lion', 'cat', 'atcatss', 'dog', 'dogcat', 'aa', 's']; + const entities: Entity[] = names.map(name => entityFrom(name)); + + const notFoundEntities: Entity[] = [ + { + apiVersion: 'a', + kind: 'k', + metadata: { name: 'something' }, + spec: {}, + }, + { + apiVersion: 'a', + kind: 'k', + metadata: { name: 'something else' }, + spec: {}, + }, + ]; + + await Promise.all( + entities.concat(notFoundEntities).map(e => addEntityToSearch(e)), + ); + + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); + + const filter = { + key: 'spec.should_include_this', + }; + + const request: QueryEntitiesInitialRequest = { + filter, + limit: 100, + + orderFields: [{ field: 'metadata.name', order: 'asc' }], + fullTextFilter: { term: 'cAt ' }, + }; + const response = await catalog.queryEntities(request); + expect(response.items).toEqual([ + entityFrom('atcatss'), + entityFrom('cat'), + entityFrom('dogcat'), + ]); + expect(response.pageInfo.nextCursor).toBeUndefined(); + expect(response.pageInfo.prevCursor).toBeUndefined(); + expect(response.totalItems).toBe(3); + }, + ); + + it.each(databases.eachSupportedId())( + 'should include totalItems and empty entities in the response in case limit is zero, %p', + async databaseId => { + await createDatabase(databaseId); + + await Promise.all( + Array(20) + .fill(0) + .map(() => + addEntityToSearch({ + apiVersion: 'a', + kind: 'k', + metadata: { name: v4() }, + }), + ), + ); + + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); + + const request: QueryEntitiesInitialRequest = { + limit: 0, + }; + const response = await catalog.queryEntities(request); + expect(response).toEqual({ totalItems: 20, items: [], pageInfo: {} }); + }, + ); + + it.each(databases.eachSupportedId())( + 'should paginate results accordingly in case of clashing items, %p', + async databaseId => { + await createDatabase(databaseId); + + await Promise.all([ + addEntityToSearch(entityFrom('AA')), + addEntityToSearch(entityFrom('AA', { namespace: 'namespace2' })), + addEntityToSearch(entityFrom('AA', { namespace: 'namespace3' })), + addEntityToSearch(entityFrom('AA', { namespace: 'namespace4' })), + addEntityToSearch(entityFrom('CC')), + addEntityToSearch(entityFrom('DD')), + ]); + + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); + + const limit = 2; + + // initial request + const request1: QueryEntitiesInitialRequest = { + limit, + orderFields: [{ field: 'metadata.name', order: 'asc' }], + }; + const response1 = await catalog.queryEntities(request1); + expect(response1.items).toMatchObject([ + entityFrom('AA'), + entityFrom('AA'), + ]); + expect(response1.pageInfo.nextCursor).toBeDefined(); + expect(response1.pageInfo.prevCursor).toBeUndefined(); + expect(response1.totalItems).toBe(6); + + // second request (forward) + const request2: QueryEntitiesCursorRequest = { + cursor: response1.pageInfo.nextCursor!, + limit, + }; + const response2 = await catalog.queryEntities(request2); + expect(response2.items).toMatchObject([ + entityFrom('AA'), + entityFrom('AA'), + ]); + expect(response2.pageInfo.nextCursor).toBeDefined(); + expect(response2.pageInfo.prevCursor).toBeDefined(); + expect(response2.totalItems).toBe(6); + + // third request (forward) + const request3: QueryEntitiesCursorRequest = { + cursor: response2.pageInfo.nextCursor!, + limit, + }; + const response3 = await catalog.queryEntities(request3); + expect(response3.items).toEqual([entityFrom('CC'), entityFrom('DD')]); + expect(response3.pageInfo.nextCursor).toBeUndefined(); + expect(response3.pageInfo.prevCursor).toBeDefined(); + expect(response3.totalItems).toBe(6); + + // forth request (backward) + const request4: QueryEntitiesCursorRequest = { + cursor: response3.pageInfo.prevCursor!, + limit, + }; + const response4 = await catalog.queryEntities(request4); + expect(response4.items).toMatchObject([ + entityFrom('AA'), + entityFrom('AA'), + ]); + expect(response4.pageInfo.nextCursor).toBeDefined(); + expect(response4.pageInfo.prevCursor).toBeDefined(); + expect(response4.totalItems).toBe(6); + + // fifth request (backward) + const request5: QueryEntitiesCursorRequest = { + cursor: response4.pageInfo.prevCursor!, + limit, + }; + const response5 = await catalog.queryEntities(request5); + expect(response5.items).toMatchObject([ + entityFrom('AA'), + entityFrom('AA'), + ]); + expect(response5.pageInfo.nextCursor).toBeDefined(); + expect(response5.pageInfo.prevCursor).toBeUndefined(); + expect(response5.totalItems).toBe(6); + }, + ); + + it.each(databases.eachSupportedId())( + 'should paginate results without sort fields, %p', + async databaseId => { + await createDatabase(databaseId); + + await Promise.all([ + addEntityToSearch(entityFrom('AA', { uid: 'id1' })), + addEntityToSearch(entityFrom('CC', { uid: 'id2' })), + addEntityToSearch( + entityFrom('AA', { namespace: 'namespace2', uid: 'id4' }), + ), + addEntityToSearch( + entityFrom('AA', { namespace: 'namespace3', uid: 'id5' }), + ), + addEntityToSearch( + entityFrom('AA', { namespace: 'namespace4', uid: 'id6' }), + ), + addEntityToSearch(entityFrom('DD', { uid: 'id3' })), + ]); + + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); + + const limit = 2; + + // initial request + const request1: QueryEntitiesInitialRequest = { + limit, + }; + const response1 = await catalog.queryEntities(request1); + expect(response1.items).toMatchObject([ + entityFrom('AA'), + entityFrom('CC'), + ]); + expect(response1.pageInfo.nextCursor).toBeDefined(); + expect(response1.pageInfo.prevCursor).toBeUndefined(); + expect(response1.totalItems).toBe(6); + + // second request (forward) + const request2: QueryEntitiesCursorRequest = { + cursor: response1.pageInfo.nextCursor!, + limit, + }; + const response2 = await catalog.queryEntities(request2); + expect(response2.items).toMatchObject([ + entityFrom('DD'), + entityFrom('AA', { namespace: 'namespace2' }), + ]); + expect(response2.pageInfo.nextCursor).toBeDefined(); + expect(response2.pageInfo.prevCursor).toBeDefined(); + expect(response2.totalItems).toBe(6); + + // third request (forward) + const request3: QueryEntitiesCursorRequest = { + cursor: response2.pageInfo.nextCursor!, + limit, + }; + const response3 = await catalog.queryEntities(request3); + expect(response3.items).toMatchObject([ + entityFrom('AA', { namespace: 'namespace3' }), + entityFrom('AA', { namespace: 'namespace4' }), + ]); + expect(response3.pageInfo.nextCursor).toBeUndefined(); + expect(response3.pageInfo.prevCursor).toBeDefined(); + expect(response3.totalItems).toBe(6); + + // forth request (backward) + const request4: QueryEntitiesCursorRequest = { + cursor: response3.pageInfo.prevCursor!, + limit, + }; + const response4 = await catalog.queryEntities(request4); + expect(response4.items).toMatchObject([ + entityFrom('DD'), + entityFrom('AA', { namespace: 'namespace2' }), + ]); + expect(response4.pageInfo.nextCursor).toBeDefined(); + expect(response4.pageInfo.prevCursor).toBeDefined(); + expect(response4.totalItems).toBe(6); + + // fifth request (backward) + const request5: QueryEntitiesCursorRequest = { + cursor: response4.pageInfo.prevCursor!, + limit, + }; + const response5 = await catalog.queryEntities(request5); + expect(response5.items).toMatchObject([ + entityFrom('AA'), + entityFrom('CC'), + ]); + expect(response5.pageInfo.nextCursor).toBeDefined(); + expect(response5.pageInfo.prevCursor).toBeUndefined(); + expect(response5.totalItems).toBe(6); + }, + ); + }); + describe('removeEntityByUid', () => { it.each(databases.eachSupportedId())( 'also clears parent hashes, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); const grandparent: Entity = { apiVersion: 'a', @@ -717,15 +1336,15 @@ describe('DefaultEntitiesCatalog', () => { spec: {}, }; - await addEntity(knex, grandparent, [{ source: 's' }]); - await addEntity(knex, parent1, [{ entity: grandparent }]); - await addEntity(knex, parent2, [{ entity: grandparent }]); - const uid = await addEntity(knex, root, [ + await addEntity(grandparent, [{ source: 's' }]); + await addEntity(parent1, [{ entity: grandparent }]); + await addEntity(parent2, [{ entity: grandparent }]); + const uid = await addEntity(root, [ { entity: parent1 }, { entity: parent2 }, ]); - await addEntity(knex, unrelated1, []); - await addEntity(knex, unrelated2, []); + await addEntity(unrelated1, []); + await addEntity(unrelated2, []); await knex('refresh_state').update({ result_hash: 'not-changed' }); await knex('relations').insert({ originating_entity_id: uid, @@ -740,7 +1359,11 @@ describe('DefaultEntitiesCatalog', () => { target_entity_ref: 'k:default/root', }); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); await catalog.removeEntityByUid(uid); await expect( @@ -767,27 +1390,31 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'can filter and collect properly, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); - await addEntityToSearch(knex, { + await addEntityToSearch({ apiVersion: 'a', kind: 'k', metadata: { name: 'one' }, spec: {}, }); - await addEntityToSearch(knex, { + await addEntityToSearch({ apiVersion: 'a', kind: 'k', metadata: { name: 'two' }, spec: {}, }); - await addEntityToSearch(knex, { + await addEntityToSearch({ apiVersion: 'a', kind: 'k2', metadata: { name: 'two' }, spec: {}, }); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); await expect(catalog.facets({ facets: ['kind'] })).resolves.toEqual({ facets: { @@ -804,9 +1431,9 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'can match on annotations and labels with dots in them, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); - await addEntityToSearch(knex, { + await addEntityToSearch({ apiVersion: 'a', kind: 'k', metadata: { @@ -816,7 +1443,7 @@ describe('DefaultEntitiesCatalog', () => { }, spec: {}, }); - await addEntityToSearch(knex, { + await addEntityToSearch({ apiVersion: 'a', kind: 'k', metadata: { @@ -826,7 +1453,11 @@ describe('DefaultEntitiesCatalog', () => { }, spec: {}, }); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); await expect( catalog.facets({ @@ -851,9 +1482,9 @@ describe('DefaultEntitiesCatalog', () => { it.each(databases.eachSupportedId())( 'can match on strings in arrays, %p', async databaseId => { - const { knex } = await createDatabase(databaseId); + await createDatabase(databaseId); - await addEntityToSearch(knex, { + await addEntityToSearch({ apiVersion: 'a', kind: 'k', metadata: { @@ -862,7 +1493,7 @@ describe('DefaultEntitiesCatalog', () => { }, spec: {}, }); - await addEntityToSearch(knex, { + await addEntityToSearch({ apiVersion: 'a', kind: 'k', metadata: { @@ -871,7 +1502,11 @@ describe('DefaultEntitiesCatalog', () => { }, spec: {}, }); - const catalog = new DefaultEntitiesCatalog(knex, stitcher); + const catalog = new DefaultEntitiesCatalog({ + database: knex, + logger: getVoidLogger(), + stitcher, + }); await expect( catalog.facets({ @@ -891,3 +1526,19 @@ describe('DefaultEntitiesCatalog', () => { ); }); }); + +function entityFrom( + name: string, + { uid, namespace }: { uid?: string; namespace?: string } = {}, +) { + return { + apiVersion: 'a', + kind: 'k', + metadata: { + name, + ...(!!namespace && { namespace }), + ...(!!uid && { uid }), + }, + spec: { should_include_this: 'yes' }, + }; +} diff --git a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts index d598881371..f983d7496b 100644 --- a/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/service/DefaultEntitiesCatalog.ts @@ -20,11 +20,14 @@ import { stringifyEntityRef, } from '@backstage/catalog-model'; import { InputError, NotFoundError } from '@backstage/errors'; -import lodash from 'lodash'; import { Knex } from 'knex'; +import { isEqual, chunk as lodashChunk } from 'lodash'; +import { Logger } from 'winston'; +import { z } from 'zod'; import { EntitiesBatchRequest, EntitiesBatchResponse, + Cursor, EntitiesCatalog, EntitiesRequest, EntitiesResponse, @@ -34,6 +37,9 @@ import { EntityFacetsResponse, EntityFilter, EntityPagination, + QueryEntitiesRequest, + QueryEntitiesResponse, + EntityOrder, } from '../catalog/types'; import { DbFinalEntitiesRow, @@ -43,8 +49,21 @@ import { DbRelationsRow, DbSearchRow, } from '../database/tables'; + import { Stitcher } from '../stitching/Stitcher'; +import { + isQueryEntitiesCursorRequest, + isQueryEntitiesInitialRequest, +} from './util'; + +const defaultSortField: EntityOrder = { + field: 'metadata.uid', + order: 'asc', +}; + +const DEFAULT_LIMIT = 20; + function parsePagination(input?: EntityPagination): { limit?: number; offset?: number; @@ -168,10 +187,15 @@ function parseFilter( } export class DefaultEntitiesCatalog implements EntitiesCatalog { - constructor( - private readonly database: Knex, - private readonly stitcher: Stitcher, - ) {} + private readonly database: Knex; + private readonly logger: Logger; + private readonly stitcher: Stitcher; + + constructor(options: { database: Knex; logger: Logger; stitcher: Stitcher }) { + this.database = options.database; + this.logger = options.logger; + this.stitcher = options.stitcher; + } async entities(request?: EntitiesRequest): Promise { const db = this.database; @@ -283,7 +307,7 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { ): Promise { const lookup = new Map(); - for (const chunk of lodash.chunk(request.entityRefs, 200)) { + for (const chunk of lodashChunk(request.entityRefs, 200)) { let query = this.database('final_entities') .innerJoin('refresh_state', { 'refresh_state.entity_id': 'final_entities.entity_id', @@ -310,6 +334,161 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { return { items }; } + async queryEntities( + request: QueryEntitiesRequest, + ): Promise { + const db = this.database; + + const limit = request.limit ?? DEFAULT_LIMIT; + + const cursor: Omit & { + orderFieldValues?: (string | null)[]; + } = { + orderFields: [defaultSortField], + isPrevious: false, + ...parseCursorFromRequest(request), + }; + + const isFetchingBackwards = cursor.isPrevious; + + if (cursor.orderFields.length > 1) { + this.logger.warn(`Only one sort field is supported, ignoring the rest`); + } + + const sortField: EntityOrder = { + ...defaultSortField, + ...cursor.orderFields[0], + }; + + const [prevItemOrderFieldValue, prevItemUid] = + cursor.orderFieldValues || []; + + const dbQuery = db('search') + .join('final_entities', 'search.entity_id', 'final_entities.entity_id') + .where('search.key', sortField.field); + + if (cursor.filter) { + parseFilter(cursor.filter, dbQuery, db, false, 'search.entity_id'); + } + + const normalizedFullTextFilterTerm = cursor.fullTextFilter?.term?.trim(); + if (normalizedFullTextFilterTerm) { + dbQuery.andWhereRaw( + 'value like ?', + `%${normalizedFullTextFilterTerm.toLocaleLowerCase('en-US')}%`, + ); + } + + const countQuery = dbQuery.clone(); + + const isOrderingDescending = sortField.order === 'desc'; + + if (prevItemOrderFieldValue) { + dbQuery.andWhere( + 'value', + isFetchingBackwards !== isOrderingDescending ? '<' : '>', + prevItemOrderFieldValue, + ); + dbQuery.orWhere(function nested() { + this.where('value', '=', prevItemOrderFieldValue).andWhere( + 'search.entity_id', + isFetchingBackwards !== isOrderingDescending ? '<' : '>', + prevItemUid, + ); + }); + } + + dbQuery + .orderBy([ + { + column: 'value', + order: isFetchingBackwards + ? invertOrder(sortField.order) + : sortField.order, + }, + { + column: 'search.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' }); + + const [rows, [{ count }]] = await Promise.all([ + dbQuery, + // for performance reasons we invoke the countQuery + // only on the first request. + // The result is then embedded into the cursor + // for subsequent requests. + typeof cursor.totalItems === 'undefined' + ? countQuery + : [{ count: cursor.totalItems }], + ]); + + const totalItems = Number(count); + + if (isFetchingBackwards) { + rows.reverse(); + } + const hasMoreResults = + limit > 0 && (isFetchingBackwards || rows.length > limit); + + // discard the extra item only when fetching forward. + if (rows.length > limit) { + rows.length -= 1; + } + + const isInitialRequest = cursor.firstSortFieldValues === undefined; + + const firstRow = rows[0]; + const lastRow = rows[rows.length - 1]; + + const firstSortFieldValues = cursor.firstSortFieldValues || [ + firstRow?.value, + firstRow?.entity_id, + ]; + + const nextCursor: Cursor | undefined = hasMoreResults + ? { + ...cursor, + orderFieldValues: sortFieldsFromRow(lastRow), + firstSortFieldValues, + isPrevious: false, + totalItems, + } + : undefined; + + const prevCursor: Cursor | undefined = + !isInitialRequest && + rows.length > 0 && + !isEqual(sortFieldsFromRow(firstRow), cursor.firstSortFieldValues) + ? { + ...cursor, + orderFieldValues: sortFieldsFromRow(firstRow), + firstSortFieldValues: cursor.firstSortFieldValues, + isPrevious: true, + totalItems, + } + : undefined; + + const items = rows + .map(e => JSON.parse(e.final_entity!)) + .map(e => (request.fields ? request.fields(e) : e)); + + return { + items, + pageInfo: { + ...(!!prevCursor && { prevCursor }), + ...(!!nextCursor && { nextCursor }), + }, + totalItems, + }; + } + async removeEntityByUid(uid: string): Promise { const dbConfig = this.database.client.config; @@ -490,3 +669,51 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog { return { facets }; } } + +const entityFilterParser: z.ZodSchema = z.lazy(() => + z + .object({ + key: z.string(), + values: z.array(z.string()).optional(), + }) + .or(z.object({ not: entityFilterParser })) + .or(z.object({ anyOf: z.array(entityFilterParser) })) + .or(z.object({ allOf: z.array(entityFilterParser) })), +); + +export const cursorParser: z.ZodSchema = z.object({ + orderFields: z.array( + z.object({ field: z.string(), order: z.enum(['asc', 'desc']) }), + ), + orderFieldValues: z.array(z.string().or(z.null())), + filter: entityFilterParser.optional(), + isPrevious: z.boolean(), + query: z.string().optional(), + firstSortFieldValues: z.array(z.string().or(z.null())).optional(), + totalItems: z.number().optional(), +}); + +function parseCursorFromRequest( + request?: QueryEntitiesRequest, +): Partial { + if (isQueryEntitiesInitialRequest(request)) { + const { + filter, + orderFields: sortFields = [defaultSortField], + fullTextFilter, + } = request; + return { filter, orderFields: sortFields, fullTextFilter }; + } + if (isQueryEntitiesCursorRequest(request)) { + return request.cursor; + } + return {}; +} + +function invertOrder(order: EntityOrder['order']) { + return order === 'asc' ? 'desc' : 'asc'; +} + +function sortFieldsFromRow(row: DbSearchRow) { + return [row.value, row.entity_id]; +} diff --git a/plugins/catalog-backend/src/service/createRouter.test.ts b/plugins/catalog-backend/src/service/createRouter.test.ts index 6379d65043..df934eae68 100644 --- a/plugins/catalog-backend/src/service/createRouter.test.ts +++ b/plugins/catalog-backend/src/service/createRouter.test.ts @@ -25,7 +25,7 @@ import { } from '@backstage/catalog-model'; import express from 'express'; import request from 'supertest'; -import { EntitiesCatalog } from '../catalog/types'; +import { Cursor, EntitiesCatalog } from '../catalog/types'; import { LocationInput, LocationService, RefreshService } from './types'; import { basicEntityFilter } from './request'; import { createRouter } from './createRouter'; @@ -34,9 +34,10 @@ import { createPermissionIntegrationRouter, createPermissionRule, } from '@backstage/plugin-permission-node'; -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; import { CatalogProcessingOrchestrator } from '../processing/types'; import { z } from 'zod'; +import { encodeCursor } from './util'; describe('createRouter readonly disabled', () => { let entitiesCatalog: jest.Mocked; @@ -52,6 +53,7 @@ describe('createRouter readonly disabled', () => { removeEntityByUid: jest.fn(), entityAncestry: jest.fn(), facets: jest.fn(), + queryEntities: jest.fn(), }; locationService = { getLocation: jest.fn(), @@ -135,6 +137,118 @@ describe('createRouter readonly disabled', () => { }); }); + describe('GET /entities/by-query', () => { + it('happy path: lists entities', async () => { + const items: Entity[] = [ + { apiVersion: 'a', kind: 'b', metadata: { name: 'n' } }, + ]; + + entitiesCatalog.queryEntities.mockResolvedValueOnce({ + items, + totalItems: 100, + pageInfo: { nextCursor: mockCursor() }, + }); + + const response = await request(app).get('/entities/by-query'); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ + items, + totalItems: 100, + pageInfo: { + nextCursor: expect.any(String), + }, + }); + }); + + it('parses initial request', async () => { + entitiesCatalog.queryEntities.mockResolvedValueOnce({ + items: [], + pageInfo: {}, + totalItems: 0, + }); + const response = await request(app).get( + '/entities/by-query?filter=a=1,a=2,b=3&filter=c=4&orderField=metadata.name,asc&orderField=metadata.uid,desc', + ); + + expect(response.status).toEqual(200); + expect(entitiesCatalog.queryEntities).toHaveBeenCalledTimes(1); + expect(entitiesCatalog.queryEntities).toHaveBeenCalledWith({ + filter: { + anyOf: [ + { + allOf: [ + { key: 'a', values: ['1', '2'] }, + { key: 'b', values: ['3'] }, + ], + }, + { allOf: [{ key: 'c', values: ['4'] }] }, + ], + }, + orderFields: [ + { field: 'metadata.name', order: 'asc' }, + { field: 'metadata.uid', order: 'desc' }, + ], + fullTextFilter: { + fields: undefined, + term: '', + }, + }); + }); + + it('parses cursor request', async () => { + const items: Entity[] = [ + { apiVersion: 'a', kind: 'b', metadata: { name: 'n' } }, + ]; + + entitiesCatalog.queryEntities.mockResolvedValueOnce({ + items, + totalItems: 100, + pageInfo: { nextCursor: mockCursor() }, + }); + + const cursor = mockCursor({ totalItems: 100, isPrevious: false }); + + const response = await request(app).get( + `/entities/by-query?cursor=${encodeCursor(cursor)}`, + ); + expect(entitiesCatalog.queryEntities).toHaveBeenCalledTimes(1); + expect(entitiesCatalog.queryEntities).toHaveBeenCalledWith({ + cursor, + }); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ + items, + totalItems: 100, + pageInfo: { nextCursor: expect.any(String) }, + }); + }); + + it('should throw in case of malformed cursor', async () => { + const items: Entity[] = [ + { apiVersion: 'a', kind: 'b', metadata: { name: 'n' } }, + ]; + + entitiesCatalog.queryEntities.mockResolvedValueOnce({ + items, + totalItems: 100, + pageInfo: { nextCursor: mockCursor() }, + }); + + let response = await request(app).get( + `/entities/by-query?cursor=${Buffer.from( + JSON.stringify({ bad: 'cursor' }), + 'utf8', + ).toString('base64')}`, + ); + expect(response.status).toEqual(400); + expect(response.body.error.message).toMatch(/Malformed cursor/); + + response = await request(app).get(`/entities/by-query?cursor=badcursor`); + expect(response.status).toEqual(400); + expect(response.body.error.message).toMatch(/Malformed cursor/); + }); + }); + describe('GET /entities/by-uid/:uid', () => { it('can fetch entity by uid', async () => { const entity: Entity = { @@ -560,6 +674,7 @@ describe('createRouter readonly enabled', () => { removeEntityByUid: jest.fn(), entityAncestry: jest.fn(), facets: jest.fn(), + queryEntities: jest.fn(), }; locationService = { getLocation: jest.fn(), @@ -750,6 +865,7 @@ describe('NextRouter permissioning', () => { removeEntityByUid: jest.fn(), entityAncestry: jest.fn(), facets: jest.fn(), + queryEntities: jest.fn(), }; locationService = { getLocation: jest.fn(), @@ -820,3 +936,12 @@ describe('NextRouter permissioning', () => { }); }); }); + +function mockCursor(partialCursor?: Partial): Cursor { + return { + orderFields: [], + orderFieldValues: [], + isPrevious: false, + ...partialCursor, + }; +} diff --git a/plugins/catalog-backend/src/service/createRouter.ts b/plugins/catalog-backend/src/service/createRouter.ts index 62a0f970c9..849096c601 100644 --- a/plugins/catalog-backend/src/service/createRouter.ts +++ b/plugins/catalog-backend/src/service/createRouter.ts @@ -39,12 +39,14 @@ import { parseEntityFilterParams, parseEntityPaginationParams, parseEntityTransformParams, + parseQueryEntitiesParams, } from './request'; import { parseEntityFacetParams } from './request/parseEntityFacetParams'; import { parseEntityOrderParams } from './request/parseEntityOrderParams'; import { LocationService, RefreshOptions, RefreshService } from './types'; import { disallowReadonlyMode, + encodeCursor, locationInput, validateRequestBody, } from './util'; @@ -130,6 +132,26 @@ export async function createRouter( // TODO(freben): encode the pageInfo in the response res.json(entities); }) + .get('/entities/by-query', async (req, res) => { + const { items, pageInfo, totalItems } = + await entitiesCatalog.queryEntities({ + ...parseQueryEntitiesParams(req.query), + authorizationToken: getBearerToken(req.header('authorization')), + }); + + res.json({ + items, + totalItems, + pageInfo: { + ...(pageInfo.nextCursor && { + nextCursor: encodeCursor(pageInfo.nextCursor), + }), + ...(pageInfo.prevCursor && { + prevCursor: encodeCursor(pageInfo.prevCursor), + }), + }, + }); + }) .get('/entities/by-uid/:uid', async (req, res) => { const { uid } = req.params; const { entities } = await entitiesCatalog.entities({ diff --git a/plugins/catalog-backend/src/service/index.ts b/plugins/catalog-backend/src/service/index.ts index 7e0c6025c3..44645d39fe 100644 --- a/plugins/catalog-backend/src/service/index.ts +++ b/plugins/catalog-backend/src/service/index.ts @@ -14,6 +14,8 @@ * limitations under the License. */ -export type { CatalogEnvironment } from './CatalogBuilder'; +export type { + CatalogEnvironment, + CatalogPermissionRuleInput, +} from './CatalogBuilder'; export { CatalogBuilder } from './CatalogBuilder'; -export { catalogPlugin } from './CatalogPlugin'; diff --git a/plugins/catalog-backend/src/service/request/index.ts b/plugins/catalog-backend/src/service/request/index.ts index 0b09355e72..d9297fc122 100644 --- a/plugins/catalog-backend/src/service/request/index.ts +++ b/plugins/catalog-backend/src/service/request/index.ts @@ -19,3 +19,4 @@ export { basicEntityFilter } from './basicEntityFilter'; export { parseEntityFilterParams } from './parseEntityFilterParams'; export { parseEntityPaginationParams } from './parseEntityPaginationParams'; export { parseEntityTransformParams } from './parseEntityTransformParams'; +export { parseQueryEntitiesParams } from './parseQueryEntitiesParams'; diff --git a/plugins/catalog-backend/src/service/request/parseEntityOrderFieldParams.test.ts b/plugins/catalog-backend/src/service/request/parseEntityOrderFieldParams.test.ts new file mode 100644 index 0000000000..b732163394 --- /dev/null +++ b/plugins/catalog-backend/src/service/request/parseEntityOrderFieldParams.test.ts @@ -0,0 +1,57 @@ +/* + * 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 { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams'; + +describe('parseEntityOrderFieldParams', () => { + it('supports no order fields', () => { + const result = parseEntityOrderFieldParams({}); + expect(result).toEqual(undefined); + }); + + it('supports single orderField', () => { + const result = parseEntityOrderFieldParams({ + orderField: ['metadata.name,desc'], + })!; + expect(result).toEqual([{ field: 'metadata.name', order: 'desc' }]); + }); + + it('supports single orderField without order', () => { + const result = parseEntityOrderFieldParams({ + orderField: ['metadata.name'], + })!; + expect(result).toEqual([{ field: 'metadata.name' }]); + }); + + it('supports multiple order fields', () => { + const result = parseEntityOrderFieldParams({ + orderField: ['metadata.name,desc', 'metadata.uid,asc'], + }); + + expect(result).toEqual([ + { field: 'metadata.name', order: 'desc' }, + { field: 'metadata.uid', order: 'asc' }, + ]); + }); + + it('throws if orderField order is not valid', () => { + expect(() => + parseEntityOrderFieldParams({ + orderField: ['metadata.name,desc', 'metadata.uid,invalid'], + }), + ).toThrow(/Invalid order field order/); + }); +}); diff --git a/plugins/catalog-backend/src/service/request/parseEntityOrderFieldParams.ts b/plugins/catalog-backend/src/service/request/parseEntityOrderFieldParams.ts new file mode 100644 index 0000000000..5ab8cbfcf9 --- /dev/null +++ b/plugins/catalog-backend/src/service/request/parseEntityOrderFieldParams.ts @@ -0,0 +1,41 @@ +/* + * 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 { InputError } from '@backstage/errors'; +import { EntityOrder } from '../../catalog/types'; +import { parseStringsParam } from './common'; + +export function parseEntityOrderFieldParams( + params: Record, +): EntityOrder[] | undefined { + const orderFieldStrings = parseStringsParam(params.orderField, 'orderField'); + if (!orderFieldStrings) { + return undefined; + } + + return orderFieldStrings.map(orderFieldString => { + const [field, order] = orderFieldString.split(','); + + if (order !== undefined && !isOrder(order)) { + throw new InputError('Invalid order field order, must be asc or desc'); + } + return { field, order }; + }); +} + +export function isOrder(order: string): order is 'asc' | 'desc' { + return ['asc', 'desc'].includes(order); +} diff --git a/plugins/catalog-backend/src/service/request/parseFullTextFilterFields.ts b/plugins/catalog-backend/src/service/request/parseFullTextFilterFields.ts new file mode 100644 index 0000000000..02ba5864fc --- /dev/null +++ b/plugins/catalog-backend/src/service/request/parseFullTextFilterFields.ts @@ -0,0 +1,28 @@ +import { parseStringParam } from './common'; + +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export function parseFullTextFilterFields(params: Record) { + const fullTextFilterFields = parseStringParam( + params.fullTextFilterFields, + 'fullTextFilterFields', + ); + if (!fullTextFilterFields) { + return undefined; + } + + return fullTextFilterFields.split(','); +} diff --git a/plugins/catalog-backend/src/service/request/parseQueryEntitiesParams.test.ts b/plugins/catalog-backend/src/service/request/parseQueryEntitiesParams.test.ts new file mode 100644 index 0000000000..43ba218eac --- /dev/null +++ b/plugins/catalog-backend/src/service/request/parseQueryEntitiesParams.test.ts @@ -0,0 +1,147 @@ +/* + * 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 { + Cursor, + QueryEntitiesCursorRequest, + QueryEntitiesInitialRequest, +} from '../../catalog/types'; +import { encodeCursor } from '../util'; +import { parseQueryEntitiesParams } from './parseQueryEntitiesParams'; + +describe('parseQueryEntitiesParams', () => { + describe('initial request', () => { + it('should parse all the defined params', () => { + const validRequest = { + authorizationToken: 'to_not_be_returned', + fields: ['kind'], + limit: '3', + filter: ['a=1', 'b=2'], + orderField: ['metadata.name,desc'], + fullTextFilterTerm: 'query', + fullTextFilterFields: 'metadata.name,metadata.namespace', + }; + const parsedObj = parseQueryEntitiesParams( + validRequest, + ) as QueryEntitiesInitialRequest; + expect(parsedObj.limit).toBe(3); + expect(parsedObj.fields).toBeDefined(); + expect(parsedObj.orderFields).toEqual([ + { field: 'metadata.name', order: 'desc' }, + ]); + expect(parsedObj.filter).toBeDefined(); + expect(parsedObj.fullTextFilter).toEqual({ + term: 'query', + fields: ['metadata.name', 'metadata.namespace'], + }); + expect(parsedObj).not.toHaveProperty('authorizationToken'); + expect(parsedObj).not.toHaveProperty('cursor'); + }); + it('should ignore optional params', () => { + const parsedObj = parseQueryEntitiesParams( + {}, + ) as QueryEntitiesInitialRequest; + expect(parsedObj.limit).toBeUndefined(); + expect(parsedObj.fields).toBeUndefined(); + expect(parsedObj.orderFields).toBeUndefined(); + expect(parsedObj.filter).toBeUndefined(); + expect(parsedObj.fullTextFilter).toEqual({ term: '', fields: undefined }); + expect(parsedObj).not.toHaveProperty('authorizationToken'); + expect(parsedObj).not.toHaveProperty('cursor'); + }); + + it.each([ + { + limit: 'asd', + }, + { filter: 3 }, + { orderField: ['metadata.uid,diagonal'] }, + { fields: [4] }, + { fullTextFilterTerm: [] }, + { fullTextFilterFields: 3 }, + ])('should throw if some parameter is not valid %p', params => { + expect(() => parseQueryEntitiesParams(params)).toThrow(); + }); + }); + + describe('cursor request', () => { + it('should parse all the defined params', () => { + const cursor: Cursor = { + totalItems: 100, + orderFields: [], + orderFieldValues: [], + isPrevious: false, + }; + const validRequest = { + authorizationToken: 'to_not_be_returned', + fields: ['kind'], + limit: '3', + cursor: encodeCursor(cursor), + }; + const parsedObj = parseQueryEntitiesParams( + validRequest, + ) as QueryEntitiesCursorRequest; + expect(parsedObj.limit).toBe(3); + expect(parsedObj.fields).toBeDefined(); + expect(parsedObj.cursor).toEqual(cursor); + }); + + it('should ignore unknown params', () => { + const cursor: Cursor = { + totalItems: 100, + orderFields: [], + orderFieldValues: [], + isPrevious: false, + }; + const validRequest = { + authorizationToken: 'to_not_be_returned', + fields: ['kind'], + limit: '3', + cursor: encodeCursor(cursor), + filter: ['a=1', 'b=2'], + orderField: 'orderField,desc', + query: 'query', + }; + const parsedObj = parseQueryEntitiesParams( + validRequest, + ) as QueryEntitiesCursorRequest; + expect(parsedObj.limit).toBe(3); + expect(parsedObj.fields).toBeDefined(); + expect(parsedObj.cursor).toEqual(cursor); + expect(parsedObj).not.toHaveProperty('filter'); + expect(parsedObj).not.toHaveProperty('orderField'); + expect(parsedObj).not.toHaveProperty('query'); + }); + + it('should ignore optional params', () => { + const parsedObj = parseQueryEntitiesParams( + {}, + ) as QueryEntitiesCursorRequest; + expect(parsedObj.limit).toBeUndefined(); + expect(parsedObj.fields).toBeUndefined(); + }); + + it.each([ + { + limit: 'asd', + }, + { cursor: [] }, + { fields: [4] }, + ])('should throw if some parameter is not valid %p', params => { + expect(() => parseQueryEntitiesParams(params)).toThrow(); + }); + }); +}); diff --git a/plugins/catalog-backend/src/service/request/parseQueryEntitiesParams.ts b/plugins/catalog-backend/src/service/request/parseQueryEntitiesParams.ts new file mode 100644 index 0000000000..ae8b649d13 --- /dev/null +++ b/plugins/catalog-backend/src/service/request/parseQueryEntitiesParams.ts @@ -0,0 +1,66 @@ +/* + * 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 { + QueryEntitiesCursorRequest, + QueryEntitiesInitialRequest, + QueryEntitiesRequest, +} from '../../catalog/types'; +import { decodeCursor } from '../util'; +import { parseIntegerParam, parseStringParam } from './common'; +import { parseEntityFilterParams } from './parseEntityFilterParams'; +import { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams'; +import { parseEntityTransformParams } from './parseEntityTransformParams'; +import { parseFullTextFilterFields } from './parseFullTextFilterFields'; + +export function parseQueryEntitiesParams( + params: Record, +): Omit { + const fields = parseEntityTransformParams(params); + const limit = parseIntegerParam(params.limit, 'limit'); + const cursor = parseStringParam(params.cursor, 'cursor'); + if (cursor) { + const decodedCursor = decodeCursor(cursor); + const response: Omit = { + cursor: decodedCursor, + fields, + limit, + }; + return response; + } + + const filter = parseEntityFilterParams(params); + const fullTextFilterTerm = parseStringParam( + params.fullTextFilterTerm, + 'fullTextFilterTerm', + ); + const fullTextFilterFields = parseFullTextFilterFields(params); + + const orderFields = parseEntityOrderFieldParams(params); + + const response: Omit = { + fields, + filter, + limit, + orderFields, + fullTextFilter: { + term: fullTextFilterTerm || '', + fields: fullTextFilterFields, + }, + }; + + return response; +} diff --git a/plugins/catalog-backend/src/service/util.ts b/plugins/catalog-backend/src/service/util.ts index 9a914aadcb..699bca2fc9 100644 --- a/plugins/catalog-backend/src/service/util.ts +++ b/plugins/catalog-backend/src/service/util.ts @@ -18,6 +18,13 @@ import { InputError, NotAllowedError } from '@backstage/errors'; import { Request } from 'express'; import lodash from 'lodash'; import { z } from 'zod'; +import { + Cursor, + EntityFilter, + QueryEntitiesCursorRequest, + QueryEntitiesInitialRequest, + QueryEntitiesRequest, +} from '../catalog/types'; export async function requireRequestBody(req: Request): Promise { const contentType = req.header('content-type'); @@ -65,3 +72,63 @@ export function disallowReadonlyMode(readonly: boolean) { throw new NotAllowedError('This operation not allowed in readonly mode'); } } + +export function isQueryEntitiesInitialRequest( + input: QueryEntitiesRequest | undefined, +): input is QueryEntitiesInitialRequest { + if (!input) { + return false; + } + return !isQueryEntitiesCursorRequest(input); +} + +export function isQueryEntitiesCursorRequest( + input: QueryEntitiesRequest | undefined, +): input is QueryEntitiesCursorRequest { + if (!input) { + return false; + } + return !!(input as QueryEntitiesCursorRequest).cursor; +} + +const entityFilterParser: z.ZodSchema = z.lazy(() => + z + .object({ + key: z.string(), + values: z.array(z.string()).optional(), + }) + .or(z.object({ not: entityFilterParser })) + .or(z.object({ anyOf: z.array(entityFilterParser) })) + .or(z.object({ allOf: z.array(entityFilterParser) })), +); + +export const cursorParser: z.ZodSchema = z.object({ + orderFields: z.array( + z.object({ field: z.string(), order: z.enum(['asc', 'desc']) }), + ), + orderFieldValues: z.array(z.string().or(z.null())), + filter: entityFilterParser.optional(), + isPrevious: z.boolean(), + query: z.string().optional(), + firstSortFieldValues: z.array(z.string().or(z.null())).optional(), + totalItems: z.number().optional(), +}); + +export function encodeCursor(cursor: Cursor) { + const json = JSON.stringify(cursor); + return Buffer.from(json, 'utf8').toString('base64'); +} + +export function decodeCursor(encodedCursor: string) { + try { + const data = Buffer.from(encodedCursor, 'base64').toString('utf8'); + const result = cursorParser.safeParse(JSON.parse(data)); + + if (!result.success) { + throw new InputError(`Malformed cursor: ${result.error}`); + } + return result.data; + } catch (e) { + throw new InputError(`Malformed cursor: ${e}`); + } +} diff --git a/plugins/catalog-backend/src/stitching/Stitcher.ts b/plugins/catalog-backend/src/stitching/Stitcher.ts index 4742c81933..38d0fd263f 100644 --- a/plugins/catalog-backend/src/stitching/Stitcher.ts +++ b/plugins/catalog-backend/src/stitching/Stitcher.ts @@ -15,10 +15,11 @@ */ import { ENTITY_STATUS_CATALOG_PROCESSING_TYPE } from '@backstage/catalog-client'; +import { AlphaEntity, EntityStatusItem } from '@backstage/catalog-model/alpha'; import { - AlphaEntity, + ANNOTATION_EDIT_URL, + ANNOTATION_VIEW_URL, EntityRelation, - EntityStatusItem, } from '@backstage/catalog-model'; import { SerializedError, stringifyError } from '@backstage/errors'; import { Knex } from 'knex'; @@ -32,6 +33,11 @@ import { import { buildEntitySearch } from './buildEntitySearch'; import { BATCH_SIZE, generateStableHash } from './util'; +// See https://github.com/facebook/react/blob/f0cf832e1d0c8544c36aa8b310960885a11a847c/packages/react-dom-bindings/src/shared/sanitizeURL.js +const scriptProtocolPattern = + // eslint-disable-next-line no-control-regex + /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; + /** * Performs the act of stitching - to take all of the various outputs from the * ingestion process, and stitching them together into the final entity JSON @@ -166,6 +172,14 @@ export class Stitcher { })); } } + // We opt to do this check here as we otherwise can't guarantee that it will be run after all processors + for (const annotation of [ANNOTATION_VIEW_URL, ANNOTATION_EDIT_URL]) { + const value = entity.metadata.annotations?.[annotation]; + if (typeof value === 'string' && scriptProtocolPattern.test(value)) { + entity.metadata.annotations![annotation] = + 'https://backstage.io/annotation-rejected-for-security-reasons'; + } + } // TODO: entityRef is lower case and should be uppercase in the final // result diff --git a/plugins/catalog-common/CHANGELOG.md b/plugins/catalog-common/CHANGELOG.md index b5dc4e29e8..753af21e7e 100644 --- a/plugins/catalog-common/CHANGELOG.md +++ b/plugins/catalog-common/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-catalog-common +## 1.0.12-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + +## 1.0.11 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + ## 1.0.11-next.1 ### Patch Changes diff --git a/plugins/catalog-common/alpha-api-report.md b/plugins/catalog-common/alpha-api-report.md new file mode 100644 index 0000000000..12e0806a9c --- /dev/null +++ b/plugins/catalog-common/alpha-api-report.md @@ -0,0 +1,45 @@ +## API Report File for "@backstage/plugin-catalog-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BasicPermission } from '@backstage/plugin-permission-common'; +import { ResourcePermission } from '@backstage/plugin-permission-common'; + +// @alpha +export const catalogEntityCreatePermission: BasicPermission; + +// @alpha +export const catalogEntityDeletePermission: ResourcePermission<'catalog-entity'>; + +// @alpha +export type CatalogEntityPermission = ResourcePermission< + typeof RESOURCE_TYPE_CATALOG_ENTITY +>; + +// @alpha +export const catalogEntityReadPermission: ResourcePermission<'catalog-entity'>; + +// @alpha +export const catalogEntityRefreshPermission: ResourcePermission<'catalog-entity'>; + +// @alpha +export const catalogLocationCreatePermission: BasicPermission; + +// @alpha +export const catalogLocationDeletePermission: BasicPermission; + +// @alpha +export const catalogLocationReadPermission: BasicPermission; + +// @alpha +export const catalogPermissions: ( + | BasicPermission + | ResourcePermission<'catalog-entity'> +)[]; + +// @alpha +export const RESOURCE_TYPE_CATALOG_ENTITY = 'catalog-entity'; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-common/api-report.md b/plugins/catalog-common/api-report.md index 1bef626c79..231c8aac34 100644 --- a/plugins/catalog-common/api-report.md +++ b/plugins/catalog-common/api-report.md @@ -3,10 +3,8 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BasicPermission } from '@backstage/plugin-permission-common'; import { Entity } from '@backstage/catalog-model'; import { IndexableDocument } from '@backstage/plugin-search-common'; -import { ResourcePermission } from '@backstage/plugin-permission-common'; // @public (undocumented) export type AnalyzeLocationEntityField = { @@ -44,12 +42,6 @@ export type AnalyzeLocationResponse = { generateEntities: AnalyzeLocationGenerateEntity[]; }; -// @alpha -export const catalogEntityCreatePermission: BasicPermission; - -// @alpha -export const catalogEntityDeletePermission: ResourcePermission<'catalog-entity'>; - // @public export interface CatalogEntityDocument extends IndexableDocument { // @deprecated (undocumented) @@ -66,39 +58,10 @@ export interface CatalogEntityDocument extends IndexableDocument { type: string; } -// @alpha -export type CatalogEntityPermission = ResourcePermission< - typeof RESOURCE_TYPE_CATALOG_ENTITY ->; - -// @alpha -export const catalogEntityReadPermission: ResourcePermission<'catalog-entity'>; - -// @alpha -export const catalogEntityRefreshPermission: ResourcePermission<'catalog-entity'>; - -// @alpha -export const catalogLocationCreatePermission: BasicPermission; - -// @alpha -export const catalogLocationDeletePermission: BasicPermission; - -// @alpha -export const catalogLocationReadPermission: BasicPermission; - -// @alpha -export const catalogPermissions: ( - | BasicPermission - | ResourcePermission<'catalog-entity'> -)[]; - // @public export type LocationSpec = { type: string; target: string; presence?: 'optional' | 'required'; }; - -// @alpha -export const RESOURCE_TYPE_CATALOG_ENTITY = 'catalog-entity'; ``` diff --git a/plugins/catalog-common/package.json b/plugins/catalog-common/package.json index 2ba16c3d2a..033ee10f3d 100644 --- a/plugins/catalog-common/package.json +++ b/plugins/catalog-common/package.json @@ -1,16 +1,27 @@ { "name": "@backstage/plugin-catalog-common", "description": "Common functionalities for the catalog plugin", - "version": "1.0.11-next.1", + "version": "1.0.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "module": "dist/index.esm.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "common-library" @@ -25,7 +36,7 @@ "backstage" ], "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -41,7 +52,6 @@ "@backstage/cli": "workspace:^" }, "files": [ - "dist", - "alpha" + "dist" ] } diff --git a/plugins/catalog-common/src/alpha.ts b/plugins/catalog-common/src/alpha.ts new file mode 100644 index 0000000000..2dfc028332 --- /dev/null +++ b/plugins/catalog-common/src/alpha.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { + RESOURCE_TYPE_CATALOG_ENTITY, + catalogEntityReadPermission, + catalogEntityCreatePermission, + catalogEntityDeletePermission, + catalogEntityRefreshPermission, + catalogLocationReadPermission, + catalogLocationCreatePermission, + catalogLocationDeletePermission, + catalogPermissions, +} from './permissions'; +export type { CatalogEntityPermission } from './permissions'; diff --git a/plugins/catalog-common/src/index.ts b/plugins/catalog-common/src/index.ts index 95bd65bc92..52860a0e66 100644 --- a/plugins/catalog-common/src/index.ts +++ b/plugins/catalog-common/src/index.ts @@ -21,19 +21,6 @@ * @packageDocumentation */ -export { - RESOURCE_TYPE_CATALOG_ENTITY, - catalogEntityReadPermission, - catalogEntityCreatePermission, - catalogEntityDeletePermission, - catalogEntityRefreshPermission, - catalogLocationReadPermission, - catalogLocationCreatePermission, - catalogLocationDeletePermission, - catalogPermissions, -} from './permissions'; -export type { CatalogEntityPermission } from './permissions'; - export * from './search'; export * from './ingestion'; export type { LocationSpec } from './common'; diff --git a/plugins/catalog-customized/CHANGELOG.md b/plugins/catalog-customized/CHANGELOG.md index f8ff5a85b8..dbcbd10520 100644 --- a/plugins/catalog-customized/CHANGELOG.md +++ b/plugins/catalog-customized/CHANGELOG.md @@ -1,5 +1,21 @@ # @internal/plugin-catalog-customized +## 0.0.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + +## 0.0.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.0.7-next.2 ### Patch Changes diff --git a/plugins/catalog-customized/package.json b/plugins/catalog-customized/package.json index 9f1e310508..3cacddf58a 100644 --- a/plugins/catalog-customized/package.json +++ b/plugins/catalog-customized/package.json @@ -1,7 +1,7 @@ { "name": "@internal/plugin-catalog-customized", "description": "The internal Backstage Customizable plugin for browsing the Backstage catalog", - "version": "0.0.7-next.2", + "version": "0.0.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index d45fa8f234..ec21c0aa66 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-catalog-graph +## 0.2.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.2.27 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- fe19058b74: Fix #16245: The CatalogGraphCard has parameter naming errors for CatalogGraphPage +- 1827710136: Expose additional props on the `CatalogGraphCard` to allow for custom node & label rendering or kind/relation filtering. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + ## 0.2.27-next.2 ### Patch Changes diff --git a/plugins/catalog-graph/README.md b/plugins/catalog-graph/README.md index 33dee92935..f723523716 100644 --- a/plugins/catalog-graph/README.md +++ b/plugins/catalog-graph/README.md @@ -24,9 +24,10 @@ The plugin comes with these features: To use the catalog graph plugin, you have to add some things to your Backstage app: -1. Add a dependency to your `packages/app/package.json`, run: +1. Add a dependency to your `packages/app/package.json`: ```sh - yarn add @backstage/plugin-catalog-graph + # From your Backstage root directory + yarn add --cwd packages/app @backstage/plugin-catalog-graph ``` 2. Add the `CatalogGraphPage` to your `packages/app/src/App.tsx`: diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index aee919241c..0e093a3ab1 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.2.27-next.2", + "version": "0.2.28-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog-graphql/CHANGELOG.md b/plugins/catalog-graphql/CHANGELOG.md index ee49cb0c3e..ede51b17fb 100644 --- a/plugins/catalog-graphql/CHANGELOG.md +++ b/plugins/catalog-graphql/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-catalog-graphql +## 0.3.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + +## 0.3.18 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + ## 0.3.18-next.1 ### Patch Changes diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json index e66e0e0db2..8fd4221a56 100644 --- a/plugins/catalog-graphql/package.json +++ b/plugins/catalog-graphql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-graphql", "description": "An experimental Backstage catalog GraphQL module", - "version": "0.3.18-next.1", + "version": "0.3.19-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -48,12 +48,12 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", - "@graphql-codegen/cli": "^2.3.1", - "@graphql-codegen/graphql-modules-preset": "^2.3.2", - "@graphql-codegen/typescript": "^2.4.2", - "@graphql-codegen/typescript-resolvers": "^2.4.3", + "@graphql-codegen/cli": "^3.0.0", + "@graphql-codegen/graphql-modules-preset": "^3.0.0", + "@graphql-codegen/typescript": "^3.0.0", + "@graphql-codegen/typescript-resolvers": "^3.0.0", "@graphql-tools/schema": "^9.0.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index 9c74c13c88..cf6e3068cc 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-catalog-import +## 0.9.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + +## 0.9.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-catalog-common@1.0.11 + ## 0.9.5-next.2 ### Patch Changes diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index a128aedfd8..57633f7b22 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-import", "description": "A Backstage plugin the helps you import entities into your catalog", - "version": "0.9.5-next.2", + "version": "0.9.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -68,7 +68,7 @@ "@testing-library/react-hooks": "^8.0.0", "@testing-library/user-event": "^14.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index 8d5667e4a6..6f4098a158 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-catalog-node +## 1.3.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + +## 1.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + ## 1.3.3-next.2 ### Patch Changes diff --git a/plugins/catalog-node/alpha-api-report.md b/plugins/catalog-node/alpha-api-report.md new file mode 100644 index 0000000000..ba1bcd47b2 --- /dev/null +++ b/plugins/catalog-node/alpha-api-report.md @@ -0,0 +1,31 @@ +## API Report File for "@backstage/plugin-catalog-node" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { CatalogApi } from '@backstage/catalog-client'; +import { CatalogProcessor } from '@backstage/plugin-catalog-node'; +import { EntityProvider } from '@backstage/plugin-catalog-node'; +import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { ServiceRef } from '@backstage/backend-plugin-api'; + +// @alpha (undocumented) +export interface CatalogProcessingExtensionPoint { + // (undocumented) + addEntityProvider( + ...providers: Array> + ): void; + // (undocumented) + addProcessor( + ...processors: Array> + ): void; +} + +// @alpha (undocumented) +export const catalogProcessingExtensionPoint: ExtensionPoint; + +// @alpha +export const catalogServiceRef: ServiceRef; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-node/api-report.md b/plugins/catalog-node/api-report.md index 9e9045db84..87da0b6944 100644 --- a/plugins/catalog-node/api-report.md +++ b/plugins/catalog-node/api-report.md @@ -5,28 +5,10 @@ ```ts /// -import { CatalogApi } from '@backstage/catalog-client'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; -import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { JsonValue } from '@backstage/types'; import { LocationSpec as LocationSpec_2 } from '@backstage/plugin-catalog-common'; -import { ServiceRef } from '@backstage/backend-plugin-api'; - -// @alpha (undocumented) -export interface CatalogProcessingExtensionPoint { - // (undocumented) - addEntityProvider( - ...providers: Array> - ): void; - // (undocumented) - addProcessor( - ...processors: Array> - ): void; -} - -// @alpha (undocumented) -export const catalogProcessingExtensionPoint: ExtensionPoint; // @public (undocumented) export type CatalogProcessor = { @@ -109,9 +91,6 @@ export type CatalogProcessorResult = | CatalogProcessorErrorResult | CatalogProcessorRefreshKeysResult; -// @alpha -export const catalogServiceRef: ServiceRef; - // @public export type DeferredEntity = { entity: Entity; diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 70071dcaea..4f122ec465 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,22 +1,34 @@ { "name": "@backstage/plugin-catalog-node", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", - "version": "1.3.3-next.2", + "version": "1.3.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "node-library" }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -37,7 +49,6 @@ "@backstage/cli": "workspace:^" }, "files": [ - "dist", - "alpha" + "dist" ] } diff --git a/plugins/catalog-node/src/alpha.ts b/plugins/catalog-node/src/alpha.ts new file mode 100644 index 0000000000..4fb07bbc25 --- /dev/null +++ b/plugins/catalog-node/src/alpha.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { catalogServiceRef } from './catalogService'; +export type { CatalogProcessingExtensionPoint } from './extensions'; +export { catalogProcessingExtensionPoint } from './extensions'; diff --git a/plugins/catalog-node/src/extensions.ts b/plugins/catalog-node/src/extensions.ts index 8dd9d8579a..0466af36b0 100644 --- a/plugins/catalog-node/src/extensions.ts +++ b/plugins/catalog-node/src/extensions.ts @@ -14,8 +14,10 @@ * limitations under the License. */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; -import { EntityProvider } from './api'; -import { CatalogProcessor } from './api/processor'; +import { + EntityProvider, + CatalogProcessor, +} from '@backstage/plugin-catalog-node'; /** * @alpha diff --git a/plugins/catalog-node/src/index.ts b/plugins/catalog-node/src/index.ts index 6393c55f31..6a1accfcbd 100644 --- a/plugins/catalog-node/src/index.ts +++ b/plugins/catalog-node/src/index.ts @@ -20,8 +20,5 @@ * @packageDocumentation */ -export type { CatalogProcessingExtensionPoint } from './extensions'; -export { catalogProcessingExtensionPoint } from './extensions'; -export { catalogServiceRef } from './catalogService'; export * from './api'; export * from './processing'; diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 662b57550a..db92d850ed 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,51 @@ # @backstage/plugin-catalog-react +## 1.4.0-next.0 + +### Minor Changes + +- 0a5b73b292: Add possibility to re-use EntityPicker for filters with multiple select. + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.11-next.0 + +## 1.3.0 + +### Minor Changes + +- 929e1afe1b: Add `initialFilter` prop to EntityLifecyclePicker. This allows you to set an initial lifecycle for the catalog. +- fab93c2fe8: Aligned buttons on "Unregister entity" dialog to keep them on the same line + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.10 + ## 1.3.0-next.2 ### Patch Changes diff --git a/plugins/catalog-react/alpha-api-report.md b/plugins/catalog-react/alpha-api-report.md new file mode 100644 index 0000000000..f9b740c07c --- /dev/null +++ b/plugins/catalog-react/alpha-api-report.md @@ -0,0 +1,22 @@ +## API Report File for "@backstage/plugin-catalog-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Entity } from '@backstage/catalog-model'; +import { ResourcePermission } from '@backstage/plugin-permission-common'; + +// @alpha +export function isOwnerOf(owner: Entity, entity: Entity): boolean; + +// @alpha +export function useEntityPermission( + permission: ResourcePermission<'catalog-entity'>, +): { + loading: boolean; + allowed: boolean; + error?: Error; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 095b6832a4..55c72122f5 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -20,7 +20,6 @@ import { Overrides } from '@material-ui/core/styles/overrides'; import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReactNode } from 'react'; -import { ResourcePermission } from '@backstage/plugin-permission-common'; import { RouteRef } from '@backstage/core-plugin-api'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { StyleRules } from '@material-ui/core/styles/withStyles'; @@ -393,9 +392,7 @@ export class EntityTagFilter implements EntityFilter { } // @public (undocumented) -export const EntityTagPicker: ( - props: EntityTagPickerProps, -) => JSX.Element | null; +export const EntityTagPicker: (props: EntityTagPickerProps) => JSX.Element; // @public (undocumented) export type EntityTagPickerProps = { @@ -476,16 +473,15 @@ export function InspectEntityDialog(props: { onClose: () => void; }): JSX.Element | null; -// @alpha -export function isOwnerOf(owner: Entity, entity: Entity): boolean; - // @public (undocumented) -export const MockEntityListContextProvider: ({ +export function MockEntityListContextProvider< + T extends DefaultEntityFilters = DefaultEntityFilters, +>({ children, value, -}: React_2.PropsWithChildren<{ - value?: Partial> | undefined; -}>) => JSX.Element; +}: PropsWithChildren<{ + value?: Partial>; +}>): JSX.Element; // @public export class MockStarredEntitiesApi implements StarredEntitiesApi { @@ -538,15 +534,6 @@ export function useEntityOwnership(): { isOwnedEntity: (entity: Entity) => boolean; }; -// @alpha -export function useEntityPermission( - permission: ResourcePermission<'catalog-entity'>, -): { - loading: boolean; - allowed: boolean; - error?: Error; -}; - // @public export function useEntityTypeFilter(): { loading: boolean; diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index c3e6cdda46..7a707240ca 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-catalog-react", "description": "A frontend library that helps other Backstage plugins interact with the catalog", - "version": "1.3.0-next.2", + "version": "1.4.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", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "web-library" @@ -24,7 +36,7 @@ "backstage" ], "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -78,7 +90,6 @@ "react-test-renderer": "^16.13.1" }, "files": [ - "dist", - "alpha" + "dist" ] } diff --git a/plugins/catalog-react/src/alpha.ts b/plugins/catalog-react/src/alpha.ts new file mode 100644 index 0000000000..e8ff21609e --- /dev/null +++ b/plugins/catalog-react/src/alpha.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { isOwnerOf } from './utils'; +export { useEntityPermission } from './hooks/useEntityPermission'; diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx new file mode 100644 index 0000000000..38edb9b064 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.test.tsx @@ -0,0 +1,272 @@ +/* + * 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 { fireEvent, render, waitFor, screen } from '@testing-library/react'; +import React from 'react'; +import { MockEntityListContextProvider } from '../../testUtils/providers'; +import { EntityAutocompletePicker } from './EntityAutocompletePicker'; +import { TestApiProvider } from '@backstage/test-utils'; +import { catalogApiRef } from '../../api'; +import { CatalogApi } from '@backstage/catalog-client'; +import { DefaultEntityFilters } from '../../hooks'; +import { Entity } from '@backstage/catalog-model'; +import { EntityFilter } from '../../types'; + +interface EntityFilters extends DefaultEntityFilters { + options?: EntityOptionFilter; +} + +const options = ['option1', 'option2', 'option3', 'option4']; + +class EntityOptionFilter implements EntityFilter { + constructor(readonly values: string[]) {} + + filterEntity(entity: Entity): boolean { + return this.values.every(v => + ((entity.spec?.options ?? []) as string[]).includes(v), + ); + } + + toQueryValue(): string[] { + return this.values; + } +} + +describe('', () => { + const mockCatalogApi = { + getEntityFacets: async () => ({ + facets: { + 'spec.options': options.map((value, idx) => ({ value, count: idx })), + }, + }), + } as unknown as CatalogApi; + + it('renders all options', async () => { + render( + + + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + /> + + , + ); + await waitFor(() => + expect(screen.getByText('Options')).toBeInTheDocument(), + ); + + fireEvent.click(screen.getByTestId('options-picker-expand')); + options.forEach(option => { + expect(screen.getByText(option)).toBeInTheDocument(); + }); + }); + + it('renders unique options in alphabetical order', async () => { + render( + + + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + /> + + , + ); + await waitFor(() => + expect(screen.getByText('Options')).toBeInTheDocument(), + ); + + fireEvent.click(screen.getByTestId('options-picker-expand')); + + expect(screen.getAllByRole('option').map(o => o.textContent)).toEqual([ + 'option1', + 'option2', + 'option3', + 'option4', + ]); + }); + + it('renders options with counts', async () => { + render( + + + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + showCounts + /> + + , + ); + await waitFor(() => + expect(screen.getByText('Options')).toBeInTheDocument(), + ); + + fireEvent.click(screen.getByTestId('options-picker-expand')); + + expect(screen.getAllByRole('option').map(o => o.textContent)).toEqual([ + 'option1 (0)', + 'option2 (1)', + 'option3 (2)', + 'option4 (3)', + ]); + }); + + it('respects the query parameter filter value', async () => { + const updateFilters = jest.fn(); + const queryParameters = { options: ['option3'] }; + render( + + + value={{ + updateFilters, + queryParameters, + }} + > + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + /> + + , + ); + + await waitFor(() => + expect(updateFilters).toHaveBeenLastCalledWith({ + options: new EntityOptionFilter(['option3']), + }), + ); + }); + + it('adds options to filters', async () => { + const updateFilters = jest.fn(); + render( + + + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + /> + + , + ); + await waitFor(() => + expect(updateFilters).toHaveBeenLastCalledWith({ + options: undefined, + }), + ); + + fireEvent.click(screen.getByTestId('options-picker-expand')); + fireEvent.click(screen.getByText('option1')); + expect(updateFilters).toHaveBeenLastCalledWith({ + options: new EntityOptionFilter(['option1']), + }); + }); + + it('removes options from filters', async () => { + const updateFilters = jest.fn(); + render( + + + value={{ + updateFilters, + filters: { options: new EntityOptionFilter(['option1']) }, + }} + > + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + /> + + , + ); + await waitFor(() => + expect(updateFilters).toHaveBeenLastCalledWith({ + options: new EntityOptionFilter(['option1']), + }), + ); + fireEvent.click(screen.getByTestId('options-picker-expand')); + expect(screen.getByLabelText('option1')).toBeChecked(); + + fireEvent.click(screen.getByLabelText('option1')); + expect(updateFilters).toHaveBeenLastCalledWith({ + options: undefined, + }); + }); + + it('responds to external queryParameters changes', async () => { + const updateFilters = jest.fn(); + const rendered = render( + + + value={{ + updateFilters, + queryParameters: { options: ['option1'] }, + }} + > + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + /> + + , + ); + await waitFor(() => + expect(updateFilters).toHaveBeenLastCalledWith({ + options: new EntityOptionFilter(['option1']), + }), + ); + rendered.rerender( + + + value={{ + updateFilters, + queryParameters: { options: ['option2'] }, + }} + > + + label="Options" + path="spec.options" + name="options" + Filter={EntityOptionFilter} + /> + + , + ); + expect(updateFilters).toHaveBeenLastCalledWith({ + options: new EntityOptionFilter(['option2']), + }); + }); +}); diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx new file mode 100644 index 0000000000..09d5a45246 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx @@ -0,0 +1,154 @@ +/* + * 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 { Box, TextFieldProps, Typography } from '@material-ui/core'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import { Autocomplete } from '@material-ui/lab'; +import React, { useEffect, useMemo, useState } from 'react'; +import { useApi } from '@backstage/core-plugin-api'; +import useAsync from 'react-use/lib/useAsync'; +import { catalogApiRef } from '../../api'; +import { EntityAutocompletePickerOption } from './EntityAutocompletePickerOption'; +import { EntityAutocompletePickerInput } from './EntityAutocompletePickerInput'; +import { + DefaultEntityFilters, + useEntityList, +} from '../../hooks/useEntityListProvider'; +import { EntityFilter } from '../../types'; +import _ from 'lodash'; + +type KeysMatchingCondition = T extends V ? K : never; +type KeysMatching = { + [K in keyof T]-?: KeysMatchingCondition; +}[keyof T]; + +type AllowedEntityFilters = KeysMatching< + T, + EntityFilter & { values: string[] } +>; + +interface ConstructableFilter { + new (values: string[]): T; +} + +/** @public */ +export type EntityAutocompletePickerProps< + T extends DefaultEntityFilters = DefaultEntityFilters, + Name extends AllowedEntityFilters = AllowedEntityFilters, +> = { + label: string; + name: Name; + path: string; + showCounts?: boolean; + Filter: ConstructableFilter>; + InputProps?: TextFieldProps; +}; + +/** @public */ +export function EntityAutocompletePicker< + T extends DefaultEntityFilters = DefaultEntityFilters, + Name extends AllowedEntityFilters = AllowedEntityFilters, +>(props: EntityAutocompletePickerProps) { + const { label, name, path, showCounts, Filter, InputProps } = props; + + const { + updateFilters, + filters, + queryParameters: { [name]: queryParameter }, + } = useEntityList(); + + const catalogApi = useApi(catalogApiRef); + const { value: availableValues } = useAsync(async () => { + const facet = path; + const { facets } = await catalogApi.getEntityFacets({ + facets: [facet], + filter: filters.kind?.getCatalogFilters(), + }); + + return Object.fromEntries( + facets[facet].map(({ value, count }) => [value, count]), + ); + }, [filters.kind]); + + const queryParameters = useMemo( + () => [queryParameter].flat().filter(Boolean) as string[], + [queryParameter], + ); + + const [selectedOptions, setSelectedOptions] = useState( + queryParameters.length + ? queryParameters + : (filters[name] as unknown as { values: string[] })?.values ?? [], + ); + + // Set selected options on query parameter updates; this happens at initial page load and from + // external updates to the page location + useEffect(() => { + if ( + queryParameters.length && + !_.isEqual(selectedOptions, queryParameters) + ) { + setSelectedOptions(queryParameters); + } + }, [selectedOptions, queryParameters]); + + const availableOptions = Object.keys(availableValues ?? {}); + const shouldAddFilter = selectedOptions.length && availableOptions.length; + + useEffect(() => { + updateFilters({ + [name]: shouldAddFilter ? new Filter(selectedOptions) : undefined, + } as Partial); + }, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]); + + if ( + (filters[name] && !('values' in filters[name])) || + !availableOptions.length + ) { + return null; + } + + return ( + + + {label} + + setSelectedOptions(options) + } + renderOption={(option, { selected }) => ( + + )} + size="small" + popupIcon={ + + } + renderInput={params => ( + + )} + /> + + + ); +} diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePickerInput.tsx b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePickerInput.tsx new file mode 100644 index 0000000000..4140feae01 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePickerInput.tsx @@ -0,0 +1,39 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { makeStyles, TextField, TextFieldProps } from '@material-ui/core'; +import React from 'react'; +import classnames from 'classnames'; + +const useStyles = makeStyles( + { + input: {}, + }, + { + name: 'CatalogReactEntityAutocompletePickerInput', + }, +); + +export function EntityAutocompletePickerInput(params: TextFieldProps) { + const classes = useStyles(); + + return ( + + ); +} diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePickerOption.tsx b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePickerOption.tsx new file mode 100644 index 0000000000..51b57257a9 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePickerOption.tsx @@ -0,0 +1,45 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Checkbox, FormControlLabel } from '@material-ui/core'; +import CheckBoxIcon from '@material-ui/icons/CheckBox'; +import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; +import React, { memo } from 'react'; + +interface Props { + selected: boolean; + value: string; + availableOptions?: Record; + showCounts: boolean; +} + +const icon = ; +const checkedIcon = ; + +function OptionCheckbox({ selected }: { selected: boolean }) { + return ; +} + +export const EntityAutocompletePickerOption = memo((props: Props) => { + const { selected, value, availableOptions, showCounts } = props; + const label = showCounts ? `${value} (${availableOptions?.[value]})` : value; + + return ( + } + label={label} + /> + ); +}); diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/index.ts b/plugins/catalog-react/src/components/EntityAutocompletePicker/index.ts new file mode 100644 index 0000000000..10ce0123b7 --- /dev/null +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { EntityAutocompletePicker } from './EntityAutocompletePicker'; +export type { EntityAutocompletePickerProps } from './EntityAutocompletePicker'; diff --git a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.test.tsx b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.test.tsx index de7bbb89be..c70217f3a4 100644 --- a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.test.tsx +++ b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.test.tsx @@ -44,7 +44,7 @@ describe('', () => { ); await waitFor(() => expect(screen.getByText('Tags')).toBeInTheDocument()); - fireEvent.click(screen.getByTestId('tag-picker-expand')); + fireEvent.click(screen.getByTestId('tags-picker-expand')); tags.forEach(tag => { expect(screen.getByText(tag)).toBeInTheDocument(); }); @@ -60,7 +60,7 @@ describe('', () => { ); await waitFor(() => expect(screen.getByText('Tags')).toBeInTheDocument()); - fireEvent.click(screen.getByTestId('tag-picker-expand')); + fireEvent.click(screen.getByTestId('tags-picker-expand')); expect(screen.getAllByRole('option').map(o => o.textContent)).toEqual([ 'tag1', @@ -80,7 +80,7 @@ describe('', () => { ); await waitFor(() => expect(screen.getByText('Tags')).toBeInTheDocument()); - fireEvent.click(screen.getByTestId('tag-picker-expand')); + fireEvent.click(screen.getByTestId('tags-picker-expand')); expect(screen.getAllByRole('option').map(o => o.textContent)).toEqual([ 'tag1 (0)', @@ -132,7 +132,7 @@ describe('', () => { }), ); - fireEvent.click(screen.getByTestId('tag-picker-expand')); + fireEvent.click(screen.getByTestId('tags-picker-expand')); fireEvent.click(screen.getByText('tag1')); expect(updateFilters).toHaveBeenLastCalledWith({ tags: new EntityTagFilter(['tag1']), @@ -158,7 +158,7 @@ describe('', () => { tags: new EntityTagFilter(['tag1']), }), ); - fireEvent.click(screen.getByTestId('tag-picker-expand')); + fireEvent.click(screen.getByTestId('tags-picker-expand')); expect(screen.getByLabelText('tag1')).toBeChecked(); fireEvent.click(screen.getByLabelText('tag1')); diff --git a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx index 4a1dc03e96..0521bb49f8 100644 --- a/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx +++ b/plugins/catalog-react/src/components/EntityTagPicker/EntityTagPicker.tsx @@ -14,132 +14,36 @@ * limitations under the License. */ -import { - Box, - Checkbox, - FormControlLabel, - makeStyles, - TextField, - Typography, -} from '@material-ui/core'; -import CheckBoxIcon from '@material-ui/icons/CheckBox'; -import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; -import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; -import { Autocomplete } from '@material-ui/lab'; -import React, { useEffect, useMemo, useState } from 'react'; -import { useEntityList } from '../../hooks/useEntityListProvider'; +import { makeStyles } from '@material-ui/core'; +import React from 'react'; import { EntityTagFilter } from '../../filters'; -import { useApi } from '@backstage/core-plugin-api'; -import useAsync from 'react-use/lib/useAsync'; -import { catalogApiRef } from '../../api'; +import { EntityAutocompletePicker } from '../EntityAutocompletePicker/EntityAutocompletePicker'; /** @public */ export type CatalogReactEntityTagPickerClassKey = 'input'; -const useStyles = makeStyles( - { - input: {}, - }, - { - name: 'CatalogReactEntityTagPicker', - }, -); - -const icon = ; -const checkedIcon = ; - /** @public */ export type EntityTagPickerProps = { showCounts?: boolean; }; +const useStyles = makeStyles( + { input: {} }, + { name: 'CatalogReactEntityTagPicker' }, +); + /** @public */ export const EntityTagPicker = (props: EntityTagPickerProps) => { const classes = useStyles(); - const { - updateFilters, - filters, - queryParameters: { tags: tagsParameter }, - } = useEntityList(); - - const catalogApi = useApi(catalogApiRef); - const { value: availableTags } = useAsync(async () => { - const facet = 'metadata.tags'; - const { facets } = await catalogApi.getEntityFacets({ - facets: [facet], - filter: filters.kind?.getCatalogFilters(), - }); - - return Object.fromEntries( - facets[facet].map(({ value, count }) => [value, count]), - ); - }, [filters.kind]); - - const queryParamTags = useMemo( - () => [tagsParameter].flat().filter(Boolean) as string[], - [tagsParameter], - ); - - const [selectedTags, setSelectedTags] = useState( - queryParamTags.length ? queryParamTags : filters.tags?.values ?? [], - ); - - // Set selected tags on query parameter updates; this happens at initial page load and from - // external updates to the page location. - useEffect(() => { - if (queryParamTags.length) { - setSelectedTags(queryParamTags); - } - }, [queryParamTags]); - - useEffect(() => { - const tags = Object.keys(availableTags ?? {}); - updateFilters({ - tags: - selectedTags.length && tags.length - ? new EntityTagFilter(selectedTags) - : undefined, - }); - }, [selectedTags, updateFilters, availableTags]); - - if (!Object.keys(availableTags ?? {}).length) return null; return ( - - - Tags - setSelectedTags(value)} - renderOption={(option, { selected }) => ( - - } - label={ - props.showCounts - ? `${option} (${availableTags?.[option]})` - : option - } - /> - )} - size="small" - popupIcon={} - renderInput={params => ( - - )} - /> - - + ); }; diff --git a/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx b/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx index f0adb878d6..09b944605f 100644 --- a/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx +++ b/plugins/catalog-react/src/components/InspectEntityDialog/components/OverviewPage.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { AlphaEntity } from '@backstage/catalog-model'; +import { AlphaEntity } from '@backstage/catalog-model/alpha'; import { Box, DialogContentText, diff --git a/plugins/catalog-react/src/filters.test.ts b/plugins/catalog-react/src/filters.test.ts index c2c92e033e..2a67190633 100644 --- a/plugins/catalog-react/src/filters.test.ts +++ b/plugins/catalog-react/src/filters.test.ts @@ -14,7 +14,8 @@ * limitations under the License. */ -import { AlphaEntity, Entity } from '@backstage/catalog-model'; +import { AlphaEntity } from '@backstage/catalog-model/alpha'; +import { Entity } from '@backstage/catalog-model'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; import { EntityErrorFilter, diff --git a/plugins/catalog-react/src/filters.ts b/plugins/catalog-react/src/filters.ts index 056b3b92c1..5bd81780d6 100644 --- a/plugins/catalog-react/src/filters.ts +++ b/plugins/catalog-react/src/filters.ts @@ -14,11 +14,8 @@ * limitations under the License. */ -import { - AlphaEntity, - Entity, - RELATION_OWNED_BY, -} from '@backstage/catalog-model'; +import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model'; +import { AlphaEntity } from '@backstage/catalog-model/alpha'; import { humanizeEntityRef } from './components/EntityRefLink'; import { EntityFilter, UserListFilterKind } from './types'; import { getEntityRelations } from './utils'; diff --git a/plugins/catalog-react/src/hooks/index.ts b/plugins/catalog-react/src/hooks/index.ts index 3570ed897c..ffd32206ef 100644 --- a/plugins/catalog-react/src/hooks/index.ts +++ b/plugins/catalog-react/src/hooks/index.ts @@ -38,4 +38,3 @@ export { useRelatedEntities } from './useRelatedEntities'; export { useStarredEntities } from './useStarredEntities'; export { useStarredEntity } from './useStarredEntity'; export { useEntityOwnership } from './useEntityOwnership'; -export { useEntityPermission } from './useEntityPermission'; diff --git a/plugins/catalog-react/src/hooks/useEntityPermission.test.tsx b/plugins/catalog-react/src/hooks/useEntityPermission.test.tsx index 766b587da3..aed6676838 100644 --- a/plugins/catalog-react/src/hooks/useEntityPermission.test.tsx +++ b/plugins/catalog-react/src/hooks/useEntityPermission.test.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common'; +import { catalogEntityDeletePermission } from '@backstage/plugin-catalog-common/alpha'; import { renderHook } from '@testing-library/react-hooks'; import { useEntityPermission } from './useEntityPermission'; import { useAsyncEntity } from './useEntity'; diff --git a/plugins/catalog-react/src/index.ts b/plugins/catalog-react/src/index.ts index 2ca7d67d59..b511116f84 100644 --- a/plugins/catalog-react/src/index.ts +++ b/plugins/catalog-react/src/index.ts @@ -31,9 +31,5 @@ export { entityRouteParams, entityRouteRef } from './routes'; export * from './testUtils'; export * from './types'; export * from './overridableComponents'; -export { - getEntityRelations, - getEntitySourceLocation, - isOwnerOf, -} from './utils'; +export { getEntityRelations, getEntitySourceLocation } from './utils'; export type { EntitySourceLocation } from './utils'; diff --git a/plugins/catalog-react/src/testUtils/providers.tsx b/plugins/catalog-react/src/testUtils/providers.tsx index 5867026a8c..9bf5b21f94 100644 --- a/plugins/catalog-react/src/testUtils/providers.tsx +++ b/plugins/catalog-react/src/testUtils/providers.tsx @@ -27,26 +27,20 @@ import { } from '../hooks/useEntityListProvider'; /** @public */ -export const MockEntityListContextProvider = ({ +export function MockEntityListContextProvider< + T extends DefaultEntityFilters = DefaultEntityFilters, +>({ children, value, }: PropsWithChildren<{ - value?: Partial; -}>) => { + value?: Partial>; +}>) { // Provides a default implementation that stores filter state, for testing components that // reflect filter state. - const [filters, setFilters] = useState( - value?.filters ?? {}, - ); + const [filters, setFilters] = useState(value?.filters ?? ({} as T)); const updateFilters = useCallback( - ( - update: - | Partial - | (( - prevFilters: DefaultEntityFilters, - ) => Partial), - ) => { + (update: Partial | ((prevFilters: T) => Partial)) => { setFilters(prevFilters => { const newFilters = typeof update === 'function' ? update(prevFilters) : update; @@ -67,7 +61,7 @@ export const MockEntityListContextProvider = ({ [], ); - const resolvedValue: EntityListContextProps = useMemo( + const resolvedValue: EntityListContextProps = useMemo( () => ({ entities: value?.entities ?? defaultValues.entities, backendEntities: value?.backendEntities ?? defaultValues.backendEntities, @@ -85,4 +79,4 @@ export const MockEntityListContextProvider = ({ {children} ); -}; +} diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 204df92577..5a4fee935a 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,57 @@ # @backstage/plugin-catalog +## 1.9.0-next.0 + +### Minor Changes + +- 3f75b7607c: Add ability to pass icon as function to have ability to customize it by search item + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 1.8.0 + +### Minor Changes + +- 0c1fc3986c: Added Markdown support in the `AboutCard` description section +- 0eaa579f89: The `CatalogSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- d7f55f6bd2: The list of entities takes into account the title when its different from the name to sort the entities. +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- 7d46ca2f68: Make catalog search result list a bit more customizable +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/integration-react@1.1.10 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-search-common@1.2.1 + ## 1.8.0-next.2 ### Patch Changes diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index 6d746f6a7c..ee0ca180f4 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -117,7 +117,7 @@ export interface CatalogSearchResultListItemProps { // (undocumented) highlight?: ResultHighlight; // (undocumented) - icon?: ReactNode; + icon?: ReactNode | ((result: IndexableDocument) => ReactNode); // (undocumented) rank?: number; // (undocumented) diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index c5e2c675c9..212f4044b4 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog", "description": "The Backstage plugin for browsing the Backstage catalog", - "version": "1.8.0-next.2", + "version": "1.9.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx index 10f06ca09e..7b92df5809 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx @@ -34,9 +34,9 @@ import { MockStarredEntitiesApi, starredEntitiesApiRef, } from '@backstage/plugin-catalog-react'; +import { MockPluginProvider } from '@backstage/test-utils/alpha'; import { mockBreakpoint, - MockPluginProvider, MockStorageApi, renderWithEffects, TestApiProvider, diff --git a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx index a277584d2f..50caf4ff8a 100644 --- a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx +++ b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx @@ -31,7 +31,9 @@ import { HighlightedSearchResultText } from '@backstage/plugin-search-react'; const useStyles = makeStyles( { - item: {}, + item: { + display: 'flex', + }, flexContainer: { flexWrap: 'wrap', }, @@ -50,7 +52,7 @@ const useStyles = makeStyles( * @public */ export interface CatalogSearchResultListItemProps { - icon?: ReactNode; + icon?: ReactNode | ((result: IndexableDocument) => ReactNode); result?: IndexableDocument; highlight?: ResultHighlight; rank?: number; @@ -69,7 +71,11 @@ export function CatalogSearchResultListItem( return (
    - {props.icon && {props.icon}} + {props.icon && ( + + {typeof props.icon === 'function' ? props.icon(result) : props.icon} + + )}
    ( #{build?.build_num} - {build?.subject} - + ); diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index 2b2c262778..7939ee1ad4 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-cloudbuild +## 0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.3.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.3.15-next.2 ### Patch Changes diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index c1ac873f30..7604fdaf63 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cloudbuild", "description": "A Backstage plugin that integrates towards Google Cloud Build", - "version": "0.3.15-next.2", + "version": "0.3.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -59,7 +59,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/code-climate/CHANGELOG.md b/plugins/code-climate/CHANGELOG.md index 5264e35a96..5d4e998846 100644 --- a/plugins/code-climate/CHANGELOG.md +++ b/plugins/code-climate/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-code-climate +## 0.1.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.1.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.1.15-next.2 ### Patch Changes diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index 9146f3e118..0f99afff6a 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-climate", - "version": "0.1.15-next.2", + "version": "0.1.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -49,7 +49,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index a5e6acae94..e6606e3eea 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-code-coverage-backend +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## 0.2.8 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + ## 0.2.8-next.2 ### Patch Changes diff --git a/plugins/code-coverage-backend/README.md b/plugins/code-coverage-backend/README.md index ae6021b07c..802e538125 100644 --- a/plugins/code-coverage-backend/README.md +++ b/plugins/code-coverage-backend/README.md @@ -4,7 +4,10 @@ This is the backend part of the `code-coverage` plugin. It takes care of process ## Installation -`yarn workspace backend add @backstage/plugin-code-coverage-backend` +```sh +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-code-coverage-backend +``` First create a `codecoverage.ts` file here: `packages/backend/src/plugins`. Now add the following as its content: diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index f9bcefbd5d..bb0c7df590 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage-backend", "description": "A Backstage backend plugin that helps you keep track of your code coverage", - "version": "0.2.8-next.2", + "version": "0.2.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -42,7 +42,7 @@ "@backstage/cli": "workspace:^", "@types/express-xml-bodyparser": "^0.3.2", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.6", "xml2js": "^0.4.23" }, diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md index 5064067470..36c7617431 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-code-coverage +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.2.8 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + ## 0.2.8-next.2 ### Patch Changes diff --git a/plugins/code-coverage/README.md b/plugins/code-coverage/README.md index ce793a78d3..d4daa6ec00 100644 --- a/plugins/code-coverage/README.md +++ b/plugins/code-coverage/README.md @@ -4,7 +4,10 @@ This is the frontend part of the code-coverage plugin. It displays code coverage ## Installation -`yarn workspace app add @backstage/plugin-code-coverage` +```sh +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-code-coverage +``` Finally you need to import and render the code coverage entity, in `packages/app/src/components/catalog/EntityPage.tsx` add the following: diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index fd15272e38..3a2de06c7f 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage", "description": "A Backstage plugin that helps you keep track of your code coverage", - "version": "0.2.8-next.2", + "version": "0.2.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -55,7 +55,7 @@ "@types/node": "^16.11.26", "@types/recharts": "^1.8.15", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/codescene/CHANGELOG.md b/plugins/codescene/CHANGELOG.md index d07630cadf..e8ab4d63cf 100644 --- a/plugins/codescene/CHANGELOG.md +++ b/plugins/codescene/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-codescene +## 0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.1.10 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + ## 0.1.10-next.1 ### Patch Changes diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index 4249e11064..23af32e94a 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-codescene", - "version": "0.1.10-next.1", + "version": "0.1.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -47,7 +47,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index 21f079f591..5a52322ec0 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-config-schema +## 0.1.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + +## 0.1.38 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + ## 0.1.38-next.1 ### Patch Changes diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 95221632e6..07773496c0 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-config-schema", "description": "A Backstage plugin that lets you browse the configuration schema of your app", - "version": "0.1.38-next.1", + "version": "0.1.39-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -49,7 +49,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index 05d55f3bfe..e94efa2602 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-cost-insights +## 0.12.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-cost-insights-common@0.1.1 + +## 0.12.4 + +### Patch Changes + +- dfa0bb737e: Fix bug in EntityCostsCard if cost aggregation array is empty. Allow title override on the Cost Insights Page +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + - @backstage/plugin-cost-insights-common@0.1.1 + ## 0.12.4-next.2 ### Patch Changes diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 02a86793b0..bce00a354f 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cost-insights", "description": "A Backstage plugin that helps you keep track of your cloud spend", - "version": "0.12.4-next.2", + "version": "0.12.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -74,7 +74,7 @@ "@types/yup": "^0.29.13", "canvas": "^2.10.2", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx index 0a9451c794..d4fdc66bdb 100644 --- a/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx +++ b/plugins/cost-insights/src/components/CostOverviewCard/CostOverviewCard.test.tsx @@ -15,7 +15,8 @@ */ import React from 'react'; import { fireEvent } from '@testing-library/react'; -import { MockPluginProvider, renderInTestApp } from '@backstage/test-utils'; +import { MockPluginProvider } from '@backstage/test-utils/alpha'; +import { renderInTestApp } from '@backstage/test-utils'; import { CostOverviewCard } from './CostOverviewCard'; import { Cost } from '@backstage/plugin-cost-insights-common'; import { diff --git a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx index f288f54e9b..6eb3369b40 100644 --- a/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx +++ b/plugins/cost-insights/src/components/EntityCosts/EntityCost.test.tsx @@ -14,11 +14,8 @@ * limitations under the License. */ import React from 'react'; -import { - MockPluginProvider, - renderInTestApp, - TestApiProvider, -} from '@backstage/test-utils'; +import { MockPluginProvider } from '@backstage/test-utils/alpha'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import { changeOf, MockAggregatedDailyCosts, diff --git a/plugins/cost-insights/src/options.ts b/plugins/cost-insights/src/options.ts index 287935d703..acc977771d 100644 --- a/plugins/cost-insights/src/options.ts +++ b/plugins/cost-insights/src/options.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { usePluginOptions } from '@backstage/core-plugin-api'; +import { usePluginOptions } from '@backstage/core-plugin-api/alpha'; export type CostInsightsPluginOptions = { hideTrendLine?: boolean; diff --git a/plugins/dynatrace/CHANGELOG.md b/plugins/dynatrace/CHANGELOG.md index e403cf500c..1daec214f0 100644 --- a/plugins/dynatrace/CHANGELOG.md +++ b/plugins/dynatrace/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-dynatrace +## 3.0.0-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 2.0.0 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 2.0.0-next.2 ### Patch Changes diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index 4cf4a84c33..ef8c2bb22b 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-dynatrace", - "version": "2.0.0-next.2", + "version": "3.0.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -50,7 +50,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "express": "^4.18.1", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/entity-feedback-backend/CHANGELOG.md b/plugins/entity-feedback-backend/CHANGELOG.md new file mode 100644 index 0000000000..86f7debc5c --- /dev/null +++ b/plugins/entity-feedback-backend/CHANGELOG.md @@ -0,0 +1,29 @@ +# @backstage/plugin-entity-feedback-backend + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-entity-feedback-common@0.1.0 + +## 0.1.0 + +### Minor Changes + +- a3c86a7ed2: Implement entity feedback plugin, check out the `README.md` for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-entity-feedback-common@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/plugin-auth-node@0.2.11 diff --git a/plugins/entity-feedback-backend/package.json b/plugins/entity-feedback-backend/package.json index 7fbc7b9f7e..b7951e1db9 100644 --- a/plugins/entity-feedback-backend/package.json +++ b/plugins/entity-feedback-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-feedback-backend", - "version": "0.0.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -40,7 +40,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.12", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.2.4" }, "files": [ diff --git a/plugins/entity-feedback-common/CHANGELOG.md b/plugins/entity-feedback-common/CHANGELOG.md new file mode 100644 index 0000000000..e646a4322d --- /dev/null +++ b/plugins/entity-feedback-common/CHANGELOG.md @@ -0,0 +1,7 @@ +# @backstage/plugin-entity-feedback-common + +## 0.1.0 + +### Minor Changes + +- a3c86a7ed2: Implement entity feedback plugin, check out the `README.md` for more details! diff --git a/plugins/entity-feedback-common/package.json b/plugins/entity-feedback-common/package.json index 6316b72943..45a5a2b131 100644 --- a/plugins/entity-feedback-common/package.json +++ b/plugins/entity-feedback-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-entity-feedback-common", "description": "Common functionalities for the entity-feedback plugin", - "version": "0.0.0", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/entity-feedback/CHANGELOG.md b/plugins/entity-feedback/CHANGELOG.md new file mode 100644 index 0000000000..4fc3561a07 --- /dev/null +++ b/plugins/entity-feedback/CHANGELOG.md @@ -0,0 +1,31 @@ +# @backstage/plugin-entity-feedback + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-entity-feedback-common@0.1.0 + +## 0.1.0 + +### Minor Changes + +- a3c86a7ed2: Implement entity feedback plugin, check out the `README.md` for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/plugin-entity-feedback-common@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 diff --git a/plugins/entity-feedback/package.json b/plugins/entity-feedback/package.json index f8560a9237..bcf3895d7b 100644 --- a/plugins/entity-feedback/package.json +++ b/plugins/entity-feedback/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-feedback", - "version": "0.0.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -55,7 +55,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/entity-validation/CHANGELOG.md b/plugins/entity-validation/CHANGELOG.md index aa1e41a299..6b80724f92 100644 --- a/plugins/entity-validation/CHANGELOG.md +++ b/plugins/entity-validation/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-entity-validation +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.1.0 + +### Minor Changes + +- d34b3267f9: First implementation for the entity validation UI. For more information refer to its `README.md`. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/plugin-catalog-common@1.0.11 + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/entity-validation/dev/index.tsx b/plugins/entity-validation/dev/index.tsx index 1e1dfa760c..42f4b152ed 100644 --- a/plugins/entity-validation/dev/index.tsx +++ b/plugins/entity-validation/dev/index.tsx @@ -16,9 +16,18 @@ import React from 'react'; import { createDevApp } from '@backstage/dev-utils'; import { entityValidationPlugin, EntityValidationPage } from '../src/plugin'; +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog-react'; createDevApp() .registerPlugin(entityValidationPlugin) + .registerApi({ + api: catalogApiRef, + deps: {}, + factory: () => + ({ + getEntities: () => ({}), + } as CatalogApi), + }) .addPage({ element: , title: 'Root Page', diff --git a/plugins/entity-validation/package.json b/plugins/entity-validation/package.json index 6a00e4ad16..5d509f1eea 100644 --- a/plugins/entity-validation/package.json +++ b/plugins/entity-validation/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-entity-validation", - "version": "0.1.0-next.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -60,7 +60,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx index dc86af8763..0f0e60366b 100644 --- a/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx +++ b/plugins/entity-validation/src/components/EntityValidationPage/EntityValidationPage.tsx @@ -13,8 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import React, { useState } from 'react'; -import { Button, Content, Header, Page } from '@backstage/core-components'; +import { Content, Header, LinkButton, Page } from '@backstage/core-components'; import { EntityTextArea } from '../EntityTextArea'; import { Grid, TextField } from '@material-ui/core'; import { CatalogProcessorResult } from '../../types'; @@ -47,7 +48,7 @@ export const EntityValidationPage = (props: { const [catalogYaml, setCatalogYaml] = useState(defaultYaml); const [yamlFiles, setYamlFiles] = useState(); - const [locationUrl, setLocationUrl] = useState(''); + const [locationUrl, setLocationUrl] = useState(defaultLocation); const parseYaml = () => { const parsedFiles = [ @@ -66,15 +67,15 @@ export const EntityValidationPage = (props: { subtitle="Tool to validate catalog-info.yaml files" /> - + setLocationUrl(e.target.value)} @@ -83,14 +84,9 @@ export const EntityValidationPage = (props: { - + diff --git a/plugins/events-backend-module-aws-sqs/CHANGELOG.md b/plugins/events-backend-module-aws-sqs/CHANGELOG.md index 31596ba402..af976da894 100644 --- a/plugins/events-backend-module-aws-sqs/CHANGELOG.md +++ b/plugins/events-backend-module-aws-sqs/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-events-backend-module-aws-sqs +## 0.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/plugin-events-node@0.2.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-aws-sqs/alpha-api-report.md b/plugins/events-backend-module-aws-sqs/alpha-api-report.md new file mode 100644 index 0000000000..b9f60c4437 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-events-backend-module-aws-sqs" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const awsSqsConsumingEventPublisherEventsModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/events-backend-module-aws-sqs/api-report.md b/plugins/events-backend-module-aws-sqs/api-report.md index ede18f2787..ffa9c888d6 100644 --- a/plugins/events-backend-module-aws-sqs/api-report.md +++ b/plugins/events-backend-module-aws-sqs/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { EventBroker } from '@backstage/plugin-events-node'; import { EventPublisher } from '@backstage/plugin-events-node'; @@ -21,7 +20,4 @@ export class AwsSqsConsumingEventPublisher implements EventPublisher { // (undocumented) setEventBroker(eventBroker: EventBroker): Promise; } - -// @alpha -export const awsSqsConsumingEventPublisherEventsModule: () => BackendFeature; ``` diff --git a/plugins/events-backend-module-aws-sqs/package.json b/plugins/events-backend-module-aws-sqs/package.json index bf06d46648..53901e5038 100644 --- a/plugins/events-backend-module-aws-sqs/package.json +++ b/plugins/events-backend-module-aws-sqs/package.json @@ -1,21 +1,33 @@ { "name": "@backstage/plugin-events-backend-module-aws-sqs", - "version": "0.1.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -42,7 +54,6 @@ "aws-sdk-client-mock": "^2.0.0" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/events-backend-module-aws-sqs/src/alpha.ts b/plugins/events-backend-module-aws-sqs/src/alpha.ts new file mode 100644 index 0000000000..00f08e4417 --- /dev/null +++ b/plugins/events-backend-module-aws-sqs/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { awsSqsConsumingEventPublisherEventsModule } from './service/AwsSqsConsumingEventPublisherEventsModule'; diff --git a/plugins/events-backend-module-aws-sqs/src/index.ts b/plugins/events-backend-module-aws-sqs/src/index.ts index 73b950856b..57f409c044 100644 --- a/plugins/events-backend-module-aws-sqs/src/index.ts +++ b/plugins/events-backend-module-aws-sqs/src/index.ts @@ -24,4 +24,3 @@ */ export { AwsSqsConsumingEventPublisher } from './publisher/AwsSqsConsumingEventPublisher'; -export { awsSqsConsumingEventPublisherEventsModule } from './service/AwsSqsConsumingEventPublisherEventsModule'; diff --git a/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.test.ts b/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.test.ts index 589b8c93fa..3963b9a8b6 100644 --- a/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.test.ts +++ b/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.test.ts @@ -18,7 +18,7 @@ import { getVoidLogger } from '@backstage/backend-common'; import { coreServices } from '@backstage/backend-plugin-api'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { TestEventBroker } from '@backstage/plugin-events-backend-test-utils'; import { awsSqsConsumingEventPublisherEventsModule } from './AwsSqsConsumingEventPublisherEventsModule'; import { AwsSqsConsumingEventPublisher } from '../publisher/AwsSqsConsumingEventPublisher'; diff --git a/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts b/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts index 50812f321b..4205bd231b 100644 --- a/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts +++ b/plugins/events-backend-module-aws-sqs/src/service/AwsSqsConsumingEventPublisherEventsModule.ts @@ -19,7 +19,7 @@ import { createBackendModule, } from '@backstage/backend-plugin-api'; import { loggerToWinstonLogger } from '@backstage/backend-common'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { AwsSqsConsumingEventPublisher } from '../publisher/AwsSqsConsumingEventPublisher'; /** diff --git a/plugins/events-backend-module-azure/CHANGELOG.md b/plugins/events-backend-module-azure/CHANGELOG.md index 83fadeba7b..54c0f53713 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.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-azure/alpha-api-report.md b/plugins/events-backend-module-azure/alpha-api-report.md new file mode 100644 index 0000000000..e3fed2cab0 --- /dev/null +++ b/plugins/events-backend-module-azure/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-events-backend-module-azure" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const azureDevOpsEventRouterEventsModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/events-backend-module-azure/api-report.md b/plugins/events-backend-module-azure/api-report.md index 2e13a7ed4a..4460aeb510 100644 --- a/plugins/events-backend-module-azure/api-report.md +++ b/plugins/events-backend-module-azure/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { EventParams } from '@backstage/plugin-events-node'; import { SubTopicEventRouter } from '@backstage/plugin-events-node'; @@ -13,7 +12,4 @@ export class AzureDevOpsEventRouter extends SubTopicEventRouter { // (undocumented) protected determineSubTopic(params: EventParams): string | undefined; } - -// @alpha -export const azureDevOpsEventRouterEventsModule: () => BackendFeature; ``` diff --git a/plugins/events-backend-module-azure/package.json b/plugins/events-backend-module-azure/package.json index 12420646ae..bdfa37d36f 100644 --- a/plugins/events-backend-module-azure/package.json +++ b/plugins/events-backend-module-azure/package.json @@ -1,21 +1,33 @@ { "name": "@backstage/plugin-events-backend-module-azure", - "version": "0.1.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -34,7 +46,6 @@ "supertest": "^6.1.3" }, "files": [ - "alpha", "dist" ] } diff --git a/plugins/events-backend-module-azure/src/alpha.ts b/plugins/events-backend-module-azure/src/alpha.ts new file mode 100644 index 0000000000..8eacbd8270 --- /dev/null +++ b/plugins/events-backend-module-azure/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { azureDevOpsEventRouterEventsModule } from './service/AzureDevOpsEventRouterEventsModule'; diff --git a/plugins/events-backend-module-azure/src/index.ts b/plugins/events-backend-module-azure/src/index.ts index 9a83f751f6..a1d56dc536 100644 --- a/plugins/events-backend-module-azure/src/index.ts +++ b/plugins/events-backend-module-azure/src/index.ts @@ -22,4 +22,3 @@ */ export { AzureDevOpsEventRouter } from './router/AzureDevOpsEventRouter'; -export { azureDevOpsEventRouterEventsModule } from './service/AzureDevOpsEventRouterEventsModule'; diff --git a/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.test.ts b/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.test.ts index 86ab7ea17d..dbd61782ae 100644 --- a/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.test.ts +++ b/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.test.ts @@ -15,7 +15,7 @@ */ import { startTestBackend } from '@backstage/backend-test-utils'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { azureDevOpsEventRouterEventsModule } from './AzureDevOpsEventRouterEventsModule'; import { AzureDevOpsEventRouter } from '../router/AzureDevOpsEventRouter'; diff --git a/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.ts b/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.ts index 1219452bd8..18851befa4 100644 --- a/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.ts +++ b/plugins/events-backend-module-azure/src/service/AzureDevOpsEventRouterEventsModule.ts @@ -15,13 +15,13 @@ */ import { createBackendModule } from '@backstage/backend-plugin-api'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { AzureDevOpsEventRouter } from '../router/AzureDevOpsEventRouter'; /** * Module for the events-backend plugin, adding an event router for Azure DevOps. * - * Registers the {@link AzureDevOpsEventRouter}. + * Registers the `AzureDevOpsEventRouter`. * * @alpha */ diff --git a/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/events-backend-module-bitbucket-cloud/CHANGELOG.md index 6808429921..2310a2eb44 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.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-bitbucket-cloud/alpha-api-report.md b/plugins/events-backend-module-bitbucket-cloud/alpha-api-report.md new file mode 100644 index 0000000000..f8e550bf98 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-events-backend-module-bitbucket-cloud" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const bitbucketCloudEventRouterEventsModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/events-backend-module-bitbucket-cloud/api-report.md b/plugins/events-backend-module-bitbucket-cloud/api-report.md index c47252ce17..4795edd89a 100644 --- a/plugins/events-backend-module-bitbucket-cloud/api-report.md +++ b/plugins/events-backend-module-bitbucket-cloud/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { EventParams } from '@backstage/plugin-events-node'; import { SubTopicEventRouter } from '@backstage/plugin-events-node'; @@ -13,7 +12,4 @@ export class BitbucketCloudEventRouter extends SubTopicEventRouter { // (undocumented) protected determineSubTopic(params: EventParams): string | undefined; } - -// @alpha -export const bitbucketCloudEventRouterEventsModule: () => BackendFeature; ``` diff --git a/plugins/events-backend-module-bitbucket-cloud/package.json b/plugins/events-backend-module-bitbucket-cloud/package.json index 04e6248a5f..0b1c5d08a7 100644 --- a/plugins/events-backend-module-bitbucket-cloud/package.json +++ b/plugins/events-backend-module-bitbucket-cloud/package.json @@ -1,21 +1,33 @@ { "name": "@backstage/plugin-events-backend-module-bitbucket-cloud", - "version": "0.1.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -34,7 +46,6 @@ "supertest": "^6.1.3" }, "files": [ - "alpha", "dist" ] } diff --git a/plugins/events-backend-module-bitbucket-cloud/src/alpha.ts b/plugins/events-backend-module-bitbucket-cloud/src/alpha.ts new file mode 100644 index 0000000000..e19ff9c9b5 --- /dev/null +++ b/plugins/events-backend-module-bitbucket-cloud/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { bitbucketCloudEventRouterEventsModule } from './service/BitbucketCloudEventRouterEventsModule'; diff --git a/plugins/events-backend-module-bitbucket-cloud/src/index.ts b/plugins/events-backend-module-bitbucket-cloud/src/index.ts index 0a58212de2..77aa9798ef 100644 --- a/plugins/events-backend-module-bitbucket-cloud/src/index.ts +++ b/plugins/events-backend-module-bitbucket-cloud/src/index.ts @@ -22,4 +22,3 @@ */ export { BitbucketCloudEventRouter } from './router/BitbucketCloudEventRouter'; -export { bitbucketCloudEventRouterEventsModule } from './service/BitbucketCloudEventRouterEventsModule'; diff --git a/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.test.ts b/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.test.ts index e456607a2b..60ce5b713e 100644 --- a/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.test.ts +++ b/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.test.ts @@ -15,7 +15,7 @@ */ import { startTestBackend } from '@backstage/backend-test-utils'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { bitbucketCloudEventRouterEventsModule } from './BitbucketCloudEventRouterEventsModule'; import { BitbucketCloudEventRouter } from '../router/BitbucketCloudEventRouter'; diff --git a/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.ts b/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.ts index 7f755a28f4..9516651aa3 100644 --- a/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.ts +++ b/plugins/events-backend-module-bitbucket-cloud/src/service/BitbucketCloudEventRouterEventsModule.ts @@ -15,13 +15,13 @@ */ import { createBackendModule } from '@backstage/backend-plugin-api'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { BitbucketCloudEventRouter } from '../router/BitbucketCloudEventRouter'; /** * Module for the events-backend plugin, adding an event router for Bitbucket Cloud. * - * Registers the {@link BitbucketCloudEventRouter}. + * Registers the `BitbucketCloudEventRouter`. * * @alpha */ diff --git a/plugins/events-backend-module-gerrit/CHANGELOG.md b/plugins/events-backend-module-gerrit/CHANGELOG.md index e05890268c..f74060b9bd 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.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-gerrit/alpha-api-report.md b/plugins/events-backend-module-gerrit/alpha-api-report.md new file mode 100644 index 0000000000..f610d518e7 --- /dev/null +++ b/plugins/events-backend-module-gerrit/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-events-backend-module-gerrit" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const gerritEventRouterEventsModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/events-backend-module-gerrit/api-report.md b/plugins/events-backend-module-gerrit/api-report.md index c8d4a7c9b6..ba3c4dd29f 100644 --- a/plugins/events-backend-module-gerrit/api-report.md +++ b/plugins/events-backend-module-gerrit/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { EventParams } from '@backstage/plugin-events-node'; import { SubTopicEventRouter } from '@backstage/plugin-events-node'; @@ -13,7 +12,4 @@ export class GerritEventRouter extends SubTopicEventRouter { // (undocumented) protected determineSubTopic(params: EventParams): string | undefined; } - -// @alpha -export const gerritEventRouterEventsModule: () => BackendFeature; ``` diff --git a/plugins/events-backend-module-gerrit/package.json b/plugins/events-backend-module-gerrit/package.json index 59cded8497..ec9f9358ab 100644 --- a/plugins/events-backend-module-gerrit/package.json +++ b/plugins/events-backend-module-gerrit/package.json @@ -1,21 +1,33 @@ { "name": "@backstage/plugin-events-backend-module-gerrit", - "version": "0.1.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -34,7 +46,6 @@ "supertest": "^6.1.3" }, "files": [ - "alpha", "dist" ] } diff --git a/plugins/events-backend-module-gerrit/src/alpha.ts b/plugins/events-backend-module-gerrit/src/alpha.ts new file mode 100644 index 0000000000..26fd89b14d --- /dev/null +++ b/plugins/events-backend-module-gerrit/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { gerritEventRouterEventsModule } from './service/GerritEventRouterEventsModule'; diff --git a/plugins/events-backend-module-gerrit/src/index.ts b/plugins/events-backend-module-gerrit/src/index.ts index 1a9ebb03ee..dfc314667f 100644 --- a/plugins/events-backend-module-gerrit/src/index.ts +++ b/plugins/events-backend-module-gerrit/src/index.ts @@ -22,4 +22,3 @@ */ export { GerritEventRouter } from './router/GerritEventRouter'; -export { gerritEventRouterEventsModule } from './service/GerritEventRouterEventsModule'; diff --git a/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.test.ts b/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.test.ts index b5fd6a80ca..6a8f4f46ff 100644 --- a/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.test.ts +++ b/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.test.ts @@ -15,7 +15,7 @@ */ import { startTestBackend } from '@backstage/backend-test-utils'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { gerritEventRouterEventsModule } from './GerritEventRouterEventsModule'; import { GerritEventRouter } from '../router/GerritEventRouter'; diff --git a/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.ts b/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.ts index 734b574edd..31f5c9b384 100644 --- a/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.ts +++ b/plugins/events-backend-module-gerrit/src/service/GerritEventRouterEventsModule.ts @@ -15,13 +15,13 @@ */ import { createBackendModule } from '@backstage/backend-plugin-api'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { GerritEventRouter } from '../router/GerritEventRouter'; /** * Module for the events-backend plugin, adding an event router for Gerrit. * - * Registers the {@link GerritEventRouter}. + * Registers the `GerritEventRouter`. * * @alpha */ diff --git a/plugins/events-backend-module-github/CHANGELOG.md b/plugins/events-backend-module-github/CHANGELOG.md index 88fe36262b..ff885d1dbf 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.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/config@1.0.6 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-github/alpha-api-report.md b/plugins/events-backend-module-github/alpha-api-report.md new file mode 100644 index 0000000000..cb95928b17 --- /dev/null +++ b/plugins/events-backend-module-github/alpha-api-report.md @@ -0,0 +1,15 @@ +## API Report File for "@backstage/plugin-events-backend-module-github" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const githubEventRouterEventsModule: () => BackendFeature; + +// @alpha +export const githubWebhookEventsModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/events-backend-module-github/api-report.md b/plugins/events-backend-module-github/api-report.md index 4f14bce789..bcf9b8ed74 100644 --- a/plugins/events-backend-module-github/api-report.md +++ b/plugins/events-backend-module-github/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { EventParams } from '@backstage/plugin-events-node'; import { RequestValidator } from '@backstage/plugin-events-node'; @@ -20,10 +19,4 @@ export class GithubEventRouter extends SubTopicEventRouter { // (undocumented) protected determineSubTopic(params: EventParams): string | undefined; } - -// @alpha -export const githubEventRouterEventsModule: () => BackendFeature; - -// @alpha -export const githubWebhookEventsModule: () => BackendFeature; ``` diff --git a/plugins/events-backend-module-github/package.json b/plugins/events-backend-module-github/package.json index 6d1fb5b412..ac7599b11f 100644 --- a/plugins/events-backend-module-github/package.json +++ b/plugins/events-backend-module-github/package.json @@ -1,21 +1,33 @@ { "name": "@backstage/plugin-events-backend-module-github", - "version": "0.1.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -36,7 +48,6 @@ "supertest": "^6.1.3" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/events-backend-module-github/src/alpha.ts b/plugins/events-backend-module-github/src/alpha.ts new file mode 100644 index 0000000000..8a712cacb1 --- /dev/null +++ b/plugins/events-backend-module-github/src/alpha.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { githubEventRouterEventsModule } from './service/GithubEventRouterEventsModule'; +export { githubWebhookEventsModule } from './service/GithubWebhookEventsModule'; diff --git a/plugins/events-backend-module-github/src/index.ts b/plugins/events-backend-module-github/src/index.ts index 8e5671d9d8..d02ea1deaf 100644 --- a/plugins/events-backend-module-github/src/index.ts +++ b/plugins/events-backend-module-github/src/index.ts @@ -23,5 +23,3 @@ export { createGithubSignatureValidator } from './http/createGithubSignatureValidator'; export { GithubEventRouter } from './router/GithubEventRouter'; -export { githubEventRouterEventsModule } from './service/GithubEventRouterEventsModule'; -export { githubWebhookEventsModule } from './service/GithubWebhookEventsModule'; diff --git a/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.test.ts b/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.test.ts index 694f5e1dbe..0e2ca69366 100644 --- a/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.test.ts +++ b/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.test.ts @@ -15,7 +15,7 @@ */ import { startTestBackend } from '@backstage/backend-test-utils'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { githubEventRouterEventsModule } from './GithubEventRouterEventsModule'; import { GithubEventRouter } from '../router/GithubEventRouter'; diff --git a/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.ts b/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.ts index 8914d07e71..56cc571763 100644 --- a/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.ts +++ b/plugins/events-backend-module-github/src/service/GithubEventRouterEventsModule.ts @@ -15,13 +15,13 @@ */ import { createBackendModule } from '@backstage/backend-plugin-api'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { GithubEventRouter } from '../router/GithubEventRouter'; /** * Module for the events-backend plugin, adding an event router for GitHub. * - * Registers the {@link GithubEventRouter}. + * Registers the `GithubEventRouter`. * * @alpha */ diff --git a/plugins/events-backend-module-github/src/service/GithubWebhookEventsModule.test.ts b/plugins/events-backend-module-github/src/service/GithubWebhookEventsModule.test.ts index 84233eedee..9e33cac6a0 100644 --- a/plugins/events-backend-module-github/src/service/GithubWebhookEventsModule.test.ts +++ b/plugins/events-backend-module-github/src/service/GithubWebhookEventsModule.test.ts @@ -17,8 +17,8 @@ import { coreServices } from '@backstage/backend-plugin-api'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { - eventsExtensionPoint, HttpPostIngressOptions, RequestDetails, } from '@backstage/plugin-events-node'; diff --git a/plugins/events-backend-module-github/src/service/GithubWebhookEventsModule.ts b/plugins/events-backend-module-github/src/service/GithubWebhookEventsModule.ts index 9a3202cb97..10cb12e431 100644 --- a/plugins/events-backend-module-github/src/service/GithubWebhookEventsModule.ts +++ b/plugins/events-backend-module-github/src/service/GithubWebhookEventsModule.ts @@ -18,7 +18,7 @@ import { coreServices, createBackendModule, } from '@backstage/backend-plugin-api'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { createGithubSignatureValidator } from '../http/createGithubSignatureValidator'; /** diff --git a/plugins/events-backend-module-gitlab/CHANGELOG.md b/plugins/events-backend-module-gitlab/CHANGELOG.md index 4265fa2c71..f3b2ac8594 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.1.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/plugin-events-node@0.2.3 + - @backstage/config@1.0.6 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/events-backend-module-gitlab/alpha-api-report.md b/plugins/events-backend-module-gitlab/alpha-api-report.md new file mode 100644 index 0000000000..64727cc844 --- /dev/null +++ b/plugins/events-backend-module-gitlab/alpha-api-report.md @@ -0,0 +1,15 @@ +## API Report File for "@backstage/plugin-events-backend-module-gitlab" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const gitlabEventRouterEventsModule: () => BackendFeature; + +// @alpha +export const gitlabWebhookEventsModule: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/events-backend-module-gitlab/api-report.md b/plugins/events-backend-module-gitlab/api-report.md index 2a88295032..8a0c513857 100644 --- a/plugins/events-backend-module-gitlab/api-report.md +++ b/plugins/events-backend-module-gitlab/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { EventParams } from '@backstage/plugin-events-node'; import { RequestValidator } from '@backstage/plugin-events-node'; @@ -18,10 +17,4 @@ export class GitlabEventRouter extends SubTopicEventRouter { // (undocumented) protected determineSubTopic(params: EventParams): string | undefined; } - -// @alpha -export const gitlabEventRouterEventsModule: () => BackendFeature; - -// @alpha -export const gitlabWebhookEventsModule: () => BackendFeature; ``` diff --git a/plugins/events-backend-module-gitlab/package.json b/plugins/events-backend-module-gitlab/package.json index ad0b497421..09c924394b 100644 --- a/plugins/events-backend-module-gitlab/package.json +++ b/plugins/events-backend-module-gitlab/package.json @@ -1,21 +1,33 @@ { "name": "@backstage/plugin-events-backend-module-gitlab", - "version": "0.1.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin-module" }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -35,7 +47,6 @@ "supertest": "^6.1.3" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/events-backend-module-gitlab/src/alpha.ts b/plugins/events-backend-module-gitlab/src/alpha.ts new file mode 100644 index 0000000000..357c9f81ce --- /dev/null +++ b/plugins/events-backend-module-gitlab/src/alpha.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { gitlabEventRouterEventsModule } from './service/GitlabEventRouterEventsModule'; +export { gitlabWebhookEventsModule } from './service/GitlabWebhookEventsModule'; diff --git a/plugins/events-backend-module-gitlab/src/index.ts b/plugins/events-backend-module-gitlab/src/index.ts index 859a6c69c0..3788e02955 100644 --- a/plugins/events-backend-module-gitlab/src/index.ts +++ b/plugins/events-backend-module-gitlab/src/index.ts @@ -23,5 +23,3 @@ export { createGitlabTokenValidator } from './http/createGitlabTokenValidator'; export { GitlabEventRouter } from './router/GitlabEventRouter'; -export { gitlabEventRouterEventsModule } from './service/GitlabEventRouterEventsModule'; -export { gitlabWebhookEventsModule } from './service/GitlabWebhookEventsModule'; diff --git a/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.test.ts b/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.test.ts index f0ffca3397..f8b03bc0f3 100644 --- a/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.test.ts +++ b/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.test.ts @@ -15,7 +15,7 @@ */ import { startTestBackend } from '@backstage/backend-test-utils'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { gitlabEventRouterEventsModule } from './GitlabEventRouterEventsModule'; import { GitlabEventRouter } from '../router/GitlabEventRouter'; diff --git a/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.ts b/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.ts index 9ab2e1263e..39ccd5cd60 100644 --- a/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.ts +++ b/plugins/events-backend-module-gitlab/src/service/GitlabEventRouterEventsModule.ts @@ -15,13 +15,13 @@ */ import { createBackendModule } from '@backstage/backend-plugin-api'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { GitlabEventRouter } from '../router/GitlabEventRouter'; /** * Module for the events-backend plugin, adding an event router for GitLab. * - * Registers the {@link GitlabEventRouter}. + * Registers the `GitlabEventRouter`. * * @alpha */ diff --git a/plugins/events-backend-module-gitlab/src/service/GitlabWebhookEventsModule.test.ts b/plugins/events-backend-module-gitlab/src/service/GitlabWebhookEventsModule.test.ts index b139f46f55..b42f2c474e 100644 --- a/plugins/events-backend-module-gitlab/src/service/GitlabWebhookEventsModule.test.ts +++ b/plugins/events-backend-module-gitlab/src/service/GitlabWebhookEventsModule.test.ts @@ -17,8 +17,8 @@ import { coreServices } from '@backstage/backend-plugin-api'; import { startTestBackend } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { - eventsExtensionPoint, HttpPostIngressOptions, RequestDetails, } from '@backstage/plugin-events-node'; diff --git a/plugins/events-backend-module-gitlab/src/service/GitlabWebhookEventsModule.ts b/plugins/events-backend-module-gitlab/src/service/GitlabWebhookEventsModule.ts index 44f13f31ef..c20e55caa9 100644 --- a/plugins/events-backend-module-gitlab/src/service/GitlabWebhookEventsModule.ts +++ b/plugins/events-backend-module-gitlab/src/service/GitlabWebhookEventsModule.ts @@ -18,7 +18,7 @@ import { coreServices, createBackendModule, } from '@backstage/backend-plugin-api'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { createGitlabTokenValidator } from '../http/createGitlabTokenValidator'; /** @@ -26,7 +26,7 @@ import { createGitlabTokenValidator } from '../http/createGitlabTokenValidator'; * registering an HTTP POST ingress with request validator * which verifies the webhook token based on a secret. * - * Registers the {@link GitlabEventRouter}. + * Registers the `GitlabEventRouter`. * * @alpha */ diff --git a/plugins/events-backend-test-utils/CHANGELOG.md b/plugins/events-backend-test-utils/CHANGELOG.md index 713df91935..2394b67a48 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.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.4-next.0 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.2.3 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/events-backend-test-utils/package.json b/plugins/events-backend-test-utils/package.json index 9df1f423e1..2a4f45aa73 100644 --- a/plugins/events-backend-test-utils/package.json +++ b/plugins/events-backend-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-events-backend-test-utils", "description": "The plugin-events-backend-test-utils for @backstage/plugin-events-node", - "version": "0.1.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/events-backend/CHANGELOG.md b/plugins/events-backend/CHANGELOG.md index 1d3ae288b4..0e04c52691 100644 --- a/plugins/events-backend/CHANGELOG.md +++ b/plugins/events-backend/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-events-backend +## 0.2.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/plugin-events-node@0.2.4-next.0 + - @backstage/config@1.0.6 + +## 0.2.3 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/plugin-events-node@0.2.3 + - @backstage/config@1.0.6 + ## 0.2.3-next.2 ### Patch Changes diff --git a/plugins/events-backend/alpha-api-report.md b/plugins/events-backend/alpha-api-report.md new file mode 100644 index 0000000000..3e32f769c1 --- /dev/null +++ b/plugins/events-backend/alpha-api-report.md @@ -0,0 +1,12 @@ +## API Report File for "@backstage/plugin-events-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; + +// @alpha +export const eventsPlugin: () => BackendFeature; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/events-backend/api-report.md b/plugins/events-backend/api-report.md index 28437772ae..7d8ede1979 100644 --- a/plugins/events-backend/api-report.md +++ b/plugins/events-backend/api-report.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { EventBroker } from '@backstage/plugin-events-node'; import { EventPublisher } from '@backstage/plugin-events-node'; @@ -28,9 +27,6 @@ export class EventsBackend { start(): Promise; } -// @alpha -export const eventsPlugin: () => BackendFeature; - // @public export class HttpPostIngressEventPublisher implements EventPublisher { // (undocumented) diff --git a/plugins/events-backend/package.json b/plugins/events-backend/package.json index 1154fc0633..fa3594528c 100644 --- a/plugins/events-backend/package.json +++ b/plugins/events-backend/package.json @@ -1,21 +1,33 @@ { "name": "@backstage/plugin-events-backend", - "version": "0.2.3-next.2", + "version": "0.2.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin" }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -40,7 +52,6 @@ "supertest": "^6.1.3" }, "files": [ - "alpha", "config.d.ts", "dist" ], diff --git a/plugins/events-backend/src/alpha.ts b/plugins/events-backend/src/alpha.ts new file mode 100644 index 0000000000..4403da1636 --- /dev/null +++ b/plugins/events-backend/src/alpha.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { eventsPlugin } from './service/EventsPlugin'; diff --git a/plugins/events-backend/src/index.ts b/plugins/events-backend/src/index.ts index 5026729015..4645e9a479 100644 --- a/plugins/events-backend/src/index.ts +++ b/plugins/events-backend/src/index.ts @@ -21,5 +21,4 @@ */ export { EventsBackend } from './service/EventsBackend'; -export { eventsPlugin } from './service/EventsPlugin'; export { HttpPostIngressEventPublisher } from './service/http'; diff --git a/plugins/events-backend/src/service/EventsPlugin.test.ts b/plugins/events-backend/src/service/EventsPlugin.test.ts index 0570b16d01..73578ae222 100644 --- a/plugins/events-backend/src/service/EventsPlugin.test.ts +++ b/plugins/events-backend/src/service/EventsPlugin.test.ts @@ -21,7 +21,7 @@ import { createBackendModule, } from '@backstage/backend-plugin-api'; import { startTestBackend } from '@backstage/backend-test-utils'; -import { eventsExtensionPoint } from '@backstage/plugin-events-node'; +import { eventsExtensionPoint } from '@backstage/plugin-events-node/alpha'; import { TestEventBroker, TestEventPublisher, diff --git a/plugins/events-backend/src/service/EventsPlugin.ts b/plugins/events-backend/src/service/EventsPlugin.ts index 402104b56c..1ae038a2ac 100644 --- a/plugins/events-backend/src/service/EventsPlugin.ts +++ b/plugins/events-backend/src/service/EventsPlugin.ts @@ -19,12 +19,14 @@ import { coreServices, } from '@backstage/backend-plugin-api'; import { loggerToWinstonLogger } from '@backstage/backend-common'; +import { + eventsExtensionPoint, + EventsExtensionPoint, +} from '@backstage/plugin-events-node/alpha'; import { EventBroker, EventPublisher, EventSubscriber, - eventsExtensionPoint, - EventsExtensionPoint, HttpPostIngressOptions, } from '@backstage/plugin-events-node'; import { InMemoryEventBroker } from './InMemoryEventBroker'; diff --git a/plugins/events-node/CHANGELOG.md b/plugins/events-node/CHANGELOG.md index 99423d1f4a..3c999d18d6 100644 --- a/plugins/events-node/CHANGELOG.md +++ b/plugins/events-node/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-events-node +## 0.2.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + +## 0.2.3 + +### Patch Changes + +- 19d4abf72c: Make `EventParams` typed for implementing tidier event handling. +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + ## 0.2.3-next.2 ### Patch Changes diff --git a/plugins/events-node/alpha-api-report.md b/plugins/events-node/alpha-api-report.md new file mode 100644 index 0000000000..fd30f54d45 --- /dev/null +++ b/plugins/events-node/alpha-api-report.md @@ -0,0 +1,32 @@ +## API Report File for "@backstage/plugin-events-node" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { EventBroker } from '@backstage/plugin-events-node'; +import { EventPublisher } from '@backstage/plugin-events-node'; +import { EventSubscriber } from '@backstage/plugin-events-node'; +import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { HttpPostIngressOptions } from '@backstage/plugin-events-node'; + +// @alpha (undocumented) +export interface EventsExtensionPoint { + // (undocumented) + addHttpPostIngress(options: HttpPostIngressOptions): void; + // (undocumented) + addPublishers( + ...publishers: Array> + ): void; + // (undocumented) + addSubscribers( + ...subscribers: Array> + ): void; + // (undocumented) + setEventBroker(eventBroker: EventBroker): void; +} + +// @alpha (undocumented) +export const eventsExtensionPoint: ExtensionPoint; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/events-node/api-report.md b/plugins/events-node/api-report.md index 8428003b85..dfda48d97e 100644 --- a/plugins/events-node/api-report.md +++ b/plugins/events-node/api-report.md @@ -3,8 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { ExtensionPoint } from '@backstage/backend-plugin-api'; - // @public export interface EventBroker { publish(params: EventParams): Promise; @@ -40,25 +38,6 @@ export abstract class EventRouter implements EventPublisher, EventSubscriber { abstract supportsEventTopics(): string[]; } -// @alpha (undocumented) -export interface EventsExtensionPoint { - // (undocumented) - addHttpPostIngress(options: HttpPostIngressOptions): void; - // (undocumented) - addPublishers( - ...publishers: Array> - ): void; - // (undocumented) - addSubscribers( - ...subscribers: Array> - ): void; - // (undocumented) - setEventBroker(eventBroker: EventBroker): void; -} - -// @alpha (undocumented) -export const eventsExtensionPoint: ExtensionPoint; - // @public export interface EventSubscriber { onEvent(params: EventParams): Promise; diff --git a/plugins/events-node/package.json b/plugins/events-node/package.json index e1b784c6c4..5d6327980e 100644 --- a/plugins/events-node/package.json +++ b/plugins/events-node/package.json @@ -1,22 +1,34 @@ { "name": "@backstage/plugin-events-node", "description": "The plugin-events-node module for @backstage/plugin-events-backend", - "version": "0.2.3-next.2", + "version": "0.2.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "node-library" }, "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "clean": "backstage-cli package clean", @@ -30,7 +42,6 @@ "@backstage/cli": "workspace:^" }, "files": [ - "alpha", "dist" ] } diff --git a/plugins/events-node/src/alpha.ts b/plugins/events-node/src/alpha.ts new file mode 100644 index 0000000000..90666ba2f3 --- /dev/null +++ b/plugins/events-node/src/alpha.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type { EventsExtensionPoint } from './extensions'; +export { eventsExtensionPoint } from './extensions'; diff --git a/plugins/events-node/src/extensions.ts b/plugins/events-node/src/extensions.ts index 945d86b49c..2e44b381af 100644 --- a/plugins/events-node/src/extensions.ts +++ b/plugins/events-node/src/extensions.ts @@ -20,7 +20,7 @@ import { EventPublisher, EventSubscriber, HttpPostIngressOptions, -} from './api'; +} from '@backstage/plugin-events-node'; /** * @alpha diff --git a/plugins/events-node/src/index.ts b/plugins/events-node/src/index.ts index 422eeb169e..2bdf456f13 100644 --- a/plugins/events-node/src/index.ts +++ b/plugins/events-node/src/index.ts @@ -21,5 +21,3 @@ */ export * from './api'; -export type { EventsExtensionPoint } from './extensions'; -export { eventsExtensionPoint } from './extensions'; diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index d2212665fd..e0356edf92 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,27 @@ # @internal/plugin-todo-list-backend +## 1.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + +## 1.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + ## 1.0.10-next.2 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 5cda8b5f52..963bf847ac 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.10-next.2", + "version": "1.0.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -40,7 +40,7 @@ "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/example-todo-list-common/package.json b/plugins/example-todo-list-common/package.json index c1be8da2f8..3d7a66e012 100644 --- a/plugins/example-todo-list-common/package.json +++ b/plugins/example-todo-list-common/package.json @@ -32,7 +32,7 @@ "@backstage/test-utils": "workspace:^", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index 6b0da992bc..715a9bfc12 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,23 @@ # @internal/plugin-todo-list +## 1.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 1.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + ## 1.0.10-next.1 ### Patch Changes diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index 7d4378b51f..4eb7d3357f 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.10-next.1", + "version": "1.0.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -43,7 +43,7 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/explore-backend/CHANGELOG.md b/plugins/explore-backend/CHANGELOG.md index 80503f396a..42a632ec7f 100644 --- a/plugins/explore-backend/CHANGELOG.md +++ b/plugins/explore-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-explore-backend +## 0.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-search-common@1.2.1 + +## 0.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-search-common@1.2.1 + ## 0.0.4-next.2 ### Patch Changes diff --git a/plugins/explore-backend/README.md b/plugins/explore-backend/README.md index 3edf48249a..86f60ae226 100644 --- a/plugins/explore-backend/README.md +++ b/plugins/explore-backend/README.md @@ -76,10 +76,9 @@ To index explore tools you will need to register the search collator in the ```diff +import { ToolDocumentCollatorFactory } from '@backstage/plugin-explore-backend'; -async function createSearchEngine( - env: PluginEnvironment, -): Promise { - ... +... + ++ // collator gathers entities from explore. + indexBuilder.addCollator({ + schedule, + factory: ToolDocumentCollatorFactory.fromConfig(env.config, { @@ -87,8 +86,8 @@ async function createSearchEngine( + logger: env.logger, + }), + }); - ... -} + +... ``` ### Wire up the Frontend diff --git a/plugins/explore-backend/package.json b/plugins/explore-backend/package.json index 77b6b05374..0a6de1ab85 100644 --- a/plugins/explore-backend/package.json +++ b/plugins/explore-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-explore-backend", - "version": "0.0.4-next.2", + "version": "0.0.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -37,7 +37,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.2.4" }, "files": [ diff --git a/plugins/explore-react/CHANGELOG.md b/plugins/explore-react/CHANGELOG.md index 2dc2181597..cb3adf2f5d 100644 --- a/plugins/explore-react/CHANGELOG.md +++ b/plugins/explore-react/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-explore-react +## 0.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/plugin-explore-common@0.0.1 + +## 0.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-explore-common@0.0.1 + ## 0.0.25 ### Patch Changes diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json index e5a47a4ab7..2aa8f1b6fc 100644 --- a/plugins/explore-react/package.json +++ b/plugins/explore-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore-react", "description": "A frontend library for Backstage plugins that want to interact with the explore plugin", - "version": "0.0.25", + "version": "0.0.27-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -44,7 +44,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index 58f14ca14d..501f4dd10c 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,46 @@ # @backstage/plugin-explore +## 0.4.1-next.0 + +### Patch Changes + +- 3f75b7607c: Add ability to pass icon as function to have ability to customize it by search item +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-explore-react@0.0.27-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 0.4.0 + +### Minor Changes + +- 0eaa579f89: The `ToolSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/errors@1.1.4 + - @backstage/plugin-explore-common@0.0.1 + - @backstage/plugin-explore-react@0.0.26 + - @backstage/plugin-search-common@1.2.1 + ## 0.4.0-next.2 ### Patch Changes diff --git a/plugins/explore/README.md b/plugins/explore/README.md index 2388d97ac1..0bb7258ae6 100644 --- a/plugins/explore/README.md +++ b/plugins/explore/README.md @@ -30,7 +30,7 @@ any path for the route, but we recommend the following: ```diff // packages/app/src/App.tsx -+ import { ExplorePage, explorePlugin } from '@backstage/plugin-explore'; ++ import { ExplorePage } from '@backstage/plugin-explore'; ... diff --git a/plugins/explore/api-report.md b/plugins/explore/api-report.md index da960ae951..8820411392 100644 --- a/plugins/explore/api-report.md +++ b/plugins/explore/api-report.md @@ -135,7 +135,7 @@ export interface ToolSearchResultListItemProps { // (undocumented) highlight?: ResultHighlight; // (undocumented) - icon?: ReactNode; + icon?: ReactNode | ((result: IndexableDocument) => ReactNode); // (undocumented) rank?: number; // (undocumented) diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 888040e1cb..c53f00ff6a 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore", "description": "A Backstage plugin for building an exploration page of your software ecosystem", - "version": "0.4.0-next.2", + "version": "0.4.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -64,7 +64,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/explore/src/components/DomainCard/DomainCard.tsx b/plugins/explore/src/components/DomainCard/DomainCard.tsx index a20a5e1f0c..0d37e3e273 100644 --- a/plugins/explore/src/components/DomainCard/DomainCard.tsx +++ b/plugins/explore/src/components/DomainCard/DomainCard.tsx @@ -31,7 +31,7 @@ import { } from '@material-ui/core'; import React from 'react'; -import { Button, ItemCardHeader } from '@backstage/core-components'; +import { LinkButton, ItemCardHeader } from '@backstage/core-components'; import { useRouteRef } from '@backstage/core-plugin-api'; /** @public */ @@ -66,9 +66,9 @@ export const DomainCard = (props: { entity: DomainEntity }) => { {entity.metadata.description} - + ); diff --git a/plugins/explore/src/components/ToolCard/ToolCard.tsx b/plugins/explore/src/components/ToolCard/ToolCard.tsx index 904db0c00b..27729ea085 100644 --- a/plugins/explore/src/components/ToolCard/ToolCard.tsx +++ b/plugins/explore/src/components/ToolCard/ToolCard.tsx @@ -26,7 +26,7 @@ import { makeStyles, Typography, } from '@material-ui/core'; -import { Button } from '@backstage/core-components'; +import { LinkButton } from '@backstage/core-components'; import classNames from 'classnames'; import React from 'react'; @@ -97,9 +97,9 @@ export const ToolCard = ({ card, objectFit }: Props) => { )} - + ); diff --git a/plugins/explore/src/components/ToolSearchResultListItem/ToolSearchResultListItem.tsx b/plugins/explore/src/components/ToolSearchResultListItem/ToolSearchResultListItem.tsx index eb12ba45d8..1aad122ee6 100644 --- a/plugins/explore/src/components/ToolSearchResultListItem/ToolSearchResultListItem.tsx +++ b/plugins/explore/src/components/ToolSearchResultListItem/ToolSearchResultListItem.tsx @@ -46,7 +46,7 @@ const useStyles = makeStyles({ * @public */ export interface ToolSearchResultListItemProps { - icon?: ReactNode; + icon?: ReactNode | ((result: IndexableDocument) => ReactNode); result?: IndexableDocument; highlight?: ResultHighlight; rank?: number; @@ -62,7 +62,11 @@ export function ToolSearchResultListItem(props: ToolSearchResultListItemProps) { return ( <> - {props.icon && {props.icon}} + {props.icon && ( + + {typeof props.icon === 'function' ? props.icon(result) : props.icon} + + )}
    .. + * Tag parts are the individual parts of a version, e.g. [major].[minor].[patch] * are the parts of a semantic version * * @public diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 5ae3bafb5d..03eaff830e 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-github-actions +## 0.5.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + +## 0.5.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/integration@1.4.2 + ## 0.5.15-next.2 ### Patch Changes diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 5165820d62..8a51def8c4 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-actions", "description": "A Backstage plugin that integrates towards GitHub Actions", - "version": "0.5.15-next.2", + "version": "0.5.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -61,7 +61,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index 9c3d9c85e4..d073a5eed9 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-github-deployments +## 0.1.47-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + +## 0.1.46 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + ## 0.1.46-next.2 ### Patch Changes diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 17d6239b90..9027c5f23a 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-deployments", "description": "A Backstage plugin that integrates towards GitHub Deployments", - "version": "0.1.46-next.2", + "version": "0.1.47-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -51,7 +51,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/github-issues/CHANGELOG.md b/plugins/github-issues/CHANGELOG.md index 35aa080016..9e4e64b628 100644 --- a/plugins/github-issues/CHANGELOG.md +++ b/plugins/github-issues/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-github-issues +## 0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + +## 0.2.4 + +### Patch Changes + +- 3f88ae9d0a: Updated README.md examples to use correct components and fixed some syntax errors. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + ## 0.2.4-next.2 ### Patch Changes diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json index 574968d61a..d891951537 100644 --- a/plugins/github-issues/package.json +++ b/plugins/github-issues/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-github-issues", - "version": "0.2.4-next.2", + "version": "0.2.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -51,7 +51,7 @@ "@types/node": "*", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/github-pull-requests-board/CHANGELOG.md b/plugins/github-pull-requests-board/CHANGELOG.md index 8dd45cd956..ec4da0406e 100644 --- a/plugins/github-pull-requests-board/CHANGELOG.md +++ b/plugins/github-pull-requests-board/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-github-pull-requests-board +## 0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration@1.4.2 + - @backstage/theme@0.2.17 + +## 0.1.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/integration@1.4.2 + ## 0.1.9-next.2 ### Patch Changes diff --git a/plugins/github-pull-requests-board/package.json b/plugins/github-pull-requests-board/package.json index 163b7a1967..e837da56e9 100644 --- a/plugins/github-pull-requests-board/package.json +++ b/plugins/github-pull-requests-board/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-pull-requests-board", "description": "A Backstage plugin that allows you to see all open Pull Requests for all the repositories owned by your team", - "version": "0.1.9-next.2", + "version": "0.1.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -58,7 +58,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "peerDependencies": { "react": "^16.13.1 || ^17.0.0", diff --git a/plugins/gitops-profiles/CHANGELOG.md b/plugins/gitops-profiles/CHANGELOG.md index 4ade8515ff..b6ef8bfede 100644 --- a/plugins/gitops-profiles/CHANGELOG.md +++ b/plugins/gitops-profiles/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-gitops-profiles +## 0.3.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.3.33 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + ## 0.3.33-next.1 ### Patch Changes diff --git a/plugins/gitops-profiles/package.json b/plugins/gitops-profiles/package.json index f43e7bb14b..1f42adc3d9 100644 --- a/plugins/gitops-profiles/package.json +++ b/plugins/gitops-profiles/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gitops-profiles", "description": "A Backstage plugin that helps you manage GitOps profiles", - "version": "0.3.33-next.1", + "version": "0.3.34-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -55,7 +55,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/gocd/CHANGELOG.md b/plugins/gocd/CHANGELOG.md index 01037953b0..2d576fa79b 100644 --- a/plugins/gocd/CHANGELOG.md +++ b/plugins/gocd/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-gocd +## 0.1.22-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + ## 0.1.21-next.2 ### Patch Changes diff --git a/plugins/gocd/package.json b/plugins/gocd/package.json index f89a11047d..4567a6e59b 100644 --- a/plugins/gocd/package.json +++ b/plugins/gocd/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gocd", "description": "A Backstage plugin that integrates towards GoCD", - "version": "0.1.21-next.2", + "version": "0.1.22-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -58,7 +58,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/graphiql/CHANGELOG.md b/plugins/graphiql/CHANGELOG.md index 68d6fa8e25..0ee2c37177 100644 --- a/plugins/graphiql/CHANGELOG.md +++ b/plugins/graphiql/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-graphiql +## 0.2.48-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.2.47 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + ## 0.2.47-next.1 ### Patch Changes diff --git a/plugins/graphiql/package.json b/plugins/graphiql/package.json index 15d15a38ca..7f1bd12beb 100644 --- a/plugins/graphiql/package.json +++ b/plugins/graphiql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphiql", "description": "Backstage plugin for browsing GraphQL APIs", - "version": "0.2.47-next.1", + "version": "0.2.48-next.0", "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -58,7 +58,7 @@ "@types/codemirror": "^5.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/graphql-backend/CHANGELOG.md b/plugins/graphql-backend/CHANGELOG.md index 28efff9546..3497d58b44 100644 --- a/plugins/graphql-backend/CHANGELOG.md +++ b/plugins/graphql-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-graphql-backend +## 0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-catalog-graphql@0.3.19-next.0 + +## 0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-catalog-graphql@0.3.18 + ## 0.1.32-next.2 ### Patch Changes diff --git a/plugins/graphql-backend/package.json b/plugins/graphql-backend/package.json index 0f44248997..11e69c3eae 100644 --- a/plugins/graphql-backend/package.json +++ b/plugins/graphql-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-backend", "description": "An experimental Backstage backend plugin for GraphQL", - "version": "0.1.32-next.2", + "version": "0.1.33-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -52,7 +52,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/graphql-voyager/CHANGELOG.md b/plugins/graphql-voyager/CHANGELOG.md index 3712169ea1..678cec72b2 100644 --- a/plugins/graphql-voyager/CHANGELOG.md +++ b/plugins/graphql-voyager/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-graphql-voyager +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.1.0 + +### Minor Changes + +- d1fb4b7bf1: Add the new GraphQL Voyager tool as a plugin for backstage, expose necessary API and components needed for it. + + For more information on how to use this plugin and configure it, please navigate to the [README](https://github.com/backstage/backstage/tree/master/plugins/graphql-voyager/README.md) of the plugin. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/graphql-voyager/package.json b/plugins/graphql-voyager/package.json index b20d045640..3f6d833f7f 100644 --- a/plugins/graphql-voyager/package.json +++ b/plugins/graphql-voyager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-graphql-voyager", "description": "Backstage plugin for GraphQL Voyager", - "version": "0.1.0-next.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -45,7 +45,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/home/CHANGELOG.md b/plugins/home/CHANGELOG.md index 400ca51ae9..c28cc9159a 100644 --- a/plugins/home/CHANGELOG.md +++ b/plugins/home/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-home +## 0.4.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.4.31 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 3d1d867d42: Fixed regression that caused the `WelcomeTitle` to not be the right size when passed to the `title` property of the `
    ` component. A Storybook entry was also added for the `WelcomeTitle` +- c553a625d2: remove unused plugin-stack-overflow dependency +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + ## 0.4.31-next.2 ### Patch Changes diff --git a/plugins/home/README.md b/plugins/home/README.md index 0cd307b706..1fdface722 100644 --- a/plugins/home/README.md +++ b/plugins/home/README.md @@ -9,7 +9,7 @@ For App Integrators, the system is designed to be composable to give total freed If you have a standalone app (you didn't clone this repo), then do ```bash -# From the Backstage repository root +# From your Backstage root directory yarn add --cwd packages/app @backstage/plugin-home ``` diff --git a/plugins/home/package.json b/plugins/home/package.json index 6923b87c83..f7f98a26fd 100644 --- a/plugins/home/package.json +++ b/plugins/home/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-home", "description": "A Backstage plugin that helps you build a home page", - "version": "0.4.31-next.2", + "version": "0.4.32-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -60,7 +60,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/ilert/CHANGELOG.md b/plugins/ilert/CHANGELOG.md index a12bd0a010..18025f037b 100644 --- a/plugins/ilert/CHANGELOG.md +++ b/plugins/ilert/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-ilert +## 0.2.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.2.4 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + ## 0.2.4-next.2 ### Patch Changes diff --git a/plugins/ilert/README.md b/plugins/ilert/README.md index c704108126..814baea507 100644 --- a/plugins/ilert/README.md +++ b/plugins/ilert/README.md @@ -26,7 +26,7 @@ In detail this plugin provides: Install the plugin: ```bash -# From the Backstage repository root +# From your Backstage root directory yarn add --cwd packages/app @backstage/plugin-ilert ``` diff --git a/plugins/ilert/package.json b/plugins/ilert/package.json index 757b91f78e..1bf968218a 100644 --- a/plugins/ilert/package.json +++ b/plugins/ilert/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-ilert", "description": "A Backstage plugin that integrates towards iLert", - "version": "0.2.4-next.2", + "version": "0.2.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -51,7 +51,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/jenkins-backend/CHANGELOG.md b/plugins/jenkins-backend/CHANGELOG.md index 00f1cdfe1b..e9405af8a1 100644 --- a/plugins/jenkins-backend/CHANGELOG.md +++ b/plugins/jenkins-backend/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-jenkins-backend +## 0.1.33-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-jenkins-common@0.1.14-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + +## 0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-jenkins-common@0.1.13 + - @backstage/plugin-permission-common@0.7.3 + ## 0.1.32-next.2 ### Patch Changes diff --git a/plugins/jenkins-backend/package.json b/plugins/jenkins-backend/package.json index d3107cba77..b9a421d408 100644 --- a/plugins/jenkins-backend/package.json +++ b/plugins/jenkins-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins-backend", "description": "A Backstage backend plugin that integrates towards Jenkins", - "version": "0.1.32-next.2", + "version": "0.1.33-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -43,7 +43,7 @@ "@backstage/cli": "workspace:^", "@types/jenkins": "^0.23.1", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/jenkins-common/CHANGELOG.md b/plugins/jenkins-common/CHANGELOG.md index 75a1470ed0..dd692185f2 100644 --- a/plugins/jenkins-common/CHANGELOG.md +++ b/plugins/jenkins-common/CHANGELOG.md @@ -1,5 +1,22 @@ # @backstage/plugin-jenkins-common +## 0.1.14-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + +## 0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + ## 0.1.13-next.1 ### Patch Changes diff --git a/plugins/jenkins-common/package.json b/plugins/jenkins-common/package.json index b37d1cfb8d..b745c50fa2 100644 --- a/plugins/jenkins-common/package.json +++ b/plugins/jenkins-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-jenkins-common", - "version": "0.1.13-next.1", + "version": "0.1.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/jenkins-common/src/permissions.ts b/plugins/jenkins-common/src/permissions.ts index 5ca5ec6adf..311bf993cc 100644 --- a/plugins/jenkins-common/src/permissions.ts +++ b/plugins/jenkins-common/src/permissions.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha'; import { createPermission } from '@backstage/plugin-permission-common'; /** diff --git a/plugins/jenkins/CHANGELOG.md b/plugins/jenkins/CHANGELOG.md index 291f175013..58dfae66d4 100644 --- a/plugins/jenkins/CHANGELOG.md +++ b/plugins/jenkins/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-jenkins +## 0.7.15-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-jenkins-common@0.1.14-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.7.14 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/plugin-jenkins-common@0.1.13 + ## 0.7.14-next.2 ### Patch Changes diff --git a/plugins/jenkins/package.json b/plugins/jenkins/package.json index d2c629136b..f6eb791af0 100644 --- a/plugins/jenkins/package.json +++ b/plugins/jenkins/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-jenkins", "description": "A Backstage plugin that integrates towards Jenkins", - "version": "0.7.14-next.2", + "version": "0.7.15-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -61,7 +61,7 @@ "@types/node": "^16.11.26", "@types/testing-library__jest-dom": "^5.9.1", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx index 0217f00513..1bb6dbaefc 100644 --- a/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx +++ b/plugins/jenkins/src/components/BuildsPage/lib/CITable/CITable.tsx @@ -15,7 +15,7 @@ */ import { Link, Progress, Table, TableColumn } from '@backstage/core-components'; import { alertApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api'; -import { useEntityPermission } from '@backstage/plugin-catalog-react'; +import { useEntityPermission } from '@backstage/plugin-catalog-react/alpha'; import { Box, IconButton, Tooltip, Typography } from '@material-ui/core'; import RetryIcon from '@material-ui/icons/Replay'; import { default as React, useState } from 'react'; diff --git a/plugins/kafka-backend/CHANGELOG.md b/plugins/kafka-backend/CHANGELOG.md index 262cca0397..89e8babe2e 100644 --- a/plugins/kafka-backend/CHANGELOG.md +++ b/plugins/kafka-backend/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-kafka-backend +## 0.2.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## 0.2.35 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + ## 0.2.35-next.2 ### Patch Changes diff --git a/plugins/kafka-backend/package.json b/plugins/kafka-backend/package.json index f0c8d10bde..33f5b667c6 100644 --- a/plugins/kafka-backend/package.json +++ b/plugins/kafka-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka-backend", "description": "A Backstage backend plugin that integrates towards Kafka", - "version": "0.2.35-next.2", + "version": "0.2.36-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kafka/CHANGELOG.md b/plugins/kafka/CHANGELOG.md index 74d5b82c97..8f0afda96d 100644 --- a/plugins/kafka/CHANGELOG.md +++ b/plugins/kafka/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-kafka +## 0.3.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.3.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + ## 0.3.15-next.2 ### Patch Changes diff --git a/plugins/kafka/package.json b/plugins/kafka/package.json index 546cf976d5..98f01102f3 100644 --- a/plugins/kafka/package.json +++ b/plugins/kafka/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kafka", "description": "A Backstage plugin that integrates towards Kafka", - "version": "0.3.15-next.2", + "version": "0.3.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -51,7 +51,7 @@ "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", "jest-when": "^3.1.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/kubernetes-backend/CHANGELOG.md b/plugins/kubernetes-backend/CHANGELOG.md index a8726b238a..26ad74cc1e 100644 --- a/plugins/kubernetes-backend/CHANGELOG.md +++ b/plugins/kubernetes-backend/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-kubernetes-backend +## 0.9.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-kubernetes-common@0.6.1-next.0 + +## 0.9.3 + +### Patch Changes + +- 2518ef5b8a: Adding new Cluster detail fields to catalogClusterLocator. Replace deprecated imports with k8s annotations from plugin-kubernetes-common. +- 7ff81f7692: Kubernetes proxy endpoint now accepts content types that are not json +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. +- a53d06afe5: The name of the header used to specify a cluster to the proxy endpoint is now visible in the API reference. +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.6.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + ## 0.9.3-next.2 ### Patch Changes diff --git a/plugins/kubernetes-backend/api-report.md b/plugins/kubernetes-backend/api-report.md index 006f980c56..a6a4bcfc58 100644 --- a/plugins/kubernetes-backend/api-report.md +++ b/plugins/kubernetes-backend/api-report.md @@ -21,7 +21,7 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common'; import type { RequestHandler } from 'express'; import { TokenCredential } from '@azure/identity'; -// @alpha (undocumented) +// @public (undocumented) export interface AWSClusterDetails extends ClusterDetails { // (undocumented) assumeRole?: string; @@ -29,7 +29,7 @@ export interface AWSClusterDetails extends ClusterDetails { externalId?: string; } -// @alpha (undocumented) +// @public (undocumented) export class AwsIamKubernetesAuthTranslator implements KubernetesAuthTranslator { @@ -54,10 +54,10 @@ export class AwsIamKubernetesAuthTranslator validCredentials(creds: SigningCreds): boolean; } -// @alpha (undocumented) +// @public (undocumented) export interface AzureClusterDetails extends ClusterDetails {} -// @alpha (undocumented) +// @public (undocumented) export class AzureIdentityKubernetesAuthTranslator implements KubernetesAuthTranslator { @@ -68,7 +68,7 @@ export class AzureIdentityKubernetesAuthTranslator ): Promise; } -// @alpha (undocumented) +// @public (undocumented) export interface ClusterDetails { // (undocumented) authProvider: string; @@ -91,25 +91,25 @@ export interface ClusterDetails { url: string; } -// @alpha @deprecated +// @public @deprecated export function createRouter(options: RouterOptions): Promise; -// @alpha (undocumented) +// @public (undocumented) export interface CustomResource extends ObjectToFetch { // (undocumented) objectType: 'customresources'; } -// @alpha (undocumented) +// @public (undocumented) export interface CustomResourcesByEntity extends KubernetesObjectsByEntity { // (undocumented) customResources: CustomResourceMatcher[]; } -// @alpha (undocumented) +// @public (undocumented) export const DEFAULT_OBJECTS: ObjectToFetch[]; -// @alpha (undocumented) +// @public (undocumented) export interface FetchResponseWrapper { // (undocumented) errors: KubernetesFetchError[]; @@ -117,10 +117,10 @@ export interface FetchResponseWrapper { responses: FetchResponse[]; } -// @alpha (undocumented) +// @public (undocumented) export interface GKEClusterDetails extends ClusterDetails {} -// @alpha (undocumented) +// @public (undocumented) export class GoogleKubernetesAuthTranslator implements KubernetesAuthTranslator { @@ -131,7 +131,7 @@ export class GoogleKubernetesAuthTranslator ): Promise; } -// @alpha (undocumented) +// @public (undocumented) export class GoogleServiceAccountAuthTranslator implements KubernetesAuthTranslator { @@ -144,7 +144,7 @@ export class GoogleServiceAccountAuthTranslator // @public export const HEADER_KUBERNETES_CLUSTER: string; -// @alpha (undocumented) +// @public (undocumented) export interface KubernetesAuthTranslator { // (undocumented) decorateClusterDetailsWithAuth( @@ -153,7 +153,7 @@ export interface KubernetesAuthTranslator { ): Promise; } -// @alpha (undocumented) +// @public (undocumented) export class KubernetesAuthTranslatorGenerator { // (undocumented) static getKubernetesAuthTranslatorInstance( @@ -164,7 +164,7 @@ export class KubernetesAuthTranslatorGenerator { ): KubernetesAuthTranslator; } -// @alpha (undocumented) +// @public (undocumented) export class KubernetesBuilder { constructor(env: KubernetesEnvironment); // (undocumented) @@ -247,7 +247,7 @@ export class KubernetesBuilder { setServiceLocator(serviceLocator?: KubernetesServiceLocator): this; } -// @alpha +// @public export type KubernetesBuilderReturn = Promise<{ router: express.Router; clusterSupplier: KubernetesClustersSupplier; @@ -258,12 +258,12 @@ export type KubernetesBuilderReturn = Promise<{ serviceLocator: KubernetesServiceLocator; }>; -// @alpha +// @public export interface KubernetesClustersSupplier { getClusters(): Promise; } -// @alpha (undocumented) +// @public (undocumented) export interface KubernetesEnvironment { // (undocumented) catalogApi: CatalogApi; @@ -273,7 +273,7 @@ export interface KubernetesEnvironment { logger: Logger; } -// @alpha +// @public export interface KubernetesFetcher { // (undocumented) fetchObjectsForService( @@ -286,7 +286,7 @@ export interface KubernetesFetcher { ): Promise; } -// @alpha (undocumented) +// @public (undocumented) export interface KubernetesObjectsByEntity { // (undocumented) auth: KubernetesRequestAuth; @@ -294,7 +294,7 @@ export interface KubernetesObjectsByEntity { entity: Entity; } -// @alpha (undocumented) +// @public (undocumented) export interface KubernetesObjectsProvider { // (undocumented) getCustomResourcesByEntity( @@ -306,7 +306,7 @@ export interface KubernetesObjectsProvider { ): Promise; } -// @alpha (undocumented) +// @public (undocumented) export interface KubernetesObjectsProviderOptions { // (undocumented) customResources: CustomResource[]; @@ -320,7 +320,7 @@ export interface KubernetesObjectsProviderOptions { serviceLocator: KubernetesServiceLocator; } -// @alpha (undocumented) +// @public (undocumented) export type KubernetesObjectTypes = | 'pods' | 'services' @@ -336,14 +336,14 @@ export type KubernetesObjectTypes = | 'statefulsets' | 'daemonsets'; -// @alpha +// @public export class KubernetesProxy { constructor(logger: Logger, clusterSupplier: KubernetesClustersSupplier); // (undocumented) createRequestHandler(): RequestHandler; } -// @alpha +// @public export interface KubernetesServiceLocator { // (undocumented) getClustersByEntity( @@ -354,7 +354,7 @@ export interface KubernetesServiceLocator { }>; } -// @alpha (undocumented) +// @public (undocumented) export class NoopKubernetesAuthTranslator implements KubernetesAuthTranslator { // (undocumented) decorateClusterDetailsWithAuth( @@ -362,7 +362,7 @@ export class NoopKubernetesAuthTranslator implements KubernetesAuthTranslator { ): Promise; } -// @alpha (undocumented) +// @public (undocumented) export interface ObjectFetchParams { // (undocumented) clusterDetails: @@ -382,10 +382,10 @@ export interface ObjectFetchParams { serviceId: string; } -// @alpha (undocumented) +// @public (undocumented) export type ObjectsByEntityRequest = KubernetesRequestBody; -// @alpha (undocumented) +// @public (undocumented) export interface ObjectToFetch { // (undocumented) apiVersion: string; @@ -397,7 +397,7 @@ export interface ObjectToFetch { plural: string; } -// @alpha (undocumented) +// @public (undocumented) export class OidcKubernetesAuthTranslator implements KubernetesAuthTranslator { // (undocumented) decorateClusterDetailsWithAuth( @@ -406,7 +406,7 @@ export class OidcKubernetesAuthTranslator implements KubernetesAuthTranslator { ): Promise; } -// @alpha (undocumented) +// @public (undocumented) export interface RouterOptions { // (undocumented) catalogApi: CatalogApi; @@ -420,13 +420,13 @@ export interface RouterOptions { logger: Logger; } -// @alpha (undocumented) +// @public (undocumented) export interface ServiceAccountClusterDetails extends ClusterDetails {} -// @alpha (undocumented) +// @public (undocumented) export type ServiceLocatorMethod = 'multiTenant' | 'http'; -// @alpha (undocumented) +// @public (undocumented) export interface ServiceLocatorRequestContext { // (undocumented) customResources: CustomResourceMatcher[]; @@ -434,7 +434,7 @@ export interface ServiceLocatorRequestContext { objectTypesToFetch: Set; } -// @alpha (undocumented) +// @public (undocumented) export type SigningCreds = { accessKeyId: string | undefined; secretAccessKey: string | undefined; diff --git a/plugins/kubernetes-backend/package.json b/plugins/kubernetes-backend/package.json index 002a5e2651..e7e03ae93e 100644 --- a/plugins/kubernetes-backend/package.json +++ b/plugins/kubernetes-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-backend", "description": "A Backstage backend plugin that integrates towards Kubernetes", - "version": "0.9.3-next.2", + "version": "0.9.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -71,7 +71,7 @@ "@types/http-proxy-middleware": "^0.19.3", "aws-sdk-mock": "^5.2.1", "mock-fs": "^5.2.0", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/AwsIamKubernetesAuthTranslator.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/AwsIamKubernetesAuthTranslator.ts index ccb0f28109..b89945902d 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/AwsIamKubernetesAuthTranslator.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/AwsIamKubernetesAuthTranslator.ts @@ -20,7 +20,7 @@ import { KubernetesAuthTranslator } from './types'; /** * - * @alpha + * @public */ export type SigningCreds = { accessKeyId: string | undefined; @@ -30,7 +30,7 @@ export type SigningCreds = { /** * - * @alpha + * @public */ export class AwsIamKubernetesAuthTranslator implements KubernetesAuthTranslator diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/AzureIdentityKubernetesAuthTranslator.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/AzureIdentityKubernetesAuthTranslator.ts index 6b1f2281c4..2633598d6c 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/AzureIdentityKubernetesAuthTranslator.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/AzureIdentityKubernetesAuthTranslator.ts @@ -27,7 +27,7 @@ const aksScope = '6dae42f8-4368-4678-94ff-3960e28e3630/.default'; // This scope /** * - * @alpha + * @public */ export class AzureIdentityKubernetesAuthTranslator implements KubernetesAuthTranslator diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleKubernetesAuthTranslator.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleKubernetesAuthTranslator.ts index cabf66b40b..e8dae56997 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleKubernetesAuthTranslator.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleKubernetesAuthTranslator.ts @@ -20,7 +20,7 @@ import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; /** * - * @alpha + * @public */ export class GoogleKubernetesAuthTranslator implements KubernetesAuthTranslator diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleServiceAccountAuthProvider.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleServiceAccountAuthProvider.ts index 1eca62b363..cca510ad6c 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleServiceAccountAuthProvider.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/GoogleServiceAccountAuthProvider.ts @@ -19,7 +19,7 @@ import * as container from '@google-cloud/container'; /** * - * @alpha + * @public */ export class GoogleServiceAccountAuthTranslator implements KubernetesAuthTranslator diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/KubernetesAuthTranslatorGenerator.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/KubernetesAuthTranslatorGenerator.ts index d4eed29653..f54e46efab 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/KubernetesAuthTranslatorGenerator.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/KubernetesAuthTranslatorGenerator.ts @@ -25,7 +25,7 @@ import { OidcKubernetesAuthTranslator } from './OidcKubernetesAuthTranslator'; /** * - * @alpha + * @public */ export class KubernetesAuthTranslatorGenerator { static getKubernetesAuthTranslatorInstance( diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/NoopKubernetesAuthTranslator.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/NoopKubernetesAuthTranslator.ts index 2ef78495a1..32aa141e50 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/NoopKubernetesAuthTranslator.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/NoopKubernetesAuthTranslator.ts @@ -19,7 +19,7 @@ import { ServiceAccountClusterDetails } from '../types/types'; /** * - * @alpha + * @public */ export class NoopKubernetesAuthTranslator implements KubernetesAuthTranslator { async decorateClusterDetailsWithAuth( diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/OidcKubernetesAuthTranslator.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/OidcKubernetesAuthTranslator.ts index e5450b2fe1..cee1ec1e0c 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/OidcKubernetesAuthTranslator.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/OidcKubernetesAuthTranslator.ts @@ -20,7 +20,7 @@ import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; /** * - * @alpha + * @public */ export class OidcKubernetesAuthTranslator implements KubernetesAuthTranslator { async decorateClusterDetailsWithAuth( diff --git a/plugins/kubernetes-backend/src/kubernetes-auth-translator/types.ts b/plugins/kubernetes-backend/src/kubernetes-auth-translator/types.ts index f8417f8468..efbbff8250 100644 --- a/plugins/kubernetes-backend/src/kubernetes-auth-translator/types.ts +++ b/plugins/kubernetes-backend/src/kubernetes-auth-translator/types.ts @@ -19,7 +19,7 @@ import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common'; /** * - * @alpha + * @public */ export interface KubernetesAuthTranslator { decorateClusterDetailsWithAuth( diff --git a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts index 92773ece6d..74ec9eada2 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesBuilder.ts @@ -43,7 +43,7 @@ import { KubernetesProxy } from './KubernetesProxy'; /** * - * @alpha + * @public */ export interface KubernetesEnvironment { logger: Logger; @@ -54,7 +54,7 @@ export interface KubernetesEnvironment { /** * The return type of the `KubernetesBuilder.build` method * - * @alpha + * @public */ export type KubernetesBuilderReturn = Promise<{ router: express.Router; @@ -68,7 +68,7 @@ export type KubernetesBuilderReturn = Promise<{ /** * - * @alpha + * @public */ export class KubernetesBuilder { private clusterSupplier?: KubernetesClustersSupplier; diff --git a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts index a738c69bcc..63e46a44e3 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesFanOutHandler.ts @@ -51,7 +51,7 @@ import { /** * - * @alpha + * @public */ export const DEFAULT_OBJECTS: ObjectToFetch[] = [ { diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index cb36c647ac..178105ef79 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -39,7 +39,7 @@ export const HEADER_KUBERNETES_CLUSTER: string = 'X-Kubernetes-Cluster'; /** * A proxy that routes requests to the Kubernetes API. * - * @alpha + * @public */ export class KubernetesProxy { private readonly middlewareForClusterName = new Map(); diff --git a/plugins/kubernetes-backend/src/service/router.ts b/plugins/kubernetes-backend/src/service/router.ts index ab27a75a18..341956553e 100644 --- a/plugins/kubernetes-backend/src/service/router.ts +++ b/plugins/kubernetes-backend/src/service/router.ts @@ -24,7 +24,7 @@ import { CatalogApi } from '@backstage/catalog-client'; /** * - * @alpha + * @public */ export interface RouterOptions { logger: Logger; @@ -47,7 +47,7 @@ export interface RouterOptions { * }).build(); * ``` * - * @alpha + * @public */ export async function createRouter( options: RouterOptions, diff --git a/plugins/kubernetes-backend/src/types/types.ts b/plugins/kubernetes-backend/src/types/types.ts index d76bfc8149..25c7abfd1f 100644 --- a/plugins/kubernetes-backend/src/types/types.ts +++ b/plugins/kubernetes-backend/src/types/types.ts @@ -28,7 +28,7 @@ import type { /** * - * @alpha + * @public */ export interface ObjectFetchParams { serviceId: string; @@ -46,7 +46,7 @@ export interface ObjectFetchParams { /** * Fetches information from a kubernetes cluster using the cluster details object to target a specific cluster * - * @alpha + * @public */ export interface KubernetesFetcher { fetchObjectsForService( @@ -60,7 +60,7 @@ export interface KubernetesFetcher { /** * - * @alpha + * @public */ export interface FetchResponseWrapper { errors: KubernetesFetchError[]; @@ -69,7 +69,7 @@ export interface FetchResponseWrapper { /** * - * @alpha + * @public */ export interface ObjectToFetch { objectType: KubernetesObjectTypes; @@ -80,7 +80,7 @@ export interface ObjectToFetch { /** * - * @alpha + * @public */ export interface CustomResource extends ObjectToFetch { objectType: 'customresources'; @@ -88,7 +88,7 @@ export interface CustomResource extends ObjectToFetch { /** * - * @alpha + * @public */ export type KubernetesObjectTypes = | 'pods' @@ -107,7 +107,7 @@ export type KubernetesObjectTypes = /** * Used to load cluster details from different sources - * @alpha + * @public */ export interface KubernetesClustersSupplier { /** @@ -120,7 +120,7 @@ export interface KubernetesClustersSupplier { } /** - * @alpha + * @public */ export interface ServiceLocatorRequestContext { objectTypesToFetch: Set; @@ -129,7 +129,7 @@ export interface ServiceLocatorRequestContext { /** * Used to locate which cluster(s) a service is running on - * @alpha + * @public */ export interface KubernetesServiceLocator { getClustersByEntity( @@ -140,13 +140,13 @@ export interface KubernetesServiceLocator { /** * - * @alpha + * @public */ export type ServiceLocatorMethod = 'multiTenant' | 'http'; // TODO implement http /** * - * @alpha + * @public */ export interface ClusterDetails { /** @@ -209,25 +209,25 @@ export interface ClusterDetails { /** * - * @alpha + * @public */ export interface GKEClusterDetails extends ClusterDetails {} /** * - * @alpha + * @public */ export interface AzureClusterDetails extends ClusterDetails {} /** * - * @alpha + * @public */ export interface ServiceAccountClusterDetails extends ClusterDetails {} /** * - * @alpha + * @public */ export interface AWSClusterDetails extends ClusterDetails { assumeRole?: string; @@ -236,7 +236,7 @@ export interface AWSClusterDetails extends ClusterDetails { /** * - * @alpha + * @public */ export interface KubernetesObjectsProviderOptions { logger: Logger; @@ -248,13 +248,13 @@ export interface KubernetesObjectsProviderOptions { /** * - * @alpha + * @public */ export type ObjectsByEntityRequest = KubernetesRequestBody; /** * - * @alpha + * @public */ export interface KubernetesObjectsByEntity { entity: Entity; @@ -263,7 +263,7 @@ export interface KubernetesObjectsByEntity { /** * - * @alpha + * @public */ export interface CustomResourcesByEntity extends KubernetesObjectsByEntity { customResources: CustomResourceMatcher[]; @@ -271,7 +271,7 @@ export interface CustomResourcesByEntity extends KubernetesObjectsByEntity { /** * - * @alpha + * @public */ export interface KubernetesObjectsProvider { getKubernetesObjectsByEntity( diff --git a/plugins/kubernetes-common/CHANGELOG.md b/plugins/kubernetes-common/CHANGELOG.md index cd4df4d54a..281d2a83af 100644 --- a/plugins/kubernetes-common/CHANGELOG.md +++ b/plugins/kubernetes-common/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-kubernetes-common +## 0.6.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + +## 0.6.0 + +### Minor Changes + +- 1728c1ef01: **BREAKING**: Renamed misspelled `LimitRangeFetchReponse` to `LimitRangeFetchResponse`. + +### Patch Changes + +- 2518ef5b8a: New K8s catalog entity annotations added that will replace now deprecated k8s annotations in the catalog-model package. K8s annotation imports should now be made from plugin-kubernetes-common. +- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. +- Updated dependencies + - @backstage/catalog-model@1.2.0 + ## 0.6.0-next.2 ### Patch Changes diff --git a/plugins/kubernetes-common/package.json b/plugins/kubernetes-common/package.json index 4a4e2a30bf..30c2e9befd 100644 --- a/plugins/kubernetes-common/package.json +++ b/plugins/kubernetes-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes-common", "description": "Common functionalities for kubernetes, to be shared between kubernetes and kubernetes-backend plugin", - "version": "0.6.0-next.2", + "version": "0.6.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/kubernetes/CHANGELOG.md b/plugins/kubernetes/CHANGELOG.md index e30b168693..a6f5a90e65 100644 --- a/plugins/kubernetes/CHANGELOG.md +++ b/plugins/kubernetes/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-kubernetes +## 0.7.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-kubernetes-common@0.6.1-next.0 + +## 0.7.8 + +### Patch Changes + +- 145a79a15b: Condenses kubernetes ui plugin to fit more onscreen and increase visibility +- 628e2bd89a: Updated dependency `@kubernetes/client-node` to `0.18.1`. +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.6.0 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + ## 0.7.8-next.2 ### Patch Changes diff --git a/plugins/kubernetes/api-report.md b/plugins/kubernetes/api-report.md index 463b4126eb..2cc2674a9e 100644 --- a/plugins/kubernetes/api-report.md +++ b/plugins/kubernetes/api-report.md @@ -101,7 +101,7 @@ export interface DeploymentResources { replicaSets: V1ReplicaSet[]; } -// @alpha +// @public export interface DetectedError { // (undocumented) cluster: string; @@ -117,10 +117,10 @@ export interface DetectedError { severity: ErrorSeverity; } -// @alpha +// @public export type DetectedErrorsByCluster = Map; -// @alpha +// @public export const detectErrors: ( objects: ObjectsByEntityResponse, ) => DetectedErrorsByCluster; @@ -137,7 +137,7 @@ export type EntityKubernetesContentProps = { refreshIntervalMs?: number; }; -// @alpha +// @public export type ErrorDetectableKind = | 'Pod' | 'Deployment' @@ -161,7 +161,7 @@ export const ErrorReporting: ({ detectedErrors, }: ErrorReportingProps) => JSX.Element; -// @alpha +// @public export type ErrorSeverity = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; // Warning: (ae-forgotten-export) The symbol "FormatClusterLinkOptions" needs to be exported by the entry point index.d.ts diff --git a/plugins/kubernetes/package.json b/plugins/kubernetes/package.json index e51726b296..b69efb0d65 100644 --- a/plugins/kubernetes/package.json +++ b/plugins/kubernetes/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-kubernetes", "description": "A Backstage plugin that integrates towards Kubernetes", - "version": "0.7.8-next.2", + "version": "0.7.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -66,7 +66,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx b/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx index 8a177cf6dd..7e194c3ec2 100644 --- a/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx +++ b/plugins/kubernetes/src/components/KubernetesDrawer/KubernetesDrawer.tsx @@ -33,7 +33,7 @@ import { V1ObjectMeta } from '@kubernetes/client-node'; import { withStyles } from '@material-ui/core/styles'; import jsYaml from 'js-yaml'; import { - Button as BackstageButton, + LinkButton as BackstageButton, CodeSnippet, StructuredMetadataTable, WarningPanel, diff --git a/plugins/kubernetes/src/error-detection/error-detection.ts b/plugins/kubernetes/src/error-detection/error-detection.ts index 3a9f1571e0..fddd4d838a 100644 --- a/plugins/kubernetes/src/error-detection/error-detection.ts +++ b/plugins/kubernetes/src/error-detection/error-detection.ts @@ -25,7 +25,7 @@ import { detectErrorsInHpa } from './hpas'; * For each cluster try to find errors in each of the object types provided * returning a map of cluster names to errors in that cluster * - * @alpha + * @public */ export const detectErrors = ( objects: ObjectsByEntityResponse, diff --git a/plugins/kubernetes/src/error-detection/types.ts b/plugins/kubernetes/src/error-detection/types.ts index 5e35cef8b6..4bc7ae164d 100644 --- a/plugins/kubernetes/src/error-detection/types.ts +++ b/plugins/kubernetes/src/error-detection/types.ts @@ -24,7 +24,7 @@ import { /** * Severity of the error, where 10 is critical and 0 is very low. * - * @alpha + * @public */ export type ErrorSeverity = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; @@ -33,7 +33,7 @@ export type ErrorDetectable = V1Pod | V1Deployment | V1HorizontalPodAutoscaler; /** * Kubernetes kinds that errors might be reported by the plugin * - * @alpha + * @public */ export type ErrorDetectableKind = | 'Pod' @@ -43,14 +43,14 @@ export type ErrorDetectableKind = /** * A list of errors keyed by Cluster name * - * @alpha + * @public */ export type DetectedErrorsByCluster = Map; /** * Represents an error found on a Kubernetes object * - * @alpha + * @public */ export interface DetectedError { severity: ErrorSeverity; diff --git a/plugins/lighthouse-backend/CHANGELOG.md b/plugins/lighthouse-backend/CHANGELOG.md index d64d035fa3..a7a8b26203 100644 --- a/plugins/lighthouse-backend/CHANGELOG.md +++ b/plugins/lighthouse-backend/CHANGELOG.md @@ -1,5 +1,35 @@ # @backstage/plugin-lighthouse-backend +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-lighthouse-common@0.1.0 + +## 0.1.0 + +### Minor Changes + +- eef62546ce: Introduce Lighthouse Backend Plugin to run scheduled Lighthouse Audits + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-lighthouse-common@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/lighthouse-backend/package.json b/plugins/lighthouse-backend/package.json index 60b8570481..0af3f7f5fb 100644 --- a/plugins/lighthouse-backend/package.json +++ b/plugins/lighthouse-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse-backend", "description": "Backend functionalities for lighthouse", - "version": "0.1.0-next.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse-common/CHANGELOG.md b/plugins/lighthouse-common/CHANGELOG.md index 189507371a..6fb22efc9f 100644 --- a/plugins/lighthouse-common/CHANGELOG.md +++ b/plugins/lighthouse-common/CHANGELOG.md @@ -1,5 +1,16 @@ # @backstage/plugin-lighthouse-common +## 0.1.0 + +### Minor Changes + +- eef62546ce: Introduce @backstage/plugin-lighthouse-common with the API implementation + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/lighthouse-common/package.json b/plugins/lighthouse-common/package.json index 50281e17ba..07061fae69 100644 --- a/plugins/lighthouse-common/package.json +++ b/plugins/lighthouse-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse-common", "description": "Common functionalities for lighthouse, to be shared between lighthouse and lighthouse-backend plugin", - "version": "0.1.0-next.0", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/lighthouse/CHANGELOG.md b/plugins/lighthouse/CHANGELOG.md index a79e4795e2..e2a035dabf 100644 --- a/plugins/lighthouse/CHANGELOG.md +++ b/plugins/lighthouse/CHANGELOG.md @@ -1,5 +1,56 @@ # @backstage/plugin-lighthouse +## 0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-lighthouse-common@0.1.0 + +## 0.4.0 + +### Minor Changes + +- eef62546ce: Require @backstage/plugin-lighthouse-common package where API implementation moved to. + + **BREAKING**: the following types have been moved to @backstage/plugin-lighthouse-common: + + - `Audit` + - `AuditBase` + - `AuditCompleted` + - `AuditFailed` + - `AuditRunning` + - `FetchError` + - `LASListRequest` + - `LASListResponse` + - `LighthouseApi` + - `LighthouseCategoryAbbr` + - `LighthouseCategoryId` + - `LighthouseConfigSettings` + - `LighthouseRestApi` + - `TriggerAuditPayload` + - `Website` + - `WebsiteListResponse` + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- 4bdd6bcb3c: Prefer Link over plain anchors +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/plugin-lighthouse-common@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/config@1.0.6 + ## 0.4.0-next.2 ### Minor Changes diff --git a/plugins/lighthouse/package.json b/plugins/lighthouse/package.json index c52858b666..0d9d1365eb 100644 --- a/plugins/lighthouse/package.json +++ b/plugins/lighthouse/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-lighthouse", "description": "A Backstage plugin that integrates towards Lighthouse", - "version": "0.4.0-next.2", + "version": "0.4.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -61,7 +61,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/lighthouse/src/components/Intro/index.tsx b/plugins/lighthouse/src/components/Intro/index.tsx index 57609476b8..8701c473aa 100644 --- a/plugins/lighthouse/src/components/Intro/index.tsx +++ b/plugins/lighthouse/src/components/Intro/index.tsx @@ -22,6 +22,7 @@ import LighthouseSupportButton from '../SupportButton'; import { ContentHeader, InfoCard, + Link, MarkdownContent, } from '@backstage/core-components'; @@ -50,8 +51,8 @@ with the environment variable \`LAS_CORS\` set to \`true\`._ When you have an instance running that Backstage can hook into, first install the plugin into your app: \`\`\`sh -cd packages/app -yarn add @backstage/plugin-lighthouse +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-lighthouse \`\`\` Modify your app routes in \`App.tsx\` to include the \`LighthousePage\` component exported from the plugin, for example: @@ -108,10 +109,9 @@ function GettingStartedCard() { diff --git a/plugins/linguist-backend/.eslintrc.js b/plugins/linguist-backend/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/linguist-backend/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/linguist-backend/CHANGELOG.md b/plugins/linguist-backend/CHANGELOG.md new file mode 100644 index 0000000000..102c42c4cc --- /dev/null +++ b/plugins/linguist-backend/CHANGELOG.md @@ -0,0 +1,40 @@ +# @backstage/plugin-linguist-backend + +## 0.2.0-next.0 + +### Minor Changes + +- 4a1c318853: **BREAKING** The linguist-backend `createRouter` now requires that the `tokenManger` is passed to the router. + +### Patch Changes + +- 2ea5782162: Fixed bug in LinguistBackendApi that caused initial batch of entities to be skipped. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-linguist-common@0.1.0 + +## 0.1.0 + +### Minor Changes + +- 75cfee5688: Introduced the Linguist plugin, checkout the plugin's `README.md` for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 diff --git a/plugins/linguist-backend/README.md b/plugins/linguist-backend/README.md new file mode 100644 index 0000000000..cd63f5db03 --- /dev/null +++ b/plugins/linguist-backend/README.md @@ -0,0 +1,96 @@ +# Linguist Backend + +Welcome to the Linguist backend plugin! This plugin provides data for the Linguist frontend features. + +## Setup + +The following sections will help you get the Linguist Backend plugin setup and running. + +### Up and Running + +Here's how to get the backend up and running: + +1. First we need to add the `@backstage/plugin-linguist-backend` package to your backend: + + ```sh + # From the Backstage root directory + cd packages/backend + yarn add @backstage/plugin-linguist-backend + ``` + +2. Then we will create a new file named `packages/backend/src/plugins/linguist.ts`, and add the + following to it: + + ```ts + import { TaskScheduleDefinition } from '@backstage/backend-tasks'; + import { createRouter } from '@backstage/plugin-linguist-backend'; + import { Router } from 'express'; + import type { PluginEnvironment } from '../types'; + + export default async function createPlugin( + env: PluginEnvironment, + ): Promise { + const schedule: TaskScheduleDefinition = { + frequency: { minutes: 2 }, + timeout: { minutes: 15 }, + initialDelay: { seconds: 90 }, + }; + + return createRouter({ schedule: schedule }, { ...env }); + } + ``` + +3. Next we wire this into the overall backend router, edit `packages/backend/src/index.ts`: + + ```ts + import linguist from './plugins/linguist'; + // ... + async function main() { + // ... + // Add this line under the other lines that follow the useHotMemoize pattern + const linguistEnv = useHotMemoize(module, () => createEnv('linguist')); + // ... + // Insert this line under the other lines that add their routers to apiRouter in the same way + apiRouter.use('/linguist', await linguist(linguistEnv)); + ``` + +4. Now run `yarn start-backend` from the repo root +5. Finally open `http://localhost:7007/api/linguist/health` in a browser and it should return `{"status":"ok"}` + +## Batch Size + +The Linguist backend is setup to process entities by acting as a queue where it will pull down all the applicable entities from the Catalog and add them to it's database (saving just the `entityRef`). Then it will grab the `n` oldest entities that have not been processed to determine their languages and process them. To control the batch size simply provide that to the `createRouter` function in your `packages/backend/src/plugins/linguist.ts` like this: + +```ts +return createRouter({ schedule: schedule, batchSize: 40 }, { ...env }); +``` + +**Note:** The default batch size is 20 + +## Refresh + +The default setup will only generate the language breakdown for entities with the linguist annotation that have not been generated yet. If you want this process to also refresh the data you can do so by adding the `age` (as a `HumanDuration`) in your `packages/backend/src/plugins/linguist.ts` when you call `createRouter`: + +```ts +return createRouter({ schedule: schedule, age: { days: 30 } }, { ...env }); +``` + +With the `age` setup like this if the language breakdown is older than 15 days it will get regenerated. It's recommended that if you choose to use this configuration to set it to a large value - 30, 90, or 180 - as this data generally does not change drastically. + +## Use Source Location + +You may wish to use the `backstage.io/source-location` annotation over using the `backstage.io/linguist` as you may not be able to quickly add that annotation to your Entities. To do this you'll just need to set the `useSourceLocation` boolean to `true` in your `packages/backend/src/plugins/linguist.ts` when you call `createRouter`: + +```ts +return createRouter( + { schedule: schedule, useSourceLocation: true }, + { ...env }, +); +``` + +**Note:** This has the potential to cause a lot of processing, be very thoughtful about this before hand + +## Links + +- [Frontend part of the plugin](../linguist/README.md) +- [The Backstage homepage](https://backstage.io) diff --git a/plugins/linguist-backend/api-report.md b/plugins/linguist-backend/api-report.md new file mode 100644 index 0000000000..18fcec978e --- /dev/null +++ b/plugins/linguist-backend/api-report.md @@ -0,0 +1,106 @@ +## API Report File for "@backstage/plugin-linguist-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { EntityResults } from '@backstage/plugin-linguist-common'; +import express from 'express'; +import { HumanDuration } from '@backstage/types'; +import { Knex } from 'knex'; +import { Languages } from '@backstage/plugin-linguist-common'; +import { Logger } from 'winston'; +import { PluginDatabaseManager } from '@backstage/backend-common'; +import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { PluginTaskScheduler } from '@backstage/backend-tasks'; +import { ProcessedEntity } from '@backstage/plugin-linguist-common'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; +import { TokenManager } from '@backstage/backend-common'; +import { UrlReader } from '@backstage/backend-common'; + +// @public (undocumented) +export function createRouter( + pluginOptions: PluginOptions, + routerOptions: RouterOptions, +): Promise; + +// @public (undocumented) +export class LinguistBackendApi { + constructor( + logger: Logger, + store: LinguistBackendStore, + urlReader: UrlReader, + discovery: PluginEndpointDiscovery, + tokenManager: TokenManager, + age?: HumanDuration, + batchSize?: number, + useSourceLocation?: boolean, + ); + // (undocumented) + getEntityLanguages(entityRef: string): Promise; + // (undocumented) + processEntities(): Promise; +} + +// @public (undocumented) +export class LinguistBackendDatabase implements LinguistBackendStore { + constructor(db: Knex); + // (undocumented) + static create(knex: Knex): Promise; + // (undocumented) + getEntityResults(entityRef: string): Promise; + // (undocumented) + getProcessedEntities(): Promise; + // (undocumented) + getUnprocessedEntities(): Promise; + // (undocumented) + insertEntityResults(entityLanguages: EntityResults): Promise; + // (undocumented) + insertNewEntity(entityRef: string): Promise; +} + +// @public (undocumented) +export interface LinguistBackendStore { + // (undocumented) + getEntityResults(entityRef: string): Promise; + // (undocumented) + getProcessedEntities(): Promise; + // (undocumented) + getUnprocessedEntities(): Promise; + // (undocumented) + insertEntityResults(entityLanguages: EntityResults): Promise; + // (undocumented) + insertNewEntity(entityRef: string): Promise; +} + +// @public (undocumented) +export interface PluginOptions { + // (undocumented) + age?: HumanDuration; + // (undocumented) + batchSize?: number; + // (undocumented) + schedule?: TaskScheduleDefinition; + // (undocumented) + useSourceLocation?: boolean; +} + +// @public (undocumented) +export interface RouterOptions { + // (undocumented) + database: PluginDatabaseManager; + // (undocumented) + discovery: PluginEndpointDiscovery; + // (undocumented) + linguistBackendApi?: LinguistBackendApi; + // (undocumented) + logger: Logger; + // (undocumented) + reader: UrlReader; + // (undocumented) + scheduler?: PluginTaskScheduler; + // (undocumented) + tokenManager: TokenManager; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/linguist-backend/migrations/20221115_init.js b/plugins/linguist-backend/migrations/20221115_init.js new file mode 100644 index 0000000000..3bcf99e08b --- /dev/null +++ b/plugins/linguist-backend/migrations/20221115_init.js @@ -0,0 +1,63 @@ +/* + * 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. + */ + +/** + * @param {import('knex').Knex} knex + */ +exports.up = async function up(knex) { + // Note for the reader: the knex increments types automatically make it a + // primary column, whether you like it or not. That's why the id column is + // not marked as primary as one might have expected; it's only used for + // lookups by ID. Because, SQLite and MySQL don't return RETURNING on + // inserts ... so we want a manually generated key for lookups (an uuid), + // and also an index for ordering guarantees :) + await knex.schema.createTable('entity_result', table => { + table.comment('Table containing results from running Linguist'); + table + .bigIncrements('index') + .notNullable() + .comment('An insert counter to ensure ordering'); + table.uuid('id').notNullable().comment('The ID of the Linguist result'); + table + .text('entity_ref') + .unique() + .notNullable() + .comment('The entity ref that this Linguist result applies to'); + table.text('languages').comment('The results json as a string'); + table + .dateTime('created_at') + .defaultTo(knex.fn.now()) + .notNullable() + .comment('The timestamp when this entry was created'); + table + .dateTime('processed_date') + .defaultTo(knex.fn.now()) + .comment('The timestamp when this entity was processed'); + table.index('index', 'entity_result_index_idx'); + table.index('entity_ref', 'entity_result_entity_ref_idx'); + }); +}; + +/** + * @param {import('knex').Knex} knex + */ +exports.down = async function down(knex) { + await knex.schema.alterTable('entity_result', table => { + table.dropIndex([], 'entity_result_index_idx'); + table.dropIndex([], 'entity_result_entity_ref_idx'); + }); + await knex.schema.dropTable('entity_result'); +}; diff --git a/plugins/linguist-backend/package.json b/plugins/linguist-backend/package.json new file mode 100644 index 0000000000..8a49f8dca2 --- /dev/null +++ b/plugins/linguist-backend/package.json @@ -0,0 +1,56 @@ +{ + "name": "@backstage/plugin-linguist-backend", + "version": "0.2.0-next.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "workspace:^", + "@backstage/backend-tasks": "workspace:^", + "@backstage/catalog-client": "workspace:^", + "@backstage/catalog-model": "workspace:^", + "@backstage/config": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", + "@backstage/plugin-linguist-common": "workspace:^", + "@backstage/types": "workspace:^", + "@types/express": "*", + "express": "^4.18.1", + "express-promise-router": "^4.1.0", + "fs-extra": "^10.0.0", + "knex": "^2.0.0", + "linguist-js": "^2.5.3", + "luxon": "^2.0.2", + "node-fetch": "^2.6.7", + "uuid": "^8.3.2", + "winston": "^3.2.1", + "yn": "^4.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@types/supertest": "^2.0.8", + "msw": "^1.0.0", + "supertest": "^6.2.4" + }, + "files": [ + "dist", + "migrations/**/*.{js,d.ts}" + ] +} diff --git a/plugins/linguist-backend/src/api/LinguistBackendApi.ts b/plugins/linguist-backend/src/api/LinguistBackendApi.ts new file mode 100644 index 0000000000..105335b0ed --- /dev/null +++ b/plugins/linguist-backend/src/api/LinguistBackendApi.ts @@ -0,0 +1,230 @@ +/* + * 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 { + EntitiesOverview, + EntityResults, + Language, + Languages, +} from '@backstage/plugin-linguist-common'; +import { + CATALOG_FILTER_EXISTS, + CatalogClient, + GetEntitiesRequest, +} from '@backstage/catalog-client'; +import { + PluginEndpointDiscovery, + TokenManager, + UrlReader, +} from '@backstage/backend-common'; + +import { DateTime } from 'luxon'; +import { LINGUIST_ANNOTATION } from '@backstage/plugin-linguist-common'; +import { LinguistBackendStore } from '../db'; +import { Logger } from 'winston'; +import fs from 'fs-extra'; +import linguist from 'linguist-js'; +import { + ANNOTATION_SOURCE_LOCATION, + stringifyEntityRef, +} from '@backstage/catalog-model'; +import { assertError } from '@backstage/errors'; +import { HumanDuration } from '@backstage/types'; + +/** @public */ +export class LinguistBackendApi { + private readonly logger: Logger; + private readonly store: LinguistBackendStore; + private readonly urlReader: UrlReader; + private readonly discovery: PluginEndpointDiscovery; + private readonly tokenManager: TokenManager; + + private readonly catalogClient: CatalogClient; + private readonly age?: HumanDuration; + private readonly batchSize?: number; + private readonly useSourceLocation?: boolean; + public constructor( + logger: Logger, + store: LinguistBackendStore, + urlReader: UrlReader, + discovery: PluginEndpointDiscovery, + tokenManager: TokenManager, + age?: HumanDuration, + batchSize?: number, + useSourceLocation?: boolean, + ) { + this.logger = logger; + this.store = store; + this.urlReader = urlReader; + this.discovery = discovery; + this.tokenManager = tokenManager; + this.catalogClient = new CatalogClient({ discoveryApi: this.discovery }); + this.batchSize = batchSize; + this.age = age; + this.useSourceLocation = useSourceLocation; + } + + public async getEntityLanguages(entityRef: string): Promise { + this.logger?.debug(`Getting languages for entity "${entityRef}"`); + + return this.store.getEntityResults(entityRef); + } + + public async processEntities() { + this.logger?.info('Updating list of entities'); + + await this.addNewEntities(); + + this.logger?.info('Processing applicable entities through Linguist'); + + await this.generateEntitiesLanguages(); + } + + private async addNewEntities() { + const annotationKey = this.useSourceLocation + ? ANNOTATION_SOURCE_LOCATION + : LINGUIST_ANNOTATION; + const request: GetEntitiesRequest = { + filter: { + kind: ['API', 'Component', 'Template'], + [`metadata.annotations.${annotationKey}`]: CATALOG_FILTER_EXISTS, + }, + fields: ['kind', 'metadata'], + }; + + const { token } = await this.tokenManager.getToken(); + const response = await this.catalogClient.getEntities(request, { token }); + const entities = response.items; + + entities.forEach(entity => { + const entityRef = stringifyEntityRef(entity); + this.store.insertNewEntity(entityRef); + }); + } + + private async generateEntitiesLanguages() { + const entitiesOverview = await this.getEntitiesOverview(); + this.logger?.info( + `Entities overview: Entity: ${entitiesOverview.entityCount}, Processed: ${entitiesOverview.processedCount}, Pending: ${entitiesOverview.pendingCount}, Stale ${entitiesOverview.staleCount}`, + ); + + const entities = entitiesOverview.filteredEntities.slice( + 0, + this.batchSize ?? 20, + ); + entities.forEach(async entityRef => { + const { token } = await this.tokenManager.getToken(); + const entity = await this.catalogClient.getEntityByRef(entityRef, { + token, + }); + const annotationKey = this.useSourceLocation + ? ANNOTATION_SOURCE_LOCATION + : LINGUIST_ANNOTATION; + + let url = entity?.metadata.annotations?.[annotationKey] ?? ''; + if (url.startsWith('url:')) { + url = url.slice(4); + } + + try { + await this.generateEntityLanguages(entityRef, url); + } catch (error) { + assertError(error); + this.logger.error( + `Unable to process "${entityRef}" using "${url}", message: ${error.message}, stack: ${error.stack}`, + ); + } + }); + } + + private async getEntitiesOverview(): Promise { + this.logger?.debug('Getting pending entities'); + + const processedEntities = await this.store.getProcessedEntities(); + const staleEntities = processedEntities + .filter(pe => { + if (this.age === undefined) return false; + const staleDate = DateTime.now().minus(this.age as HumanDuration); + return DateTime.fromJSDate(pe.processedDate) <= staleDate; + }) + .map(pe => pe.entityRef); + + const unprocessedEntities = await this.store.getUnprocessedEntities(); + const filteredEntities = staleEntities.concat(unprocessedEntities); + + const entitiesOverview: EntitiesOverview = { + entityCount: unprocessedEntities.length, + processedCount: processedEntities.length, + staleCount: staleEntities.length, + pendingCount: filteredEntities.length, + filteredEntities: filteredEntities, + }; + + return entitiesOverview; + } + + private async generateEntityLanguages( + entityRef: string, + url: string, + ): Promise { + this.logger?.info( + `Processing languages for entity ${entityRef} from ${url}`, + ); + + const readTreeResponse = await this.urlReader.readTree(url); + const dir = await readTreeResponse.dir(); + + const results = await linguist(dir); + + try { + const totalBytes = results.languages.bytes; + const langResults = results.languages.results; + + const breakdown: Language[] = []; + for (const key in langResults) { + if (Object.prototype.hasOwnProperty.call(langResults, key)) { + const lang: Language = { + name: key, + percentage: +((langResults[key].bytes / totalBytes) * 100).toFixed( + 2, + ), + bytes: langResults[key].bytes, + type: langResults[key].type, + color: langResults[key].color, + }; + breakdown.push(lang); + } + } + + const languages: Languages = { + languageCount: results.languages.count, + totalBytes: totalBytes, + processedDate: new Date().toISOString(), + breakdown: breakdown, + }; + + const entityResults: EntityResults = { + entityRef: entityRef, + results: languages, + }; + + return await this.store.insertEntityResults(entityResults); + } finally { + this.logger?.info(`Cleaning up files from ${dir}`); + await fs.remove(dir); + } + } +} diff --git a/plugins/linguist-backend/src/api/index.ts b/plugins/linguist-backend/src/api/index.ts new file mode 100644 index 0000000000..a88fa051d4 --- /dev/null +++ b/plugins/linguist-backend/src/api/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { LinguistBackendApi } from './LinguistBackendApi'; diff --git a/plugins/linguist-backend/src/db/LinguistBackendDatabase.ts b/plugins/linguist-backend/src/db/LinguistBackendDatabase.ts new file mode 100644 index 0000000000..cf93374800 --- /dev/null +++ b/plugins/linguist-backend/src/db/LinguistBackendDatabase.ts @@ -0,0 +1,147 @@ +/* + * 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 { resolvePackagePath } from '@backstage/backend-common'; +import { Knex } from 'knex'; +import { v4 as uuid } from 'uuid'; +import { + EntityResults, + Languages, + ProcessedEntity, +} from '@backstage/plugin-linguist-common'; + +export type RawDbEntityResultRow = { + id: string; + entity_ref: string; + languages: string; + processed_date: Date; +}; + +/** @public */ +export interface LinguistBackendStore { + insertEntityResults(entityLanguages: EntityResults): Promise; + insertNewEntity(entityRef: string): Promise; + getEntityResults(entityRef: string): Promise; + getProcessedEntities(): Promise; + getUnprocessedEntities(): Promise; +} + +const migrationsDir = resolvePackagePath( + '@backstage/plugin-linguist-backend', + 'migrations', +); + +/** @public */ +export class LinguistBackendDatabase implements LinguistBackendStore { + static async create(knex: Knex): Promise { + await knex.migrate.latest({ + directory: migrationsDir, + }); + return new LinguistBackendDatabase(knex); + } + + constructor(private readonly db: Knex) {} + + async insertEntityResults(entityLanguages: EntityResults): Promise { + const entityLanguageId = uuid(); + const entityRef = entityLanguages.entityRef; + + const [result] = await this.db('entity_result') + .insert({ + id: entityLanguageId, + entity_ref: entityRef, + languages: JSON.stringify(entityLanguages.results), + processed_date: new Date(entityLanguages.results.processedDate), + }) + .onConflict('entity_ref') + .merge(['languages', 'processed_date']) + .returning('id'); + + return result.id; + } + + async insertNewEntity(entityRef: string): Promise { + const entityLanguageId = uuid(); + + await this.db('entity_result') + .insert({ + id: entityLanguageId, + entity_ref: entityRef, + }) + .onConflict('entity_ref') + .ignore(); // If the entity_ref is in the table already then we don't want to add it again + } + + async getEntityResults(entityRef: string): Promise { + const entityResults = await this.db('entity_result') + .whereNotNull('languages') + .where({ entity_ref: entityRef }) + .first(); + + if (!entityResults) { + const emptyResults: Languages = { + languageCount: 0, + totalBytes: 0, + processedDate: 'undefined', + breakdown: [], + }; + return emptyResults; + } + + try { + return JSON.parse(entityResults.languages); + } catch (error) { + throw new Error(`Failed to parse languages for '${entityRef}', ${error}`); + } + } + + async getProcessedEntities(): Promise { + const rawEntities = await this.db('entity_result') + .whereNotNull('processed_date') + .whereNotNull('languages'); + + if (!rawEntities) { + return []; + } + + const processedEntities = rawEntities.map(rawEntity => { + const processEntity = { + entityRef: rawEntity.entity_ref, + processedDate: rawEntity.processed_date, + }; + + return processEntity; + }); + + return processedEntities; + } + + async getUnprocessedEntities(): Promise { + const rawEntities = await this.db('entity_result') + .whereNull('languages') + .orderBy('created_at', 'asc'); + + if (!rawEntities) { + return []; + } + + const unprocessedEntities = rawEntities.map(rawEntity => { + return rawEntity.entity_ref; + }); + + return unprocessedEntities; + } +} diff --git a/plugins/linguist-backend/src/db/index.ts b/plugins/linguist-backend/src/db/index.ts new file mode 100644 index 0000000000..c8ec15da68 --- /dev/null +++ b/plugins/linguist-backend/src/db/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { LinguistBackendDatabase } from './LinguistBackendDatabase'; +export type { LinguistBackendStore } from './LinguistBackendDatabase'; diff --git a/plugins/linguist-backend/src/index.ts b/plugins/linguist-backend/src/index.ts new file mode 100644 index 0000000000..da1e0ffb00 --- /dev/null +++ b/plugins/linguist-backend/src/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './service/router'; +export { LinguistBackendApi } from './api'; +export { LinguistBackendDatabase } from './db'; +export type { LinguistBackendStore } from './db'; diff --git a/plugins/linguist-backend/src/run.ts b/plugins/linguist-backend/src/run.ts new file mode 100644 index 0000000000..d945aa13f0 --- /dev/null +++ b/plugins/linguist-backend/src/run.ts @@ -0,0 +1,33 @@ +/* + * 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 { getRootLogger } from '@backstage/backend-common'; +import yn from 'yn'; +import { startStandaloneServer } from './service/standaloneServer'; + +const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; +const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); +const logger = getRootLogger(); + +startStandaloneServer({ port, enableCors, logger }).catch(err => { + logger.error(err); + process.exit(1); +}); + +process.on('SIGINT', () => { + logger.info('CTRL+C pressed; exiting.'); + process.exit(0); +}); diff --git a/plugins/linguist-backend/src/service/router.test.ts b/plugins/linguist-backend/src/service/router.test.ts new file mode 100644 index 0000000000..b8bde9d35d --- /dev/null +++ b/plugins/linguist-backend/src/service/router.test.ts @@ -0,0 +1,99 @@ +/* + * 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 { + DatabaseManager, + getVoidLogger, + PluginDatabaseManager, + PluginEndpointDiscovery, + TokenManager, + UrlReaders, +} from '@backstage/backend-common'; +import express from 'express'; +import request from 'supertest'; +import { ConfigReader } from '@backstage/config'; +import { createRouter } from './router'; +import { LinguistBackendApi } from '../api'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; + +function createDatabase(): PluginDatabaseManager { + return DatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { + client: 'better-sqlite3', + connection: ':memory:', + }, + }, + }), + ).forPlugin('code-coverage'); +} + +const testDiscovery: jest.Mocked = { + getBaseUrl: jest + .fn() + .mockResolvedValue('http://localhost:7007/api/code-coverage'), + getExternalBaseUrl: jest.fn(), +}; + +const mockedTokenManager: jest.Mocked = { + getToken: jest.fn(), + authenticate: jest.fn(), +}; + +const mockUrlReader = UrlReaders.default({ + logger: getVoidLogger(), + config: new ConfigReader({}), +}); + +const schedule: TaskScheduleDefinition = { + frequency: { minutes: 2 }, + timeout: { minutes: 15 }, + initialDelay: { seconds: 15 }, +}; + +describe('createRouter', () => { + let linguistBackendApi: jest.Mocked; + let app: express.Express; + + beforeAll(async () => { + const router = await createRouter( + { schedule: schedule, age: { days: 30 }, useSourceLocation: false }, + { + linguistBackendApi, + discovery: testDiscovery, + database: createDatabase(), + reader: mockUrlReader, + logger: getVoidLogger(), + tokenManager: mockedTokenManager, + }, + ); + app = express().use(router); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('GET /health', () => { + it('returns ok', async () => { + const response = await request(app).get('/health'); + + expect(response.status).toEqual(200); + expect(response.body).toEqual({ status: 'ok' }); + }); + }); +}); diff --git a/plugins/linguist-backend/src/service/router.ts b/plugins/linguist-backend/src/service/router.ts new file mode 100644 index 0000000000..18c43d996a --- /dev/null +++ b/plugins/linguist-backend/src/service/router.ts @@ -0,0 +1,122 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + errorHandler, + PluginDatabaseManager, + PluginEndpointDiscovery, + TokenManager, + UrlReader, +} from '@backstage/backend-common'; +import express from 'express'; +import Router from 'express-promise-router'; +import { Logger } from 'winston'; +import { LinguistBackendApi } from '../api'; +import { LinguistBackendDatabase } from '../db'; +import { + PluginTaskScheduler, + TaskScheduleDefinition, +} from '@backstage/backend-tasks'; +import { HumanDuration } from '@backstage/types'; + +/** @public */ +export interface PluginOptions { + schedule?: TaskScheduleDefinition; + age?: HumanDuration; + batchSize?: number; + useSourceLocation?: boolean; +} + +/** @public */ +export interface RouterOptions { + linguistBackendApi?: LinguistBackendApi; + logger: Logger; + reader: UrlReader; + tokenManager: TokenManager; + database: PluginDatabaseManager; + discovery: PluginEndpointDiscovery; + scheduler?: PluginTaskScheduler; +} + +/** @public */ +export async function createRouter( + pluginOptions: PluginOptions, + routerOptions: RouterOptions, +): Promise { + const { schedule, age, batchSize, useSourceLocation } = pluginOptions; + + const { logger, reader, database, discovery, scheduler, tokenManager } = + routerOptions; + + const linguistBackendStore = await LinguistBackendDatabase.create( + await database.getClient(), + ); + + const linguistBackendApi = + routerOptions.linguistBackendApi || + new LinguistBackendApi( + logger, + linguistBackendStore, + reader, + discovery, + tokenManager, + age, + batchSize, + useSourceLocation, + ); + + if (scheduler && schedule) { + logger.info( + `Scheduling processing of entities with: ${JSON.stringify(schedule)}`, + ); + await scheduler.scheduleTask({ + id: 'linguist_process_entities', + frequency: schedule.frequency, + timeout: schedule.timeout, + initialDelay: schedule.initialDelay, + scope: schedule.scope, + fn: async () => { + await linguistBackendApi.processEntities(); + }, + }); + } + + const router = Router(); + router.use(express.json()); + + router.get('/health', (_, response) => { + response.send({ status: 'ok' }); + }); + + /** + * /entity-languages?entity=component:default/my-component + */ + router.get('/entity-languages', async (req, res) => { + const { entityRef: entityRef } = req.query; + + if (!entityRef) { + throw new Error('No entityRef was provided'); + } + + const entityLanguages = await linguistBackendApi.getEntityLanguages( + entityRef as string, + ); + res.status(200).json(entityLanguages); + }); + + router.use(errorHandler()); + return router; +} diff --git a/plugins/linguist-backend/src/service/standaloneServer.ts b/plugins/linguist-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..11604cddfb --- /dev/null +++ b/plugins/linguist-backend/src/service/standaloneServer.ts @@ -0,0 +1,87 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createServiceBuilder, + loadBackendConfig, + SingleHostDiscovery, + UrlReaders, + useHotMemoize, + ServerTokenManager, +} from '@backstage/backend-common'; +import { Server } from 'http'; +import { Logger } from 'winston'; +import { createRouter } from './router'; +import knexFactory from 'knex'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'linguist-backend' }); + const config = await loadBackendConfig({ logger, argv: process.argv }); + const db = useHotMemoize(module, () => { + const knex = knexFactory({ + client: 'sqlite3', + connection: ':memory:', + useNullAsDefault: true, + }); + + knex.client.pool.on('createSuccess', (_eventId: any, resource: any) => { + resource.run('PRAGMA foreign_keys = ON', () => {}); + }); + + return knex; + }); + + const schedule: TaskScheduleDefinition = { + frequency: { minutes: 2 }, + timeout: { minutes: 15 }, + initialDelay: { seconds: 15 }, + }; + + logger.debug('Starting application server...'); + const router = await createRouter( + { schedule: schedule, age: { days: 30 }, useSourceLocation: false }, + { + database: { getClient: async () => db }, + discovery: SingleHostDiscovery.fromConfig(config), + reader: UrlReaders.default({ logger, config }), + logger, + tokenManager: ServerTokenManager.noop(), + }, + ); + + let service = createServiceBuilder(module) + .setPort(options.port) + .addRouter('/linguist', router); + if (options.enableCors) { + service = service.enableCors({ origin: 'http://localhost:3000' }); + } + + return await service.start().catch(err => { + logger.error(err); + process.exit(1); + }); +} + +module.hot?.accept(); diff --git a/plugins/linguist-backend/src/setupTests.ts b/plugins/linguist-backend/src/setupTests.ts new file mode 100644 index 0000000000..813cdeaae3 --- /dev/null +++ b/plugins/linguist-backend/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {}; diff --git a/plugins/linguist-common/.eslintrc.js b/plugins/linguist-common/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/linguist-common/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/linguist-common/CHANGELOG.md b/plugins/linguist-common/CHANGELOG.md new file mode 100644 index 0000000000..f2b34faa84 --- /dev/null +++ b/plugins/linguist-common/CHANGELOG.md @@ -0,0 +1,7 @@ +# @backstage/plugin-linguist-common + +## 0.1.0 + +### Minor Changes + +- 75cfee5688: Introduced the Linguist plugin, checkout the plugin's `README.md` for more details! diff --git a/plugins/linguist-common/README.md b/plugins/linguist-common/README.md new file mode 100644 index 0000000000..9408f7fcc5 --- /dev/null +++ b/plugins/linguist-common/README.md @@ -0,0 +1,3 @@ +# Linguist Common + +Common types, permissions, and constants for the Linguist plugin. diff --git a/plugins/linguist-common/api-report.md b/plugins/linguist-common/api-report.md new file mode 100644 index 0000000000..954bef7904 --- /dev/null +++ b/plugins/linguist-common/api-report.md @@ -0,0 +1,48 @@ +## API Report File for "@backstage/plugin-linguist-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +// @public (undocumented) +export type EntitiesOverview = { + entityCount: number; + processedCount: number; + pendingCount: number; + staleCount: number; + filteredEntities: string[]; +}; + +// @public (undocumented) +export type EntityResults = { + entityRef: string; + results: Languages; +}; + +// @public (undocumented) +export type Language = { + name: string; + percentage: number; + bytes: number; + type: string; + color?: `#${string}`; +}; + +// @public (undocumented) +export type Languages = { + languageCount: number; + totalBytes: number; + processedDate: string; + breakdown: Language[]; +}; + +// @public (undocumented) +export const LINGUIST_ANNOTATION = 'backstage.io/linguist'; + +// @public (undocumented) +export type ProcessedEntity = { + entityRef: string; + processedDate: Date; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/linguist-common/package.json b/plugins/linguist-common/package.json new file mode 100644 index 0000000000..c13f40dee2 --- /dev/null +++ b/plugins/linguist-common/package.json @@ -0,0 +1,31 @@ +{ + "name": "@backstage/plugin-linguist-common", + "description": "Common functionalities for the linguist plugin", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "common-library" + }, + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/linguist-common/src/constants.ts b/plugins/linguist-common/src/constants.ts new file mode 100644 index 0000000000..55b3d21d02 --- /dev/null +++ b/plugins/linguist-common/src/constants.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @public */ +export const LINGUIST_ANNOTATION = 'backstage.io/linguist'; diff --git a/plugins/linguist-common/src/index.ts b/plugins/linguist-common/src/index.ts new file mode 100644 index 0000000000..88fe08c714 --- /dev/null +++ b/plugins/linguist-common/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './types'; +export * from './constants'; diff --git a/plugins/linguist-common/src/setupTests.ts b/plugins/linguist-common/src/setupTests.ts new file mode 100644 index 0000000000..8b9b6bd586 --- /dev/null +++ b/plugins/linguist-common/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/plugins/linguist-common/src/types.ts b/plugins/linguist-common/src/types.ts new file mode 100644 index 0000000000..28a25ed059 --- /dev/null +++ b/plugins/linguist-common/src/types.ts @@ -0,0 +1,53 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @public */ +export type EntityResults = { + entityRef: string; + results: Languages; +}; + +/** @public */ +export type Languages = { + languageCount: number; + totalBytes: number; + processedDate: string; + breakdown: Language[]; +}; + +/** @public */ +export type Language = { + name: string; + percentage: number; + bytes: number; + type: string; + color?: `#${string}`; +}; + +/** @public */ +export type ProcessedEntity = { + entityRef: string; + processedDate: Date; +}; + +/** @public */ +export type EntitiesOverview = { + entityCount: number; + processedCount: number; + pendingCount: number; + staleCount: number; + filteredEntities: string[]; +}; diff --git a/plugins/linguist/.eslintrc.js b/plugins/linguist/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/linguist/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/linguist/CHANGELOG.md b/plugins/linguist/CHANGELOG.md new file mode 100644 index 0000000000..ee28cf7354 --- /dev/null +++ b/plugins/linguist/CHANGELOG.md @@ -0,0 +1,31 @@ +# @backstage/plugin-linguist + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-linguist-common@0.1.0 + +## 0.1.0 + +### Minor Changes + +- 75cfee5688: Introduced the Linguist plugin, checkout the plugin's `README.md` for more details! + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-linguist-common@0.1.0 + - @backstage/errors@1.1.4 diff --git a/plugins/linguist/README.md b/plugins/linguist/README.md new file mode 100644 index 0000000000..d5ca2199dd --- /dev/null +++ b/plugins/linguist/README.md @@ -0,0 +1,88 @@ +# Linguist + +Welcome to the Linguist plugin! + +## Features + +The Linguist plugin consists of a card that will give you the breakdown of the languages used by the configured Entity in the Catalog. + +When there is no Linguist data yet the card will be empty: + +![Example of empty Linguist card](./docs/linguist-no-data.png) + +Clicking on the refresh icon will generate the language breakdown: + +![Example of Linguist card with data](./docs/linguist-with-data.png) + +Here's an example where the permissions are hiding the refresh button: + +![Example of Linguist card without the refresh button](./docs/linguist-no-refresh.png) + +## Setup + +The following sections will help you get the Linguist plugin setup and running. + +### Backend + +You need to setup the [Linguist backend plugin](../linguist-backend/README.md) before you move forward with any of the following steps if you haven't already. + +### Entity Annotation + +To be able to use the Linguist plugin you need to add the following annotation to any entities you want to use it with: + +```yaml +backstage.io/linguist: https://url.to/your/srouce/code +``` + +Linguist uses the `UrlReader` to pull down the files before it scans them to determine the languages, this means you can pull files from all the supported providers - GitHub, GitLab, Bitbucket, Azure, Google GCS, AWS S3, etc. + +Here's what that will look like in action using the Backstage repo as an example: + +```yaml +# Example catalog-info.yaml entity definition file +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + # ... + annotations: + backstage.io/linguist: https://github.com/backstage/backstage +spec: + type: service + # ... +``` + +### Frontend + +To setup the Linguist Card frontend you'll need to do the following steps: + +1. First we need to add the `@backstage/plugin-linguist` package to your frontend app: + + ```sh + # From your Backstage root directory + yarn add --cwd packages/app @backstage/plugin-linguist + ``` + +2. Second we need to add the `EntityLinguistCard` extension to the entity page in your app: + + ```tsx + // In packages/app/src/components/catalog/EntityPage.tsx + import { isLinguistAvailable, EntityLinguistCard } from '@backstage/plugin-linguist'; + + // For example in the Overview section + const overviewContent = ( + + // ... + + + + + + + + // ... + + ``` + +**Notes:** + +- The `if` prop is optional on the `EntitySwitch.Case`, you can remove it if you always want to see the tab even if the entity being viewed does not have the needed annotation diff --git a/plugins/linguist/api-report.md b/plugins/linguist/api-report.md new file mode 100644 index 0000000000..469b3b93c0 --- /dev/null +++ b/plugins/linguist/api-report.md @@ -0,0 +1,21 @@ +## API Report File for "@backstage/plugin-linguist" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; + +// @public (undocumented) +export const EntityLinguistCard: () => JSX.Element; + +// @public (undocumented) +export const isLinguistAvailable: (entity: Entity) => boolean; + +// @public (undocumented) +export const linguistPlugin: BackstagePlugin<{}, {}, {}>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/linguist/dev/index.tsx b/plugins/linguist/dev/index.tsx new file mode 100644 index 0000000000..bb6fb64b52 --- /dev/null +++ b/plugins/linguist/dev/index.tsx @@ -0,0 +1,27 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { linguistPlugin, EntityLinguistCard } from '../src/plugin'; + +createDevApp() + .registerPlugin(linguistPlugin) + .addPage({ + element: , + title: 'Root Page', + path: '/linguist', + }) + .render(); diff --git a/plugins/linguist/docs/linguist-no-data.png b/plugins/linguist/docs/linguist-no-data.png new file mode 100644 index 0000000000..208b8df5d5 Binary files /dev/null and b/plugins/linguist/docs/linguist-no-data.png differ diff --git a/plugins/linguist/docs/linguist-no-refresh.png b/plugins/linguist/docs/linguist-no-refresh.png new file mode 100644 index 0000000000..a3b4e4fde7 Binary files /dev/null and b/plugins/linguist/docs/linguist-no-refresh.png differ diff --git a/plugins/linguist/docs/linguist-with-data.png b/plugins/linguist/docs/linguist-with-data.png new file mode 100644 index 0000000000..e673f994fa Binary files /dev/null and b/plugins/linguist/docs/linguist-with-data.png differ diff --git a/plugins/linguist/package.json b/plugins/linguist/package.json new file mode 100644 index 0000000000..0b234878b1 --- /dev/null +++ b/plugins/linguist/package.json @@ -0,0 +1,63 @@ +{ + "name": "@backstage/plugin-linguist", + "version": "0.1.1-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" + }, + "backstage": { + "role": "frontend-plugin" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/linguist" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/catalog-model": "workspace:^", + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/plugin-catalog-react": "workspace:^", + "@backstage/plugin-linguist-common": "workspace:^", + "@backstage/theme": "workspace:^", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.57", + "luxon": "^2.0.2", + "react-use": "^17.2.4", + "slugify": "^1.6.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/node": "*", + "cross-fetch": "^3.1.5", + "msw": "^1.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/linguist/src/api/LinguistApi.ts b/plugins/linguist/src/api/LinguistApi.ts new file mode 100644 index 0000000000..6593453f31 --- /dev/null +++ b/plugins/linguist/src/api/LinguistApi.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createApiRef } from '@backstage/core-plugin-api'; +import { Languages } from '@backstage/plugin-linguist-common'; + +export const linguistApiRef = createApiRef({ + id: 'plugin.linguist.service', +}); + +export interface LinguistApi { + getLanguages(entityRef: string): Promise; +} diff --git a/plugins/linguist/src/api/LinguistClient.ts b/plugins/linguist/src/api/LinguistClient.ts new file mode 100644 index 0000000000..3e327ff21e --- /dev/null +++ b/plugins/linguist/src/api/LinguistClient.ts @@ -0,0 +1,59 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; +import { ResponseError } from '@backstage/errors'; +import { Languages } from '@backstage/plugin-linguist-common'; +import { LinguistApi } from './LinguistApi'; + +export class LinguistClient implements LinguistApi { + private readonly discoveryApi: DiscoveryApi; + private readonly identityApi: IdentityApi; + + public constructor(options: { + discoveryApi: DiscoveryApi; + identityApi: IdentityApi; + }) { + this.discoveryApi = options.discoveryApi; + this.identityApi = options.identityApi; + } + + public async getLanguages(entityRef: string): Promise { + const queryString = new URLSearchParams(); + queryString.append('entityRef', entityRef); + + const urlSegment = `entity-languages?${queryString}`; + + const items = await this.get(urlSegment); + return items; + } + + private async get(path: string): Promise { + const baseUrl = `${await this.discoveryApi.getBaseUrl('linguist')}/`; + const url = new URL(path, baseUrl); + + const { token } = await this.identityApi.getCredentials(); + const response = await fetch(url.toString(), { + headers: token ? { Authorization: `Bearer ${token}` } : {}, + }); + + if (!response.ok) { + throw await ResponseError.fromResponse(response); + } + + return response.json() as Promise; + } +} diff --git a/plugins/linguist/src/api/index.ts b/plugins/linguist/src/api/index.ts new file mode 100644 index 0000000000..ca60b60d53 --- /dev/null +++ b/plugins/linguist/src/api/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './LinguistApi'; +export * from './LinguistClient'; diff --git a/plugins/linguist/src/components/LinguistCard/LinguistCard.tsx b/plugins/linguist/src/components/LinguistCard/LinguistCard.tsx new file mode 100644 index 0000000000..6014487d30 --- /dev/null +++ b/plugins/linguist/src/components/LinguistCard/LinguistCard.tsx @@ -0,0 +1,153 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Box, + Chip, + Tooltip, + Typography, + makeStyles, + Grid, + useTheme, +} from '@material-ui/core'; +import { InfoCard, Progress } from '@backstage/core-components'; +import Alert from '@material-ui/lab/Alert'; +import { DateTime } from 'luxon'; +import React from 'react'; +import slugify from 'slugify'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { useLanguages } from '../../hooks'; + +const useStyles = makeStyles(theme => ({ + infoCard: { + marginBottom: theme.spacing(3), + }, + barContainer: { + height: theme.spacing(2), + marginBottom: theme.spacing(3), + borderRadius: '4px', + backgroundColor: 'transparent', + overflow: 'hidden', + }, + bar: { + height: '100%', + position: 'relative', + }, + languageDot: { + width: '10px', + height: '10px', + borderRadius: '50%', + marginRight: theme.spacing(1), + display: 'inline-block', + }, + label: { + color: 'inherit', + }, +})); + +export const LinguistCard = () => { + const classes = useStyles(); + const theme = useTheme(); + const { entity } = useEntity(); + const { items, loading, error } = useLanguages(entity); + let barWidth = 0; + + if (loading) { + return ; + } else if (error) { + return {error.message}; + } + + if (items && items.languageCount === 0 && items.totalBytes === 0) { + return ( + + + + + There is currently no language data for this entity. + + + + + ); + } + + const breakdown = items?.breakdown.sort((a, b) => + a.percentage < b.percentage ? 1 : -1, + ); + const processedDate = items?.processedDate; + + return breakdown && processedDate ? ( + + + {breakdown.map((language, index: number) => { + barWidth = barWidth + language.percentage; + return ( + + + + ); + })} + + + + {breakdown.map(languages => ( + + + {languages.name} - {languages.percentage}% + + } + variant="outlined" + key={slugify(languages.name, { lower: true })} + /> + ))} + + + + ) : ( + <> + ); +}; diff --git a/plugins/linguist/src/components/LinguistCard/index.ts b/plugins/linguist/src/components/LinguistCard/index.ts new file mode 100644 index 0000000000..aefae143fd --- /dev/null +++ b/plugins/linguist/src/components/LinguistCard/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { LinguistCard } from './LinguistCard'; diff --git a/plugins/linguist/src/hooks/index.ts b/plugins/linguist/src/hooks/index.ts new file mode 100644 index 0000000000..6f8913cf35 --- /dev/null +++ b/plugins/linguist/src/hooks/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './useLanguages'; diff --git a/plugins/linguist/src/hooks/useLanguages.ts b/plugins/linguist/src/hooks/useLanguages.ts new file mode 100644 index 0000000000..3e99243e94 --- /dev/null +++ b/plugins/linguist/src/hooks/useLanguages.ts @@ -0,0 +1,41 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; +import { linguistApiRef } from '../api'; +import { useApi } from '@backstage/core-plugin-api'; +import useAsync from 'react-use/lib/useAsync'; + +import { Languages } from '@backstage/plugin-linguist-common'; + +export function useLanguages(entity: Entity): { + items?: Languages; + loading: boolean; + error?: Error; +} { + const entityRef = stringifyEntityRef(entity); + + const api = useApi(linguistApiRef); + const { value, loading, error } = useAsync(() => { + return api.getLanguages(entityRef); + }, [api, entityRef]); + + return { + items: value, + loading, + error, + }; +} diff --git a/plugins/linguist/src/index.ts b/plugins/linguist/src/index.ts new file mode 100644 index 0000000000..ce9cd98cbd --- /dev/null +++ b/plugins/linguist/src/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { + linguistPlugin, + isLinguistAvailable, + EntityLinguistCard, +} from './plugin'; diff --git a/plugins/linguist/src/plugin.test.ts b/plugins/linguist/src/plugin.test.ts new file mode 100644 index 0000000000..d2a1016a22 --- /dev/null +++ b/plugins/linguist/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { linguistPlugin } from './plugin'; + +describe('linguist', () => { + it('should export plugin', () => { + expect(linguistPlugin).toBeDefined(); + }); +}); diff --git a/plugins/linguist/src/plugin.ts b/plugins/linguist/src/plugin.ts new file mode 100644 index 0000000000..917a13ca9a --- /dev/null +++ b/plugins/linguist/src/plugin.ts @@ -0,0 +1,53 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createApiFactory, + createComponentExtension, + createPlugin, + discoveryApiRef, + identityApiRef, +} from '@backstage/core-plugin-api'; +import { linguistApiRef, LinguistClient } from './api'; +import { LINGUIST_ANNOTATION } from '@backstage/plugin-linguist-common'; +import { Entity } from '@backstage/catalog-model'; + +/** @public */ +export const isLinguistAvailable = (entity: Entity) => + Boolean(entity.metadata.annotations?.[LINGUIST_ANNOTATION]); + +/** @public */ +export const linguistPlugin = createPlugin({ + id: 'linguist', + apis: [ + createApiFactory({ + api: linguistApiRef, + deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef }, + factory: ({ discoveryApi, identityApi }) => + new LinguistClient({ discoveryApi, identityApi }), + }), + ], +}); + +/** @public */ +export const EntityLinguistCard = linguistPlugin.provide( + createComponentExtension({ + name: 'EntityLinguistCard', + component: { + lazy: () => import('./components/LinguistCard').then(m => m.LinguistCard), + }, + }), +); diff --git a/plugins/linguist/src/setupTests.ts b/plugins/linguist/src/setupTests.ts new file mode 100644 index 0000000000..2b5b615b19 --- /dev/null +++ b/plugins/linguist/src/setupTests.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; diff --git a/plugins/microsoft-calendar/CHANGELOG.md b/plugins/microsoft-calendar/CHANGELOG.md new file mode 100644 index 0000000000..c9e1da8fb1 --- /dev/null +++ b/plugins/microsoft-calendar/CHANGELOG.md @@ -0,0 +1,28 @@ +# @backstage/plugin-microsoft-calendar + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.1.0 + +### Minor Changes + +- 44412375bb: Created a new plugin `@backstage/plugin-microsoft-calendar` to display events from a Microsoft Calendar. + + please refer to the [README.md](https://github.com/backstage/backstage/blob/master/plugins/microsoft-calendar/README.md) for step-by-step instructions to setup the plugin in your Backstage instance. + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/errors@1.1.4 diff --git a/plugins/microsoft-calendar/README.md b/plugins/microsoft-calendar/README.md index 73a66b15f5..219a7cf2dc 100644 --- a/plugins/microsoft-calendar/README.md +++ b/plugins/microsoft-calendar/README.md @@ -25,7 +25,7 @@ The following sections will help you set up the Microsoft calendar plugin. 1. Install the plugin by running this command ```bash -# From the Backstage repository root +# From your Backstage root directory yarn add --cwd packages/app @backstage/plugin-microsoft-calendar ``` diff --git a/plugins/microsoft-calendar/package.json b/plugins/microsoft-calendar/package.json index 2a2e0ca013..ce2f148d6c 100644 --- a/plugins/microsoft-calendar/package.json +++ b/plugins/microsoft-calendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-microsoft-calendar", - "version": "0.0.0", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -55,7 +55,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/newrelic-dashboard/CHANGELOG.md b/plugins/newrelic-dashboard/CHANGELOG.md index 78aadfc390..c3de323d2d 100644 --- a/plugins/newrelic-dashboard/CHANGELOG.md +++ b/plugins/newrelic-dashboard/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-newrelic-dashboard +## 0.2.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + +## 0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + ## 0.2.8-next.2 ### Patch Changes diff --git a/plugins/newrelic-dashboard/package.json b/plugins/newrelic-dashboard/package.json index 5fe39fd8a3..462352b69e 100644 --- a/plugins/newrelic-dashboard/package.json +++ b/plugins/newrelic-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-newrelic-dashboard", - "version": "0.2.8-next.2", + "version": "0.2.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/newrelic/CHANGELOG.md b/plugins/newrelic/CHANGELOG.md index 8858555c7c..ba75aface5 100644 --- a/plugins/newrelic/CHANGELOG.md +++ b/plugins/newrelic/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-newrelic +## 0.3.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.3.33 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + ## 0.3.33-next.1 ### Patch Changes diff --git a/plugins/newrelic/package.json b/plugins/newrelic/package.json index e02c690eff..9d183f34d6 100644 --- a/plugins/newrelic/package.json +++ b/plugins/newrelic/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-newrelic", "description": "A Backstage plugin that integrates towards New Relic", - "version": "0.3.33-next.1", + "version": "0.3.34-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -54,7 +54,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/octopus-deploy/.eslintrc.js b/plugins/octopus-deploy/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/octopus-deploy/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/octopus-deploy/CHANGELOG.md b/plugins/octopus-deploy/CHANGELOG.md new file mode 100644 index 0000000000..15be227555 --- /dev/null +++ b/plugins/octopus-deploy/CHANGELOG.md @@ -0,0 +1,16 @@ +# @backstage/plugin-octopus-deploy + +## 0.1.0-next.0 + +### Minor Changes + +- b7fff1171f: Initial version + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 diff --git a/plugins/octopus-deploy/README.md b/plugins/octopus-deploy/README.md new file mode 100644 index 0000000000..abc0559896 --- /dev/null +++ b/plugins/octopus-deploy/README.md @@ -0,0 +1,61 @@ +# Octopus Deploy Plugin + +Welcome to the octopus-deploy plugin! + +## Features + +- Display the deployment status of the most recent releases for a project in Octopus Deploy straight from the Backstage catalog + +## Getting started + +This plugin (currently) uses the Backstage proxy to securely communicate with the Octopus Deploy API. + +To use it, you will need to generate an [API Key](https://octopus.com/docs/octopus-rest-api/how-to-create-an-api-key) within Octopus Deploy. + +1. Add the following to your app-config.yaml to enable the proxy: + +``` +// app-config.yaml +proxy: + '/octopus-deploy': + target: '' + headers: + X-Octopus-ApiKey: ${OCTOPUS_API_KEY} +``` + +2. Add the following to `EntityPage.tsx` to display Octopus Releases + +``` +// In packages/app/src/components/catalog/EntityPage.tsx +import { + isOctopusDeployAvailable + EntityOctopusDeployContent +} from '@backstage/plugin-octopus-deploy'; + +const cicdContent = ( + + {/* other components... */} + + + + +) +``` + +3. Add `octopus.com/project-id` annotation in catalog descriptor file + +To obtain a projects ID you will have to query the Octopus API. In the future we'll add support for using a projects slug as well. + +``` +// catalog-info.yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + # ... + annotations: + octopus.com/project-id: Projects-102 +spec: + type: service +``` + +All set , you will be able to see the plugin in action! diff --git a/plugins/octopus-deploy/api-report.md b/plugins/octopus-deploy/api-report.md new file mode 100644 index 0000000000..82512ebcef --- /dev/null +++ b/plugins/octopus-deploy/api-report.md @@ -0,0 +1,86 @@ +## API Report File for "@backstage/plugin-octopus-deploy" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { ApiRef } from '@backstage/core-plugin-api'; +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; +import { FetchApi } from '@backstage/core-plugin-api'; + +// @public (undocumented) +export const EntityOctopusDeployContent: (props: { + defaultLimit?: number | undefined; +}) => JSX.Element; + +// @public (undocumented) +export const isOctopusDeployAvailable: (entity: Entity) => boolean; + +// @public (undocumented) +export const OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION = 'octopus.com/project-id'; + +// @public (undocumented) +export interface OctopusDeployApi { + // (undocumented) + getReleaseProgression( + projectId: string, + releaseHistoryCount: number, + ): Promise; +} + +// @public (undocumented) +export const octopusDeployApiRef: ApiRef; + +// @public (undocumented) +export class OctopusDeployClient implements OctopusDeployApi { + constructor(options: { + discoveryApi: DiscoveryApi; + fetchApi: FetchApi; + proxyPathBase?: string; + }); + // (undocumented) + getReleaseProgression( + projectId: string, + releaseHistoryCount: number, + ): Promise; +} + +// @public (undocumented) +export type OctopusDeployment = { + State: string; +}; + +// @public (undocumented) +export const octopusDeployPlugin: BackstagePlugin<{}, {}, {}>; + +// @public (undocumented) +export type OctopusEnvironment = { + Id: string; + Name: string; +}; + +// @public (undocumented) +export type OctopusProgression = { + Environments: OctopusEnvironment[]; + Releases: OctopusReleaseProgression[]; +}; + +// @public (undocumented) +export type OctopusRelease = { + Id: string; + Version: string; +}; + +// @public (undocumented) +export type OctopusReleaseProgression = { + Release: OctopusRelease; + Deployments: { + [key: string]: OctopusDeployment[]; + }; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/octopus-deploy/dev/index.tsx b/plugins/octopus-deploy/dev/index.tsx new file mode 100644 index 0000000000..d3d6cb3215 --- /dev/null +++ b/plugins/octopus-deploy/dev/index.tsx @@ -0,0 +1,28 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { octopusDeployPlugin } from '../src/plugin'; +import { EntityPageOctopusDeploy } from '../src/components/EntityPageOctopusDeploy'; + +createDevApp() + .registerPlugin(octopusDeployPlugin) + .addPage({ + element: , + title: 'Root Page', + path: '/octopus-deploy', + }) + .render(); diff --git a/plugins/octopus-deploy/package.json b/plugins/octopus-deploy/package.json new file mode 100644 index 0000000000..c469b55c38 --- /dev/null +++ b/plugins/octopus-deploy/package.json @@ -0,0 +1,53 @@ +{ + "name": "@backstage/plugin-octopus-deploy", + "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" + }, + "backstage": { + "role": "frontend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/catalog-model": "workspace:^", + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/plugin-catalog-react": "workspace:^", + "@backstage/theme": "workspace:^", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "4.0.0-alpha.57", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/node": "*", + "cross-fetch": "^3.1.5", + "msw": "^1.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/octopus-deploy/src/api/index.ts b/plugins/octopus-deploy/src/api/index.ts new file mode 100644 index 0000000000..9cba49d6c0 --- /dev/null +++ b/plugins/octopus-deploy/src/api/index.ts @@ -0,0 +1,118 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createApiRef, + DiscoveryApi, + FetchApi, +} from '@backstage/core-plugin-api'; + +/** @public */ +export type OctopusProgression = { + Environments: OctopusEnvironment[]; + Releases: OctopusReleaseProgression[]; +}; + +/** @public */ +export type OctopusEnvironment = { + Id: string; + Name: string; +}; + +/** @public */ +export type OctopusReleaseProgression = { + Release: OctopusRelease; + Deployments: { [key: string]: OctopusDeployment[] }; +}; + +/** @public */ +export type OctopusRelease = { + Id: string; + Version: string; +}; + +/** @public */ +export type OctopusDeployment = { + State: string; +}; + +/** @public */ +export const octopusDeployApiRef = createApiRef({ + id: 'plugin.octopusdeploy.service', +}); + +const DEFAULT_PROXY_PATH_BASE = '/octopus-deploy'; + +/** @public */ +export interface OctopusDeployApi { + getReleaseProgression( + projectId: string, + releaseHistoryCount: number, + ): Promise; +} + +/** @public */ +export class OctopusDeployClient implements OctopusDeployApi { + private readonly discoveryApi: DiscoveryApi; + private readonly fetchApi: FetchApi; + private readonly proxyPathBase: string; + + constructor(options: { + discoveryApi: DiscoveryApi; + fetchApi: FetchApi; + proxyPathBase?: string; + }) { + this.discoveryApi = options.discoveryApi; + this.fetchApi = options.fetchApi; + this.proxyPathBase = options.proxyPathBase ?? DEFAULT_PROXY_PATH_BASE; + } + + async getReleaseProgression( + projectId: string, + releaseHistoryCount: number, + ): Promise { + const url = await this.getApiUrl(projectId, releaseHistoryCount); + + const response = await this.fetchApi.fetch(url); + + let responseJson; + + try { + responseJson = await response.json(); + } catch (e) { + responseJson = { releases: [] }; + } + + if (response.status !== 200) { + throw new Error( + `Error communicating with Octopus Deploy: ${ + responseJson?.error?.title || response.statusText + }`, + ); + } + + return responseJson; + } + + private async getApiUrl(projectId: string, releaseHistoryCount: number) { + const proxyUrl = await this.discoveryApi.getBaseUrl('proxy'); + const queryParameters = new URLSearchParams({ + releaseHistoryCount: releaseHistoryCount.toString(), + }); + return `${proxyUrl}${this.proxyPathBase}/projects/${encodeURIComponent( + projectId, + )}/progression?${queryParameters}`; + } +} diff --git a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx new file mode 100644 index 0000000000..de28edb9e0 --- /dev/null +++ b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/EntityPageOctopusDeploy.tsx @@ -0,0 +1,40 @@ +/* + * 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 { useEntity } from '@backstage/plugin-catalog-react'; +import { useReleases } from '../../hooks/useReleases'; +import { getAnnotationFromEntity } from '../../utils/getAnnotationFromEntity'; +import React from 'react'; +import { ReleaseTable } from '../ReleaseTable'; + +export const EntityPageOctopusDeploy = (props: { defaultLimit?: number }) => { + const { entity } = useEntity(); + + const projectId = getAnnotationFromEntity(entity); + + const { environments, releases, loading, error } = useReleases( + projectId, + props.defaultLimit ?? 3, + ); + + return ( + + ); +}; diff --git a/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts new file mode 100644 index 0000000000..e168735130 --- /dev/null +++ b/plugins/octopus-deploy/src/components/EntityPageOctopusDeploy/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { EntityPageOctopusDeploy } from './EntityPageOctopusDeploy'; diff --git a/plugins/octopus-deploy/src/components/ReleaseTable/ReleaseTable.tsx b/plugins/octopus-deploy/src/components/ReleaseTable/ReleaseTable.tsx new file mode 100644 index 0000000000..dfda291e1a --- /dev/null +++ b/plugins/octopus-deploy/src/components/ReleaseTable/ReleaseTable.tsx @@ -0,0 +1,150 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Box, Typography } from '@material-ui/core'; +import { OctopusEnvironment, OctopusReleaseProgression } from '../../api'; + +import React from 'react'; +import { + ResponseErrorPanel, + StatusAborted, + StatusError, + StatusOK, + StatusPending, + StatusRunning, + StatusWarning, + Table, + TableColumn, +} from '@backstage/core-components'; + +type ReleaseTableProps = { + environments?: OctopusEnvironment[]; + releases?: OctopusReleaseProgression[]; + loading: boolean; + error?: Error; +}; + +export const getDeploymentStatusComponent = (state: string | undefined) => { + switch (state) { + case 'Success': + return ( + + Success + + ); + case 'Queued': + return ( + + Queued + + ); + case 'Executing': + return ( + + Executing + + ); + case 'Failed': + return ( + + Failed + + ); + case 'Cancelling': + return ( + + Cancelling + + ); + case 'Canceled': + return ( + + Canceled + + ); + case 'TimedOut': + return ( + + Timed Out + + ); + default: + return ( + + Unknown + + ); + } +}; + +export const ReleaseTable = ({ + environments, + releases, + loading, + error, +}: ReleaseTableProps) => { + if (error) { + return ; + } + + const columns: TableColumn[] = [ + { + title: 'Version', + field: 'Release.Version', + highlight: false, + width: 'auto', + }, + ...(environments?.map(env => ({ + title: env.Name, + width: 'auto', + render: (row: Partial) => { + const deploymentsForEnvironment = row.Deployments + ? row.Deployments[env.Id] + : null; + if (deploymentsForEnvironment) { + return ( + + + {getDeploymentStatusComponent( + deploymentsForEnvironment[0].State, + )} + + + ); + } + return ; + }, + })) ?? []), + ]; + + return ( + + Octopus Deploy - Releases ({releases ? releases.length : 0}) + + } + data={releases ?? []} + /> + ); +}; diff --git a/plugins/octopus-deploy/src/components/ReleaseTable/index.ts b/plugins/octopus-deploy/src/components/ReleaseTable/index.ts new file mode 100644 index 0000000000..d0c679a48e --- /dev/null +++ b/plugins/octopus-deploy/src/components/ReleaseTable/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { ReleaseTable } from './ReleaseTable'; diff --git a/plugins/octopus-deploy/src/constants.ts b/plugins/octopus-deploy/src/constants.ts new file mode 100644 index 0000000000..3bdc48252f --- /dev/null +++ b/plugins/octopus-deploy/src/constants.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @public */ +export const OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION = 'octopus.com/project-id'; diff --git a/plugins/octopus-deploy/src/hooks/useReleases.ts b/plugins/octopus-deploy/src/hooks/useReleases.ts new file mode 100644 index 0000000000..742ce78dca --- /dev/null +++ b/plugins/octopus-deploy/src/hooks/useReleases.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { useApi } from '@backstage/core-plugin-api'; +import useAsync from 'react-use/lib/useAsync'; +import { + octopusDeployApiRef, + OctopusEnvironment, + OctopusReleaseProgression, +} from '../api'; + +export function useReleases( + projectId: string, + releaseHistoryCount: number, +): { + environments?: OctopusEnvironment[]; + releases?: OctopusReleaseProgression[]; + loading: boolean; + error?: Error; +} { + const api = useApi(octopusDeployApiRef); + + const { value, loading, error } = useAsync(() => { + return api.getReleaseProgression(projectId, releaseHistoryCount); + }, [api, projectId, releaseHistoryCount]); + + return { + environments: value?.Environments, + releases: value?.Releases, + loading, + error, + }; +} diff --git a/plugins/octopus-deploy/src/index.ts b/plugins/octopus-deploy/src/index.ts new file mode 100644 index 0000000000..e3264efaf0 --- /dev/null +++ b/plugins/octopus-deploy/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { + octopusDeployPlugin, + EntityOctopusDeployContent, + isOctopusDeployAvailable, +} from './plugin'; + +export * from './api'; + +export { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from './constants'; diff --git a/plugins/octopus-deploy/src/plugin.test.ts b/plugins/octopus-deploy/src/plugin.test.ts new file mode 100644 index 0000000000..a18e74f689 --- /dev/null +++ b/plugins/octopus-deploy/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { octopusDeployPlugin } from './plugin'; + +describe('octopus-deploy', () => { + it('should export plugin', () => { + expect(octopusDeployPlugin).toBeDefined(); + }); +}); diff --git a/plugins/octopus-deploy/src/plugin.ts b/plugins/octopus-deploy/src/plugin.ts new file mode 100644 index 0000000000..9365f93bdb --- /dev/null +++ b/plugins/octopus-deploy/src/plugin.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from './constants'; +import { octopusDeployEntityContentRouteRef } from './routes'; + +import { OctopusDeployClient, octopusDeployApiRef } from './api'; + +import { + createApiFactory, + createPlugin, + createRoutableExtension, + discoveryApiRef, + fetchApiRef, +} from '@backstage/core-plugin-api'; + +import { Entity } from '@backstage/catalog-model'; + +/** @public */ +export const isOctopusDeployAvailable = (entity: Entity) => + Boolean(entity.metadata.annotations?.[OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION]); + +/** @public */ +export const octopusDeployPlugin = createPlugin({ + id: 'octopus-deploy', + apis: [ + createApiFactory({ + api: octopusDeployApiRef, + deps: { discoveryApi: discoveryApiRef, fetchApi: fetchApiRef }, + factory: ({ discoveryApi, fetchApi }) => + new OctopusDeployClient({ discoveryApi, fetchApi }), + }), + ], +}); + +/** @public */ +export const EntityOctopusDeployContent = octopusDeployPlugin.provide( + createRoutableExtension({ + name: 'EntityOctopusDeployContent', + component: () => + import('./components/EntityPageOctopusDeploy').then( + m => m.EntityPageOctopusDeploy, + ), + mountPoint: octopusDeployEntityContentRouteRef, + }), +); diff --git a/plugins/octopus-deploy/src/routes.ts b/plugins/octopus-deploy/src/routes.ts new file mode 100644 index 0000000000..824b6ae113 --- /dev/null +++ b/plugins/octopus-deploy/src/routes.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRouteRef } from '@backstage/core-plugin-api'; + +export const octopusDeployEntityContentRouteRef = createRouteRef({ + id: 'octopus-deploy-entity-content', +}); diff --git a/plugins/octopus-deploy/src/setupTests.ts b/plugins/octopus-deploy/src/setupTests.ts new file mode 100644 index 0000000000..73dd8dce47 --- /dev/null +++ b/plugins/octopus-deploy/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; diff --git a/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts b/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts new file mode 100644 index 0000000000..e59a32235f --- /dev/null +++ b/plugins/octopus-deploy/src/utils/getAnnotationFromEntity.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION } from '../constants'; + +import { Entity } from '@backstage/catalog-model'; + +export function getAnnotationFromEntity(entity: Entity): string { + const annotation = + entity.metadata.annotations?.[OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION]; + if (!annotation) { + throw new Error( + `Value for annotation ${OCTOPUS_DEPLOY_PROJECT_ID_ANNOTATION} was not found`, + ); + } + + return annotation; +} diff --git a/plugins/org-react/CHANGELOG.md b/plugins/org-react/CHANGELOG.md index 6af5e01b9b..54fd9629ce 100644 --- a/plugins/org-react/CHANGELOG.md +++ b/plugins/org-react/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-org-react +## 0.1.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.1.4 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + ## 0.1.4-next.2 ### Patch Changes diff --git a/plugins/org-react/package.json b/plugins/org-react/package.json index 6e939b1954..42dd6c1f26 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.4-next.2", + "version": "0.1.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -54,7 +54,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/org/CHANGELOG.md b/plugins/org/CHANGELOG.md index 31c7843fa4..2fd85644ff 100644 --- a/plugins/org/CHANGELOG.md +++ b/plugins/org/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-org +## 0.6.6-next.0 + +### Patch Changes + +- 36bccb5252: Fix small UI-glitch in MemberListCard +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.6.5 + +### Patch Changes + +- 5a4fa8859b: Updated `LinksGroup` to use `Link` over `ListItem` as this makes the links more obvious and follows the pattern already used in the `GroupProfileCard`. Also updated the `GroupProfileCard` `ExtraDetails` story in Storybook to enable the `showLinks` feature with this off there is no difference between it and the `default` story. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.6.5-next.2 ### Patch Changes diff --git a/plugins/org/package.json b/plugins/org/package.json index 240e473b88..c1a4e8b1e5 100644 --- a/plugins/org/package.json +++ b/plugins/org/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-org", "description": "A Backstage plugin that helps you create entity pages for your organization", - "version": "0.6.5-next.2", + "version": "0.6.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -56,7 +56,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx index cfb3d847a4..f183ab4d8e 100644 --- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx +++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.stories.tsx @@ -123,7 +123,7 @@ export const ExtraDetails = () => ( - + diff --git a/plugins/org/src/components/Cards/Meta/LinksGroup.tsx b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx index eeade18411..dfc654c14b 100644 --- a/plugins/org/src/components/Cards/Meta/LinksGroup.tsx +++ b/plugins/org/src/components/Cards/Meta/LinksGroup.tsx @@ -23,6 +23,7 @@ import { Divider, } from '@material-ui/core'; import React from 'react'; +import { Link } from '@backstage/core-components'; const WebLink = ({ href, @@ -33,9 +34,11 @@ const WebLink = ({ text?: string; Icon?: IconComponent; }) => ( - + {Icon ? : } - {text} + + {text} + ); diff --git a/plugins/pagerduty/CHANGELOG.md b/plugins/pagerduty/CHANGELOG.md index f9424baaea..a69e2da666 100644 --- a/plugins/pagerduty/CHANGELOG.md +++ b/plugins/pagerduty/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-pagerduty +## 0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.5.8 + +### Patch Changes + +- 804746dd58: The PagerDutyCard now supports an optional `readOnly` property (``) for suppressing the rendering of the "Create Incident" button from the Backstage UI. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + ## 0.5.8-next.2 ### Patch Changes diff --git a/plugins/pagerduty/README.md b/plugins/pagerduty/README.md index 98f769e9f3..ac3ba529dd 100644 --- a/plugins/pagerduty/README.md +++ b/plugins/pagerduty/README.md @@ -16,7 +16,7 @@ # Support -If you need help with this plugin, please reach out on the [Backstage Discord server](https://discord.gg/MUpMjP2). +If you need help with this plugin, please reach out on the [Backstage Discord server](https://discord.gg/backstage-687207715902193673). # Integration Walk-through diff --git a/plugins/pagerduty/dev/index.tsx b/plugins/pagerduty/dev/index.tsx index 676eb687a4..e45e0ffd8f 100644 --- a/plugins/pagerduty/dev/index.tsx +++ b/plugins/pagerduty/dev/index.tsx @@ -13,7 +13,153 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { createDevApp } from '@backstage/dev-utils'; -import { pagerDutyPlugin } from '../src/plugin'; -createDevApp().registerPlugin(pagerDutyPlugin).render(); +import React from 'react'; +import { Entity } from '@backstage/catalog-model'; +import { EntityProvider } from '@backstage/plugin-catalog-react'; +import { createDevApp } from '@backstage/dev-utils'; +import { pagerDutyPlugin, EntityPagerDutyCard } from '../src/plugin'; +import { pagerDutyApiRef } from '../src/api'; +import { PagerDutyApi, PagerDutyTriggerAlarmRequest } from '../src/api/types'; +import { + PagerDutyIncident, + PagerDutyChangeEvent, +} from '../src/components/types'; + +const mockEntity: Entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'backstage', + description: 'backstage.io', + annotations: { + 'github.com/project-slug': 'backstage/backstage', + 'pagerduty.com/service-id': 'foo', + 'pagerduty.com/integration-key': 'foo', + }, + }, + spec: { + lifecycle: 'production', + type: 'website', + owner: 'user:guest', + }, +}; + +const mockPagerDutyApi: PagerDutyApi = { + async getServiceByEntity(entity: Entity) { + return { + service: { + name: entity.metadata.name, + integrationKey: 'key', + id: '123', + html_url: 'http://service', + escalation_policy: { + id: '123', + html_url: 'http://escalationpolicy', + user: { + id: '123', + summary: 'summary', + email: 'email@email.com', + html_url: 'http://user', + name: 'some-user', + }, + }, + }, + }; + }, + + async getIncidentsByServiceId(serviceId: string) { + const incident = (title: string) => { + return { + id: '123', + title: title, + status: 'acknowledged', + html_url: 'http://incident', + assignments: [ + { + assignee: { + id: '123', + summary: 'Jane Doe', + html_url: 'http://assignee', + }, + }, + ], + serviceId: serviceId, + created_at: '2015-10-06T21:30:42Z', + } as PagerDutyIncident; + }; + + return { + incidents: [ + incident('Some Alerting Incident'), + incident('Another Alerting Incident'), + ], + }; + }, + + async getChangeEventsByServiceId(serviceId: string) { + const changeEvent = (description: string) => { + return { + id: serviceId, + source: 'some-source', + html_url: 'http://changeevent', + links: [ + { + href: 'http://link', + text: 'link text', + }, + ], + summary: description, + timestamp: '2018-10-06T21:30:42Z', + } as PagerDutyChangeEvent; + }; + + return { + change_events: [ + changeEvent('us-east-1 deployment'), + changeEvent('us-west-2 deployment'), + ], + }; + }, + + async getOnCallByPolicyId() { + const oncall = (name: string, escalation: number) => { + return { + user: { + id: '123', + name: name, + html_url: 'http://assignee', + summary: 'summary', + email: 'email@email.com', + }, + escalation_level: escalation, + }; + }; + + return { + oncalls: [oncall('Jane Doe', 1), oncall('John Doe', 2)], + }; + }, + + async triggerAlarm(request: PagerDutyTriggerAlarmRequest) { + return new Response(request.description); + }, +}; + +createDevApp() + .registerApi({ + api: pagerDutyApiRef, + deps: {}, + factory: () => mockPagerDutyApi, + }) + .registerPlugin(pagerDutyPlugin) + .addPage({ + path: '/pagerduty', + title: 'PagerDuty', + element: ( + + + + ), + }) + .render(); diff --git a/plugins/pagerduty/package.json b/plugins/pagerduty/package.json index df20b498ed..f248c6f31f 100644 --- a/plugins/pagerduty/package.json +++ b/plugins/pagerduty/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-pagerduty", "description": "A Backstage plugin that integrates towards PagerDuty", - "version": "0.5.8-next.2", + "version": "0.5.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -61,7 +61,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/periskop-backend/CHANGELOG.md b/plugins/periskop-backend/CHANGELOG.md index 1e6ff6f307..55769cb201 100644 --- a/plugins/periskop-backend/CHANGELOG.md +++ b/plugins/periskop-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-periskop-backend +## 0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + +## 0.1.13 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + ## 0.1.13-next.2 ### Patch Changes diff --git a/plugins/periskop-backend/package.json b/plugins/periskop-backend/package.json index 419d430fac..0472be43b0 100644 --- a/plugins/periskop-backend/package.json +++ b/plugins/periskop-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop-backend", - "version": "0.1.13-next.2", + "version": "0.1.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -37,7 +37,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/periskop/CHANGELOG.md b/plugins/periskop/CHANGELOG.md index eeabe21052..1a700f5aa0 100644 --- a/plugins/periskop/CHANGELOG.md +++ b/plugins/periskop/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-periskop +## 0.1.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.1.13 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + ## 0.1.13-next.2 ### Patch Changes diff --git a/plugins/periskop/package.json b/plugins/periskop/package.json index 08d875e51f..eba10dc41e 100644 --- a/plugins/periskop/package.json +++ b/plugins/periskop/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-periskop", - "version": "0.1.13-next.2", + "version": "0.1.14-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -50,7 +50,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/permission-backend/CHANGELOG.md b/plugins/permission-backend/CHANGELOG.md index f8cb24795b..87be1e49e1 100644 --- a/plugins/permission-backend/CHANGELOG.md +++ b/plugins/permission-backend/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-permission-backend +## 0.5.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + +## 0.5.17 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + ## 0.5.17-next.2 ### Patch Changes diff --git a/plugins/permission-backend/package.json b/plugins/permission-backend/package.json index b0b54f6b6e..eaa2f6ddd1 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.17-next.2", + "version": "0.5.18-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -42,7 +42,7 @@ "@backstage/cli": "workspace:^", "@types/lodash": "^4.14.151", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index 472a86aaab..960ca249d3 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -50,6 +50,6 @@ }, "devDependencies": { "@backstage/cli": "workspace:^", - "msw": "^0.49.0" + "msw": "^1.0.0" } } diff --git a/plugins/permission-node/CHANGELOG.md b/plugins/permission-node/CHANGELOG.md index 51c27671db..8d2789e615 100644 --- a/plugins/permission-node/CHANGELOG.md +++ b/plugins/permission-node/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-permission-node +## 0.7.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + +## 0.7.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + ## 0.7.5-next.2 ### Patch Changes diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md index 3f712fe362..569fb5c6ea 100644 --- a/plugins/permission-node/api-report.md +++ b/plugins/permission-node/api-report.md @@ -137,17 +137,17 @@ export const createPermissionRule: < rule: PermissionRule, ) => PermissionRule; -// @alpha +// @public export const isAndCriteria: ( criteria: PermissionCriteria, ) => criteria is AllOfCriteria; -// @alpha +// @public export const isNotCriteria: ( criteria: PermissionCriteria, ) => criteria is NotCriteria; -// @alpha +// @public export const isOrCriteria: ( criteria: PermissionCriteria, ) => criteria is AnyOfCriteria; diff --git a/plugins/permission-node/package.json b/plugins/permission-node/package.json index c43904fd00..673250cd19 100644 --- a/plugins/permission-node/package.json +++ b/plugins/permission-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-permission-node", "description": "Common permission and authorization utilities for backend plugins", - "version": "0.7.5-next.2", + "version": "0.7.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -48,7 +48,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/permission-node/src/integration/util.ts b/plugins/permission-node/src/integration/util.ts index e448068e17..9be90e15fc 100644 --- a/plugins/permission-node/src/integration/util.ts +++ b/plugins/permission-node/src/integration/util.ts @@ -33,7 +33,7 @@ export type NoInfer = T extends infer S ? S : never; /** * Utility function used to parse a PermissionCriteria * @param criteria - a PermissionCriteria - * @alpha + * @public * * @returns `true` if the permission criteria is of type allOf, * narrowing down `criteria` to the specific type. @@ -46,7 +46,7 @@ export const isAndCriteria = ( /** * Utility function used to parse a PermissionCriteria of type * @param criteria - a PermissionCriteria - * @alpha + * @public * * @returns `true` if the permission criteria is of type anyOf, * narrowing down `criteria` to the specific type. @@ -59,7 +59,7 @@ export const isOrCriteria = ( /** * Utility function used to parse a PermissionCriteria * @param criteria - a PermissionCriteria - * @alpha + * @public * * @returns `true` if the permission criteria is of type not, * narrowing down `criteria` to the specific type. diff --git a/plugins/permission-react/CHANGELOG.md b/plugins/permission-react/CHANGELOG.md index 4093b6a430..914552da32 100644 --- a/plugins/permission-react/CHANGELOG.md +++ b/plugins/permission-react/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-permission-react +## 0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-permission-common@0.7.3 + +## 0.4.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/plugin-permission-common@0.7.3 + ## 0.4.9 ### Patch Changes diff --git a/plugins/permission-react/package.json b/plugins/permission-react/package.json index beef8e093d..dcf45270f4 100644 --- a/plugins/permission-react/package.json +++ b/plugins/permission-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-permission-react", - "version": "0.4.9", + "version": "0.4.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/playlist-backend/CHANGELOG.md b/plugins/playlist-backend/CHANGELOG.md index c634e3c2e0..9dcf4493ea 100644 --- a/plugins/playlist-backend/CHANGELOG.md +++ b/plugins/playlist-backend/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-playlist-backend +## 0.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + - @backstage/plugin-playlist-common@0.1.4 + +## 0.2.5 + +### Patch Changes + +- b977c2e69f: Minor improvements to the descriptions provided with permission rules schemas +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + - @backstage/plugin-playlist-common@0.1.4 + ## 0.2.5-next.2 ### Patch Changes diff --git a/plugins/playlist-backend/package.json b/plugins/playlist-backend/package.json index cc3e62eb5a..b4232ff786 100644 --- a/plugins/playlist-backend/package.json +++ b/plugins/playlist-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist-backend", - "version": "0.2.5-next.2", + "version": "0.2.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -45,7 +45,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/playlist/CHANGELOG.md b/plugins/playlist/CHANGELOG.md index ea27ee40f3..e6d1a1d809 100644 --- a/plugins/playlist/CHANGELOG.md +++ b/plugins/playlist/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-playlist +## 0.1.7-next.0 + +### Patch Changes + +- 122a37a880: Internal update to work with newer versions of react-router +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.11-next.0 + - @backstage/plugin-playlist-common@0.1.4 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 0.1.6 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/errors@1.1.4 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-react@0.4.10 + - @backstage/plugin-playlist-common@0.1.4 + ## 0.1.6-next.2 ### Patch Changes diff --git a/plugins/playlist/package.json b/plugins/playlist/package.json index 624fdbcd75..0cf67652f3 100644 --- a/plugins/playlist/package.json +++ b/plugins/playlist/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-playlist", - "version": "0.1.6-next.2", + "version": "0.1.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -61,7 +61,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.49.0", + "msw": "^1.0.0", "swr": "^2.0.0" }, "files": [ diff --git a/plugins/playlist/src/components/PlaylistCard/PlaylistCard.tsx b/plugins/playlist/src/components/PlaylistCard/PlaylistCard.tsx index 2db7e85f7e..1bf698f6be 100644 --- a/plugins/playlist/src/components/PlaylistCard/PlaylistCard.tsx +++ b/plugins/playlist/src/components/PlaylistCard/PlaylistCard.tsx @@ -15,8 +15,8 @@ */ import { - Button, ItemCardHeader, + LinkButton, MarkdownContent, } from '@backstage/core-components'; import { useRouteRef } from '@backstage/core-plugin-api'; @@ -118,13 +118,13 @@ export const PlaylistCard = ({ playlist }: PlaylistCardProps) => { - + ); diff --git a/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx b/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx index 05dd4da231..fe08870bcd 100644 --- a/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx +++ b/plugins/playlist/src/components/PlaylistPage/AddEntitiesDrawer.tsx @@ -102,12 +102,16 @@ export const AddEntitiesDrawer = ({ const entityRoute = useRouteRef(entityRouteRef); const entityLocationRegex = useMemo(() => { const forwardSlashRegex = new RegExp('/', 'g'); + // We need to do this in two steps, since entityRoute will ruin some special chars, like question marks const locationRegex = entityRoute({ - namespace: '(?.+?)', - kind: '(?.+?)', - name: '(?.+?)', - }).replace(forwardSlashRegex, '\\/'); - + namespace: '__REPLACE_WITH_NAMESPACE__', + kind: '__REPLACE_WITH_KIND__', + name: '__REPLACE_WITH_NAME__', + }) + .replace('__REPLACE_WITH_NAMESPACE__', '(?.+?)') + .replace('__REPLACE_WITH_KIND__', '(?.+?)') + .replace('__REPLACE_WITH_NAME__', '(?.+?)') + .replace(forwardSlashRegex, '\\/'); return new RegExp(`${locationRegex}$`); }, [entityRoute]); @@ -127,12 +131,12 @@ export const AddEntitiesDrawer = ({ const addEntity = useCallback( entityResult => { - // TODO (kuangp): this parsing of the location is not great. Ideally `CatalogEntityDocument` + // TODO(kuangp): this parsing of the location is not great. Ideally `CatalogEntityDocument` // contains the `metadata.name` field so we can derive the full ref and we only fall back to // parsing location if it's missing (ie. for older versions) - const { groups } = entityResult.location.match(entityLocationRegex); - if (groups) { - onAdd(stringifyEntityRef(groups)); + const match = entityResult.location.match(entityLocationRegex); + if (match?.groups) { + onAdd(stringifyEntityRef(match?.groups)); } else { // eslint-disable-next-line no-console console.error( diff --git a/plugins/proxy-backend/CHANGELOG.md b/plugins/proxy-backend/CHANGELOG.md index ad235f36e8..2f5c46445a 100644 --- a/plugins/proxy-backend/CHANGELOG.md +++ b/plugins/proxy-backend/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-proxy-backend +## 0.2.37-next.0 + +### Patch Changes + +- 3e3eea4bc7: The proxy-backend plugin now supports reviving request bodies that have previously been consumed by an express middleware (e.g. `express.json()`). This is done by setting `reviveConsumedRequestBodies: true` on the proxy `RouterOptions`. In order to preserve the current behavior, the proxy will **not** revive request bodies by default. + + The following is an example of a proxy `createRouter` invocation that revives request bodies: + + ```diff + const router = await createRouter({ + config, + logger, + discovery, + + reviveConsumedRequestBodies: true, + }); + ``` + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + +## 0.2.36 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + ## 0.2.36-next.2 ### Patch Changes diff --git a/plugins/proxy-backend/api-report.md b/plugins/proxy-backend/api-report.md index 741f7c3b54..12d799bdf7 100644 --- a/plugins/proxy-backend/api-report.md +++ b/plugins/proxy-backend/api-report.md @@ -17,6 +17,7 @@ export const proxyPlugin: ( options?: | { skipInvalidProxies?: boolean | undefined; + reviveConsumedRequestBodies?: boolean | undefined; } | undefined, ) => BackendFeature; @@ -30,6 +31,8 @@ export interface RouterOptions { // (undocumented) logger: Logger; // (undocumented) + reviveConsumedRequestBodies?: boolean; + // (undocumented) skipInvalidProxies?: boolean; } ``` diff --git a/plugins/proxy-backend/package.json b/plugins/proxy-backend/package.json index 76440ce0a9..a08900fd83 100644 --- a/plugins/proxy-backend/package.json +++ b/plugins/proxy-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-proxy-backend", "description": "A Backstage backend plugin that helps you set up proxy endpoints in the backend", - "version": "0.2.36-next.2", + "version": "0.2.37-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -53,7 +53,7 @@ "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", "@types/yup": "^0.29.13", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/proxy-backend/src/plugin.ts b/plugins/proxy-backend/src/plugin.ts index d095bee527..66eeb4a7b2 100644 --- a/plugins/proxy-backend/src/plugin.ts +++ b/plugins/proxy-backend/src/plugin.ts @@ -27,7 +27,10 @@ import { createRouter } from './service/router'; * @alpha */ export const proxyPlugin = createBackendPlugin( - (options?: { skipInvalidProxies?: boolean }) => ({ + (options?: { + skipInvalidProxies?: boolean; + reviveConsumedRequestBodies?: boolean; + }) => ({ pluginId: 'proxy', register(env) { env.registerInit({ @@ -44,6 +47,7 @@ export const proxyPlugin = createBackendPlugin( discovery, logger: loggerToWinstonLogger(logger), skipInvalidProxies: options?.skipInvalidProxies, + reviveConsumedRequestBodies: options?.reviveConsumedRequestBodies, }), ); }, diff --git a/plugins/proxy-backend/src/service/router.test.ts b/plugins/proxy-backend/src/service/router.test.ts index afe78aebeb..9e8c909d25 100644 --- a/plugins/proxy-backend/src/service/router.test.ts +++ b/plugins/proxy-backend/src/service/router.test.ts @@ -18,11 +18,16 @@ import { getVoidLogger, SingleHostDiscovery } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { Request, Response } from 'express'; import * as http from 'http'; -import { createProxyMiddleware, Options } from 'http-proxy-middleware'; +import { + createProxyMiddleware, + fixRequestBody, + Options, +} from 'http-proxy-middleware'; import { buildMiddleware, createRouter } from './router'; jest.mock('http-proxy-middleware', () => ({ createProxyMiddleware: jest.fn(() => () => undefined), + fixRequestBody: jest.fn(), })); const mockCreateProxyMiddleware = createProxyMiddleware as jest.MockedFunction< @@ -31,25 +36,30 @@ const mockCreateProxyMiddleware = createProxyMiddleware as jest.MockedFunction< describe('createRouter', () => { describe('where all proxy config are valid', () => { + const logger = getVoidLogger(); + const config = new ConfigReader({ + backend: { + baseUrl: 'https://example.com:7007', + listen: { + port: 7007, + }, + }, + proxy: { + '/test': { + target: 'https://example.com', + headers: { + Authorization: 'Bearer supersecret', + }, + }, + }, + }); + const discovery = SingleHostDiscovery.fromConfig(config); + + beforeEach(() => { + mockCreateProxyMiddleware.mockClear(); + }); + it('works', async () => { - const logger = getVoidLogger(); - const config = new ConfigReader({ - backend: { - baseUrl: 'https://example.com:7007', - listen: { - port: 7007, - }, - }, - proxy: { - '/test': { - target: 'https://example.com', - headers: { - Authorization: 'Bearer supersecret', - }, - }, - }, - }); - const discovery = SingleHostDiscovery.fromConfig(config); const router = await createRouter({ config, logger, @@ -57,6 +67,36 @@ describe('createRouter', () => { }); expect(router).toBeDefined(); }); + + it('revives request bodies when set', async () => { + const router = await createRouter({ + config, + logger, + discovery, + reviveConsumedRequestBodies: true, + }); + expect(router).toBeDefined(); + + expect( + mockCreateProxyMiddleware.mock.calls[0][1]?.onProxyReq, + ).toBeDefined(); + expect(mockCreateProxyMiddleware.mock.calls[0][1]?.onProxyReq).toEqual( + fixRequestBody, + ); + }); + + it('does not revive request bodies when not set', async () => { + const router = await createRouter({ + config, + logger, + discovery, + }); + expect(router).toBeDefined(); + + expect( + mockCreateProxyMiddleware.mock.calls[0][1]?.onProxyReq, + ).not.toBeDefined(); + }); }); describe('where buildMiddleware would fail', () => { @@ -389,6 +429,46 @@ describe('buildMiddleware', () => { expect(Object.keys(testClientResponse.headers!)).toEqual(['set-cookie']); }); + it('revives request body when configured', async () => { + buildMiddleware( + '/proxy', + logger, + '/test', + { + target: 'http://mocked', + }, + true, + ); + + expect(createProxyMiddleware).toHaveBeenCalledTimes(1); + + const config = mockCreateProxyMiddleware.mock.calls[0][1] as Options; + + expect(config).toBeDefined(); + expect(config.onProxyReq).toBeDefined(); + + config.onProxyReq!( + {} as http.ClientRequest, + {} as Request, + {} as Response, + {}, + ); + expect(fixRequestBody).toHaveBeenCalledTimes(1); + }); + + it('does not revive request body when not configured', async () => { + buildMiddleware('/proxy', logger, '/test', { + target: 'http://mocked', + }); + + expect(createProxyMiddleware).toHaveBeenCalledTimes(1); + + const config = mockCreateProxyMiddleware.mock.calls[0][1] as Options; + + expect(config).toBeDefined(); + expect(config.onProxyReq).not.toBeDefined(); + }); + it('rejects malformed target URLs', async () => { expect(() => buildMiddleware('/proxy', logger, '/test', 'backstage.io'), diff --git a/plugins/proxy-backend/src/service/router.ts b/plugins/proxy-backend/src/service/router.ts index 224c2c6202..b669e82f3f 100644 --- a/plugins/proxy-backend/src/service/router.ts +++ b/plugins/proxy-backend/src/service/router.ts @@ -19,6 +19,7 @@ import express from 'express'; import Router from 'express-promise-router'; import { createProxyMiddleware, + fixRequestBody, Options, RequestHandler, } from 'http-proxy-middleware'; @@ -53,11 +54,13 @@ export interface RouterOptions { config: Config; discovery: PluginEndpointDiscovery; skipInvalidProxies?: boolean; + reviveConsumedRequestBodies?: boolean; } export interface ProxyConfig extends Options { allowedMethods?: string[]; allowedHeaders?: string[]; + reviveRequestBody?: boolean; } // Creates a proxy middleware, possibly with defaults added on top of the @@ -67,6 +70,7 @@ export function buildMiddleware( logger: Logger, route: string, config: string | ProxyConfig, + reviveConsumedRequestBodies?: boolean, ): RequestHandler { const fullConfig = typeof config === 'string' ? { target: config } : { ...config }; @@ -175,6 +179,10 @@ export function buildMiddleware( }); }; + if (reviveConsumedRequestBodies) { + fullConfig.onProxyReq = fixRequestBody; + } + return createProxyMiddleware(filter, fullConfig); } @@ -242,7 +250,13 @@ function configureMiddlewares( try { router.use( route, - buildMiddleware(pathPrefix, options.logger, route, proxyRouteConfig), + buildMiddleware( + pathPrefix, + options.logger, + route, + proxyRouteConfig, + options.reviveConsumedRequestBodies, + ), ); } catch (e) { if (options.skipInvalidProxies) { diff --git a/plugins/rollbar-backend/CHANGELOG.md b/plugins/rollbar-backend/CHANGELOG.md index 9e6955c033..41a5df307f 100644 --- a/plugins/rollbar-backend/CHANGELOG.md +++ b/plugins/rollbar-backend/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-rollbar-backend +## 0.1.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + +## 0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + ## 0.1.39-next.2 ### Patch Changes diff --git a/plugins/rollbar-backend/package.json b/plugins/rollbar-backend/package.json index 876c797a78..7a2f27cea0 100644 --- a/plugins/rollbar-backend/package.json +++ b/plugins/rollbar-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar-backend", "description": "A Backstage backend plugin that integrates towards Rollbar", - "version": "0.1.39-next.2", + "version": "0.1.40-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -52,7 +52,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/rollbar/CHANGELOG.md b/plugins/rollbar/CHANGELOG.md index 1fe3b3d6ba..77235a2c74 100644 --- a/plugins/rollbar/CHANGELOG.md +++ b/plugins/rollbar/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-rollbar +## 0.4.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.4.15 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.4.15-next.2 ### Patch Changes diff --git a/plugins/rollbar/package.json b/plugins/rollbar/package.json index 2d65565015..f95f2cb8c4 100644 --- a/plugins/rollbar/package.json +++ b/plugins/rollbar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-rollbar", "description": "A Backstage plugin that integrates towards Rollbar", - "version": "0.4.15-next.2", + "version": "0.4.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -61,7 +61,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md index 65121ebda8..ed849b36f1 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-cookiecutter/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-scaffolder-backend-module-cookiecutter +## 0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.11.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## 0.2.17 + +### Patch Changes + +- d72866f0cc: Internal refactor to use the new `@backstage/plugin-scaffolder-node` package for some functionality +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/plugin-scaffolder-backend@1.11.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + ## 0.2.17-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-cookiecutter/package.json b/plugins/scaffolder-backend-module-cookiecutter/package.json index 669f498c1e..de055be7e8 100644 --- a/plugins/scaffolder-backend-module-cookiecutter/package.json +++ b/plugins/scaffolder-backend-module-cookiecutter/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-cookiecutter", "description": "A module for the scaffolder backend that lets you template projects using cookiecutter", - "version": "0.2.17-next.2", + "version": "0.2.18-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -41,7 +41,7 @@ "@types/fs-extra": "^9.0.1", "@types/mock-fs": "^4.13.0", "mock-fs": "^5.1.0", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/scaffolder-backend-module-rails/CHANGELOG.md b/plugins/scaffolder-backend-module-rails/CHANGELOG.md index 51a6a9b796..65cc7fa77d 100644 --- a/plugins/scaffolder-backend-module-rails/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-rails/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-scaffolder-backend-module-rails +## 0.4.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.11.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## 0.4.10 + +### Patch Changes + +- d72866f0cc: Internal refactor to use the new `@backstage/plugin-scaffolder-node` package for some functionality +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/plugin-scaffolder-backend@1.11.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + ## 0.4.10-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-rails/package.json b/plugins/scaffolder-backend-module-rails/package.json index 1e4d881ef0..2ae2a6dd3f 100644 --- a/plugins/scaffolder-backend-module-rails/package.json +++ b/plugins/scaffolder-backend-module-rails/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-backend-module-rails", "description": "A module for the scaffolder backend that lets you template projects using Rails", - "version": "0.4.10-next.2", + "version": "0.4.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md index 9a7df7e14b..059b43bd90 100644 --- a/plugins/scaffolder-backend-module-sentry/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-sentry/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-scaffolder-backend-module-sentry +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## 0.1.2 + +### Patch Changes + +- da418c89e4: Fix broken module exports and dependencies to match a backend module, rather than a frontend plugin. +- d72866f0cc: Internal refactor to use the new `@backstage/plugin-scaffolder-node` package for some functionality +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + ## 0.1.2-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-sentry/package.json b/plugins/scaffolder-backend-module-sentry/package.json index 903ad54dc1..8c1e2f5742 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.2-next.2", + "version": "0.1.3-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md index 5c4acbd85c..c099722329 100644 --- a/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md +++ b/plugins/scaffolder-backend-module-yeoman/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-scaffolder-backend-module-yeoman +## 0.2.16-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## 0.2.15 + +### Patch Changes + +- d72866f0cc: Internal refactor to use the new `@backstage/plugin-scaffolder-node` package for some functionality +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + ## 0.2.15-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend-module-yeoman/package.json b/plugins/scaffolder-backend-module-yeoman/package.json index 7ae88b60e6..6b609d8b39 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.2.15-next.2", + "version": "0.2.16-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-backend/CHANGELOG.md b/plugins/scaffolder-backend/CHANGELOG.md index d6db10f4ae..2d31ac43c1 100644 --- a/plugins/scaffolder-backend/CHANGELOG.md +++ b/plugins/scaffolder-backend/CHANGELOG.md @@ -1,5 +1,62 @@ # @backstage/plugin-scaffolder-backend +## 1.11.1-next.0 + +### Patch Changes + +- c6c78b4acb: throw error from catalog:fetch scaffolder action when entity is null and optional is false +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-backend@1.8.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + - @backstage/plugin-scaffolder-node@0.1.1-next.0 + +## 1.11.0 + +### Minor Changes + +- 0b2952ee4b: Added the option to overwrite files in the `targetPath` of the `template:fetch` action +- 127154930f: Renamed the export `scaffolderCatalogModule` to `catalogModuleTemplateKind` in order to follow the new recommended naming patterns of backend system items. This is technically a breaking change but in an alpha export, so take care to change your imports if you have already migrated to the new backend system. + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- ad3edc402d: **Deprecations**: The following are deprecated and should instead be imported from the new package `@backstage/plugin-scaffolder-node`: + + - `ActionContext` + - `createTemplateAction` + - `TaskSecrets` + - `TemplateAction` + +- 6c70919f1a: Provide better error messaging when GitHub fails due to missing team definitions +- 66cf22fdc4: Updated dependency `esbuild` to `^0.17.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.7.2 + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/plugin-scaffolder-node@0.1.0 + - @backstage/catalog-model@1.2.0 + - @backstage/plugin-catalog-node@1.3.3 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-scaffolder-common@1.2.5 + ## 1.11.0-next.2 ### Patch Changes diff --git a/plugins/scaffolder-backend/alpha-api-report.md b/plugins/scaffolder-backend/alpha-api-report.md new file mode 100644 index 0000000000..3199444c6b --- /dev/null +++ b/plugins/scaffolder-backend/alpha-api-report.md @@ -0,0 +1,30 @@ +## API Report File for "@backstage/plugin-scaffolder-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { TaskBroker } from '@backstage/plugin-scaffolder-backend'; +import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +import { TemplateFilter } from '@backstage/plugin-scaffolder-backend'; +import { TemplateGlobal } from '@backstage/plugin-scaffolder-backend'; + +// @alpha +export const catalogModuleTemplateKind: () => BackendFeature; + +// @alpha +export const scaffolderPlugin: ( + options: ScaffolderPluginOptions, +) => BackendFeature; + +// @alpha +export type ScaffolderPluginOptions = { + actions?: TemplateAction[]; + taskWorkers?: number; + taskBroker?: TaskBroker; + additionalTemplateFilters?: Record; + additionalTemplateGlobals?: Record; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 0d745862a1..293ff7ed29 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -6,7 +6,6 @@ /// import { ActionContext as ActionContext_2 } from '@backstage/plugin-scaffolder-node'; -import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; @@ -38,9 +37,6 @@ import { Writable } from 'stream'; // @public @deprecated (undocumented) export type ActionContext = ActionContext_2; -// @alpha -export const catalogModuleTemplateKind: () => BackendFeature; - // @public export const createBuiltinActions: ( options: CreateBuiltInActionsOptions, @@ -666,20 +662,6 @@ export class ScaffolderEntitiesProcessor implements CatalogProcessor { validateEntityKind(entity: Entity): Promise; } -// @alpha -export const scaffolderPlugin: ( - options: ScaffolderPluginOptions, -) => BackendFeature; - -// @alpha -export type ScaffolderPluginOptions = { - actions?: TemplateAction_2[]; - taskWorkers?: number; - taskBroker?: TaskBroker; - additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; -}; - // @public export type SerializedTask = { id: string; diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index ccc586f55b..12ef31899c 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-scaffolder-backend", "description": "The Backstage backend plugin that helps you create new things", - "version": "1.11.0-next.2", + "version": "1.11.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "backend-plugin" @@ -25,7 +37,7 @@ ], "scripts": { "start": "backstage-cli package start", - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -95,12 +107,11 @@ "esbuild": "^0.17.0", "jest-when": "^3.1.0", "mock-fs": "^5.1.0", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3", "yaml": "^2.0.0" }, "files": [ - "alpha", "dist", "migrations", "config.d.ts", diff --git a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts index 3b0d26be21..182bb60223 100644 --- a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts +++ b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts @@ -20,14 +20,18 @@ import { } from '@backstage/backend-plugin-api'; import { loggerToWinstonLogger } from '@backstage/backend-common'; import { ScmIntegrations } from '@backstage/integration'; -import { catalogServiceRef } from '@backstage/plugin-catalog-node'; +import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; import { scaffolderActionsExtensionPoint, ScaffolderActionsExtensionPoint, TemplateAction, } from '@backstage/plugin-scaffolder-node'; -import { TemplateFilter, TemplateGlobal } from './lib'; -import { createBuiltinActions, TaskBroker } from './scaffolder'; +import { + TemplateFilter, + TemplateGlobal, + TaskBroker, +} from '@backstage/plugin-scaffolder-backend'; +import { createBuiltinActions } from './scaffolder'; import { createRouter } from './service/router'; /** diff --git a/plugins/scaffolder-backend/src/alpha.ts b/plugins/scaffolder-backend/src/alpha.ts new file mode 100644 index 0000000000..ac96f081ad --- /dev/null +++ b/plugins/scaffolder-backend/src/alpha.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './modules'; +export { scaffolderPlugin } from './ScaffolderPlugin'; +export type { ScaffolderPluginOptions } from './ScaffolderPlugin'; diff --git a/plugins/scaffolder-backend/src/index.ts b/plugins/scaffolder-backend/src/index.ts index ba69a55a24..ba2c25f80a 100644 --- a/plugins/scaffolder-backend/src/index.ts +++ b/plugins/scaffolder-backend/src/index.ts @@ -24,8 +24,5 @@ export * from './scaffolder'; export * from './service/router'; export * from './lib'; export * from './processor'; -export * from './modules'; -export { scaffolderPlugin } from './ScaffolderPlugin'; -export type { ScaffolderPluginOptions } from './ScaffolderPlugin'; export * from './deprecated'; diff --git a/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.test.ts b/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.test.ts index 7652f60386..7b8b99f5e2 100644 --- a/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.test.ts +++ b/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { ScaffolderEntitiesProcessor } from '../processor'; import { catalogModuleTemplateKind } from './catalogModuleTemplateKind'; import { startTestBackend } from '@backstage/backend-test-utils'; diff --git a/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.ts b/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.ts index 622e5a003a..3359bd1dba 100644 --- a/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.ts +++ b/plugins/scaffolder-backend/src/modules/catalogModuleTemplateKind.ts @@ -15,7 +15,7 @@ */ import { createBackendModule } from '@backstage/backend-plugin-api'; -import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha'; import { ScaffolderEntitiesProcessor } from '../processor'; /** diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts index f8bdf2bdcb..52c76c8769 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.test.ts @@ -90,7 +90,7 @@ describe('catalog:fetch', () => { expect(mockContext.output).toHaveBeenCalledWith('entity', null); }); - it('should throw error if entity not in catalog and optional is false', async () => { + it('should throw error if entity fetch fails from catalog and optional is false', async () => { getEntityByRef.mockImplementationOnce(() => { throw new Error('Not found'); }); @@ -109,4 +109,22 @@ describe('catalog:fetch', () => { }); expect(mockContext.output).not.toHaveBeenCalled(); }); + + it('should throw error if entity not in catalog and optional is false', async () => { + getEntityByRef.mockReturnValueOnce(null); + + await expect( + action.handler({ + ...mockContext, + input: { + entityRef: 'component:default/test', + }, + }), + ).rejects.toThrow('Entity component:default/test not found'); + + expect(getEntityByRef).toHaveBeenCalledWith('component:default/test', { + token: 'secret', + }); + expect(mockContext.output).not.toHaveBeenCalled(); + }); }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts index 913bf32cce..17e510ce64 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/catalog/fetch.ts @@ -93,6 +93,11 @@ export function createFetchCatalogEntityAction(options: { throw e; } } + + if (!entity && !optional) { + throw new Error(`Entity ${entityRef} not found`); + } + ctx.output('entity', entity ?? null); }, }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts index f15747fd6b..a9ef8c3daa 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubRepoCreate.test.ts @@ -42,6 +42,7 @@ const mockOctokit = { }, teams: { addOrUpdateRepoPermissionsInOrg: jest.fn(), + getByName: jest.fn(), }, }, }; @@ -96,6 +97,13 @@ describe('github:repo:create', () => { data: { type: 'Organization' }, }); + mockOctokit.rest.teams.getByName.mockResolvedValue({ + data: { + name: 'blam', + id: 42, + }, + }); + mockOctokit.rest.repos.createInOrg.mockResolvedValue({ data: {} }); await action.handler(mockContext); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts index dae5e16374..75c8f25d8b 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/helpers.ts @@ -15,7 +15,7 @@ */ import { Config } from '@backstage/config'; -import { assertError, InputError } from '@backstage/errors'; +import { assertError, InputError, NotFoundError } from '@backstage/errors'; import { DefaultGithubCredentialsProvider, GithubCredentialsProvider, @@ -135,6 +135,10 @@ export async function createGithubRepoWithCollaboratorsAndTopics( username: owner, }); + if (access?.startsWith(`${owner}/`)) { + await validateAccessTeam(client, access); + } + const repoCreationPromise = user.data.type === 'Organization' ? client.rest.repos.createInOrg({ @@ -351,3 +355,22 @@ function extractCollaboratorName( if ('user' in collaborator) return collaborator.user; return collaborator.team; } + +async function validateAccessTeam(client: Octokit, access: string) { + const [org, team_slug] = access.split('/'); + try { + // Below rule disabled because of a 'getByName' check for a different library + // incorrectly triggers here. + // eslint-disable-next-line testing-library/no-await-sync-query + await client.rest.teams.getByName({ + org, + team_slug, + }); + } catch (e) { + if (e.response.data.message === 'Not Found') { + const message = `Received 'Not Found' from the API; one of org: + ${org} or team: ${team_slug} was not found within GitHub.`; + throw new NotFoundError(message); + } + } +} diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts index 8ead489ea4..94b51f3e94 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts @@ -45,6 +45,7 @@ const mockOctokit = { replaceAllTopics: jest.fn(), }, teams: { + getByName: jest.fn(), addOrUpdateRepoPermissionsInOrg: jest.fn(), }, }, @@ -96,11 +97,41 @@ describe('publish:github', () => { }); }); + it('should fail to create if the team is not found in the org', async () => { + mockOctokit.rest.users.getByUsername.mockResolvedValue({ + data: { type: 'Organization' }, + }); + + mockOctokit.rest.teams.getByName.mockRejectedValue({ + response: { + status: 404, + data: { + message: 'Not Found', + documentation_url: + 'https://docs.github.com/en/rest/teams/teams#add-or-update-team-repository-permissions', + }, + }, + }); + + await expect(action.handler(mockContext)).rejects.toThrow( + "Received 'Not Found' from the API;", + ); + + expect(mockOctokit.rest.repos.createInOrg).not.toHaveBeenCalled(); + }); + it('should call the githubApis with the correct values for createInOrg', async () => { mockOctokit.rest.users.getByUsername.mockResolvedValue({ data: { type: 'Organization' }, }); + mockOctokit.rest.teams.getByName.mockResolvedValue({ + data: { + name: 'blam', + id: 42, + }, + }); + mockOctokit.rest.repos.createInOrg.mockResolvedValue({ data: {} }); await action.handler(mockContext); @@ -518,6 +549,30 @@ describe('publish:github', () => { }); }); + it('should provide an adequate failure message when adding access', async () => { + mockOctokit.rest.users.getByUsername.mockResolvedValue({ + data: { type: 'User' }, + }); + + mockOctokit.rest.teams.getByName.mockRejectedValue({ + response: { + status: 404, + data: { + message: 'Not Found', + documentation_url: + 'https://docs.github.com/en/rest/teams/teams#add-or-update-team-repository-permissions', + }, + }, + }); + await expect(action.handler(mockContext)).rejects.toThrow( + "Received 'Not Found' from the API;", + ); + + expect( + mockOctokit.rest.repos.createForAuthenticatedUser, + ).not.toHaveBeenCalled(); + }); + it('should add outside collaborators when provided', async () => { mockOctokit.rest.users.getByUsername.mockResolvedValue({ data: { type: 'User' }, diff --git a/plugins/scaffolder-common/CHANGELOG.md b/plugins/scaffolder-common/CHANGELOG.md index e1936292f9..c9c785d777 100644 --- a/plugins/scaffolder-common/CHANGELOG.md +++ b/plugins/scaffolder-common/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/plugin-scaffolder-common +## 1.2.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/types@1.0.2 + +## 1.2.5 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/types@1.0.2 + ## 1.2.5-next.1 ### Patch Changes diff --git a/plugins/scaffolder-common/package.json b/plugins/scaffolder-common/package.json index 3ec3528427..4e78d531e3 100644 --- a/plugins/scaffolder-common/package.json +++ b/plugins/scaffolder-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-common", "description": "Common functionalities for the scaffolder, to be shared between scaffolder and scaffolder-backend plugin", - "version": "1.2.5-next.1", + "version": "1.2.6-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-node/CHANGELOG.md b/plugins/scaffolder-node/CHANGELOG.md index cd2ef0259e..5bc9d498b6 100644 --- a/plugins/scaffolder-node/CHANGELOG.md +++ b/plugins/scaffolder-node/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-scaffolder-node +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + +## 0.1.0 + +### Minor Changes + +- d72866f0cc: New package that takes over some of the types and functionality from `@backstage/plugin-scaffolder-backend` that are shared with other modules + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/catalog-model@1.2.0 + - @backstage/types@1.0.2 + - @backstage/plugin-scaffolder-common@1.2.5 + ## 0.1.0-next.2 ### Patch Changes diff --git a/plugins/scaffolder-node/package.json b/plugins/scaffolder-node/package.json index ce82f57f5f..642a59b801 100644 --- a/plugins/scaffolder-node/package.json +++ b/plugins/scaffolder-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-scaffolder-node", "description": "The plugin-scaffolder-node module for @backstage/plugin-scaffolder-backend", - "version": "0.1.0-next.2", + "version": "0.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/scaffolder-react/CHANGELOG.md b/plugins/scaffolder-react/CHANGELOG.md index 51fa1abc63..24ccc34e4e 100644 --- a/plugins/scaffolder-react/CHANGELOG.md +++ b/plugins/scaffolder-react/CHANGELOG.md @@ -1,5 +1,54 @@ # @backstage/plugin-scaffolder-react +## 1.1.1-next.0 + +### Patch Changes + +- c8d78b9ae9: fix bug with `hasErrors` returning false when dealing with empty objects +- 928a12a9b3: Internal refactor of `/alpha` exports. +- cc418d652a: scaffolder/next: Added the ability to get the fields definition in the schema in the validation function +- d4100d0ec4: Fix alignment bug for owners on `TemplateCard` +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + +## 1.1.0 + +### Minor Changes + +- a07750745b: Added `DescriptionField` field override to the `next/scaffolder` +- a521379688: Migrating the `TemplateEditorPage` to work with the new components from `@backstage/plugin-scaffolder-react` +- 8c2966536b: Embed scaffolder workflow in other components +- 5555e17313: refactor `createAsyncValidators` to be recursive to ensure validators are called in nested schemas. + +### Patch Changes + +- 04f717a8e1: `scaffolder/next`: bump `react-jsonschema-form` libraries to `v5-stable` +- b46f385eff: scaffolder/next: Implementing a simple `OngoingTask` page +- cbab8ac107: lock versions of `@rjsf/*-beta` packages +- 346d6b6630: Upgrade `@rjsf` version 5 dependencies to `beta.18` +- ccbf91051b: bump `@rjsf` `v5` dependencies to 5.1.0 +- d2ddde2108: Add `ScaffolderLayouts` to `NextScaffolderPage` +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-scaffolder-common@1.2.5 + ## 1.1.0-next.2 ### Minor Changes diff --git a/plugins/scaffolder-react/alpha-api-report.md b/plugins/scaffolder-react/alpha-api-report.md new file mode 100644 index 0000000000..ad44cd3707 --- /dev/null +++ b/plugins/scaffolder-react/alpha-api-report.md @@ -0,0 +1,222 @@ +## API Report File for "@backstage/plugin-scaffolder-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { ApiHolder } from '@backstage/core-plugin-api'; +import { ComponentType } from 'react'; +import { CustomFieldExtensionSchema } from '@backstage/plugin-scaffolder-react'; +import { Dispatch } from 'react'; +import { Extension } from '@backstage/core-plugin-api'; +import { FieldExtensionComponent } from '@backstage/plugin-scaffolder-react'; +import { FieldProps } from '@rjsf/utils'; +import { FieldValidation } from '@rjsf/utils'; +import { FormProps as FormProps_2 } from '@rjsf/core-v5'; +import { IconComponent } from '@backstage/core-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { JsonValue } from '@backstage/types'; +import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; +import { PropsWithChildren } from 'react'; +import { default as React_2 } from 'react'; +import { ReactNode } from 'react'; +import { RJSFSchema } from '@rjsf/utils'; +import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; +import { SetStateAction } from 'react'; +import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; +import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; +import { UIOptionsType } from '@rjsf/utils'; +import { UiSchema } from '@rjsf/utils'; + +// @alpha +export const createFieldValidation: () => FieldValidation; + +// @alpha +export function createNextScaffolderFieldExtension< + TReturnValue = unknown, + TInputProps extends UIOptionsType = {}, +>( + options: NextFieldExtensionOptions, +): Extension>; + +// @alpha +export const DefaultTemplateOutputs: (props: { + output?: ScaffolderTaskOutput; +}) => JSX.Element | null; + +// @alpha (undocumented) +export const EmbeddableWorkflow: (props: WorkflowProps) => JSX.Element; + +// @alpha +export const extractSchemaFromStep: (inputStep: JsonObject) => { + uiSchema: UiSchema; + schema: JsonObject; +}; + +// @alpha (undocumented) +export const Form: ComponentType>; + +// @alpha +export type FormProps = Pick< + FormProps_2, + 'transformErrors' | 'noHtml5Validate' +>; + +// @alpha +export type NextCustomFieldValidator = ( + data: TFieldReturnValue, + field: FieldValidation, + context: { + apiHolder: ApiHolder; + formData: JsonObject; + schema: JsonObject; + }, +) => void | Promise; + +// @alpha +export interface NextFieldExtensionComponentProps< + TFieldReturnValue, + TUiOptions = {}, +> extends PropsWithChildren> { + // (undocumented) + uiSchema?: UiSchema & { + 'ui:options'?: TUiOptions & UIOptionsType; + }; +} + +// @alpha +export type NextFieldExtensionOptions< + TFieldReturnValue = unknown, + TInputProps = unknown, +> = { + name: string; + component: ( + props: NextFieldExtensionComponentProps, + ) => JSX.Element | null; + validation?: NextCustomFieldValidator; + schema?: CustomFieldExtensionSchema; +}; + +// @alpha +export interface ParsedTemplateSchema { + // (undocumented) + description?: string; + // (undocumented) + mergedSchema: JsonObject; + // (undocumented) + schema: JsonObject; + // (undocumented) + title: string; + // (undocumented) + uiSchema: UiSchema; +} + +// @alpha +export const ReviewState: (props: ReviewStateProps) => JSX.Element; + +// @alpha +export type ReviewStateProps = { + schemas: ParsedTemplateSchema[]; + formState: JsonObject; +}; + +// @alpha +export const Stepper: (stepperProps: StepperProps) => JSX.Element; + +// @alpha +export type StepperProps = { + manifest: TemplateParameterSchema; + extensions: NextFieldExtensionOptions[]; + templateName?: string; + FormProps?: FormProps; + initialState?: Record; + onCreate: (values: Record) => Promise; + components?: { + ReviewStateComponent?: (props: ReviewStateProps) => JSX.Element; + createButtonText?: ReactNode; + reviewButtonText?: ReactNode; + }; + layouts?: LayoutOptions[]; +}; + +// @alpha +export const TemplateCard: (props: TemplateCardProps) => JSX.Element; + +// @alpha +export interface TemplateCardProps { + // (undocumented) + additionalLinks?: { + icon: IconComponent; + text: string; + url: string; + }[]; + // (undocumented) + onSelected?: (template: TemplateEntityV1beta3) => void; + // (undocumented) + template: TemplateEntityV1beta3; +} + +// @alpha +export const TemplateGroup: (props: TemplateGroupProps) => JSX.Element; + +// @alpha +export interface TemplateGroupProps { + // (undocumented) + components?: { + CardComponent?: React_2.ComponentType; + }; + // (undocumented) + onSelected: (template: TemplateEntityV1beta3) => void; + // (undocumented) + templates: { + template: TemplateEntityV1beta3; + additionalLinks?: { + icon: IconComponent; + text: string; + url: string; + }[]; + }[]; + // (undocumented) + title: React_2.ReactNode; +} + +// @alpha +export const useFormDataFromQuery: ( + initialState?: Record, +) => [Record, Dispatch>>]; + +// @alpha (undocumented) +export const useTemplateParameterSchema: (templateRef: string) => { + manifest: TemplateParameterSchema; + loading: boolean; + error: Error | undefined; +}; + +// @alpha +export const useTemplateSchema: (manifest: TemplateParameterSchema) => { + steps: ParsedTemplateSchema[]; +}; + +// @alpha (undocumented) +export const Workflow: (workflowProps: WorkflowProps) => JSX.Element | null; + +// @alpha (undocumented) +export type WorkflowProps = { + title?: string; + description?: string; + namespace: string; + templateName: string; + onError(error: Error | undefined): JSX.Element | null; +} & Pick< + StepperProps, + | 'extensions' + | 'FormProps' + | 'components' + | 'onCreate' + | 'initialState' + | 'layouts' +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/scaffolder-react/api-report.md b/plugins/scaffolder-react/api-report.md index 72a0b92eef..9b50eef884 100644 --- a/plugins/scaffolder-react/api-report.md +++ b/plugins/scaffolder-react/api-report.md @@ -7,27 +7,18 @@ import { ApiHolder } from '@backstage/core-plugin-api'; import { ApiRef } from '@backstage/core-plugin-api'; -import { Dispatch } from 'react'; import { Extension } from '@backstage/core-plugin-api'; import { FieldProps } from '@rjsf/core'; -import { FieldProps as FieldProps_2 } from '@rjsf/utils'; import { FieldValidation } from '@rjsf/core'; -import { FieldValidation as FieldValidation_2 } from '@rjsf/utils'; -import type { FormProps as FormProps_2 } from '@rjsf/core-v5'; -import { IconComponent } from '@backstage/core-plugin-api'; +import type { FormProps } from '@rjsf/core-v5'; import { JsonObject } from '@backstage/types'; import { JSONSchema7 } from 'json-schema'; import { JsonValue } from '@backstage/types'; import { Observable } from '@backstage/types'; import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; -import { ReactNode } from 'react'; -import { SetStateAction } from 'react'; import { TaskSpec } from '@backstage/plugin-scaffolder-common'; import { TaskStep } from '@backstage/plugin-scaffolder-common'; -import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { UIOptionsType } from '@rjsf/utils'; -import { UiSchema } from '@rjsf/utils'; // @public export type Action = { @@ -46,17 +37,6 @@ export type ActionExample = { example: string; }; -// @alpha -export const createFieldValidation: () => FieldValidation_2; - -// @alpha -export function createNextScaffolderFieldExtension< - TReturnValue = unknown, - TInputProps extends UIOptionsType = {}, ->( - options: NextFieldExtensionOptions, -): Extension>; - // @public export function createScaffolderFieldExtension< TReturnValue = unknown, @@ -85,20 +65,6 @@ export type CustomFieldValidator = ( }, ) => void | Promise; -// @alpha -export const DefaultTemplateOutputs: (props: { - output?: ScaffolderTaskOutput; -}) => JSX.Element | null; - -// @alpha (undocumented) -export const EmbeddableWorkflow: (props: WorkflowProps) => JSX.Element; - -// @alpha -export const extractSchemaFromStep: (inputStep: JsonObject) => { - uiSchema: UiSchema; - schema: JsonObject; -}; - // @public export type FieldExtensionComponent<_TReturnValue, _TInputProps> = () => null; @@ -126,12 +92,6 @@ export type FieldExtensionOptions< schema?: CustomFieldExtensionSchema; }; -// @public -export type FormProps = Pick< - FormProps_2, - 'transformErrors' | 'noHtml5Validate' ->; - // @public export type LayoutComponent<_TInputProps> = () => null; @@ -145,7 +105,7 @@ export interface LayoutOptions

    { // @public export type LayoutTemplate = NonNullable< - FormProps_2['uiSchema'] + FormProps['uiSchema'] >['ui:ObjectFieldTemplate']; // @public @@ -164,63 +124,6 @@ export type LogEvent = { taskId: string; }; -// @alpha -export type NextCustomFieldValidator = ( - data: TFieldReturnValue, - field: FieldValidation_2, - context: { - apiHolder: ApiHolder; - formData: JsonObject; - }, -) => void | Promise; - -// @alpha -export interface NextFieldExtensionComponentProps< - TFieldReturnValue, - TUiOptions = {}, -> extends PropsWithChildren> { - // (undocumented) - uiSchema?: UiSchema & { - 'ui:options'?: TUiOptions & UIOptionsType; - }; -} - -// @alpha -export type NextFieldExtensionOptions< - TFieldReturnValue = unknown, - TInputProps = unknown, -> = { - name: string; - component: ( - props: NextFieldExtensionComponentProps, - ) => JSX.Element | null; - validation?: NextCustomFieldValidator; - schema?: CustomFieldExtensionSchema; -}; - -// @alpha -export interface ParsedTemplateSchema { - // (undocumented) - description?: string; - // (undocumented) - mergedSchema: JsonObject; - // (undocumented) - schema: JsonObject; - // (undocumented) - title: string; - // (undocumented) - uiSchema: UiSchema; -} - -// @alpha -export const ReviewState: (props: ReviewStateProps) => JSX.Element; - -// @alpha -export type ReviewStateProps = { - schemas: ParsedTemplateSchema[]; - formState: JsonObject; -}; - // @public export interface ScaffolderApi { // (undocumented) @@ -374,66 +277,6 @@ export const SecretsContextProvider: ({ children, }: PropsWithChildren<{}>) => JSX.Element; -// @alpha -export const Stepper: (stepperProps: StepperProps) => JSX.Element; - -// @alpha -export type StepperProps = { - manifest: TemplateParameterSchema; - extensions: NextFieldExtensionOptions[]; - templateName?: string; - FormProps?: FormProps; - initialState?: Record; - onCreate: (values: Record) => Promise; - components?: { - ReviewStateComponent?: (props: ReviewStateProps) => JSX.Element; - createButtonText?: ReactNode; - reviewButtonText?: ReactNode; - }; - layouts?: LayoutOptions[]; -}; - -// @alpha -export const TemplateCard: (props: TemplateCardProps) => JSX.Element; - -// @alpha -export interface TemplateCardProps { - // (undocumented) - additionalLinks?: { - icon: IconComponent; - text: string; - url: string; - }[]; - // (undocumented) - onSelected?: (template: TemplateEntityV1beta3) => void; - // (undocumented) - template: TemplateEntityV1beta3; -} - -// @alpha -export const TemplateGroup: (props: TemplateGroupProps) => JSX.Element; - -// @alpha -export interface TemplateGroupProps { - // (undocumented) - components?: { - CardComponent?: React_2.ComponentType; - }; - // (undocumented) - onSelected: (template: TemplateEntityV1beta3) => void; - // (undocumented) - templates: { - template: TemplateEntityV1beta3; - additionalLinks?: { - icon: IconComponent; - text: string; - url: string; - }[]; - }[]; - // (undocumented) - title: React_2.ReactNode; -} - // @public export type TemplateParameterSchema = { title: string; @@ -457,45 +300,8 @@ export const useCustomLayouts: >( outlet: React.ReactNode, ) => TComponentDataType[]; -// @alpha -export const useFormDataFromQuery: ( - initialState?: Record, -) => [Record, Dispatch>>]; - -// @alpha (undocumented) -export const useTemplateParameterSchema: (templateRef: string) => { - manifest: TemplateParameterSchema | undefined; - loading: boolean; - error: Error | undefined; -}; - -// @alpha -export const useTemplateSchema: (manifest: TemplateParameterSchema) => { - steps: ParsedTemplateSchema[]; -}; - // @public export const useTemplateSecrets: () => ScaffolderUseTemplateSecrets; -// @alpha (undocumented) -export const Workflow: (workflowProps: WorkflowProps) => JSX.Element | null; - -// @alpha (undocumented) -export type WorkflowProps = { - title?: string; - description?: string; - namespace: string; - templateName: string; - onError(error: Error | undefined): JSX.Element | null; -} & Pick< - StepperProps, - | 'extensions' - | 'FormProps' - | 'components' - | 'onCreate' - | 'initialState' - | 'layouts' ->; - // (No @packageDocumentation comment for this package) ``` diff --git a/plugins/scaffolder-react/package.json b/plugins/scaffolder-react/package.json index e26bd973d5..2d3e10ed9f 100644 --- a/plugins/scaffolder-react/package.json +++ b/plugins/scaffolder-react/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-scaffolder-react", "description": "A frontend library that helps other Backstage plugins interact with the Scaffolder", - "version": "1.1.0-next.2", + "version": "1.1.1-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", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "web-library" @@ -24,7 +36,7 @@ "backstage" ], "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -80,7 +92,6 @@ "@testing-library/user-event": "^14.0.0" }, "files": [ - "dist", - "alpha" + "dist" ] } diff --git a/plugins/scaffolder-react/src/alpha.ts b/plugins/scaffolder-react/src/alpha.ts new file mode 100644 index 0000000000..731b8e07d9 --- /dev/null +++ b/plugins/scaffolder-react/src/alpha.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './next'; +export type { FormProps } from './next'; diff --git a/plugins/scaffolder-react/src/index.ts b/plugins/scaffolder-react/src/index.ts index 67703e3ed1..1b20c19414 100644 --- a/plugins/scaffolder-react/src/index.ts +++ b/plugins/scaffolder-react/src/index.ts @@ -20,5 +20,3 @@ export * from './secrets'; export * from './api'; export * from './hooks'; export * from './layouts'; - -export * from './next'; diff --git a/plugins/scaffolder-react/src/next/components/Form/Form.tsx b/plugins/scaffolder-react/src/next/components/Form/Form.tsx new file mode 100644 index 0000000000..79bcaa8475 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/Form/Form.tsx @@ -0,0 +1,23 @@ +/* + * 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 { withTheme } from '@rjsf/core-v5'; + +// TODO(blam): We require here, as the types in this package depend on @rjsf/core explicitly +// which is what we're using here as the default types, it needs to depend on @rjsf/core-v5 because +// of the re-writing we're doing. Once we've migrated, we can import this the exact same as before. +/** @alpha */ +export const Form = withTheme(require('@rjsf/material-ui-v5').Theme); diff --git a/plugins/scaffolder-react/src/next/components/Form/index.ts b/plugins/scaffolder-react/src/next/components/Form/index.ts new file mode 100644 index 0000000000..6f780e92a4 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/Form/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { Form } from './Form'; diff --git a/plugins/scaffolder-react/src/next/components/Stepper/FieldOverrides/DescriptionField.tsx b/plugins/scaffolder-react/src/next/components/Stepper/FieldOverrides/DescriptionField.tsx new file mode 100644 index 0000000000..eded38beee --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/Stepper/FieldOverrides/DescriptionField.tsx @@ -0,0 +1,22 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { MarkdownContent } from '@backstage/core-components'; +import { FieldProps } from '@rjsf/utils'; + +export const DescriptionField = ({ description }: FieldProps) => + description && ; diff --git a/plugins/scaffolder-react/src/next/components/Stepper/FieldOverrides/index.ts b/plugins/scaffolder-react/src/next/components/Stepper/FieldOverrides/index.ts new file mode 100644 index 0000000000..d6d0bf3499 --- /dev/null +++ b/plugins/scaffolder-react/src/next/components/Stepper/FieldOverrides/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { DescriptionField } from './DescriptionField'; diff --git a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx index f802121597..444e463064 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx +++ b/plugins/scaffolder-react/src/next/components/Stepper/Stepper.tsx @@ -22,11 +22,11 @@ import { Button, makeStyles, } from '@material-ui/core'; -import { type IChangeEvent, withTheme } from '@rjsf/core-v5'; +import { type IChangeEvent } from '@rjsf/core-v5'; import { ErrorSchema } from '@rjsf/utils'; import React, { useCallback, useMemo, useState, type ReactNode } from 'react'; import { NextFieldExtensionOptions } from '../../extensions'; -import { TemplateParameterSchema } from '../../../types'; +import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; import { createAsyncValidators, type FormValidation, @@ -36,9 +36,11 @@ import { useTemplateSchema } from '../../hooks/useTemplateSchema'; import validator from '@rjsf/validator-ajv8'; import { useFormDataFromQuery } from '../../hooks'; import { FormProps } from '../../types'; -import { LayoutOptions } from '../../../layouts'; +import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; import { useTransformSchemaToProps } from '../../hooks/useTransformSchemaToProps'; import { hasErrors } from './utils'; +import * as FieldOverrides from './FieldOverrides'; +import { Form } from '../Form'; const useStyles = makeStyles(theme => ({ backButton: { @@ -74,11 +76,6 @@ export type StepperProps = { layouts?: LayoutOptions[]; }; -// TODO(blam): We require here, as the types in this package depend on @rjsf/core explicitly -// which is what we're using here as the default types, it needs to depend on @rjsf/core-v5 because -// of the re-writing we're doing. Once we've migrated, we can import this the exact same as before. -const Form = withTheme(require('@rjsf/material-ui-v5').Theme); - /** * The `Stepper` component is the Wizard that is rendered when a user selects a template * @alpha @@ -175,7 +172,7 @@ export const Stepper = (stepperProps: StepperProps) => { schema={currentStep.schema} uiSchema={currentStep.uiSchema} onSubmit={handleNext} - fields={extensions} + fields={{ ...FieldOverrides, ...extensions }} showErrorList={false} onChange={handleChange} {...(props.FormProps ?? {})} diff --git a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts index fe8b41a9f3..196bae0255 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts +++ b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.test.ts @@ -56,6 +56,79 @@ describe('createAsyncValidators', () => { expect(validators.AddressField).toHaveBeenCalled(); }); + it('should call the validator function with the correct schema in the context', async () => { + const schema: JsonObject = { + type: 'object', + properties: { + name: { + type: 'string', + 'ui:options': { + bob: true, + }, + pattern: 'lols', + 'ui:field': 'NameField', + }, + address: { + type: 'object', + 'ui:field': 'AddressField', + properties: { + street: { + type: 'string', + }, + postcode: { + type: 'string', + }, + }, + }, + }, + }; + + const validators = { NameField: jest.fn(), AddressField: jest.fn() }; + + const validate = createAsyncValidators(schema, validators, { + apiHolder: { get: jest.fn() }, + }); + + await validate({ + name: 'asd', + address: { street: 'street', postcode: 'postcode' }, + }); + + expect(validators.NameField).toHaveBeenCalledWith( + 'asd', + expect.anything(), + expect.objectContaining({ + schema: { + type: 'string', + 'ui:options': { + bob: true, + }, + pattern: 'lols', + 'ui:field': 'NameField', + }, + }), + ); + + expect(validators.AddressField).toHaveBeenCalledWith( + { street: 'street', postcode: 'postcode' }, + expect.anything(), + expect.objectContaining({ + schema: { + type: 'object', + 'ui:field': 'AddressField', + properties: { + street: { + type: 'string', + }, + postcode: { + type: 'string', + }, + }, + }, + }), + ); + }); + it('should return the correct errors to the frontend', async () => { const schema: JsonObject = { type: 'object', @@ -272,4 +345,59 @@ describe('createAsyncValidators', () => { }, }); }); + + it('should call a validator for array property from a custom field extension', async () => { + const schema: JsonObject = { + type: 'object', + properties: { + tags: { + title: 'Tags', + type: 'array', + items: { + type: 'string', + 'ui:field': 'TagField', + }, + }, + }, + }; + + const validators = { TagField: jest.fn() }; + + const validate = createAsyncValidators(schema, validators, { + apiHolder: { get: jest.fn() }, + }); + + await validate({ + tags: ['tag-1', 'tag-2'], + }); + + expect(validators.TagField).toHaveBeenCalled(); + }); + + it('should does not call a validator if no ui field specified', async () => { + const schema: JsonObject = { + type: 'object', + properties: { + tags: { + title: 'Tags', + type: 'array', + items: { + type: 'string', + }, + }, + }, + }; + + const validators = { TagField: jest.fn() }; + + const validate = createAsyncValidators(schema, validators, { + apiHolder: { get: jest.fn() }, + }); + + await validate({ + tags: ['asd', 'asd$'], + }); + + expect(validators.TagField).not.toHaveBeenCalled(); + }); }); diff --git a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts index 86b7619b34..111f3a0f1f 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts +++ b/plugins/scaffolder-react/src/next/components/Stepper/createAsyncValidators.ts @@ -15,7 +15,7 @@ */ import { FieldValidation } from '@rjsf/utils'; -import type { JsonObject } from '@backstage/types'; +import type { JsonObject, JsonValue } from '@backstage/types'; import { ApiHolder } from '@backstage/core-plugin-api'; import { Draft07 as JSONSchema } from 'json-schema-library'; import { createFieldValidation } from '../../lib'; @@ -44,20 +44,53 @@ export const createAsyncValidators = ( const parsedSchema = new JSONSchema(rootSchema); const formValidation: FormValidation = {}; + const validateForm = async ( + validatorName: string, + key: string, + value: JsonValue | undefined, + schema: JsonObject, + ) => { + const validator = validators[validatorName]; + if (validator) { + const fieldValidation = createFieldValidation(); + try { + await validator(value, fieldValidation, { + ...context, + formData, + schema, + }); + } catch (ex) { + fieldValidation.addError(ex.message); + } + formValidation[key] = fieldValidation; + } + }; + for (const [key, value] of Object.entries(current)) { const path = `${pathPrefix}/${key}`; const definitionInSchema = parsedSchema.getSchema(path, formData); if (definitionInSchema && 'ui:field' in definitionInSchema) { - const validator = validators[definitionInSchema['ui:field']]; - if (validator) { - const fieldValidation = createFieldValidation(); - try { - await validator(value, fieldValidation, { ...context, formData }); - } catch (ex) { - fieldValidation.addError(ex.message); - } - formValidation[key] = fieldValidation; + if ('ui:field' in definitionInSchema) { + await validateForm( + definitionInSchema['ui:field'], + key, + value, + definitionInSchema, + ); + } + } else if ( + definitionInSchema && + definitionInSchema.items && + 'ui:field' in definitionInSchema.items + ) { + if ('ui:field' in definitionInSchema.items) { + await validateForm( + definitionInSchema.items['ui:field'], + key, + value, + definitionInSchema.items, + ); } } else if (isObject(value)) { formValidation[key] = await validate(formData, path, value); diff --git a/plugins/scaffolder-react/src/next/components/Stepper/utils.test.ts b/plugins/scaffolder-react/src/next/components/Stepper/utils.test.ts index f6a1b012ac..24c62ebb35 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/utils.test.ts +++ b/plugins/scaffolder-react/src/next/components/Stepper/utils.test.ts @@ -58,4 +58,35 @@ describe('hasErrors', () => { }), ).toBe(true); }); + + it('should not return false when the error is an empty object', () => { + const errors = { + something: {}, + otherThing: {}, + someName: { + __errors: [ + 'Accepts alphanumeric values along with _(underscore) and -(hypen) as special characters', + ], + addError: jest.fn(), + }, + someOtherName: { + __errors: ['Must start with an alphabet & not contain .(period)'], + addError: jest.fn(), + }, + aName: { + __errors: [], + addError: jest.fn(), + }, + bName: { + __errors: [], + addError: jest.fn(), + }, + cName: { + __errors: [], + addError: jest.fn(), + }, + }; + + expect(hasErrors(errors)).toBe(true); + }); }); diff --git a/plugins/scaffolder-react/src/next/components/Stepper/utils.ts b/plugins/scaffolder-react/src/next/components/Stepper/utils.ts index 7d3efa9d94..0b70f57813 100644 --- a/plugins/scaffolder-react/src/next/components/Stepper/utils.ts +++ b/plugins/scaffolder-react/src/next/components/Stepper/utils.ts @@ -35,7 +35,9 @@ export function hasErrors(errors?: FormValidation): boolean { continue; } - return hasErrors(error); + if (hasErrors(error)) { + return true; + } } return false; diff --git a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx index 6f89808405..af44085151 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateCard/TemplateCard.tsx @@ -162,7 +162,7 @@ export const TemplateCard = (props: TemplateCardProps) => { )} - +

    {ownedByRelations.length > 0 && ( diff --git a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx index 5fbd3a5142..4d908461b0 100644 --- a/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx +++ b/plugins/scaffolder-react/src/next/components/TemplateOutputs/DefaultTemplateOutputs.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { Box, Paper } from '@material-ui/core'; import { LinkOutputs } from './LinkOutputs'; -import { ScaffolderTaskOutput } from '../../../api'; +import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; /** * The DefaultOutputs renderer for the scaffolder task output diff --git a/plugins/scaffolder-react/src/next/components/index.ts b/plugins/scaffolder-react/src/next/components/index.ts index 05e5a1105a..60a8fd9a51 100644 --- a/plugins/scaffolder-react/src/next/components/index.ts +++ b/plugins/scaffolder-react/src/next/components/index.ts @@ -19,3 +19,4 @@ export * from './ReviewState'; export * from './TemplateGroup'; export * from './Workflow'; export * from './TemplateOutputs'; +export * from './Form'; diff --git a/plugins/scaffolder-react/src/next/extensions/index.tsx b/plugins/scaffolder-react/src/next/extensions/index.tsx index ee9b1cd326..b2d402c93f 100644 --- a/plugins/scaffolder-react/src/next/extensions/index.tsx +++ b/plugins/scaffolder-react/src/next/extensions/index.tsx @@ -21,7 +21,8 @@ import { } from './types'; import { Extension, attachComponentData } from '@backstage/core-plugin-api'; import { UIOptionsType } from '@rjsf/utils'; -import { FieldExtensionComponent } from '../../extensions'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { FieldExtensionComponent } from '@backstage/plugin-scaffolder-react'; import { FIELD_EXTENSION_KEY } from '../../extensions/keys'; /** diff --git a/plugins/scaffolder-react/src/next/extensions/types.ts b/plugins/scaffolder-react/src/next/extensions/types.ts index 27778b0420..0917efe85d 100644 --- a/plugins/scaffolder-react/src/next/extensions/types.ts +++ b/plugins/scaffolder-react/src/next/extensions/types.ts @@ -22,7 +22,7 @@ import { } from '@rjsf/utils'; import { PropsWithChildren } from 'react'; import { JsonObject } from '@backstage/types'; -import { CustomFieldExtensionSchema } from '../../extensions'; +import { CustomFieldExtensionSchema } from '@backstage/plugin-scaffolder-react'; /** * Type for Field Extension Props for RJSF v5 @@ -46,7 +46,11 @@ export interface NextFieldExtensionComponentProps< export type NextCustomFieldValidator = ( data: TFieldReturnValue, field: FieldValidationV5, - context: { apiHolder: ApiHolder; formData: JsonObject }, + context: { + apiHolder: ApiHolder; + formData: JsonObject; + schema: JsonObject; + }, ) => void | Promise; /** diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts b/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts index 36b8b1e0bc..d060b9a09f 100644 --- a/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateParameterSchema.ts @@ -1,5 +1,3 @@ -import { useApi } from '@backstage/core-plugin-api'; - /* * Copyright 2023 The Backstage Authors * @@ -15,8 +13,11 @@ import { useApi } from '@backstage/core-plugin-api'; * See the License for the specific language governing permissions and * limitations under the License. */ + import useAsync from 'react-use/lib/useAsync'; import { scaffolderApiRef } from '../../api/ref'; +import { useApi } from '@backstage/core-plugin-api'; +import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; /** * @alpha @@ -28,5 +29,5 @@ export const useTemplateParameterSchema = (templateRef: string) => { [scaffolderApi, templateRef], ); - return { manifest: value, loading, error }; + return { manifest: value as TemplateParameterSchema, loading, error }; }; diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx index 153c48468d..ab33652338 100644 --- a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.test.tsx @@ -18,7 +18,7 @@ import { renderHook } from '@testing-library/react-hooks'; import { TestApiProvider } from '@backstage/test-utils'; import React from 'react'; import { featureFlagsApiRef } from '@backstage/core-plugin-api'; -import { TemplateParameterSchema } from '../../types'; +import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; describe('useTemplateSchema', () => { it('should generate the correct schema', () => { diff --git a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts index 2b2e48cf68..26980b15cf 100644 --- a/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts +++ b/plugins/scaffolder-react/src/next/hooks/useTemplateSchema.ts @@ -16,7 +16,7 @@ import { featureFlagsApiRef, useApi } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; import { UiSchema } from '@rjsf/utils'; -import { TemplateParameterSchema } from '../../types'; +import { TemplateParameterSchema } from '@backstage/plugin-scaffolder-react'; import { extractSchemaFromStep } from '../lib'; /** diff --git a/plugins/scaffolder-react/src/next/hooks/useTransformSchemaToProps.ts b/plugins/scaffolder-react/src/next/hooks/useTransformSchemaToProps.ts index 881c4f90c5..612ad5427b 100644 --- a/plugins/scaffolder-react/src/next/hooks/useTransformSchemaToProps.ts +++ b/plugins/scaffolder-react/src/next/hooks/useTransformSchemaToProps.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { type ParsedTemplateSchema } from './useTemplateSchema'; -import { type LayoutOptions } from '../../layouts'; +import { type LayoutOptions } from '@backstage/plugin-scaffolder-react'; interface Options { layouts?: LayoutOptions[]; diff --git a/plugins/scaffolder-react/src/next/types.ts b/plugins/scaffolder-react/src/next/types.ts index 54a64a5323..192fdf4146 100644 --- a/plugins/scaffolder-react/src/next/types.ts +++ b/plugins/scaffolder-react/src/next/types.ts @@ -23,7 +23,7 @@ import type { FormProps as SchemaFormProps } from '@rjsf/core-v5'; /** * Any `@rjsf/core` form properties that are publicly exposed to the `NextScaffolderpage` * - * @public + * @alpha */ export type FormProps = Pick< SchemaFormProps, diff --git a/plugins/scaffolder/CHANGELOG.md b/plugins/scaffolder/CHANGELOG.md index 37da3b63e1..2c12e00c10 100644 --- a/plugins/scaffolder/CHANGELOG.md +++ b/plugins/scaffolder/CHANGELOG.md @@ -1,5 +1,71 @@ # @backstage/plugin-scaffolder +## 1.11.1-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/plugin-scaffolder-react@1.1.1-next.0 + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/plugin-permission-react@0.4.11-next.0 + - @backstage/plugin-scaffolder-common@1.2.6-next.0 + +## 1.11.0 + +### Minor Changes + +- d6bb12a2e7: - **Deprecation** - Deprecated the following exports, please import them directly from `@backstage/plugin-scaffolder-react` instead + + ``` + createScaffolderLayout + ScaffolderLayouts + LayoutOptions + LayoutTemplate + ``` + +- a521379688: Migrating the `TemplateEditorPage` to work with the new components from `@backstage/plugin-scaffolder-react` +- 074f7e81b5: Added a missing validator check for items in an array +- 8c2966536b: Embed scaffolder workflow in other components + +### Patch Changes + +- 04f717a8e1: `scaffolder/next`: bump `react-jsonschema-form` libraries to `v5-stable` +- b46f385eff: scaffolder/next: Implementing a simple `OngoingTask` page +- cbab8ac107: lock versions of `@rjsf/*-beta` packages +- 346d6b6630: Upgrade `@rjsf` version 5 dependencies to `beta.18` +- ccbf91051b: bump `@rjsf` `v5` dependencies to 5.1.0 +- d2ddde2108: Add `ScaffolderLayouts` to `NextScaffolderPage` +- 0f0da2f256: Prefer schema ordering of template properties during review content generation. +- 38992bdbaf: Fixed bug in review step refactor that caused schema-based display settings for individual property values to be discarded. +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.1.0 + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/types@1.0.2 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-react@0.4.10 + - @backstage/plugin-scaffolder-common@1.2.5 + ## 1.11.0-next.2 ### Patch Changes diff --git a/plugins/scaffolder/alpha-api-report.md b/plugins/scaffolder/alpha-api-report.md new file mode 100644 index 0000000000..bf37acafc3 --- /dev/null +++ b/plugins/scaffolder/alpha-api-report.md @@ -0,0 +1,70 @@ +## API Report File for "@backstage/plugin-scaffolder" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { Entity } from '@backstage/catalog-model'; +import { FormProps as FormProps_2 } from '@backstage/plugin-scaffolder-react/alpha'; +import type { FormProps as FormProps_3 } from '@rjsf/core-v5'; +import { PathParams } from '@backstage/core-plugin-api'; +import { PropsWithChildren } from 'react'; +import { default as React_2 } from 'react'; +import { RouteRef } from '@backstage/core-plugin-api'; +import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; +import { SubRouteRef } from '@backstage/core-plugin-api'; +import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; + +// @alpha @deprecated +export type FormProps = Pick< + FormProps_3, + 'transformErrors' | 'noHtml5Validate' +>; + +// @alpha (undocumented) +export const nextRouteRef: RouteRef; + +// @alpha +export type NextRouterProps = { + components?: { + TemplateCardComponent?: React_2.ComponentType<{ + template: TemplateEntityV1beta3; + }>; + TaskPageComponent?: React_2.ComponentType<{}>; + TemplateOutputsComponent?: React_2.ComponentType<{ + output?: ScaffolderTaskOutput; + }>; + }; + groups?: TemplateGroupFilter[]; + FormProps?: FormProps_2; + contextMenu?: { + editor?: boolean; + actions?: boolean; + tasks?: boolean; + }; +}; + +// @alpha +export const NextScaffolderPage: ( + props: PropsWithChildren, +) => JSX.Element; + +// @alpha (undocumented) +export const nextScaffolderTaskRouteRef: SubRouteRef< + PathParams<'/tasks/:taskId'> +>; + +// @alpha (undocumented) +export const nextSelectedTemplateRouteRef: SubRouteRef< + PathParams<'/templates/:namespace/:templateName'> +>; + +// @alpha (undocumented) +export type TemplateGroupFilter = { + title?: React_2.ReactNode; + filter: (entity: Entity) => boolean; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/scaffolder/api-report.md b/plugins/scaffolder/api-report.md index 43b885b81a..43cc657a03 100644 --- a/plugins/scaffolder/api-report.md +++ b/plugins/scaffolder/api-report.md @@ -21,8 +21,6 @@ import { FieldExtensionComponent as FieldExtensionComponent_2 } from '@backstage import { FieldExtensionComponentProps as FieldExtensionComponentProps_2 } from '@backstage/plugin-scaffolder-react'; import { FieldExtensionOptions as FieldExtensionOptions_2 } from '@backstage/plugin-scaffolder-react'; import { FieldValidation } from '@rjsf/core'; -import { FormProps as FormProps_2 } from '@backstage/plugin-scaffolder-react'; -import type { FormProps as FormProps_3 } from '@rjsf/core-v5'; import { IdentityApi } from '@backstage/core-plugin-api'; import { JsonObject } from '@backstage/types'; import { LayoutOptions as LayoutOptions_2 } from '@backstage/plugin-scaffolder-react'; @@ -31,7 +29,6 @@ import { ListActionsResponse as ListActionsResponse_2 } from '@backstage/plugin- import { LogEvent as LogEvent_2 } from '@backstage/plugin-scaffolder-react'; import { Observable } from '@backstage/types'; import { PathParams } from '@backstage/core-plugin-api'; -import { PropsWithChildren } from 'react'; import { default as React_2 } from 'react'; import { ReactNode } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; @@ -155,12 +152,6 @@ export interface FieldSchema { readonly uiOptionsType: TUiOptions; } -// @alpha @deprecated -export type FormProps = Pick< - FormProps_3, - 'transformErrors' | 'noHtml5Validate' ->; - // @public @deprecated (undocumented) export type LayoutOptions = LayoutOptions_2; @@ -187,44 +178,6 @@ export function makeFieldSchemaFromZod< : never >; -// @alpha (undocumented) -export const nextRouteRef: RouteRef; - -// @alpha -export type NextRouterProps = { - components?: { - TemplateCardComponent?: React_2.ComponentType<{ - template: TemplateEntityV1beta3; - }>; - TaskPageComponent?: React_2.ComponentType<{}>; - TemplateOutputsComponent?: React_2.ComponentType<{ - output?: ScaffolderTaskOutput_2; - }>; - }; - groups?: TemplateGroupFilter[]; - FormProps?: FormProps_2; - contextMenu?: { - editor?: boolean; - actions?: boolean; - tasks?: boolean; - }; -}; - -// @alpha -export const NextScaffolderPage: ( - props: PropsWithChildren, -) => JSX.Element; - -// @alpha (undocumented) -export const nextScaffolderTaskRouteRef: SubRouteRef< - PathParams<'/tasks/:taskId'> ->; - -// @alpha (undocumented) -export const nextSelectedTemplateRouteRef: SubRouteRef< - PathParams<'/templates/:namespace/:templateName'> ->; - // @public export const OwnedEntityPickerFieldExtension: FieldExtensionComponent_2< string, @@ -514,12 +467,6 @@ export type TaskPageProps = { loadingText?: string; }; -// @alpha (undocumented) -export type TemplateGroupFilter = { - title?: React_2.ReactNode; - filter: (entity: Entity) => boolean; -}; - // @public @deprecated (undocumented) export type TemplateParameterSchema = TemplateParameterSchema_2; diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 86f9100deb..b3d33298cb 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -1,15 +1,27 @@ { "name": "@backstage/plugin-scaffolder", "description": "The Backstage plugin that helps you create new things", - "version": "1.11.0-next.2", + "version": "1.11.1-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", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./alpha": "./src/alpha.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "alpha": [ + "src/alpha.ts" + ], + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "frontend-plugin" @@ -24,7 +36,7 @@ "backstage" ], "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "start": "backstage-cli package start", "lint": "backstage-cli package lint", "test": "backstage-cli package test", @@ -58,6 +70,7 @@ "@rjsf/core": "^3.2.1", "@rjsf/material-ui": "^3.2.1", "@rjsf/utils": "5.1.0", + "@rjsf/validator-ajv8": "5.1.0", "@uiw/react-codemirror": "^4.9.3", "classnames": "^2.2.6", "git-url-parse": "^13.0.0", @@ -95,10 +108,9 @@ "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", "event-source-polyfill": "1.0.25", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ - "dist", - "alpha" + "dist" ] } diff --git a/plugins/scaffolder/src/alpha.ts b/plugins/scaffolder/src/alpha.ts new file mode 100644 index 0000000000..a460b0d7cc --- /dev/null +++ b/plugins/scaffolder/src/alpha.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { NextScaffolderPage } from './plugin'; +export { + nextRouteRef, + nextScaffolderTaskRouteRef, + nextSelectedTemplateRouteRef, + type TemplateGroupFilter, + type NextRouterProps, + type FormProps, +} from './next'; diff --git a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx index a74b65b885..0924c4f2e6 100644 --- a/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx +++ b/plugins/scaffolder/src/components/MultistepJsonForm/MultistepJsonForm.tsx @@ -37,11 +37,9 @@ import cloneDeep from 'lodash/cloneDeep'; import * as fieldOverrides from './FieldOverrides'; import { ReviewStepProps } from '../types'; import { ReviewStep } from './ReviewStep'; -import { - extractSchemaFromStep, - type LayoutOptions, -} from '@backstage/plugin-scaffolder-react'; +import { extractSchemaFromStep } from '@backstage/plugin-scaffolder-react/alpha'; import { selectedTemplateRouteRef } from '../../routes'; +import { LayoutOptions } from '@backstage/plugin-scaffolder-react'; const Form = withTheme(MuiTheme); diff --git a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx index 50221f3a83..e153c2e232 100644 --- a/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx +++ b/plugins/scaffolder/src/components/ScaffolderPage/ScaffolderPage.tsx @@ -36,7 +36,7 @@ import { import React, { ComponentType } from 'react'; import { TemplateList } from '../TemplateList'; import { TemplateTypePicker } from '../TemplateTypePicker'; -import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common'; +import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; import { usePermission } from '@backstage/plugin-permission-react'; import { ScaffolderPageContextMenu } from './ScaffolderPageContextMenu'; import { registerComponentRouteRef } from '../../routes'; diff --git a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx index 984e51f3b5..e557f4d165 100644 --- a/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx +++ b/plugins/scaffolder/src/components/TemplateCard/TemplateCard.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { DEFAULT_NAMESPACE, Entity, @@ -22,9 +23,9 @@ import { stringifyEntityRef, } from '@backstage/catalog-model'; import { - Button, ItemCardHeader, Link, + LinkButton, MarkdownContent, } from '@backstage/core-components'; import { @@ -291,13 +292,13 @@ export const TemplateCard = ({ template, deprecated }: TemplateCardProps) => { ))}
    - + ); diff --git a/plugins/scaffolder/src/components/TemplatePage/createValidator.test.ts b/plugins/scaffolder/src/components/TemplatePage/createValidator.test.ts index 177697eda0..f5be77811a 100644 --- a/plugins/scaffolder/src/components/TemplatePage/createValidator.test.ts +++ b/plugins/scaffolder/src/components/TemplatePage/createValidator.test.ts @@ -17,14 +17,32 @@ import { createValidator } from './createValidator'; import { CustomFieldValidator } from '@backstage/plugin-scaffolder-react'; import { ApiHolder } from '@backstage/core-plugin-api'; -import { FormValidation } from '@rjsf/core'; +import { FieldValidation, FormValidation } from '@rjsf/core'; describe('createValidator', () => { const validators: Record> = { - CustomPicker: (value, validation, _context) => { + CustomPicker: ( + value: unknown, + fieldValidation: FieldValidation, + _context: { apiHolder: ApiHolder }, + ) => { if (!value || !(value as { value?: unknown }).value) { - validation.addError('Error !'); + fieldValidation.addError('Error !'); + } + }, + TagPicker: ( + values: unknown, + fieldValidation: FieldValidation, + _context: { apiHolder: ApiHolder }, + ) => { + const input = values as string[]; + for (const item of input) { + if (!/^[a-z0-9-]+$/.test(item)) { + fieldValidation.addError( + 'A tag name can only contain lowercase letters, numeric characters or dashes', + ); + } } }, }; @@ -39,7 +57,7 @@ describe('createValidator', () => { apiHolder: apiHolderMock, }; - it('Should call validator for object property from a custom field extension', () => { + it('should call validator for object property from a custom field extension', () => { /* GIVEN */ const rootSchema = { title: 'Title', @@ -70,4 +88,39 @@ describe('createValidator', () => { expect(result).not.toBeNull(); expect(result.p1.addError).toHaveBeenCalledTimes(1); }); + + it('should call validator for array property from a custom field extension', () => { + /* GIVEN */ + const rootSchema = { + title: 'My form', + properties: { + tags: { + title: 'Tags', + type: 'array', + items: { + type: 'string', + 'ui:field': 'TagPicker', + }, + }, + }, + }; + const validator = createValidator(rootSchema, validators, context); + + const formData = { + tags: ['invalid-tag$$'], + }; + const errors = { + addError: jest.fn(), + tags: { + addError: jest.fn(), + } as unknown as FormValidation, + } as unknown as FormValidation; + + /* WHEN */ + const result = validator(formData, errors); + + /* THEN */ + expect(result).not.toBeNull(); + expect(result.tags.addError).toHaveBeenCalledTimes(1); + }); }); diff --git a/plugins/scaffolder/src/components/TemplatePage/createValidator.ts b/plugins/scaffolder/src/components/TemplatePage/createValidator.ts index 4a64481fc3..123a7e800e 100644 --- a/plugins/scaffolder/src/components/TemplatePage/createValidator.ts +++ b/plugins/scaffolder/src/components/TemplatePage/createValidator.ts @@ -23,6 +23,10 @@ function isObject(obj: unknown): obj is JsonObject { return typeof obj === 'object' && obj !== null && !Array.isArray(obj); } +function isArray(obj: unknown): obj is JsonObject { + return typeof obj === 'object' && obj !== null && Array.isArray(obj); +} + export const createValidator = ( rootSchema: JsonObject, validators: Record>, @@ -46,8 +50,8 @@ export const createValidator = ( for (const [key, propData] of Object.entries(formData)) { const propValidation = errors[key]; + const propSchemaProps = schemaProps[key]; if (isObject(propData)) { - const propSchemaProps = schemaProps[key]; if (isObject(propSchemaProps)) { validate( propSchemaProps, @@ -55,10 +59,24 @@ export const createValidator = ( propValidation as FormValidation, ); } + } else if (isArray(propData)) { + if (isObject(propSchemaProps)) { + const { items } = propSchemaProps; + if (isObject(items)) { + const fieldName = items['ui:field'] as string; + if (fieldName && typeof validators[fieldName] === 'function') { + validators[fieldName]!( + propData as JsonObject[], + propValidation, + context, + ); + } + } + } } else { - const propSchema = schemaProps[key]; const fieldName = - isObject(propSchema) && (propSchema['ui:field'] as string); + isObject(propSchemaProps) && + (propSchemaProps['ui:field'] as string); if (fieldName && typeof validators[fieldName] === 'function') { validators[fieldName]!( propData as JsonValue, diff --git a/plugins/scaffolder/src/index.ts b/plugins/scaffolder/src/index.ts index aa78874f9d..bc56629a2c 100644 --- a/plugins/scaffolder/src/index.ts +++ b/plugins/scaffolder/src/index.ts @@ -34,14 +34,3 @@ export { export * from './components'; export * from './deprecated'; - -/** next exports */ -export { NextScaffolderPage } from './plugin'; -export { - nextRouteRef, - nextScaffolderTaskRouteRef, - nextSelectedTemplateRouteRef, - type TemplateGroupFilter, - type NextRouterProps, - type FormProps, -} from './next'; diff --git a/plugins/scaffolder/src/next/OngoingTask/OngoingTask.tsx b/plugins/scaffolder/src/next/OngoingTask/OngoingTask.tsx index a68df01ed5..d0aaf4b838 100644 --- a/plugins/scaffolder/src/next/OngoingTask/OngoingTask.tsx +++ b/plugins/scaffolder/src/next/OngoingTask/OngoingTask.tsx @@ -25,10 +25,8 @@ import { nextSelectedTemplateRouteRef } from '../routes'; import { useRouteRef } from '@backstage/core-plugin-api'; import qs from 'qs'; import { ContextMenu } from './ContextMenu'; -import { - DefaultTemplateOutputs, - ScaffolderTaskOutput, -} from '@backstage/plugin-scaffolder-react'; +import { ScaffolderTaskOutput } from '@backstage/plugin-scaffolder-react'; +import { DefaultTemplateOutputs } from '@backstage/plugin-scaffolder-react/alpha'; const useStyles = makeStyles({ contentWrapper: { diff --git a/plugins/scaffolder/src/next/Router/Router.tsx b/plugins/scaffolder/src/next/Router/Router.tsx index 049579e16c..5e199cae9b 100644 --- a/plugins/scaffolder/src/next/Router/Router.tsx +++ b/plugins/scaffolder/src/next/Router/Router.tsx @@ -19,11 +19,13 @@ import { TemplateListPage } from '../TemplateListPage'; import { TemplateWizardPage } from '../TemplateWizardPage'; import { NextFieldExtensionOptions, + FormProps, +} from '@backstage/plugin-scaffolder-react/alpha'; +import { ScaffolderTaskOutput, SecretsContextProvider, useCustomFieldExtensions, useCustomLayouts, - type FormProps, } from '@backstage/plugin-scaffolder-react'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; @@ -32,6 +34,7 @@ import { DEFAULT_SCAFFOLDER_FIELD_EXTENSIONS } from '../../extensions/default'; import { nextActionsRouteRef, + nextEditRouteRef, nextScaffolderListTaskRouteRef, nextScaffolderTaskRouteRef, nextSelectedTemplateRouteRef, @@ -40,6 +43,7 @@ import { ErrorPage } from '@backstage/core-components'; import { OngoingTask } from '../OngoingTask'; import { ActionsPage } from '../../components/ActionsPage'; import { ListTasksPage } from '../../components/ListTasksPage'; +import { TemplateEditorPage } from '../TemplateEditorPage'; /** * The Props for the Scaffolder Router @@ -130,6 +134,18 @@ export const Router = (props: PropsWithChildren) => { /> } /> + + + + } + /> + } /> ({ + root: { + gridArea: 'pageContent', + display: 'grid', + gridTemplateAreas: ` + "controls controls" + "fieldForm preview" + `, + gridTemplateRows: 'auto 1fr', + gridTemplateColumns: '1fr 1fr', + }, + controls: { + gridArea: 'controls', + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + margin: theme.spacing(1), + }, + fieldForm: { + gridArea: 'fieldForm', + }, + preview: { + gridArea: 'preview', + }, +})); + +export const CustomFieldExplorer = ({ + customFieldExtensions = [], + onClose, +}: { + customFieldExtensions?: NextFieldExtensionOptions[]; + onClose?: () => void; +}) => { + const classes = useStyles(); + const fieldOptions = customFieldExtensions.filter(field => !!field.schema); + const [selectedField, setSelectedField] = useState(fieldOptions[0]); + const [fieldFormState, setFieldFormState] = useState({}); + const [refreshKey, setRefreshKey] = useState(Date.now()); + const sampleFieldTemplate = useMemo( + () => + yaml.stringify({ + parameters: [ + { + title: `${selectedField.name} Example`, + properties: { + [selectedField.name]: { + type: selectedField.schema?.returnValue?.type, + 'ui:field': selectedField.name, + 'ui:options': fieldFormState, + }, + }, + }, + ], + }), + [fieldFormState, selectedField], + ); + + const fieldComponents = useMemo(() => { + return Object.fromEntries( + customFieldExtensions.map(({ name, component }) => [name, component]), + ); + }, [customFieldExtensions]); + + const handleSelectionChange = useCallback( + selection => { + setSelectedField(selection); + setFieldFormState({}); + }, + [setFieldFormState, setSelectedField], + ); + + const handleFieldConfigChange = useCallback( + state => { + setFieldFormState(state); + // Force TemplateEditorForm to re-render since some fields + // may not be responsive to ui:option changes + setRefreshKey(Date.now()); + }, + [setFieldFormState, setRefreshKey], + ); + + return ( +
    +
    + + + Choose Custom Field Extension + + + + + + + +
    +
    + + + +
    handleFieldConfigChange(e.formData)} + validator={validator} + schema={selectedField.schema?.uiOptions || {}} + > + + +
    +
    +
    +
    + + + + + + + null} + /> +
    +
    + ); +}; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx new file mode 100644 index 0000000000..16067e8095 --- /dev/null +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditor.tsx @@ -0,0 +1,92 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { makeStyles } from '@material-ui/core'; +import React, { useState } from 'react'; +import type { LayoutOptions } from '@backstage/plugin-scaffolder-react'; +import { NextFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; +import { TemplateDirectoryAccess } from '../../lib/filesystem'; +import { DirectoryEditorProvider } from '../../components/TemplateEditorPage/DirectoryEditorContext'; +import { DryRunProvider } from '../../components/TemplateEditorPage/DryRunContext'; +import { DryRunResults } from '../../components/TemplateEditorPage/DryRunResults'; +import { TemplateEditorBrowser } from '../../components/TemplateEditorPage/TemplateEditorBrowser'; +import { TemplateEditorForm } from './TemplateEditorForm'; +import { TemplateEditorTextArea } from '../../components/TemplateEditorPage/TemplateEditorTextArea'; + +const useStyles = makeStyles({ + // Reset and fix sizing to make sure scrolling behaves correctly + root: { + gridArea: 'pageContent', + + display: 'grid', + gridTemplateAreas: ` + "browser editor preview" + "results results results" + `, + gridTemplateColumns: '1fr 3fr 2fr', + gridTemplateRows: '1fr auto', + }, + browser: { + gridArea: 'browser', + overflow: 'auto', + }, + editor: { + gridArea: 'editor', + overflow: 'auto', + }, + preview: { + gridArea: 'preview', + overflow: 'auto', + }, + results: { + gridArea: 'results', + }, +}); + +export const TemplateEditor = (props: { + directory: TemplateDirectoryAccess; + fieldExtensions?: NextFieldExtensionOptions[]; + layouts?: LayoutOptions[]; + onClose?: () => void; +}) => { + const classes = useStyles(); + + const [errorText, setErrorText] = useState(); + + return ( + + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + ); +}; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx new file mode 100644 index 0000000000..898487e200 --- /dev/null +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorForm.tsx @@ -0,0 +1,235 @@ +/* + * 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 { useApiHolder } from '@backstage/core-plugin-api'; +import { JsonObject, JsonValue } from '@backstage/types'; +import { makeStyles } from '@material-ui/core/styles'; +import React, { Component, ReactNode, useState } from 'react'; +import useDebounce from 'react-use/lib/useDebounce'; +import yaml from 'yaml'; +import { + LayoutOptions, + TemplateParameterSchema, +} from '@backstage/plugin-scaffolder-react'; +import { + NextFieldExtensionOptions, + Stepper, +} from '@backstage/plugin-scaffolder-react/alpha'; +import { useDryRun } from '../../components/TemplateEditorPage/DryRunContext'; +import { useDirectoryEditor } from '../../components/TemplateEditorPage/DirectoryEditorContext'; + +const useStyles = makeStyles({ + containerWrapper: { + position: 'relative', + width: '100%', + height: '100%', + }, + container: { + position: 'absolute', + top: 0, + bottom: 0, + left: 0, + right: 0, + overflow: 'auto', + }, +}); + +interface ErrorBoundaryProps { + invalidator: unknown; + setErrorText(errorText: string | undefined): void; + children: ReactNode; +} + +interface ErrorBoundaryState { + shouldRender: boolean; +} + +class ErrorBoundary extends Component { + state = { + shouldRender: true, + }; + + componentDidUpdate(prevProps: { invalidator: unknown }) { + if (prevProps.invalidator !== this.props.invalidator) { + this.setState({ shouldRender: true }); + } + } + + componentDidCatch(error: Error) { + this.props.setErrorText(error.message); + this.setState({ shouldRender: false }); + } + + render() { + return this.state.shouldRender ? this.props.children : null; + } +} + +interface TemplateEditorFormProps { + content?: string; + /** Setting this to true will cause the content to be parsed as if it is the template entity spec */ + contentIsSpec?: boolean; + setErrorText: (errorText?: string) => void; + onDryRun?: (data: JsonObject) => Promise; + fieldExtensions?: NextFieldExtensionOptions[]; + layouts?: LayoutOptions[]; +} + +function isJsonObject(value: JsonValue | undefined): value is JsonObject { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} + +/** Shows the a template form that is parsed from the provided content */ +export function TemplateEditorForm(props: TemplateEditorFormProps) { + const { + content, + contentIsSpec, + onDryRun, + setErrorText, + fieldExtensions = [], + layouts = [], + } = props; + const classes = useStyles(); + const apiHolder = useApiHolder(); + + const [steps, setSteps] = useState(); + + useDebounce( + () => { + try { + if (!content) { + setSteps(undefined); + return; + } + const parsed: JsonValue = yaml.parse(content); + + if (!isJsonObject(parsed)) { + setSteps(undefined); + return; + } + + let rootObj = parsed; + if (!contentIsSpec) { + const isTemplate = + String(parsed.kind).toLocaleLowerCase('en-US') === 'template'; + if (!isTemplate) { + setSteps(undefined); + return; + } + + rootObj = isJsonObject(parsed.spec) ? parsed.spec : {}; + } + + const { parameters } = rootObj; + + if (!Array.isArray(parameters)) { + setErrorText('Template parameters must be an array'); + setSteps(undefined); + return; + } + + setErrorText(); + setSteps( + parameters.flatMap(param => + isJsonObject(param) + ? [ + { + title: String(param.title), + schema: param, + }, + ] + : [], + ), + ); + } catch (e) { + setErrorText(e.message); + } + }, + 250, + [contentIsSpec, content, apiHolder], + ); + + if (!steps) { + return null; + } + + return ( +
    +
    + + { + await onDryRun?.(data); + }} + layouts={layouts} + components={{ createButtonText: onDryRun && 'Try It' }} + /> + +
    +
    + ); +} + +/** A version of the TemplateEditorForm that is connected to the DirectoryEditor and DryRun contexts */ +export function TemplateEditorFormDirectoryEditorDryRun( + props: Pick< + TemplateEditorFormProps, + 'setErrorText' | 'fieldExtensions' | 'layouts' + >, +) { + const { setErrorText, fieldExtensions = [], layouts } = props; + const dryRun = useDryRun(); + + const directoryEditor = useDirectoryEditor(); + const { selectedFile } = directoryEditor; + + const handleDryRun = async (values: JsonObject) => { + if (!selectedFile) { + return; + } + + try { + await dryRun.execute({ + templateContent: selectedFile.content, + values, + files: directoryEditor.files, + }); + setErrorText(); + } catch (e) { + setErrorText(String(e.cause || e)); + throw e; + } + }; + + const content = + selectedFile && selectedFile.path.match(/\.ya?ml$/) + ? selectedFile.content + : undefined; + + return ( + + ); +} + +TemplateEditorForm.DirectoryEditorDryRun = + TemplateEditorFormDirectoryEditorDryRun; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx new file mode 100644 index 0000000000..9863e99c73 --- /dev/null +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateEditorPage.tsx @@ -0,0 +1,105 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React, { useState } from 'react'; +import { Content, Header, Page } from '@backstage/core-components'; +import { + TemplateDirectoryAccess, + WebFileSystemAccess, +} from '../../lib/filesystem'; +import { CustomFieldExplorer } from './CustomFieldExplorer'; +import { TemplateEditor } from './TemplateEditor'; +import { TemplateFormPreviewer } from './TemplateFormPreviewer'; +import { type LayoutOptions } from '@backstage/plugin-scaffolder-react'; +import { NextFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; +import { TemplateEditorIntro } from '../../components/TemplateEditorPage/TemplateEditorIntro'; + +type Selection = + | { + type: 'local'; + directory: TemplateDirectoryAccess; + } + | { + type: 'form'; + } + | { + type: 'field-explorer'; + }; + +interface TemplateEditorPageProps { + defaultPreviewTemplate?: string; + customFieldExtensions?: NextFieldExtensionOptions[]; + layouts?: LayoutOptions[]; +} + +export function TemplateEditorPage(props: TemplateEditorPageProps) { + const [selection, setSelection] = useState(); + + let content: JSX.Element | null = null; + if (selection?.type === 'local') { + content = ( + setSelection(undefined)} + layouts={props.layouts} + /> + ); + } else if (selection?.type === 'form') { + content = ( + setSelection(undefined)} + layouts={props.layouts} + /> + ); + } else if (selection?.type === 'field-explorer') { + content = ( + setSelection(undefined)} + /> + ); + } else { + content = ( + + { + if (option === 'local') { + WebFileSystemAccess.requestDirectoryAccess() + .then(directory => setSelection({ type: 'local', directory })) + .catch(() => {}); + } else if (option === 'form') { + setSelection({ type: 'form' }); + } else if (option === 'field-explorer') { + setSelection({ type: 'field-explorer' }); + } + }} + /> + + ); + } + + return ( + +
    + {content} + + ); +} diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx new file mode 100644 index 0000000000..2aa1cc764d --- /dev/null +++ b/plugins/scaffolder/src/next/TemplateEditorPage/TemplateFormPreviewer.tsx @@ -0,0 +1,217 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Entity } from '@backstage/catalog-model'; +import { alertApiRef, useApi } from '@backstage/core-plugin-api'; +import { + catalogApiRef, + humanizeEntityRef, +} from '@backstage/plugin-catalog-react'; +import { + FormControl, + IconButton, + InputLabel, + LinearProgress, + makeStyles, + MenuItem, + Select, +} from '@material-ui/core'; +import CloseIcon from '@material-ui/icons/Close'; +import React, { useCallback, useState } from 'react'; +import useAsync from 'react-use/lib/useAsync'; +import yaml from 'yaml'; +import { type LayoutOptions } from '@backstage/plugin-scaffolder-react'; +import { NextFieldExtensionOptions } from '@backstage/plugin-scaffolder-react/alpha'; +import { TemplateEditorForm } from './TemplateEditorForm'; +import { TemplateEditorTextArea } from '../../components/TemplateEditorPage/TemplateEditorTextArea'; + +const EXAMPLE_TEMPLATE_PARAMS_YAML = `# Edit the template parameters below to see how they will render in the scaffolder form UI +parameters: + - title: Fill in some steps + required: + - name + properties: + name: + title: Name + type: string + description: Unique name of the component + owner: + title: Owner + type: string + description: Owner of the component + ui:field: OwnerPicker + ui:options: + catalogFilter: + kind: Group + - title: Choose a location + required: + - repoUrl + properties: + repoUrl: + title: Repository Location + type: string + ui:field: RepoUrlPicker + ui:options: + allowedHosts: + - github.com +steps: + - id: fetch-base + name: Fetch Base + action: fetch:template + input: + url: ./template + values: + name: \${{parameters.name}} +`; + +type TemplateOption = { + label: string; + value: Entity; +}; + +const useStyles = makeStyles(theme => ({ + root: { + gridArea: 'pageContent', + display: 'grid', + gridTemplateAreas: ` + "controls controls" + "textArea preview" + `, + gridTemplateRows: 'auto 1fr', + gridTemplateColumns: '1fr 1fr', + }, + controls: { + gridArea: 'controls', + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + margin: theme.spacing(1), + }, + textArea: { + gridArea: 'textArea', + }, + preview: { + gridArea: 'preview', + }, +})); + +export const TemplateFormPreviewer = ({ + defaultPreviewTemplate = EXAMPLE_TEMPLATE_PARAMS_YAML, + customFieldExtensions = [], + onClose, + layouts = [], +}: { + defaultPreviewTemplate?: string; + customFieldExtensions?: NextFieldExtensionOptions[]; + onClose?: () => void; + layouts?: LayoutOptions[]; +}) => { + const classes = useStyles(); + const alertApi = useApi(alertApiRef); + const catalogApi = useApi(catalogApiRef); + const [selectedTemplate, setSelectedTemplate] = useState(''); + const [errorText, setErrorText] = useState(); + const [templateOptions, setTemplateOptions] = useState([]); + const [templateYaml, setTemplateYaml] = useState(defaultPreviewTemplate); + + const { loading } = useAsync( + () => + catalogApi + .getEntities({ + filter: { kind: 'template' }, + fields: [ + 'kind', + 'metadata.namespace', + 'metadata.name', + 'metadata.title', + 'spec.parameters', + 'spec.steps', + 'spec.output', + ], + }) + .then(({ items }) => + setTemplateOptions( + items.map(template => ({ + label: + template.metadata.title ?? + humanizeEntityRef(template, { defaultKind: 'template' }), + value: template, + })), + ), + ) + .catch(e => + alertApi.post({ + message: `Error loading exisiting templates: ${e.message}`, + severity: 'error', + }), + ), + [catalogApi], + ); + + const handleSelectChange = useCallback( + selected => { + setSelectedTemplate(selected); + setTemplateYaml(yaml.stringify(selected.spec)); + }, + [setTemplateYaml], + ); + + return ( + <> + {loading && } +
    +
    + + + Load Existing Template + + + + + + + +
    +
    + +
    +
    + +
    +
    + + ); +}; diff --git a/plugins/scaffolder/src/next/TemplateEditorPage/index.ts b/plugins/scaffolder/src/next/TemplateEditorPage/index.ts new file mode 100644 index 0000000000..7ec6bddb64 --- /dev/null +++ b/plugins/scaffolder/src/next/TemplateEditorPage/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { TemplateEditorPage } from './TemplateEditorPage'; diff --git a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx b/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx index 16e0a355a3..069a2cc6c5 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx +++ b/plugins/scaffolder/src/next/TemplateListPage/RegisterExistingButton.tsx @@ -21,7 +21,7 @@ import useMediaQuery from '@material-ui/core/useMediaQuery'; import React from 'react'; import { Link as RouterLink, LinkProps } from 'react-router-dom'; import AddCircleOutline from '@material-ui/icons/AddCircleOutline'; -import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common'; +import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; import { usePermission } from '@backstage/plugin-permission-react'; /** diff --git a/plugins/scaffolder/src/next/TemplateListPage/TemplateGroups.test.tsx b/plugins/scaffolder/src/next/TemplateListPage/TemplateGroups.test.tsx index f76c1a4ab6..6fe2d6beb9 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/TemplateGroups.test.tsx +++ b/plugins/scaffolder/src/next/TemplateListPage/TemplateGroups.test.tsx @@ -18,7 +18,7 @@ jest.mock('@backstage/plugin-catalog-react', () => ({ useEntityList: jest.fn(), })); -jest.mock('@backstage/plugin-scaffolder-react', () => ({ +jest.mock('@backstage/plugin-scaffolder-react/alpha', () => ({ TemplateGroup: jest.fn(() => null), })); @@ -27,7 +27,7 @@ import { useEntityList } from '@backstage/plugin-catalog-react'; import { TemplateGroups } from './TemplateGroups'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import { errorApiRef } from '@backstage/core-plugin-api'; -import { TemplateGroup } from '@backstage/plugin-scaffolder-react'; +import { TemplateGroup } from '@backstage/plugin-scaffolder-react/alpha'; import { nextRouteRef } from '../routes'; describe('TemplateGroups', () => { diff --git a/plugins/scaffolder/src/next/TemplateListPage/TemplateGroups.tsx b/plugins/scaffolder/src/next/TemplateListPage/TemplateGroups.tsx index 485b0e40cd..590ef802bd 100644 --- a/plugins/scaffolder/src/next/TemplateListPage/TemplateGroups.tsx +++ b/plugins/scaffolder/src/next/TemplateListPage/TemplateGroups.tsx @@ -30,7 +30,7 @@ import { useApp, useRouteRef, } from '@backstage/core-plugin-api'; -import { TemplateGroup } from '@backstage/plugin-scaffolder-react'; +import { TemplateGroup } from '@backstage/plugin-scaffolder-react/alpha'; import { viewTechDocRouteRef } from '../../routes'; import { nextSelectedTemplateRouteRef } from '../routes'; import { useNavigate } from 'react-router-dom'; diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx index b71d0bd7a3..4825715fcb 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx +++ b/plugins/scaffolder/src/next/TemplateWizardPage/TemplateWizardPage.tsx @@ -25,13 +25,13 @@ import { import { scaffolderApiRef, useTemplateSecrets, - Workflow, type LayoutOptions, } from '@backstage/plugin-scaffolder-react'; import { - NextFieldExtensionOptions, FormProps, -} from '@backstage/plugin-scaffolder-react'; + Workflow, + NextFieldExtensionOptions, +} from '@backstage/plugin-scaffolder-react/alpha'; import { JsonValue } from '@backstage/types'; import { Header, Page } from '@backstage/core-components'; import { diff --git a/plugins/search-backend-module-elasticsearch/CHANGELOG.md b/plugins/search-backend-module-elasticsearch/CHANGELOG.md index 71dccfef4f..1a73eecf55 100644 --- a/plugins/search-backend-module-elasticsearch/CHANGELOG.md +++ b/plugins/search-backend-module-elasticsearch/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-search-backend-module-elasticsearch +## 1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/plugin-search-backend-node@1.1.4-next.0 + - @backstage/plugin-search-common@1.2.1 + +## 1.1.3 + +### Patch Changes + +- 896566906b: Export `decodeElasticSearchPageCursor` utility function +- Updated dependencies + - @backstage/config@1.0.6 + - @backstage/plugin-search-backend-node@1.1.3 + - @backstage/plugin-search-common@1.2.1 + ## 1.1.3-next.2 ### Patch Changes diff --git a/plugins/search-backend-module-elasticsearch/package.json b/plugins/search-backend-module-elasticsearch/package.json index 2eb85f5f2c..d8e1ee7021 100644 --- a/plugins/search-backend-module-elasticsearch/package.json +++ b/plugins/search-backend-module-elasticsearch/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-elasticsearch", "description": "A module for the search backend that implements search using ElasticSearch", - "version": "1.1.3-next.2", + "version": "1.1.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-module-pg/CHANGELOG.md b/plugins/search-backend-module-pg/CHANGELOG.md index 1d17c6707c..abfc6e5060 100644 --- a/plugins/search-backend-module-pg/CHANGELOG.md +++ b/plugins/search-backend-module-pg/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-search-backend-module-pg +## 0.5.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-search-backend-node@1.1.4-next.0 + - @backstage/plugin-search-common@1.2.1 + +## 0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-search-backend-node@1.1.3 + - @backstage/plugin-search-common@1.2.1 + ## 0.5.3-next.2 ### Patch Changes diff --git a/plugins/search-backend-module-pg/package.json b/plugins/search-backend-module-pg/package.json index 7883475f34..f944cf7c59 100644 --- a/plugins/search-backend-module-pg/package.json +++ b/plugins/search-backend-module-pg/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-module-pg", "description": "A module for the search backend that implements search using PostgreSQL", - "version": "0.5.3-next.2", + "version": "0.5.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend-node/CHANGELOG.md b/plugins/search-backend-node/CHANGELOG.md index bf9306cb1d..eedafe3497 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.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + +## 1.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + ## 1.1.3-next.2 ### Patch Changes diff --git a/plugins/search-backend-node/package.json b/plugins/search-backend-node/package.json index 1bf73971d1..f8ec1c00b0 100644 --- a/plugins/search-backend-node/package.json +++ b/plugins/search-backend-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend-node", "description": "A library for Backstage backend plugins that want to interact with the search backend plugin", - "version": "1.1.3-next.2", + "version": "1.1.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-backend/CHANGELOG.md b/plugins/search-backend/CHANGELOG.md index c31930c867..3bd3b84554 100644 --- a/plugins/search-backend/CHANGELOG.md +++ b/plugins/search-backend/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-search-backend +## 1.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.6-next.0 + - @backstage/plugin-search-backend-node@1.1.4-next.0 + - @backstage/plugin-search-common@1.2.1 + +## 1.2.3 + +### Patch Changes + +- 1b30c9a0f7: Change the router's response to include the error message instead of its object type in case it fails during a search query because the messages have more info. +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-permission-node@0.7.5 + - @backstage/plugin-search-backend-node@1.1.3 + - @backstage/plugin-search-common@1.2.1 + ## 1.2.3-next.2 ### Patch Changes diff --git a/plugins/search-backend/package.json b/plugins/search-backend/package.json index 31594bc8af..4eb8187a2a 100644 --- a/plugins/search-backend/package.json +++ b/plugins/search-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search-backend", "description": "The Backstage backend plugin that provides your backstage app with search", - "version": "1.2.3-next.2", + "version": "1.2.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-react/CHANGELOG.md b/plugins/search-react/CHANGELOG.md index fa58979796..52ac478207 100644 --- a/plugins/search-react/CHANGELOG.md +++ b/plugins/search-react/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-search-react +## 1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-search-common@1.2.1 + +## 1.5.0 + +### Minor Changes + +- 0eaa579f89: - Create the search results extensions, for more details see the documentation [here](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions); + - Update the `SearchResult`, `SearchResultList` and `SearchResultGroup` components to use extensions and default their props to optionally accept a query, when the query is not passed, the component tries to get it from the search context. + +### Patch Changes + +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-search-common@1.2.1 + ## 1.5.0-next.1 ### Patch Changes diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index d353189add..fd8242b552 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-search-react", - "version": "1.5.0-next.1", + "version": "1.5.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.stories.tsx b/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.stories.tsx index a790c12a8a..7049b7f4ef 100644 --- a/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.stories.tsx +++ b/plugins/search-react/src/components/DefaultResultListItem/DefaultResultListItem.stories.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { Button } from '@backstage/core-components'; +import { LinkButton } from '@backstage/core-components'; import { lightTheme } from '@backstage/theme'; import { Grid } from '@material-ui/core'; import CssBaseline from '@material-ui/core/CssBaseline'; @@ -66,7 +66,7 @@ export const WithSecondaryAction = () => { { style={{ textTransform: 'lowercase' }} > {mockSearchResult.owner} - + } /> ); diff --git a/plugins/search/CHANGELOG.md b/plugins/search/CHANGELOG.md index 7853a44abb..974fcc4a5d 100644 --- a/plugins/search/CHANGELOG.md +++ b/plugins/search/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-search +## 1.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 1.1.0 + +### Minor Changes + +- 0eaa579f89: Update `SearchModal` component to use `SearchResult` extensions. + +### Patch Changes + +- 26fb21aa8b: Implement a `showCounts` option to display result counts per type in `SearchType.Accordion` +- 66e2aab4c4: Updated colors for each tab used on search modal, to improve color contrast. Aria label added to tabs wrapper component. `disableRipple` property on the `Tab` component removed to improve keyboard navigation indicator. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/version-bridge@1.0.3 + - @backstage/plugin-search-common@1.2.1 + ## 1.1.0-next.2 ### Patch Changes diff --git a/plugins/search/package.json b/plugins/search/package.json index c2f635f762..31b57878dd 100644 --- a/plugins/search/package.json +++ b/plugins/search/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-search", "description": "The Backstage plugin that provides your backstage app with search", - "version": "1.1.0-next.2", + "version": "1.1.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -65,7 +65,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index 922b06c8d8..1f23a87326 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-sentry +## 0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.5.0 + +### Minor Changes + +- 6a8d6b9a0c: Add option to filter issues based on the time it was triggered + +### Patch Changes + +- 85b04f659a: Internal refactor to not use deprecated `substr` +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.5.0-next.2 ### Minor Changes diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index e757ff25a4..7d385260f4 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sentry", "description": "A Backstage plugin that integrates towards Sentry", - "version": "0.5.0-next.2", + "version": "0.5.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -62,7 +62,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md index 94baec18aa..ed4df4535b 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-shortcuts +## 0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + +## 0.3.7 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/types@1.0.2 + ## 0.3.7-next.1 ### Patch Changes diff --git a/plugins/shortcuts/README.md b/plugins/shortcuts/README.md index d7f8f19aec..cd79901656 100644 --- a/plugins/shortcuts/README.md +++ b/plugins/shortcuts/README.md @@ -7,7 +7,8 @@ The shortcuts plugin allows a user to have easy access to pages within a Backsta ### Install the package: ```bash -yarn add @backstage/plugin-shortcuts +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-shortcuts ``` ### Register plugin: diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 61b48b1c55..0209e76ec7 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-shortcuts", "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", - "version": "0.3.7-next.1", + "version": "0.3.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -50,7 +50,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/sonarqube-backend/CHANGELOG.md b/plugins/sonarqube-backend/CHANGELOG.md index 6fb7414acb..2543e6ca49 100644 --- a/plugins/sonarqube-backend/CHANGELOG.md +++ b/plugins/sonarqube-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-sonarqube-backend +## 0.1.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## 0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + ## 0.1.7-next.2 ### Patch Changes diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json index 99c0a8b486..6fc9a7080a 100644 --- a/plugins/sonarqube-backend/package.json +++ b/plugins/sonarqube-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-sonarqube-backend", - "version": "0.1.7-next.2", + "version": "0.1.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -36,7 +36,7 @@ "@backstage/cli": "workspace:^", "@backstage/test-utils": "workspace:^", "@types/supertest": "^2.0.12", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.2.4" }, "files": [ diff --git a/plugins/sonarqube-react/CHANGELOG.md b/plugins/sonarqube-react/CHANGELOG.md index b938ce8b37..7372052227 100644 --- a/plugins/sonarqube-react/CHANGELOG.md +++ b/plugins/sonarqube-react/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-sonarqube-react +## 0.1.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- 8ae65a0bc1: Moved imports from `/alpha` to main public exports. +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/sonarqube-react/alpha-api-report.md b/plugins/sonarqube-react/alpha-api-report.md new file mode 100644 index 0000000000..4fad469d12 --- /dev/null +++ b/plugins/sonarqube-react/alpha-api-report.md @@ -0,0 +1,65 @@ +## API Report File for "@backstage/plugin-sonarqube-react" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ApiRef } from '@backstage/core-plugin-api'; +import { Entity } from '@backstage/catalog-model'; + +// @public (undocumented) +export interface FindingSummary { + // (undocumented) + getComponentMeasuresUrl: SonarUrlProcessorFunc; + // (undocumented) + getIssuesUrl: SonarUrlProcessorFunc; + // (undocumented) + getSecurityHotspotsUrl: () => string; + // (undocumented) + lastAnalysis: string; + // (undocumented) + metrics: Metrics; + // (undocumented) + projectUrl: string; +} + +// @public (undocumented) +export type MetricKey = + | 'alert_status' + | 'bugs' + | 'reliability_rating' + | 'vulnerabilities' + | 'security_rating' + | 'code_smells' + | 'sqale_rating' + | 'security_hotspots_reviewed' + | 'security_review_rating' + | 'coverage' + | 'duplicated_lines_density'; + +// @public +export type Metrics = { + [key in MetricKey]: string | undefined; +}; + +// @public (undocumented) +export type SonarQubeApi = { + getFindingSummary(options: { + componentKey?: string; + projectInstance?: string; + }): Promise; +}; + +// @public (undocumented) +export const sonarQubeApiRef: ApiRef; + +// @public (undocumented) +export type SonarUrlProcessorFunc = (identifier: string) => string; + +// @public +export const useProjectInfo: (entity: Entity) => { + projectInstance: string | undefined; + projectKey: string | undefined; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/sonarqube-react/api-report.md b/plugins/sonarqube-react/api-report.md index be84c45cce..6ffa98915b 100644 --- a/plugins/sonarqube-react/api-report.md +++ b/plugins/sonarqube-react/api-report.md @@ -6,7 +6,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; -// @alpha (undocumented) +// @public (undocumented) export interface FindingSummary { // (undocumented) getComponentMeasuresUrl: SonarUrlProcessorFunc; @@ -25,7 +25,7 @@ export interface FindingSummary { // @public (undocumented) export const isSonarQubeAvailable: (entity: Entity) => boolean; -// @alpha (undocumented) +// @public (undocumented) export type MetricKey = | 'alert_status' | 'bugs' @@ -39,7 +39,7 @@ export type MetricKey = | 'coverage' | 'duplicated_lines_density'; -// @alpha +// @public export type Metrics = { [key in MetricKey]: string | undefined; }; @@ -47,7 +47,7 @@ export type Metrics = { // @public (undocumented) export const SONARQUBE_PROJECT_KEY_ANNOTATION = 'sonarqube.org/project-key'; -// @alpha (undocumented) +// @public (undocumented) export type SonarQubeApi = { getFindingSummary(options: { componentKey?: string; @@ -55,13 +55,13 @@ export type SonarQubeApi = { }): Promise; }; -// @alpha (undocumented) +// @public (undocumented) export const sonarQubeApiRef: ApiRef; -// @alpha (undocumented) +// @public (undocumented) export type SonarUrlProcessorFunc = (identifier: string) => string; -// @alpha +// @public export const useProjectInfo: (entity: Entity) => { projectInstance: string | undefined; projectKey: string | undefined; diff --git a/plugins/sonarqube-react/package.json b/plugins/sonarqube-react/package.json index 53837a47cf..9a567040cb 100644 --- a/plugins/sonarqube-react/package.json +++ b/plugins/sonarqube-react/package.json @@ -1,14 +1,22 @@ { "name": "@backstage/plugin-sonarqube-react", - "version": "0.1.2-next.1", + "version": "0.1.4-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", - "alphaTypes": "dist/index.alpha.d.ts" + "access": "public" + }, + "exports": { + ".": "./src/index.ts", + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "package.json": [ + "package.json" + ] + } }, "backstage": { "role": "web-library" @@ -23,7 +31,7 @@ "backstage" ], "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", diff --git a/plugins/sonarqube-react/src/api/SonarQubeApi.ts b/plugins/sonarqube-react/src/api/SonarQubeApi.ts index ee6b1bb6a3..13517d97fe 100644 --- a/plugins/sonarqube-react/src/api/SonarQubeApi.ts +++ b/plugins/sonarqube-react/src/api/SonarQubeApi.ts @@ -16,7 +16,7 @@ import { createApiRef } from '@backstage/core-plugin-api'; -/** @alpha */ +/** @public */ export type MetricKey = // alert status | 'alert_status' @@ -43,11 +43,11 @@ export type MetricKey = // duplicated lines | 'duplicated_lines_density'; -/** @alpha */ +/** @public */ export type SonarUrlProcessorFunc = (identifier: string) => string; /** - * @alpha + * @public * * Define a type to make sure that all metrics are used */ @@ -55,7 +55,7 @@ export type Metrics = { [key in MetricKey]: string | undefined; }; -/** @alpha */ +/** @public */ export interface FindingSummary { lastAnalysis: string; metrics: Metrics; @@ -65,12 +65,12 @@ export interface FindingSummary { getSecurityHotspotsUrl: () => string; } -/** @alpha */ +/** @public */ export const sonarQubeApiRef = createApiRef({ id: 'plugin.sonarqube.service', }); -/** @alpha */ +/** @public */ export type SonarQubeApi = { getFindingSummary(options: { componentKey?: string; diff --git a/plugins/sonarqube-react/src/hooks/useProjectInfo.ts b/plugins/sonarqube-react/src/hooks/useProjectInfo.ts index 119e568e46..3336bd1805 100644 --- a/plugins/sonarqube-react/src/hooks/useProjectInfo.ts +++ b/plugins/sonarqube-react/src/hooks/useProjectInfo.ts @@ -25,7 +25,7 @@ export const SONARQUBE_PROJECT_INSTANCE_SEPARATOR = '/'; * * If part or all info are not found, they will default to undefined * - * @alpha + * @public * @param entity - entity to find the sonarqube information from. * @returns a ProjectInfo properly populated. */ diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index e51e0a65ac..7235835af6 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-sonarqube +## 0.6.5-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- 8ae65a0bc1: Moved imports from `/alpha` to main public exports. +- d3d624e8e8: Show a more appropriate icon if there are no code smells and/or vulnerabilities. +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/plugin-sonarqube-react@0.1.4-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.6.3 + +### Patch Changes + +- 6310eacc11: Additional export added in order to bind SonarQubeClient to its apiref +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-sonarqube-react@0.1.2 + ## 0.6.3-next.2 ### Patch Changes diff --git a/plugins/sonarqube/api-report.md b/plugins/sonarqube/api-report.md index f77c66ac59..db3f38e31d 100644 --- a/plugins/sonarqube/api-report.md +++ b/plugins/sonarqube/api-report.md @@ -42,7 +42,7 @@ export const SonarQubeCard: (props: { duplicationRatings?: DuplicationRating[]; }) => JSX.Element; -// @alpha (undocumented) +// @public (undocumented) export class SonarQubeClient implements SonarQubeApi { constructor({ discoveryApi, diff --git a/plugins/sonarqube/dev/index.tsx b/plugins/sonarqube/dev/index.tsx index a34c4d4e82..8d38c7314a 100644 --- a/plugins/sonarqube/dev/index.tsx +++ b/plugins/sonarqube/dev/index.tsx @@ -22,10 +22,10 @@ import { EntitySonarQubeCard, sonarQubePlugin } from '../src'; import { Content, Header, Page } from '@backstage/core-components'; import { FindingSummary, - SONARQUBE_PROJECT_KEY_ANNOTATION, SonarQubeApi, sonarQubeApiRef, } from '@backstage/plugin-sonarqube-react'; +import { SONARQUBE_PROJECT_KEY_ANNOTATION } from '@backstage/plugin-sonarqube-react'; const entity = (name?: string) => ({ diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 80dd578523..ef14f6da58 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.6.3-next.2", + "version": "0.6.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -61,7 +61,7 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/sonarqube/src/api/SonarQubeClient.ts b/plugins/sonarqube/src/api/SonarQubeClient.ts index f742fe026f..14c7936e92 100644 --- a/plugins/sonarqube/src/api/SonarQubeClient.ts +++ b/plugins/sonarqube/src/api/SonarQubeClient.ts @@ -23,7 +23,7 @@ import { import { InstanceUrlWrapper, FindingsWrapper } from './types'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; -/** @alpha */ +/** @public */ export class SonarQubeClient implements SonarQubeApi { discoveryApi: DiscoveryApi; identityApi: IdentityApi; diff --git a/plugins/sonarqube/src/api/types.ts b/plugins/sonarqube/src/api/types.ts index 470d05903a..29b7e7ca54 100644 --- a/plugins/sonarqube/src/api/types.ts +++ b/plugins/sonarqube/src/api/types.ts @@ -14,8 +14,10 @@ * limitations under the License. */ -import { MetricKey as NonDeprecatedMetricKey } from '@backstage/plugin-sonarqube-react'; -import { SonarUrlProcessorFunc as NonDeprecatedSonarUrlProcessorFunc } from '@backstage/plugin-sonarqube-react'; +import { + MetricKey as NonDeprecatedMetricKey, + SonarUrlProcessorFunc as NonDeprecatedSonarUrlProcessorFunc, +} from '@backstage/plugin-sonarqube-react'; export interface InstanceUrlWrapper { instanceUrl: string; diff --git a/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx b/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx index 900c8d082c..932641e48d 100644 --- a/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx +++ b/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx @@ -16,16 +16,18 @@ import { useEntity } from '@backstage/plugin-catalog-react'; import { - SONARQUBE_PROJECT_KEY_ANNOTATION, sonarQubeApiRef, useProjectInfo, } from '@backstage/plugin-sonarqube-react'; +import { SONARQUBE_PROJECT_KEY_ANNOTATION } from '@backstage/plugin-sonarqube-react'; import { Chip, Grid } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; import BugReport from '@material-ui/icons/BugReport'; +import Lock from '@material-ui/icons/Lock'; import LockOpen from '@material-ui/icons/LockOpen'; import Security from '@material-ui/icons/Security'; import SentimentVeryDissatisfied from '@material-ui/icons/SentimentVeryDissatisfied'; +import SentimentVerySatisfied from '@material-ui/icons/SentimentVerySatisfied'; import React, { useMemo } from 'react'; import useAsync from 'react-use/lib/useAsync'; import { Percentage } from './Percentage'; @@ -200,14 +202,26 @@ export const SonarQubeCard = (props: { rightSlot={} /> } + titleIcon={ + value.metrics.vulnerabilities === '0' ? ( + + ) : ( + + ) + } title="Vulnerabilities" link={value.getIssuesUrl('VULNERABILITY')} leftSlot={} rightSlot={} /> } + titleIcon={ + value.metrics.code_smells === '0' ? ( + + ) : ( + + ) + } title="Code Smells" link={value.getIssuesUrl('CODE_SMELL')} leftSlot={} diff --git a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx index 59258e5312..0bf5f04640 100644 --- a/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx +++ b/plugins/sonarqube/src/components/SonarQubeContentPage/SonarQubeContentPage.test.tsx @@ -18,10 +18,10 @@ import { EntityProvider } from '@backstage/plugin-catalog-react'; import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; import React from 'react'; import { - isSonarQubeAvailable, - SONARQUBE_PROJECT_KEY_ANNOTATION, SonarQubeApi, sonarQubeApiRef, + isSonarQubeAvailable, + SONARQUBE_PROJECT_KEY_ANNOTATION, } from '@backstage/plugin-sonarqube-react'; const Providers = ({ diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index c5de65a3d3..abf9a2cca9 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-splunk-on-call +## 0.4.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.4.4 + +### Patch Changes + +- 3598136ac7: Refactor plugin Card component to not rerender contents unnecessarily. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + ## 0.4.4-next.2 ### Patch Changes diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index 097cc1c6fd..2703a95871 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-splunk-on-call", "description": "A Backstage plugin that integrates towards Splunk On-Call", - "version": "0.4.4-next.2", + "version": "0.4.5-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -60,7 +60,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "configSchema": "config.d.ts", "files": [ diff --git a/plugins/stack-overflow-backend/CHANGELOG.md b/plugins/stack-overflow-backend/CHANGELOG.md index aac07808c9..d10de5de42 100644 --- a/plugins/stack-overflow-backend/CHANGELOG.md +++ b/plugins/stack-overflow-backend/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-stack-overflow-backend +## 0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/plugin-search-common@1.2.1 + +## 0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/config@1.0.6 + - @backstage/plugin-search-common@1.2.1 + ## 0.1.11-next.2 ### Patch Changes diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index e40e3e846a..e5cf07c515 100644 --- a/plugins/stack-overflow-backend/package.json +++ b/plugins/stack-overflow-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow-backend", - "version": "0.1.11-next.2", + "version": "0.1.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -43,7 +43,7 @@ "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/stack-overflow/CHANGELOG.md b/plugins/stack-overflow/CHANGELOG.md index f80e350a03..91ea342e8a 100644 --- a/plugins/stack-overflow/CHANGELOG.md +++ b/plugins/stack-overflow/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-stack-overflow +## 0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-home@0.4.32-next.0 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/plugin-home@0.4.31 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/config@1.0.6 + - @backstage/plugin-search-common@1.2.1 + ## 0.1.11-next.2 ### Patch Changes diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index c9fbe7e7a3..cd0cfeabf3 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow", - "version": "0.1.11-next.2", + "version": "0.1.12-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -49,7 +49,7 @@ "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/stackstorm/.eslintrc.js b/plugins/stackstorm/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/stackstorm/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/stackstorm/CHANGELOG.md b/plugins/stackstorm/CHANGELOG.md new file mode 100644 index 0000000000..c6718679a3 --- /dev/null +++ b/plugins/stackstorm/CHANGELOG.md @@ -0,0 +1,15 @@ +# @backstage/plugin-stackstorm + +## 0.1.0-next.0 + +### Minor Changes + +- f3a15259e9: Add StackStorm plugin to Backstage which is interfacing with StackStorm API. It allows users to view workflow executions, packs and actions. For installation and configuration instructions please view [README.md](https://github.com/backstage/backstage/tree/master/plugins/stackstorm/README.md) + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 diff --git a/plugins/stackstorm/README.md b/plugins/stackstorm/README.md new file mode 100644 index 0000000000..0d5caeaca2 --- /dev/null +++ b/plugins/stackstorm/README.md @@ -0,0 +1,61 @@ +# StackStorm Plugin + +Welcome to the StackStorm plugin! + +A Backstage integration for the [StackStorm](https://docs.stackstorm.com/overview.html). +This plugin allows you to display a list of executions, view execution details, +browse installed packs, actions and more. + +## Getting started + +To get started, first you need a running instance of StackStorm. +One of the quickest ways is [running StackStorm with Docker](https://docs.stackstorm.com/install/docker.html). + +### Installation + +1. Install the plugin with `yarn` in the root of your Backstage directory + +```bash +# From your Backstage root directory +yarn --cwd packages/app add @backstage/plugin-stackstorm +``` + +2. Import and use the plugin in `packages/app/src/App.tsx` + +```tsx +import { StackstormPage } from '@backstage/plugin-stackstorm'; + +const routes = ( + + {/* ...other routes */} + } /> + +``` + +### Configuration + +1. Configure `webUrl` for links to the StackStorm Web UI in `app-config.yaml`. + +```yaml +stackstorm: + webUrl: 'https://your.stackstorm.webui.com' +``` + +2. Configure `stackstorm` proxy + This plugin uses the Backstage proxy to securely communicate with StackStorm API. + Add the following to your `app-config.yaml` to enable this configuration: + +```yaml +proxy: + '/stackstorm': + target: https://your.stackstorm.instance.com/api + headers: + St2-Api-Key: ${ST2_API_KEY} +``` + +In your production deployment of Backstage, you would also need to ensure that +you've set the `ST2_API_KEY` environment variable before starting +the backend. + +Read more about how to find or generate this key in the +[StackStorm Authentication Documentation](https://docs.stackstorm.com/authentication.html#api-keys). diff --git a/plugins/stackstorm/api-report.md b/plugins/stackstorm/api-report.md new file mode 100644 index 0000000000..3e3d79fe27 --- /dev/null +++ b/plugins/stackstorm/api-report.md @@ -0,0 +1,22 @@ +## API Report File for "@backstage/plugin-stackstorm" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { RouteRef } from '@backstage/core-plugin-api'; + +// @public +export const StackstormPage: () => JSX.Element; + +// @public +export const stackstormPlugin: BackstagePlugin< + { + root: RouteRef; + }, + {}, + {} +>; +``` diff --git a/plugins/stackstorm/config.d.ts b/plugins/stackstorm/config.d.ts new file mode 100644 index 0000000000..bf7b56823a --- /dev/null +++ b/plugins/stackstorm/config.d.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export interface Config { + stackstorm?: { + /** + * StackStorm Web UI url + * Used in links to StackStorm web UI + * @visibility frontend + */ + webUrl: string; + }; +} diff --git a/plugins/stackstorm/dev/index.tsx b/plugins/stackstorm/dev/index.tsx new file mode 100644 index 0000000000..33bd89adda --- /dev/null +++ b/plugins/stackstorm/dev/index.tsx @@ -0,0 +1,27 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { stackstormPlugin, StackstormPage } from '../src/plugin'; + +createDevApp() + .registerPlugin(stackstormPlugin) + .addPage({ + element: , + title: 'Root Page', + path: '/stackstorm', + }) + .render(); diff --git a/plugins/stackstorm/package.json b/plugins/stackstorm/package.json new file mode 100644 index 0000000000..e00821cf77 --- /dev/null +++ b/plugins/stackstorm/package.json @@ -0,0 +1,66 @@ +{ + "name": "@backstage/plugin-stackstorm", + "description": "A Backstage plugin that integrates towards StackStorm", + "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" + }, + "backstage": { + "role": "frontend-plugin" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/stackstorm" + }, + "keywords": [ + "backstage", + "stackstorm", + "st2" + ], + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/core-components": "workspace:^", + "@backstage/core-plugin-api": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/theme": "workspace:^", + "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.57", + "react-use": "^17.2.4" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "workspace:^", + "@backstage/core-app-api": "workspace:^", + "@backstage/dev-utils": "workspace:^", + "@backstage/test-utils": "workspace:^", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/node": "*", + "cross-fetch": "^3.1.5", + "msw": "^1.0.0" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts" +} diff --git a/plugins/stackstorm/src/api/StackstormClient.test.ts b/plugins/stackstorm/src/api/StackstormClient.test.ts new file mode 100644 index 0000000000..9757bde2af --- /dev/null +++ b/plugins/stackstorm/src/api/StackstormClient.test.ts @@ -0,0 +1,226 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ConfigReader, UrlPatternDiscovery } from '@backstage/core-app-api'; +import { MockFetchApi, setupRequestMockHandlers } from '@backstage/test-utils'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { StackstormClient } from './StackstormClient'; +import { Action, Execution, Pack } from './types'; + +const server = setupServer(); + +const executions: Execution[] = [ + { + id: '63dcac3e18ba00e09e7bb3b6', + action: { + name: 'post_message', + ref: 'chatops.post_message', + description: 'Post a message to stream for chatops', + pack: 'chatops', + runner_type: 'announcement', + id: '62fe101b11935b6aaff4ff92', + }, + status: 'succeeded', + start_timestamp: new Date().toISOString(), + end_timestamp: new Date().toISOString(), + result: {}, + parameters: {}, + elapsed_seconds: 2.2, + log: [], + }, + { + id: '63dcac3e18ba00e09e7bb3b6', + action: { + name: 'post_result', + ref: 'chatops.post_result', + description: 'Post an execution result to stream for chatops', + pack: 'chatops', + runner_type: 'orquesta', + id: '62fe101b11935b6aaff4ff93', + }, + status: 'succeeded', + start_timestamp: new Date().toISOString(), + end_timestamp: new Date().toISOString(), + result: {}, + parameters: {}, + elapsed_seconds: 18.5, + log: [], + }, + { + id: '63dcac3c9e0b4fe98f46becc', + action: { + name: 'run', + ref: 'shell.run', + description: 'Run shell script', + pack: 'shell', + runner_type: 'shell', + id: '63736caac3d8557c4d61883a', + }, + status: 'failed', + start_timestamp: new Date().toISOString(), + end_timestamp: new Date().toISOString(), + result: {}, + parameters: {}, + elapsed_seconds: 5.0, + log: [], + }, +]; + +const executionWithDetails: Execution = { + id: '63dcac3e18ba00e09e7bb3b6', + action: { + name: 'post_message', + ref: 'chatops.post_message', + description: 'Post a message to stream for chatops', + pack: 'chatops', + runner_type: 'announcement', + id: '62fe101b11935b6aaff4ff92', + }, + status: 'succeeded', + start_timestamp: new Date().toISOString(), + end_timestamp: new Date().toISOString(), + result: { + output: { + result: 'hello', + }, + }, + parameters: { + var: 'val', + }, + elapsed_seconds: 2.2, + log: [ + { status: 'requested', timestamp: new Date().toISOString() }, + { status: 'succeeded', timestamp: new Date().toISOString() }, + ], +}; + +const packs: Pack[] = [ + { + ref: 'chatops', + description: 'ChatOps integration pack', + version: '3.7.0', + }, + { + ref: 'core', + description: 'Basic core actions.', + version: '3.7.0', + }, +]; + +const actions: Action[] = [ + { + id: '62fe101b11935b6aaff4ff96', + name: 'announcement', + ref: 'core.announcement', + pack: 'core', + description: + 'Action that broadcasts the announcement to all stream consumers.', + runner_type: 'announcement', + }, + { + id: '62fe101b11935b6aaff4ff97', + name: 'echo', + ref: 'core.echo', + pack: 'core', + description: + 'Action that executes the Linux echo command on the localhost.', + runner_type: 'local-shell-cmd', + }, +]; + +describe('StackstormClient', () => { + setupRequestMockHandlers(server); + + const mockBaseUrl = 'http://backstage:9191/api/proxy'; + const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); + let client: StackstormClient; + + const setupHandlers = () => { + server.use( + rest.get(`${mockBaseUrl}/stackstorm/executions`, (req, res, ctx) => { + const limit = req.url.searchParams.get('limit') + ? Number(req.url.searchParams.get('limit')) + : executions.length; + const offset = req.url.searchParams.get('offset') + ? Number(req.url.searchParams.get('offset')) + : 0; + return res(ctx.json(executions.slice(offset, offset + limit))); + }), + rest.get( + `${mockBaseUrl}/stackstorm/executions/63dcac3e18ba00e09e7bb3b6`, + (_req, res, ctx) => { + return res(ctx.json(executionWithDetails)); + }, + ), + rest.get(`${mockBaseUrl}/stackstorm/packs`, (_req, res, ctx) => { + return res(ctx.json(packs)); + }), + rest.get(`${mockBaseUrl}/stackstorm/actions`, (req, res, ctx) => { + const name = req.url.searchParams.get('pack'); + return res(ctx.json(name === 'core' ? actions : [])); + }), + ); + }; + + beforeEach(() => { + setupHandlers(); + client = StackstormClient.fromConfig( + new ConfigReader({ + stackstorm: { + webUrl: 'http://stackstorm.example.com:8080', + }, + }), + { + discoveryApi: discoveryApi, + fetchApi: new MockFetchApi(), + }, + ); + }); + + it('getExecutions should return executions with emulated pagination', async () => { + const got = await client.getExecutions(2, 1); + expect(got.length).toEqual(2); + expect(got).toMatchObject(executions.slice(1, 3)); + }); + + it('getExecution should return one execution', async () => { + const got = await client.getExecution('63dcac3e18ba00e09e7bb3b6'); + expect(got).toMatchObject(executionWithDetails); + }); + + it('getPacks should return list of all packs', async () => { + const got = await client.getPacks(); + expect(got.length).toEqual(packs.length); + expect(got).toMatchObject(packs); + }); + + it('getActions should return list of actions', async () => { + const got = await client.getActions('core'); + expect(got).toMatchObject(actions); + }); + + it('getExecutionHistoryUrl should return webUrl for executions', async () => { + const got = client.getExecutionHistoryUrl('123abc'); + expect(got).toEqual('http://stackstorm.example.com:8080/?#/history/123abc'); + }); + + it('getActionUrl should return webUrl for action', async () => { + const got = client.getActionUrl('core.shell'); + expect(got).toEqual( + 'http://stackstorm.example.com:8080/?#/actions/core.shell', + ); + }); +}); diff --git a/plugins/stackstorm/src/api/StackstormClient.ts b/plugins/stackstorm/src/api/StackstormClient.ts new file mode 100644 index 0000000000..495384e8a5 --- /dev/null +++ b/plugins/stackstorm/src/api/StackstormClient.ts @@ -0,0 +1,102 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Action, Execution, Pack, StackstormApi } from './types'; +import { ConfigApi, DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; +import { ResponseError } from '@backstage/errors'; + +export class StackstormClient implements StackstormApi { + private readonly discoveryApi: DiscoveryApi; + private readonly fetchApi: FetchApi; + private readonly webUrl: string; + + private constructor({ + discoveryApi, + fetchApi, + webUrl, + }: { + discoveryApi: DiscoveryApi; + fetchApi: FetchApi; + webUrl: string; + }) { + this.discoveryApi = discoveryApi; + this.fetchApi = fetchApi; + this.webUrl = webUrl; + } + + static fromConfig( + config: ConfigApi, + dependencies: { + discoveryApi: DiscoveryApi; + fetchApi: FetchApi; + }, + ): StackstormClient { + return new StackstormClient({ + discoveryApi: dependencies.discoveryApi, + fetchApi: dependencies.fetchApi, + webUrl: config.getString('stackstorm.webUrl'), + }); + } + + private async get(input: string): Promise { + const apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/stackstorm`; + const response = await this.fetchApi.fetch(`${apiUrl}${input}`, { + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) throw await ResponseError.fromResponse(response); + return (await response.json()) as T; + } + + async getExecutions(limit?: number, offset?: number): Promise { + const params = { + limit: limit?.toString() || '10', + offset: offset?.toString() || '0', + include_attributes: + 'id,status,start_timestamp,action.ref,action.name,rule.ref', + parent: 'null', + }; + const path = `/executions?${new URLSearchParams(params)}`; + return this.get(path); + } + + async getExecution(id: string): Promise { + const path = `/executions/${encodeURIComponent(id)}`; + return this.get(path); + } + + async getPacks(): Promise { + return this.get('/packs'); + } + + async getActions(pack: string): Promise { + const params = { + include_attributes: 'id,ref,name,pack,description,runner_type', + pack: pack, + }; + const path = `/actions?${new URLSearchParams(params)}`; + return this.get(path); + } + + getExecutionHistoryUrl(id: string): string { + return `${this.webUrl}/?#/history/${encodeURIComponent(id)}`; + } + + getActionUrl(ref: string): string { + return `${this.webUrl}/?#/actions/${encodeURIComponent(ref)}`; + } +} diff --git a/plugins/stackstorm/src/api/index.ts b/plugins/stackstorm/src/api/index.ts new file mode 100644 index 0000000000..0ce652e27b --- /dev/null +++ b/plugins/stackstorm/src/api/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { stackstormApiRef } from './types'; +export type { + Action, + Execution, + ExecutionLog, + Pack, + StackstormApi, +} from './types'; +export { StackstormClient } from './StackstormClient'; diff --git a/plugins/stackstorm/src/api/types.ts b/plugins/stackstorm/src/api/types.ts new file mode 100644 index 0000000000..6ebf3d67a6 --- /dev/null +++ b/plugins/stackstorm/src/api/types.ts @@ -0,0 +1,61 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createApiRef } from '@backstage/core-plugin-api'; + +export const stackstormApiRef = createApiRef({ + id: 'plugin.stackstorm.service', +}); + +export type Execution = { + id: string; + action: Action; + status: string; + start_timestamp: string; + end_timestamp: string; + result: object; + parameters: object; + elapsed_seconds: number; + log: ExecutionLog[]; +}; + +export type ExecutionLog = { + status: string; + timestamp: string; +}; + +export type Action = { + id: string; + name: string; + ref: string; + pack: string; + description: string; + runner_type: string; +}; + +export type Pack = { + ref: string; + description: string; + version: string; +}; + +export interface StackstormApi { + getExecutions(limit: number, offset: number): Promise; + getExecution(id: string): Promise; + getPacks(): Promise; + getActions(pack: string): Promise; + getExecutionHistoryUrl(id: string): string; + getActionUrl(ref: string): string; +} diff --git a/plugins/stackstorm/src/components/ActionsList/ActionsList.test.tsx b/plugins/stackstorm/src/components/ActionsList/ActionsList.test.tsx new file mode 100644 index 0000000000..2a65db427a --- /dev/null +++ b/plugins/stackstorm/src/components/ActionsList/ActionsList.test.tsx @@ -0,0 +1,91 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import React from 'react'; +import { Action, Pack, StackstormApi, stackstormApiRef } from '../../api'; +import { ActionsList, PackListItem } from './ActionsList'; + +const packs: Pack[] = [ + { + ref: 'chatops', + description: 'ChatOps integration pack', + version: '3.7.0', + }, + { + ref: 'core', + description: 'Basic core actions.', + version: '3.7.1', + }, +]; + +const actions: Action[] = [ + { + id: '62fe101b11935b6aaff4ff96', + name: 'announcement', + ref: 'core.announcement', + pack: 'core', + description: + 'Action that broadcasts the announcement to all stream consumers.', + runner_type: 'broadcast', + }, + { + id: '62fe101b11935b6aaff4ff97', + name: 'echo', + ref: 'core.echo', + pack: 'core', + description: + 'Action that executes the Linux echo command on the localhost.', + runner_type: 'local-shell-cmd', + }, +]; + +describe('ActionsList', () => { + const mockApi: jest.Mocked = { + getPacks: jest.fn().mockResolvedValue(packs), + getActions: jest.fn().mockResolvedValue(actions), + getActionUrl: jest + .fn() + .mockResolvedValue( + 'http://stackstorm.example.com:8080/?#/actions/core.action', + ), + } as any; + + it('should render all packs', async () => { + const { getByText } = await renderInTestApp( + + + , + ); + + packs.forEach(p => { + expect(getByText(p.ref)).toBeInTheDocument(); + expect(getByText(p.description)).toBeInTheDocument(); + }); + }); + + it('should render all pack actions', async () => { + const { getByText } = await renderInTestApp( + + {}} /> + , + ); + + actions.forEach(a => { + expect(getByText(a.name)).toBeInTheDocument(); + expect(getByText(a.runner_type)).toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx b/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx new file mode 100644 index 0000000000..1080f67373 --- /dev/null +++ b/plugins/stackstorm/src/components/ActionsList/ActionsList.tsx @@ -0,0 +1,159 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React, { useState } from 'react'; +import useAsync from 'react-use/lib/useAsync'; +import { Link, Progress, ResponseErrorPanel } from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; +import { + List, + ListItemText, + Collapse, + ListItem, + ListItemSecondaryAction, + ListItemIcon, +} from '@material-ui/core'; +import { makeStyles } from '@material-ui/core/styles'; +import ExpandMore from '@material-ui/icons/ExpandMore'; +import ExpandLess from '@material-ui/icons/ExpandLess'; +import { Action, Pack, stackstormApiRef } from '../../api'; + +const useStyles = makeStyles(theme => ({ + root: { + width: '100%', + backgroundColor: theme.palette.background.paper, + }, + actions: { + borderBottom: `2px solid ${theme.palette.divider}`, + }, + nested: { + paddingLeft: theme.spacing(8), + paddingRight: theme.spacing(4), + }, + icon: { + minWidth: '34px', + }, +})); + +type ActionItemsProps = { + pack: Pack; +}; + +export const ActionItems = ({ pack }: ActionItemsProps) => { + const classes = useStyles(); + const st2 = useApi(stackstormApiRef); + + const { value, loading, error } = useAsync(async (): Promise => { + const data = await st2.getActions(pack.ref); + return data; + }, []); + + if (loading) { + return ; + } else if (error) { + return ; + } + + return ( + + {(value || []).map(a => { + return ( + + + {a.runner_type} + + ); + })} + + ); +}; + +type PackListItemProps = { + pack: Pack; + opened: boolean; + onClick: (ref: string) => any; +}; + +export const PackListItem = ({ pack, opened, onClick }: PackListItemProps) => { + const classes = useStyles(); + + return ( + <> + onClick(pack.ref)}> + + {opened ? : } + + + + version: {pack.version} + + + + + + + ); +}; + +export const ActionsList = () => { + const st2 = useApi(stackstormApiRef); + + const classes = useStyles(); + const [expanded, setExpanded] = useState([]); + + const onClick = (ref: string) => { + setExpanded(refs => + refs.includes(ref) ? refs.filter(r => r !== ref) : refs.concat(ref), + ); + }; + + const { value, loading, error } = useAsync(async (): Promise => { + const data = await st2.getPacks(); + return data; + }, []); + + if (loading) { + return ; + } else if (error) { + return ; + } + + return ( + + {(value || []).map(p => { + return ( + + ); + })} + + ); +}; diff --git a/plugins/stackstorm/src/components/ActionsList/index.ts b/plugins/stackstorm/src/components/ActionsList/index.ts new file mode 100644 index 0000000000..1606d1be3d --- /dev/null +++ b/plugins/stackstorm/src/components/ActionsList/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { ActionsList } from './ActionsList'; diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx new file mode 100644 index 0000000000..53930d339f --- /dev/null +++ b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.test.tsx @@ -0,0 +1,71 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import React from 'react'; +import { Execution, StackstormApi, stackstormApiRef } from '../../api'; +import { ExecutionPanel } from './ExecutionPanel'; + +const execution: Execution = { + id: '63dcac3e18ba00e09e7bb3b6', + action: { + name: 'post_message', + ref: 'chatops.post_message', + description: 'Post a message to stream for chatops', + pack: 'chatops', + runner_type: 'announcement', + id: '62fe101b11935b6aaff4ff92', + }, + status: 'succeeded', + start_timestamp: new Date().toISOString(), + end_timestamp: new Date().toISOString(), + result: { + output: { + result: 'hello world!', + }, + }, + parameters: { + var: 'my funky partameter', + }, + elapsed_seconds: 2.2, + log: [ + { status: 'requested', timestamp: new Date().toISOString() }, + { status: 'succeeded', timestamp: new Date().toISOString() }, + ], +}; + +describe('ExecutionPanel', () => { + const mockApi: jest.Mocked = { + getExecution: jest.fn().mockResolvedValue(execution), + getExecutionHistoryUrl: jest + .fn() + .mockResolvedValue( + 'http://stackstorm.example.com:8080/?#/history/63dcac3e18ba00e09e7bb3b6', + ), + } as any; + + it('should render execution details', async () => { + const { getByText } = await renderInTestApp( + + + , + ); + + expect(getByText(execution.id)).toBeInTheDocument(); + expect(getByText(execution.status)).toBeInTheDocument(); + expect(getByText('"hello world!"')).toBeInTheDocument(); + expect(getByText('"my funky partameter"')).toBeInTheDocument(); + }); +}); diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx new file mode 100644 index 0000000000..8a55c31246 --- /dev/null +++ b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionPanel.tsx @@ -0,0 +1,170 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { + CodeSnippet, + Progress, + ResponseErrorPanel, +} from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; +import { Execution, stackstormApiRef } from '../../api'; +import useAsync from 'react-use/lib/useAsync'; +import { + Button, + Card, + CardActions, + CardContent, + makeStyles, + Table, + TableBody, + TableCell, + TableRow, + Typography, + withStyles, +} from '@material-ui/core'; +import { Status } from './Status'; + +const useStyles = makeStyles(theme => ({ + table: { + maxWidth: '50%', + flex: 'i', + }, + title: { + paddingTop: theme.spacing(2), + fontSize: 14, + fontWeight: 'bold', + textTransform: 'uppercase', + }, + card: { + borderBottom: `2px solid ${theme.palette.divider}`, + }, +})); + +const THead = withStyles(() => ({ + root: { + paddingLeft: 0, + }, +}))(TableCell); + +const TRow = withStyles(theme => ({ + root: { + '&:nth-of-type(odd)': { + backgroundColor: theme.palette.background.paper, + }, + }, +}))(TableRow); + +const ExecutionCard = ({ e }: { e: Execution }) => { + const st2 = useApi(stackstormApiRef); + const classes = useStyles(); + + return ( + + +
  • + + + + Name + + {e.action.ref} + + + + Status + + + + + + + + Execution ID + + {e.id} + + + + Started + + {new Date(e.start_timestamp).toUTCString()} + + + + Finished + + {new Date(e.end_timestamp).toUTCString()} + + + + Execution Time + + {Math.round(e.elapsed_seconds)} s + + + + Runner + + {e.action.runner_type} + + +
    + + Action Output + + + + Action Input + + + + + + + + ); +}; + +export const ExecutionPanel = ({ id }: { id: string }) => { + const st2 = useApi(stackstormApiRef); + + const { value, loading, error } = useAsync(async (): Promise => { + const data = await st2.getExecution(id); + return data; + }, []); + + if (loading) { + return ; + } else if (error) { + return ; + } + + return ; +}; diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx new file mode 100644 index 0000000000..6727f3cc56 --- /dev/null +++ b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.test.tsx @@ -0,0 +1,101 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import React from 'react'; +import { Execution, StackstormApi, stackstormApiRef } from '../../api'; +import { ExecutionsTable } from './ExecutionsTable'; + +const executions: Execution[] = [ + { + id: '63dcac3e18ba00e09e7bb3b6', + action: { + name: 'post_message', + ref: 'chatops.post_message', + description: 'Post a message to stream for chatops', + pack: 'chatops', + runner_type: 'announcement', + id: '62fe101b11935b6aaff4ff92', + }, + status: 'processing', + start_timestamp: new Date().toISOString(), + end_timestamp: new Date().toISOString(), + result: {}, + parameters: {}, + elapsed_seconds: 2.2, + log: [], + }, + { + id: '62fe101b11935b6aaff4ff93', + action: { + name: 'post_result', + ref: 'chatops.post_result', + description: 'Post an execution result to stream for chatops', + pack: 'chatops', + runner_type: 'orquesta', + id: '62fe101b11935b6aaff4ff93', + }, + status: 'succeeded', + start_timestamp: new Date().toISOString(), + end_timestamp: new Date().toISOString(), + result: {}, + parameters: {}, + elapsed_seconds: 18.5, + log: [], + }, + { + id: '63dcac3c9e0b4fe98f46becc', + action: { + name: 'run', + ref: 'shell.run', + description: 'Run shell script', + pack: 'shell', + runner_type: 'shell', + id: '63736caac3d8557c4d61883a', + }, + status: 'failed', + start_timestamp: new Date().toISOString(), + end_timestamp: new Date().toISOString(), + result: {}, + parameters: {}, + elapsed_seconds: 5.0, + log: [], + }, +]; + +describe('ExecutionsTable', () => { + const mockApi: jest.Mocked = { + getExecutions: jest.fn().mockResolvedValue(executions), + getExecutionHistoryUrl: jest + .fn() + .mockResolvedValue( + 'http://stackstorm.example.com:8080/?#/history/123abc', + ), + } as any; + + it('should render all executions', async () => { + const { getByText } = await renderInTestApp( + + + , + ); + + executions.forEach(e => { + expect(getByText(e.id)).toBeInTheDocument(); + expect(getByText(e.action.ref)).toBeInTheDocument(); + expect(getByText(e.status)).toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx new file mode 100644 index 0000000000..f034cb64e8 --- /dev/null +++ b/plugins/stackstorm/src/components/ExecutionsTable/ExecutionsTable.tsx @@ -0,0 +1,120 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React, { useState } from 'react'; +import { + Link, + ResponseErrorPanel, + Table, + TableColumn, +} from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; +import { Execution, stackstormApiRef } from '../../api'; +import { Status } from './Status'; +import { ExecutionPanel } from './ExecutionPanel'; +import useAsync from 'react-use/lib/useAsync'; + +type DenseTableProps = { + executions: Execution[]; + loading: boolean; + page: number; + pageSize: number; + onPageChange: (page: number) => void; + onRowsPerPageChange: (rows: number) => void; +}; + +export const DenseTable = ({ + executions, + loading, + page, + pageSize, + onPageChange, + onRowsPerPageChange, +}: DenseTableProps) => { + const st2 = useApi(stackstormApiRef); + + const columns: TableColumn[] = [ + { + title: 'Status', + field: 'status', + render: e => , + }, + { + title: 'Time', + field: 'start_timestamp', + render: e => `${new Date(e.start_timestamp).toUTCString()}`, + }, + { title: 'Name', field: 'action.ref' }, + { + title: 'Execution ID', + field: 'id', + render: e => {e.id}, + }, + ]; + + const count = + pageSize > executions.length + ? (page + 1) * pageSize + executions.length - pageSize + : (page + 1) * pageSize + 1; + + return ( + { + return ; + }} + /> + ); +}; + +export const ExecutionsTable = () => { + const st2 = useApi(stackstormApiRef); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); + + const { value, loading, error } = useAsync(async (): Promise => { + const data = await st2.getExecutions(rowsPerPage, page * rowsPerPage); + return data; + }, [page, rowsPerPage, st2]); + + if (error) { + return ; + } + + return ( + + ); +}; diff --git a/plugins/stackstorm/src/components/ExecutionsTable/Status.tsx b/plugins/stackstorm/src/components/ExecutionsTable/Status.tsx new file mode 100644 index 0000000000..99a94df2c8 --- /dev/null +++ b/plugins/stackstorm/src/components/ExecutionsTable/Status.tsx @@ -0,0 +1,57 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + StatusOK, + StatusError, + StatusRunning, + StatusWarning, +} from '@backstage/core-components'; +import React from 'react'; + +export const Status = ({ status }: { status: string | undefined }) => { + if (status === undefined) return null; + const st = status.toLocaleLowerCase('en-US'); + switch (status) { + case 'succeeded': + case 'enabled': + case 'complete': + return ( + <> + {st} + + ); + case 'scheduled': + case 'running': + return ( + <> + {st} + + ); + case 'failed': + case 'error': + return ( + <> + {st} + + ); + default: + return ( + <> + {st} + + ); + } +}; diff --git a/plugins/stackstorm/src/components/ExecutionsTable/index.ts b/plugins/stackstorm/src/components/ExecutionsTable/index.ts new file mode 100644 index 0000000000..402d8e557d --- /dev/null +++ b/plugins/stackstorm/src/components/ExecutionsTable/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { ExecutionsTable } from './ExecutionsTable'; diff --git a/plugins/stackstorm/src/components/PacksTable/PacksTable.test.tsx b/plugins/stackstorm/src/components/PacksTable/PacksTable.test.tsx new file mode 100644 index 0000000000..9de17e2f14 --- /dev/null +++ b/plugins/stackstorm/src/components/PacksTable/PacksTable.test.tsx @@ -0,0 +1,52 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import React from 'react'; +import { Pack, StackstormApi, stackstormApiRef } from '../../api'; +import { PacksTable } from './PacksTable'; + +const packs: Pack[] = [ + { + ref: 'chatops', + description: 'ChatOps integration pack', + version: '3.7.0', + }, + { + ref: 'core', + description: 'Basic core actions.', + version: '3.7.1', + }, +]; + +describe('PacksTable', () => { + const mockApi: jest.Mocked = { + getPacks: jest.fn().mockResolvedValue(packs), + } as any; + + it('should render all packs', async () => { + const { getByText } = await renderInTestApp( + + + , + ); + + packs.forEach(p => { + expect(getByText(p.ref)).toBeInTheDocument(); + expect(getByText(p.description)).toBeInTheDocument(); + expect(getByText(p.version)).toBeInTheDocument(); + }); + }); +}); diff --git a/plugins/stackstorm/src/components/PacksTable/PacksTable.tsx b/plugins/stackstorm/src/components/PacksTable/PacksTable.tsx new file mode 100644 index 0000000000..2167200e8e --- /dev/null +++ b/plugins/stackstorm/src/components/PacksTable/PacksTable.tsx @@ -0,0 +1,63 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { + Progress, + ResponseErrorPanel, + Table, + TableColumn, +} from '@backstage/core-components'; +import useAsync from 'react-use/lib/useAsync'; +import { useApi } from '@backstage/core-plugin-api'; +import { Pack, stackstormApiRef } from '../../api'; + +type DenseTableProps = { + packs: Pack[]; +}; + +export const DenseTable = ({ packs }: DenseTableProps) => { + const columns: TableColumn[] = [ + { title: 'Name', field: 'ref' }, + { title: 'Description', field: 'description' }, + { title: 'Version', field: 'version' }, + ]; + + return ( +
    + ); +}; + +export const PacksTable = () => { + const st2 = useApi(stackstormApiRef); + + const { value, loading, error } = useAsync(async (): Promise => { + const data = await st2.getPacks(); + return data; + }, []); + + if (loading) { + return ; + } else if (error) { + return ; + } + + return ; +}; diff --git a/plugins/stackstorm/src/components/PacksTable/index.ts b/plugins/stackstorm/src/components/PacksTable/index.ts new file mode 100644 index 0000000000..378e32a5d5 --- /dev/null +++ b/plugins/stackstorm/src/components/PacksTable/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { PacksTable } from './PacksTable'; diff --git a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx new file mode 100644 index 0000000000..897cec61c1 --- /dev/null +++ b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.test.tsx @@ -0,0 +1,38 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { StackstormHome } from './StackstormHome'; +import { screen } from '@testing-library/react'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { StackstormApi, stackstormApiRef } from '../../api'; + +describe('StackstormHome', () => { + const mockApi: jest.Mocked = { + getExecutions: jest.fn().mockResolvedValue([]), + getExecution: jest.fn().mockResolvedValue({}), + getPacks: jest.fn().mockResolvedValue([]), + getActions: jest.fn().mockResolvedValue([]), + } as any; + + it('should render', async () => { + await renderInTestApp( + + + , + ); + expect(screen.getByText('Welcome to StackStorm!')).toBeInTheDocument(); + }); +}); diff --git a/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx new file mode 100644 index 0000000000..d96d45e82d --- /dev/null +++ b/plugins/stackstorm/src/components/StackstormHome/StackstormHome.tsx @@ -0,0 +1,56 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { IconButton } from '@material-ui/core'; +import { + Header, + Page, + HeaderLabel, + TabbedLayout, + Content, +} from '@backstage/core-components'; +import LibraryBooks from '@material-ui/icons/LibraryBooks'; +import { ExecutionsTable } from '../ExecutionsTable'; +import { PacksTable } from '../PacksTable/PacksTable'; +import { ActionsList } from '../ActionsList'; + +export const StackstormHome = () => ( + +
    + + + + +
    + + + + + + + + + + + + + + + + + +
    +); diff --git a/plugins/stackstorm/src/components/StackstormHome/index.ts b/plugins/stackstorm/src/components/StackstormHome/index.ts new file mode 100644 index 0000000000..2063d21f34 --- /dev/null +++ b/plugins/stackstorm/src/components/StackstormHome/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { StackstormHome } from './StackstormHome'; diff --git a/plugins/stackstorm/src/index.ts b/plugins/stackstorm/src/index.ts new file mode 100644 index 0000000000..b64ae207e4 --- /dev/null +++ b/plugins/stackstorm/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * A Backstage plugin that integrates towards StackStorm + * + * @packageDocumentation + */ + +export { stackstormPlugin, StackstormPage } from './plugin'; diff --git a/plugins/stackstorm/src/plugin.test.ts b/plugins/stackstorm/src/plugin.test.ts new file mode 100644 index 0000000000..9ef2f438c1 --- /dev/null +++ b/plugins/stackstorm/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { stackstormPlugin } from './plugin'; + +describe('stackstorm', () => { + it('should export plugin', () => { + expect(stackstormPlugin).toBeDefined(); + }); +}); diff --git a/plugins/stackstorm/src/plugin.ts b/plugins/stackstorm/src/plugin.ts new file mode 100644 index 0000000000..be4b9c065c --- /dev/null +++ b/plugins/stackstorm/src/plugin.ts @@ -0,0 +1,67 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + configApiRef, + createApiFactory, + createPlugin, + createRoutableExtension, + discoveryApiRef, + fetchApiRef, +} from '@backstage/core-plugin-api'; +import { stackstormApiRef, StackstormClient } from './api'; +import { rootRouteRef } from './routes'; + +/** + * The Backstage plugin that holds stackstorm specific components + * + * @public + */ +export const stackstormPlugin = createPlugin({ + id: 'stackstorm', + apis: [ + createApiFactory({ + api: stackstormApiRef, + deps: { + configApi: configApiRef, + discoveryApi: discoveryApiRef, + fetchApi: fetchApiRef, + }, + factory: ({ configApi, discoveryApi, fetchApi }) => + StackstormClient.fromConfig(configApi, { + discoveryApi, + fetchApi, + }), + }), + ], + routes: { + root: rootRouteRef, + }, +}); + +/** + * A component to display a stackstorm home page + * + * @public + */ +export const StackstormPage = stackstormPlugin.provide( + createRoutableExtension({ + name: 'StackstormPage', + component: () => + import('./components/StackstormHome').then(m => m.StackstormHome), + mountPoint: rootRouteRef, + }), +); diff --git a/plugins/stackstorm/src/routes.ts b/plugins/stackstorm/src/routes.ts new file mode 100644 index 0000000000..90cf7760bc --- /dev/null +++ b/plugins/stackstorm/src/routes.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRouteRef } from '@backstage/core-plugin-api'; + +export const rootRouteRef = createRouteRef({ + id: 'stackstorm', +}); diff --git a/plugins/stackstorm/src/setupTests.ts b/plugins/stackstorm/src/setupTests.ts new file mode 100644 index 0000000000..73dd8dce47 --- /dev/null +++ b/plugins/stackstorm/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md index 28a8ae4e05..d97c864580 100644 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-tech-insights-backend-module-jsonfc +## 0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/plugin-tech-insights-node@0.4.1-next.0 + +## 0.1.26 + +### Patch Changes + +- d6b912f963: Surface the cause of the json rules engine +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/plugin-tech-insights-node@0.4.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + ## 0.1.26-next.2 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index d3a3260f87..062829135e 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.26-next.2", + "version": "0.1.27-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md index bef4e4c472..262e5a6d0a 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-tech-insights-backend +## 0.5.9-next.0 + +### Patch Changes + +- f244b58916: Add DB index to improve latency of latest fact query +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/plugin-tech-insights-node@0.4.1-next.0 + +## 0.5.8 + +### Patch Changes + +- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. + TechInsightsClient now implements method getFactSchemas(). + + **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common + + These changes are **required** if you were importing this type directly. + + ```diff + - import { FactSchema } from '@backstage/plugin-tech-insights-node'; + + import { FactSchema } from '@backstage/plugin-tech-insights-common'; + ``` + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/plugin-tech-insights-node@0.4.0 + - @backstage/catalog-model@1.2.0 + - @backstage/backend-tasks@0.4.3 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + ## 0.5.8-next.2 ### Patch Changes diff --git a/plugins/tech-insights-backend/migrations/20230213170839_latest-facts-index.js b/plugins/tech-insights-backend/migrations/20230213170839_latest-facts-index.js new file mode 100644 index 0000000000..94a589f59d --- /dev/null +++ b/plugins/tech-insights-backend/migrations/20230213170839_latest-facts-index.js @@ -0,0 +1,36 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const indexName = 'fact_id_entity_timestamp_idx'; +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.up = async knex => { + await knex.schema.alterTable('facts', table => { + table.index(['id', 'entity', 'timestamp'], indexName); + }); +}; + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +exports.down = async knex => { + await knex.schema.alterTable('facts', table => { + table.dropIndex(indexName); + }); +}; diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 2b32f72763..98152f39ac 100644 --- a/plugins/tech-insights-backend/package.json +++ b/plugins/tech-insights-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend", - "version": "0.5.8-next.2", + "version": "0.5.9-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-common/CHANGELOG.md b/plugins/tech-insights-common/CHANGELOG.md index 347a4387d0..bf0f8f62ba 100644 --- a/plugins/tech-insights-common/CHANGELOG.md +++ b/plugins/tech-insights-common/CHANGELOG.md @@ -1,5 +1,24 @@ # @backstage/plugin-tech-insights-common +## 0.2.10 + +### Patch Changes + +- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. + TechInsightsClient now implements method getFactSchemas(). + + **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common + + These changes are **required** if you were importing this type directly. + + ```diff + - import { FactSchema } from '@backstage/plugin-tech-insights-node'; + + import { FactSchema } from '@backstage/plugin-tech-insights-common'; + ``` + +- Updated dependencies + - @backstage/types@1.0.2 + ## 0.2.10-next.0 ### Patch Changes diff --git a/plugins/tech-insights-common/package.json b/plugins/tech-insights-common/package.json index d7534b2834..bb6b6e9a57 100644 --- a/plugins/tech-insights-common/package.json +++ b/plugins/tech-insights-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-common", - "version": "0.2.10-next.0", + "version": "0.2.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md index aa058fdc3b..84694fc518 100644 --- a/plugins/tech-insights-node/CHANGELOG.md +++ b/plugins/tech-insights-node/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-tech-insights-node +## 0.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + +## 0.4.0 + +### Minor Changes + +- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. + TechInsightsClient now implements method getFactSchemas(). + + **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common + + These changes are **required** if you were importing this type directly. + + ```diff + - import { FactSchema } from '@backstage/plugin-tech-insights-node'; + + import { FactSchema } from '@backstage/plugin-tech-insights-common'; + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/types@1.0.2 + ## 0.4.0-next.2 ### Patch Changes diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index 7f49679030..e6a06bd615 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-node", - "version": "0.4.0-next.2", + "version": "0.4.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md index 37e46a4b5a..1703832055 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-tech-insights +## 0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + - @backstage/plugin-tech-insights-common@0.2.10 + +## 0.3.7 + +### Patch Changes + +- 4024b37449: TechInsightsApi interface now has getFactSchemas() method. + TechInsightsClient now implements method getFactSchemas(). + + **BREAKING** FactSchema type moved from @backstage/plugin-tech-insights-node into @backstage/plugin-tech-insights-common + + These changes are **required** if you were importing this type directly. + + ```diff + - import { FactSchema } from '@backstage/plugin-tech-insights-node'; + + import { FactSchema } from '@backstage/plugin-tech-insights-common'; + ``` + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/plugin-tech-insights-common@0.2.10 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + ## 0.3.7-next.2 ### Patch Changes diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index e874d2ba30..25b72e0de5 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights", - "version": "0.3.7-next.2", + "version": "0.3.8-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -56,7 +56,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index 37aa1e8336..0ac00e3cfe 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-tech-radar +## 0.6.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/theme@0.2.17 + +## 0.6.1 + +### Patch Changes + +- acf6c8c10b: Deprecate `RadarEntry.url` - use `RadarEntry.links` instead + + ```diff + - url: 'https://www.javascript.com/', + key: 'javascript', + id: 'javascript', + title: 'JavaScript', + quadrant: 'languages', + links: [ + + { + + url: 'https://www.javascript.com/', + + title: 'Learn more', + + }, + ], + ``` + +- 18024a231c: Allow to set additional links to the entry description. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + ## 0.6.1-next.1 ### Patch Changes diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index 2aad00f224..afb484dc06 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-tech-radar", "description": "A Backstage plugin that lets you display a Tech Radar for your organization", - "version": "0.6.1-next.1", + "version": "0.6.2-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -59,7 +59,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 9afcf3aace..7f8b72744e 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.11-next.0 + +### Patch Changes + +- 2b00d8a225: Fix bug/problem with test helper +- Updated dependencies + - @backstage/plugin-techdocs@1.6.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/test-utils@1.2.6-next.0 + - @backstage/plugin-catalog@1.9.0-next.0 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 1.0.10 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- Updated dependencies + - @backstage/plugin-catalog@1.8.0 + - @backstage/plugin-techdocs@1.5.0 + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/integration-react@1.1.10 + - @backstage/test-utils@1.2.5 + - @backstage/plugin-techdocs-react@1.1.3 + ## 1.0.10-next.2 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index 1ad762a09d..2f9078c7f8 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.10-next.2", + "version": "1.0.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -63,7 +63,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/techdocs-addons-test-utils/src/test-utils.tsx b/plugins/techdocs-addons-test-utils/src/test-utils.tsx index 0d65e7e51e..e60a96402c 100644 --- a/plugins/techdocs-addons-test-utils/src/test-utils.tsx +++ b/plugins/techdocs-addons-test-utils/src/test-utils.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { ReactElement, Fragment } from 'react'; +import React, { ReactElement } from 'react'; // Shadow DOM support for the simple and complete DOM testing utilities // https://github.com/testing-library/dom-testing-library/issues/742#issuecomment-674987855 @@ -236,9 +236,9 @@ export class TechDocsAddonTester { element={} > - {this.addons.map((addon, index) => ( - {addon} - ))} + {this.addons.map((addon, index) => + React.cloneElement(addon, { key: index }), + )} diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index dbad0b17b1..4ba0a36a48 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-techdocs-backend +## 1.5.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-common@1.0.12-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-node@1.5.1-next.0 + +## 1.5.3 + +### Patch Changes + +- 6f097023fc: Keep the tech docs sync event stream alive even if it is taking a while to build. +- 339d9a5b5c: Added support for using a default `mkdocs.yml` configuration file when none is provided +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/plugin-techdocs-node@1.5.0 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/plugin-catalog-common@1.0.11 + - @backstage/plugin-permission-common@0.7.3 + - @backstage/plugin-search-common@1.2.1 + ## 1.5.3-next.2 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 9c8ce22bef..5964e3f58f 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-backend", "description": "The Backstage backend plugin that renders technical documentation for your components", - "version": "1.5.3-next.2", + "version": "1.5.4-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -59,7 +59,7 @@ "@backstage/cli": "workspace:^", "@backstage/plugin-search-backend-node": "workspace:^", "@types/dockerode": "^3.3.0", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts index a76ea66729..86ab9e6cd8 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollator.ts @@ -29,7 +29,7 @@ import unescape from 'lodash/unescape'; import { Logger } from 'winston'; import pLimit from 'p-limit'; import { Config } from '@backstage/config'; -import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common'; +import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha'; import { Permission } from '@backstage/plugin-permission-common'; import { CatalogApi, diff --git a/plugins/techdocs-backend/src/search/DefaultTechDocsCollatorFactory.ts b/plugins/techdocs-backend/src/search/DefaultTechDocsCollatorFactory.ts index aaddb4fa51..e2c6f5913c 100644 --- a/plugins/techdocs-backend/src/search/DefaultTechDocsCollatorFactory.ts +++ b/plugins/techdocs-backend/src/search/DefaultTechDocsCollatorFactory.ts @@ -30,7 +30,7 @@ import { stringifyEntityRef, } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; -import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common'; +import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha'; import { Permission } from '@backstage/plugin-permission-common'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { TechDocsDocument } from '@backstage/plugin-techdocs-node'; diff --git a/plugins/techdocs-backend/src/service/DocsSynchronizer.ts b/plugins/techdocs-backend/src/service/DocsSynchronizer.ts index 3d89d1647f..8456f64a6a 100644 --- a/plugins/techdocs-backend/src/service/DocsSynchronizer.ts +++ b/plugins/techdocs-backend/src/service/DocsSynchronizer.ts @@ -165,7 +165,7 @@ export class DocsSynchronizer { ); error( new NotFoundError( - 'Sorry! It took too long for the generated docs to show up in storage. Check back later.', + 'Sorry! It took too long for the generated docs to show up in storage. Are you sure the docs project is generating an `index.html` file? Otherwise, check back later.', ), ); return; diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 22630158f1..abe7bc542f 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,61 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + +## 1.0.10 + +### Patch Changes + +- d950d3e217: Depend on `@material-ui/core` version `^4.12.2` like all other in-repo packages +- 4660b63947: Create a TechDocs `` addon that allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page. + + Here's an example on how to use it in a Backstage app: + + ```diff + import { + DefaultTechDocsHome, + TechDocsIndexPage, + TechDocsReaderPage, + } from '@backstage/plugin-techdocs'; + import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha'; + +import { LightBox } from '@backstage/plugin-techdocs-module-addons-contrib'; + + const AppRoutes = () => { + + // other plugin routes + }> + + + } + > + + + + + + ; + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-techdocs-react@1.1.3 + ## 1.0.10-next.2 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index c077ccdd6c..51d656007d 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", "description": "Plugin module for contributed TechDocs Addons", - "version": "1.0.10-next.2", + "version": "1.0.11-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -62,7 +62,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index a6d32d8d9f..4c14489d5a 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-techdocs-node +## 1.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-aws-node@0.1.1 + - @backstage/plugin-search-common@1.2.1 + +## 1.5.0 + +### Minor Changes + +- dd1e37649f: Deprecated getMkDocsYml in favor of getMkdocsYml (lowercase 'd') + +### Patch Changes + +- 87ab76e55c: Fixed bug caused by recent migration to AWS SDK V3 for techdocs-node. Instead of s3ForcePathStyle, forcePathStyle should be passed. +- 339d9a5b5c: Added support for using a default `mkdocs.yml` configuration file when none is provided +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-aws-node@0.1.1 + - @backstage/plugin-search-common@1.2.1 + ## 1.4.6-next.2 ### Patch Changes diff --git a/plugins/techdocs-node/api-report.md b/plugins/techdocs-node/api-report.md index ce5bd1ae09..11ff53514b 100644 --- a/plugins/techdocs-node/api-report.md +++ b/plugins/techdocs-node/api-report.md @@ -88,8 +88,22 @@ export const getLocationForEntity: ( scmIntegration: ScmIntegrationRegistry, ) => ParsedLocationAnnotation; -// @public +// @public @deprecated (undocumented) export const getMkDocsYml: ( + inputDir: string, + siteOptions?: + | { + name?: string | undefined; + } + | undefined, +) => Promise<{ + path: string; + content: string; + configIsTemporary: boolean; +}>; + +// @public +export const getMkdocsYml: ( inputDir: string, siteOptions?: { name?: string; diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 0a6ffd721b..4f458c4fff 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-node", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "1.4.6-next.2", + "version": "1.5.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "publishConfig": { diff --git a/plugins/techdocs-node/src/stages/generate/helpers.test.ts b/plugins/techdocs-node/src/stages/generate/helpers.test.ts index e635542a7c..b24d85430b 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.test.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.test.ts @@ -25,7 +25,7 @@ import { ParsedLocationAnnotation } from '../../helpers'; import { createOrUpdateMetadata, getGeneratorKey, - getMkDocsYml, + getMkdocsYml, getRepoUrlFromLocationAnnotation, patchIndexPreBuild, storeEtagMetadata, @@ -34,7 +34,7 @@ import { import { patchMkdocsYmlPreBuild, pathMkdocsYmlWithTechdocsPlugin, -} from './mkDocsPatchers'; +} from './mkdocsPatchers'; import yaml from 'js-yaml'; const mockEntity = { @@ -517,7 +517,7 @@ describe('helpers', () => { }); }); - describe('getMkDocsYml', () => { + describe('getMkdocsYml', () => { const inputDir = resolvePath(__filename, '../__fixtures__/'); const siteOptions = { name: mockEntity.metadata.title, @@ -530,7 +530,7 @@ describe('helpers', () => { path: mkdocsPath, content, configIsTemporary, - } = await getMkDocsYml(inputDir, siteOptions); + } = await getMkdocsYml(inputDir, siteOptions); expect(mkdocsPath).toBe(key); expect(content).toBe(mkdocsYml.toString()); @@ -544,7 +544,7 @@ describe('helpers', () => { path: mkdocsPath, content, configIsTemporary, - } = await getMkDocsYml(inputDir, siteOptions); + } = await getMkdocsYml(inputDir, siteOptions); expect(mkdocsPath).toBe(key); expect(content).toBe(mkdocsYml.toString()); expect(configIsTemporary).toBe(false); @@ -562,7 +562,7 @@ describe('helpers', () => { path: mkdocsPath, content, configIsTemporary, - } = await getMkDocsYml(inputDir, defaultSiteOptions); + } = await getMkdocsYml(inputDir, defaultSiteOptions); expect(mkdocsPath).toBe(key); expect(content).toBe(mkdocsDefaultYml.toString()); @@ -571,7 +571,7 @@ describe('helpers', () => { it('throws when neither .yml nor .yaml nor default file is present', async () => { const invalidInputDir = resolvePath(__filename); - await expect(getMkDocsYml(invalidInputDir, siteOptions)).rejects.toThrow( + await expect(getMkdocsYml(invalidInputDir, siteOptions)).rejects.toThrow( /Could not read MkDocs YAML config file mkdocs.yml or mkdocs.yaml or default for validation/, ); }); diff --git a/plugins/techdocs-node/src/stages/generate/helpers.ts b/plugins/techdocs-node/src/stages/generate/helpers.ts index 27c24ea66e..e16293f906 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.ts @@ -193,7 +193,7 @@ export const generateMkdocsYml = async ( * @param siteOptions - options for the site: `name` property will be used in mkdocs.yml for the * required `site_name` property, default value is "Documentation Site" */ -export const getMkDocsYml = async ( +export const getMkdocsYml = async ( inputDir: string, siteOptions?: { name?: string }, ): Promise<{ path: string; content: string; configIsTemporary: boolean }> => { diff --git a/plugins/techdocs-node/src/stages/generate/index.ts b/plugins/techdocs-node/src/stages/generate/index.ts index fa36486a0f..aaf27026c2 100644 --- a/plugins/techdocs-node/src/stages/generate/index.ts +++ b/plugins/techdocs-node/src/stages/generate/index.ts @@ -15,7 +15,7 @@ */ export { TechdocsGenerator } from './techdocs'; export { Generators } from './generators'; -export { getMkDocsYml } from './helpers'; +export { getMkdocsYml } from './helpers'; export type { GeneratorBase, GeneratorOptions, @@ -23,3 +23,10 @@ export type { GeneratorRunOptions, SupportedGeneratorKey, } from './types'; +import { getMkdocsYml } from './helpers'; +/** + * @public + * @deprecated + * Deprecated in favor of getMkdocsYml (lowercase 'd') + */ +export const getMkDocsYml = getMkdocsYml; diff --git a/plugins/techdocs-node/src/stages/generate/mkDocsPatchers.ts b/plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts similarity index 100% rename from plugins/techdocs-node/src/stages/generate/mkDocsPatchers.ts rename to plugins/techdocs-node/src/stages/generate/mkdocsPatchers.ts diff --git a/plugins/techdocs-node/src/stages/generate/techdocs.ts b/plugins/techdocs-node/src/stages/generate/techdocs.ts index 93285b7468..2f88e1a8ad 100644 --- a/plugins/techdocs-node/src/stages/generate/techdocs.ts +++ b/plugins/techdocs-node/src/stages/generate/techdocs.ts @@ -24,7 +24,7 @@ import { } from '@backstage/integration'; import { createOrUpdateMetadata, - getMkDocsYml, + getMkdocsYml, patchIndexPreBuild, runCommand, storeEtagMetadata, @@ -34,7 +34,7 @@ import { import { patchMkdocsYmlPreBuild, pathMkdocsYmlWithTechdocsPlugin, -} from './mkDocsPatchers'; +} from './mkdocsPatchers'; import { GeneratorBase, GeneratorConfig, @@ -100,7 +100,7 @@ export class TechdocsGenerator implements GeneratorBase { } = options; // Do some updates to mkdocs.yml before generating docs e.g. adding repo_url - const { path: mkdocsYmlPath, content } = await getMkDocsYml( + const { path: mkdocsYmlPath, content } = await getMkdocsYml( inputDir, siteOptions, ); diff --git a/plugins/techdocs-node/src/stages/publish/helpers.test.ts b/plugins/techdocs-node/src/stages/publish/helpers.test.ts index fa934d6dd9..7b303b3bf5 100644 --- a/plugins/techdocs-node/src/stages/publish/helpers.test.ts +++ b/plugins/techdocs-node/src/stages/publish/helpers.test.ts @@ -158,6 +158,16 @@ describe('getStaleFiles', () => { expect(staleFiles).toHaveLength(1); expect(staleFiles).toEqual(expect.arrayContaining(['stale_file.png'])); }); + + it('should not return directories as stale files if they are parent directories of new files', () => { + const oldFiles = [...defaultFiles, 'default/Component/backstage/foo']; + const newFiles = [ + ...defaultFiles, + 'default/Component/backstage/foo/bar/index.html', + ]; + const staleFiles = getStaleFiles(newFiles, oldFiles); + expect(staleFiles).toHaveLength(0); + }); }); describe('getCloudPathForLocalPath', () => { diff --git a/plugins/techdocs-node/src/stages/publish/helpers.ts b/plugins/techdocs-node/src/stages/publish/helpers.ts index decefae187..0b9384dba3 100644 --- a/plugins/techdocs-node/src/stages/publish/helpers.ts +++ b/plugins/techdocs-node/src/stages/publish/helpers.ts @@ -169,8 +169,21 @@ export const getStaleFiles = ( oldFiles: string[], ): string[] => { const staleFiles = new Set(oldFiles); + const removedParentDirs = new Set(); newFiles.forEach(newFile => { staleFiles.delete(newFile); + + // We have to traverse through the directory hierarchy of a new file and + // ensure that we won't try to delete one of the parent directories. + let parentDir = newFile.substring(0, newFile.lastIndexOf('/')); + while ( + !removedParentDirs.has(parentDir) && + parentDir.length >= newFile.indexOf('/') + ) { + staleFiles.delete(parentDir); + removedParentDirs.add(parentDir); + parentDir = parentDir.substring(0, parentDir.lastIndexOf('/')); + } }); return Array.from(staleFiles); }; diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index 34617eb3f5..fdaba0ebe4 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-techdocs-react +## 1.1.4-next.0 + +### Patch Changes + +- 928a12a9b3: Internal refactor of `/alpha` exports. +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/version-bridge@1.0.3 + +## 1.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/config@1.0.6 + - @backstage/version-bridge@1.0.3 + ## 1.1.3-next.2 ### Patch Changes diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 29587c3e1e..1b184136b3 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,10 +1,9 @@ { "name": "@backstage/plugin-techdocs-react", "description": "Shared frontend utilities for TechDocs and Addons", - "version": "1.1.3-next.2", + "version": "1.1.4-next.0", "publishConfig": { "access": "public", - "alphaTypes": "dist/index.alpha.d.ts", "main": "dist/index.esm.js", "types": "dist/index.d.ts" }, @@ -25,7 +24,7 @@ "main": "src/index.ts", "types": "src/index.ts", "scripts": { - "build": "backstage-cli package build --experimental-type-build", + "build": "backstage-cli package build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index 352114d77d..01a028f605 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,88 @@ # @backstage/plugin-techdocs +## 1.6.0-next.0 + +### Minor Changes + +- 3f75b7607c: Add ability to pass icon as function to have ability to customize it by search item + +### Patch Changes + +- f320c299c6: The HTML tag attributes in the documentation content inserted to shadow DOM is preserved to improve accessibility +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-techdocs-react@1.1.4-next.0 + - @backstage/config@1.0.6 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.11-next.0 + - @backstage/theme@0.2.17 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-search-react@1.5.1-next.0 + +## 1.5.0 + +### Minor Changes + +- 20840b36b4: Update DocsTable and EntityListDocsTable to accept overrides for Material Table options. +- 0eaa579f89: The `TechDocsSearchResultListItem` component is now a search result extension. This means that when rendered as a child of components that render search extensions, the `result`, `rank`, and `highlight` properties are optional. See the [documentation](https://backstage.io/docs/features/search/how-to-guides#how-to-render-search-results-using-extensions) for more details. + +### Patch Changes + +- c8e09cc383: Fixed bug in Techdocs reader where a techdocs page with a hash in the URL did not always jump to the document anchor. +- cad5607411: Improve view: remove footer overlay on large screen +- 66e2aab4c4: `ListItem` wrapper component moved to `SearchResultListItemExtension` for all `*SearchResultListItems` that are exported as extensions. This is to make sure the list only contains list elements. + + Note: If you have implemented a custom result list item, we recommend you to remove the list item wrapper to avoid nested `
  • ` elements. + +- 4660b63947: Create a TechDocs `` addon that allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page. + + Here's an example on how to use it in a Backstage app: + + ```diff + import { + DefaultTechDocsHome, + TechDocsIndexPage, + TechDocsReaderPage, + } from '@backstage/plugin-techdocs'; + import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha'; + +import { LightBox } from '@backstage/plugin-techdocs-module-addons-contrib'; + + const AppRoutes = () => { + + // other plugin routes + }> + + + } + > + + + + + + ; + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/plugin-search-react@1.5.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + - @backstage/integration-react@1.1.10 + - @backstage/plugin-search-common@1.2.1 + - @backstage/plugin-techdocs-react@1.1.3 + ## 1.5.0-next.2 ### Patch Changes diff --git a/plugins/techdocs/api-report.md b/plugins/techdocs/api-report.md index 9452b38feb..bb59732021 100644 --- a/plugins/techdocs/api-report.md +++ b/plugins/techdocs/api-report.md @@ -406,7 +406,7 @@ export const TechDocsSearchResultListItem: ( // @public export type TechDocsSearchResultListItemProps = { - icon?: ReactNode; + icon?: ReactNode | ((result: any) => ReactNode); result?: any; highlight?: ResultHighlight; rank?: number; diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 5e113f3e7f..57eca44976 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs", "description": "The Backstage plugin that renders technical documentation for your components", - "version": "1.5.0-next.2", + "version": "1.6.0-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -78,7 +78,7 @@ "@types/node": "^16.11.26", "canvas": "^2.10.2", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist", diff --git a/plugins/techdocs/src/home/components/Grids/DocsCardGrid.tsx b/plugins/techdocs/src/home/components/Grids/DocsCardGrid.tsx index 6f1d9fbe61..8843249291 100644 --- a/plugins/techdocs/src/home/components/Grids/DocsCardGrid.tsx +++ b/plugins/techdocs/src/home/components/Grids/DocsCardGrid.tsx @@ -19,7 +19,7 @@ import { toLowerMaybe } from '../../../helpers'; import { Entity } from '@backstage/catalog-model'; import { useApi, useRouteRef, configApiRef } from '@backstage/core-plugin-api'; import { - Button, + LinkButton, ItemCardGrid, ItemCardHeader, } from '@backstage/core-components'; @@ -58,7 +58,7 @@ export const DocsCardGrid = (props: DocsCardGridProps) => { {entity.metadata.description} - + ))} diff --git a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx index 842c80018f..5e5b41ee3e 100644 --- a/plugins/techdocs/src/home/components/Tables/DocsTable.tsx +++ b/plugins/techdocs/src/home/components/Tables/DocsTable.tsx @@ -25,7 +25,7 @@ import { } from '@backstage/plugin-catalog-react'; import { rootDocsRouteRef } from '../../../routes'; import { - Button, + LinkButton, EmptyState, Table, TableColumn, @@ -121,13 +121,13 @@ export const DocsTable = (props: DocsTableProps) => { title="No documents to show" description="Create your own document. Check out our Getting Started Information" action={ - + } /> )} diff --git a/plugins/techdocs/src/reader/transformers/html/transformer.ts b/plugins/techdocs/src/reader/transformers/html/transformer.ts index a197a2d4b7..61498a37b0 100644 --- a/plugins/techdocs/src/reader/transformers/html/transformer.ts +++ b/plugins/techdocs/src/reader/transformers/html/transformer.ts @@ -15,12 +15,12 @@ */ import DOMPurify from 'dompurify'; -import { useMemo, useCallback } from 'react'; +import { useCallback, useMemo } from 'react'; -import { useApi, configApiRef } from '@backstage/core-plugin-api'; +import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { Transformer } from '../transformer'; -import { removeUnsafeLinks, removeUnsafeIframes } from './hooks'; +import { removeUnsafeIframes, removeUnsafeLinks } from './hooks'; /** * Returns html sanitizer configuration @@ -34,7 +34,7 @@ const useSanitizerConfig = () => { }; /** - * Returns a transformer that sanitizes the dom's internal html. + * Returns a transformer that sanitizes the dom */ export const useSanitizerTransformer = (): Transformer => { const config = useSanitizerConfig(); @@ -51,7 +51,8 @@ export const useSanitizerTransformer = (): Transformer => { DOMPurify.addHook('beforeSanitizeElements', removeUnsafeIframes(hosts)); } - return DOMPurify.sanitize(dom.innerHTML, { + // using outerHTML as we want to preserve the html tag attributes (lang) + return DOMPurify.sanitize(dom.outerHTML, { ADD_TAGS: tags, FORBID_TAGS: ['style'], WHOLE_DOCUMENT: true, diff --git a/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx b/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx index 9bf8b76092..3c0d2314e2 100644 --- a/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx +++ b/plugins/techdocs/src/search/components/TechDocsSearchResultListItem.tsx @@ -37,7 +37,7 @@ const useStyles = makeStyles({ * @public */ export type TechDocsSearchResultListItemProps = { - icon?: ReactNode; + icon?: ReactNode | ((result: any) => ReactNode); result?: any; highlight?: ResultHighlight; rank?: number; @@ -151,7 +151,11 @@ export const TechDocsSearchResultListItem = ( const ListItemWrapper = ({ children }: PropsWithChildren<{}>) => asListItem ? ( <> - {icon && {icon}} + {icon && ( + + {typeof icon === 'function' ? icon(result) : icon} + + )}
    {children}
    ) : ( diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index 9f44d33d18..39a9a56a70 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,32 @@ # @backstage/plugin-todo-backend +## 0.1.40-next.0 + +### Patch Changes + +- 4120513412: todo-backend is now exposed as a plugin which uses the new plugin system +- Updated dependencies + - @backstage/catalog-client@1.4.0-next.0 + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/plugin-catalog-node@1.3.4-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + +## 0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/catalog-client@1.3.1 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + - @backstage/integration@1.4.2 + ## 0.1.39-next.2 ### Patch Changes diff --git a/plugins/todo-backend/api-report.md b/plugins/todo-backend/api-report.md index 277c87fea9..6db1e012e9 100644 --- a/plugins/todo-backend/api-report.md +++ b/plugins/todo-backend/api-report.md @@ -3,12 +3,14 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { CompoundEntityRef } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import express from 'express'; import { Logger } from 'winston'; import { ScmIntegrations } from '@backstage/integration'; +import { ServiceRef } from '@backstage/backend-plugin-api'; import { UrlReader } from '@backstage/backend-common'; // @public (undocumented) @@ -88,6 +90,9 @@ export type TodoParserResult = { lineNumber: number; }; +// @public +export const todoPlugin: () => BackendFeature; + // @public (undocumented) export interface TodoReader { readTodos(options: ReadTodosOptions): Promise; @@ -113,6 +118,9 @@ export type TodoReaderServiceOptions = { defaultPageSize?: number; }; +// @public (undocumented) +export const todoReaderServiceRef: ServiceRef; + // @public (undocumented) export class TodoScmReader implements TodoReader { constructor(options: TodoScmReaderOptions); diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index 6120e76a5e..f95ae498a7 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo-backend", "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.1.39-next.2", + "version": "0.1.40-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,11 +30,13 @@ }, "dependencies": { "@backstage/backend-common": "workspace:^", + "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-client": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", + "@backstage/plugin-catalog-node": "workspace:^", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -45,7 +47,7 @@ "devDependencies": { "@backstage/cli": "workspace:^", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/todo-backend/src/index.ts b/plugins/todo-backend/src/index.ts index 973c91df44..b1654327d6 100644 --- a/plugins/todo-backend/src/index.ts +++ b/plugins/todo-backend/src/index.ts @@ -22,3 +22,4 @@ export * from './lib'; export * from './service'; +export * from './plugin'; diff --git a/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts b/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts index 2696f0d54b..276d176efb 100644 --- a/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts +++ b/plugins/todo-backend/src/lib/TodoReader/TodoScmReader.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { UrlReader } from '@backstage/backend-common'; +import { loggerToWinstonLogger, UrlReader } from '@backstage/backend-common'; import { ScmIntegrations } from '@backstage/integration'; import { Logger } from 'winston'; @@ -28,6 +28,11 @@ import { import { Config } from '@backstage/config'; import { createTodoParser } from './createTodoParser'; import path from 'path'; +import { + coreServices, + createServiceFactory, + createServiceRef, +} from '@backstage/backend-plugin-api'; const excludedExtensions = [ '.png', @@ -167,3 +172,26 @@ export class TodoScmReader implements TodoReader { return { result: { items: todos }, etag: tree.etag }; } } + +/** + * @public + */ +export const todoReaderServiceRef = createServiceRef({ + id: 'todo.todoReader', + defaultFactory: async service => + createServiceFactory({ + service, + deps: { + reader: coreServices.urlReader, + config: coreServices.config, + logger: coreServices.logger, + }, + factory: async ({ reader, config, logger }) => { + const winstonLogger = loggerToWinstonLogger(logger); + return TodoScmReader.fromConfig(config, { + logger: winstonLogger, + reader, + }); + }, + }), +}); diff --git a/plugins/todo-backend/src/lib/TodoReader/index.ts b/plugins/todo-backend/src/lib/TodoReader/index.ts index d0537861da..a325fcbe65 100644 --- a/plugins/todo-backend/src/lib/TodoReader/index.ts +++ b/plugins/todo-backend/src/lib/TodoReader/index.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -export { TodoScmReader } from './TodoScmReader'; +export { TodoScmReader, todoReaderServiceRef } from './TodoScmReader'; export type { TodoScmReaderOptions } from './TodoScmReader'; export { createTodoParser } from './createTodoParser'; export type { TodoParserOptions } from './createTodoParser'; diff --git a/plugins/todo-backend/src/lib/utils.ts b/plugins/todo-backend/src/lib/utils.ts new file mode 100644 index 0000000000..cf0c2e4ea6 --- /dev/null +++ b/plugins/todo-backend/src/lib/utils.ts @@ -0,0 +1,107 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { InputError } from '@backstage/errors'; + +export const parseIntegerParam = ( + str: unknown, + ctx: string, +): number | undefined => { + if (str === undefined) { + return undefined; + } + if (typeof str !== 'string') { + throw new InputError(`invalid ${ctx}, must be a string`); + } + const parsed = parseInt(str, 10); + if (!Number.isInteger(parsed) || String(parsed) !== str) { + throw new InputError(`invalid ${ctx}, not an integer`); + } + return parsed; +}; + +export const parseOrderByParam = ( + str: unknown, + allowedFields: T, +): { field: T[number]; direction: 'asc' | 'desc' } | undefined => { + if (str === undefined) { + return undefined; + } + if (typeof str !== 'string') { + throw new InputError(`invalid orderBy query, must be a string`); + } + const [field, direction] = str.split('='); + if (!field) { + throw new InputError(`invalid orderBy query, field name is empty`); + } + if (direction !== 'asc' && direction !== 'desc') { + throw new InputError( + `invalid orderBy query, order direction must be 'asc' or 'desc'`, + ); + } + + if (field && !allowedFields.includes(field)) { + throw new InputError( + `invalid orderBy field, must be one of ${allowedFields.join(', ')}`, + ); + } + return { field, direction }; +}; + +export const parseFilterParam = ( + str: unknown, + allowedFields: T, +): { field: T[number]; value: string }[] | undefined => { + if (str === undefined) { + return undefined; + } + + const filters = new Array<{ field: T[number]; value: string }>(); + + const strs = [str].flat(); + for (const filterStr of strs) { + if (typeof filterStr !== 'string') { + throw new InputError( + `invalid filter query, must be a string or list of strings`, + ); + } + const splitIndex = filterStr.indexOf('='); + if (splitIndex <= 0) { + throw new InputError( + `invalid filter query, must separate field from value using '='`, + ); + } + + const field = filterStr.slice(0, splitIndex); + if (!allowedFields.includes(field)) { + throw new InputError( + `invalid filter field, must be one of ${allowedFields.join(', ')}`, + ); + } + + const value = filterStr.slice(splitIndex + 1); + if (!value) { + throw new InputError(`invalid filter query, value may not be empty`); + } + filters.push({ field, value }); + } + + return filters; +}; + +export const getBearerToken = (header?: string): string | undefined => { + return header?.match(/Bearer\s+(\S+)/i)?.[1]; +}; diff --git a/plugins/todo-backend/src/plugin.ts b/plugins/todo-backend/src/plugin.ts new file mode 100644 index 0000000000..b9a73a84ee --- /dev/null +++ b/plugins/todo-backend/src/plugin.ts @@ -0,0 +1,46 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendPlugin, + coreServices, +} from '@backstage/backend-plugin-api'; + +import { todoServiceRef } from './service/TodoReaderService'; +import { createRouter } from './service/router'; + +/** + * The Todos plugin is responsible for aggregating todo comments within source. + * @public + */ +export const todoPlugin = createBackendPlugin({ + pluginId: 'todo-backend', + register(env) { + env.registerInit({ + deps: { + todoReader: todoServiceRef, + http: coreServices.httpRouter, + }, + async init({ http, todoReader }) { + http.use( + await createRouter({ + todoService: todoReader, + }), + ); + }, + }); + }, +}); diff --git a/plugins/todo-backend/src/service/TodoReaderService.ts b/plugins/todo-backend/src/service/TodoReaderService.ts index 35fd76b8be..6ce38709f1 100644 --- a/plugins/todo-backend/src/service/TodoReaderService.ts +++ b/plugins/todo-backend/src/service/TodoReaderService.ts @@ -20,7 +20,14 @@ import { getEntitySourceLocation, stringifyEntityRef, } from '@backstage/catalog-model'; -import { TodoReader } from '../lib'; +import { + createServiceFactory, + createServiceRef, + ServiceRef, +} from '@backstage/backend-plugin-api'; +import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha'; + +import { TodoReader, todoReaderServiceRef } from '../lib'; import { ListTodosRequest, ListTodosResponse, TodoService } from './types'; const DEFAULT_DEFAULT_PAGE_SIZE = 10; @@ -130,3 +137,23 @@ export class TodoReaderService implements TodoService { }; } } + +export const todoServiceRef: ServiceRef = + createServiceRef({ + id: 'todo.client', + defaultFactory: async service => + createServiceFactory({ + service, + deps: { + catalogApi: catalogServiceRef, + todoReader: todoReaderServiceRef, + }, + async factory({ catalogApi, todoReader }) { + const todoReaderService = new TodoReaderService({ + catalogClient: catalogApi, + todoReader, + }); + return todoReaderService; + }, + }), + }); diff --git a/plugins/todo-backend/src/service/router.test.ts b/plugins/todo-backend/src/service/router.test.ts index 0254147681..f2d9f2c7a3 100644 --- a/plugins/todo-backend/src/service/router.test.ts +++ b/plugins/todo-backend/src/service/router.test.ts @@ -18,12 +18,12 @@ import express from 'express'; import request from 'supertest'; import { errorHandler } from '@backstage/backend-common'; +import { createRouter } from './router'; import { - createRouter, parseFilterParam, parseIntegerParam, parseOrderByParam, -} from './router'; +} from '../lib/utils'; import { TodoService } from './types'; const mockListBody = { diff --git a/plugins/todo-backend/src/service/router.ts b/plugins/todo-backend/src/service/router.ts index 33356a83d6..5954fab009 100644 --- a/plugins/todo-backend/src/service/router.ts +++ b/plugins/todo-backend/src/service/router.ts @@ -18,15 +18,13 @@ import { CompoundEntityRef, parseEntityRef } from '@backstage/catalog-model'; import { InputError } from '@backstage/errors'; import express from 'express'; import Router from 'express-promise-router'; -import { TodoService } from './types'; - -const TODO_FIELDS = [ - 'text', - 'tag', - 'author', - 'viewUrl', - 'repoFilePath', -] as const; +import { type TodoService, TODO_FIELDS } from './types'; +import { + getBearerToken, + parseFilterParam, + parseIntegerParam, + parseOrderByParam, +} from '../lib/utils'; /** @public */ export interface RouterOptions { @@ -78,93 +76,3 @@ export async function createRouter( return router; } - -export function parseIntegerParam( - str: unknown, - ctx: string, -): number | undefined { - if (str === undefined) { - return undefined; - } - if (typeof str !== 'string') { - throw new InputError(`invalid ${ctx}, must be a string`); - } - const parsed = parseInt(str, 10); - if (!Number.isInteger(parsed) || String(parsed) !== str) { - throw new InputError(`invalid ${ctx}, not an integer`); - } - return parsed; -} - -export function parseOrderByParam( - str: unknown, - allowedFields: T, -): { field: T[number]; direction: 'asc' | 'desc' } | undefined { - if (str === undefined) { - return undefined; - } - if (typeof str !== 'string') { - throw new InputError(`invalid orderBy query, must be a string`); - } - const [field, direction] = str.split('='); - if (!field) { - throw new InputError(`invalid orderBy query, field name is empty`); - } - if (direction !== 'asc' && direction !== 'desc') { - throw new InputError( - `invalid orderBy query, order direction must be 'asc' or 'desc'`, - ); - } - - if (field && !allowedFields.includes(field)) { - throw new InputError( - `invalid orderBy field, must be one of ${allowedFields.join(', ')}`, - ); - } - return { field, direction }; -} - -export function parseFilterParam( - str: unknown, - allowedFields: T, -): { field: T[number]; value: string }[] | undefined { - if (str === undefined) { - return undefined; - } - - const filters = new Array<{ field: T[number]; value: string }>(); - - const strs = [str].flat(); - for (const filterStr of strs) { - if (typeof filterStr !== 'string') { - throw new InputError( - `invalid filter query, must be a string or list of strings`, - ); - } - const splitIndex = filterStr.indexOf('='); - if (splitIndex <= 0) { - throw new InputError( - `invalid filter query, must separate field from value using '='`, - ); - } - - const field = filterStr.slice(0, splitIndex); - if (!allowedFields.includes(field)) { - throw new InputError( - `invalid filter field, must be one of ${allowedFields.join(', ')}`, - ); - } - - const value = filterStr.slice(splitIndex + 1); - if (!value) { - throw new InputError(`invalid filter query, value may not be empty`); - } - filters.push({ field, value }); - } - - return filters; -} - -function getBearerToken(header?: string): string | undefined { - return header?.match(/Bearer\s+(\S+)/i)?.[1]; -} diff --git a/plugins/todo-backend/src/service/types.ts b/plugins/todo-backend/src/service/types.ts index 88d2f2b340..ab15e20027 100644 --- a/plugins/todo-backend/src/service/types.ts +++ b/plugins/todo-backend/src/service/types.ts @@ -48,3 +48,11 @@ export interface TodoService { options?: { token?: string }, ): Promise; } + +export const TODO_FIELDS = [ + 'text', + 'tag', + 'author', + 'viewUrl', + 'repoFilePath', +] as const; diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index 49a8241e30..35c607ba30 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-todo +## 0.2.18-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.2.17 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + ## 0.2.17-next.2 ### Patch Changes diff --git a/plugins/todo/package.json b/plugins/todo/package.json index d337834872..8c925c5cf7 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,14 +1,15 @@ { "name": "@backstage/plugin-todo", "description": "A Backstage plugin that lets you browse TODO comments in your source code", - "version": "0.2.17-next.2", + "version": "0.2.18-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" + "types": "dist/index.d.ts", + "alphaTypes": "dist/index.alpha.d.ts" }, "backstage": { "role": "frontend-plugin" @@ -20,7 +21,7 @@ "directory": "plugins/todo" }, "scripts": { - "build": "backstage-cli package build", + "build": "backstage-cli package build --experimental-type-build", "start": "backstage-cli package start", "lint": "backstage-cli package lint", "test": "backstage-cli package test", @@ -54,9 +55,10 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ - "dist" + "dist", + "alpha" ] } diff --git a/plugins/user-settings-backend/CHANGELOG.md b/plugins/user-settings-backend/CHANGELOG.md index 20a7f0c6e5..4a6c211adb 100644 --- a/plugins/user-settings-backend/CHANGELOG.md +++ b/plugins/user-settings-backend/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-user-settings-backend +## 0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.4.1-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.12-next.0 + +## 0.1.6 + +### Patch Changes + +- 0ff03319be: Updated usage of `createBackendPlugin`. +- 4a6f38a535: Added a Backend System plugin feature +- Updated dependencies + - @backstage/backend-plugin-api@0.4.0 + - @backstage/backend-common@0.18.2 + - @backstage/catalog-model@1.2.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + - @backstage/plugin-auth-node@0.2.11 + ## 0.1.6-next.2 ### Patch Changes diff --git a/plugins/user-settings-backend/package.json b/plugins/user-settings-backend/package.json index b77050a5af..61ef65c231 100644 --- a/plugins/user-settings-backend/package.json +++ b/plugins/user-settings-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings-backend", "description": "The Backstage backend plugin to manage user settings", - "version": "0.1.6-next.2", + "version": "0.1.7-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index 478b60b6da..784956b16d 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/plugin-user-settings +## 0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-app-api@1.5.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + - @backstage/types@1.0.2 + +## 0.7.0 + +### Minor Changes + +- db10b6ef65: Added a Bitbucket Server Auth Provider and added its API to the app defaults + +### Patch Changes + +- c4940b6322: Added a message to advise a page reload when toggling feature flags +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-app-api@1.5.0 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + - @backstage/types@1.0.2 + ## 0.6.3-next.2 ### Patch Changes diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 319ce98fee..cce6dfa1e5 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings", "description": "A Backstage plugin that provides a settings page", - "version": "0.6.3-next.2", + "version": "0.7.1-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -59,7 +59,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/user-settings/src/components/AuthProviders/DefaultProviderSettings.tsx b/plugins/user-settings/src/components/AuthProviders/DefaultProviderSettings.tsx index f8e1fb190c..772ec80982 100644 --- a/plugins/user-settings/src/components/AuthProviders/DefaultProviderSettings.tsx +++ b/plugins/user-settings/src/components/AuthProviders/DefaultProviderSettings.tsx @@ -24,6 +24,7 @@ import { oktaAuthApiRef, microsoftAuthApiRef, bitbucketAuthApiRef, + bitbucketServerAuthApiRef, atlassianAuthApiRef, oneloginAuthApiRef, } from '@backstage/core-plugin-api'; @@ -99,6 +100,14 @@ export const DefaultProviderSettings = (props: { icon={Star} /> )} + {configuredProviders.includes('bitbucketServer') && ( + + )} ); }; diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md index 2c7715cd73..4f57faf78e 100644 --- a/plugins/vault-backend/CHANGELOG.md +++ b/plugins/vault-backend/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/plugin-vault-backend +## 0.2.10-next.0 + +### Patch Changes + +- 66b3a3956b: Ignore the `eslint` error +- Updated dependencies + - @backstage/backend-tasks@0.4.4-next.0 + - @backstage/backend-common@0.18.3-next.0 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + +## 0.2.8 + +### Patch Changes + +- 5b7cd5580d: Moving the backend-test-utils to devDependencies. +- Updated dependencies + - @backstage/backend-common@0.18.2 + - @backstage/backend-tasks@0.4.3 + - @backstage/config@1.0.6 + - @backstage/errors@1.1.4 + ## 0.2.8-next.2 ### Patch Changes diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index ae7c89a61c..fda7059dc5 100644 --- a/plugins/vault-backend/package.json +++ b/plugins/vault-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-backend", "description": "A Backstage backend plugin that integrates towards Vault", - "version": "0.2.8-next.2", + "version": "0.2.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -53,7 +53,7 @@ "@backstage/cli": "workspace:^", "@types/compression": "^1.7.2", "@types/supertest": "^2.0.8", - "msw": "^0.49.0", + "msw": "^1.0.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/vault-backend/src/service/standaloneApplication.ts b/plugins/vault-backend/src/service/standaloneApplication.ts index bcec8ca419..ba4c0edc3e 100644 --- a/plugins/vault-backend/src/service/standaloneApplication.ts +++ b/plugins/vault-backend/src/service/standaloneApplication.ts @@ -28,6 +28,10 @@ import helmet from 'helmet'; import { Logger } from 'winston'; import { createRouter } from './router'; import { ConfigReader } from '@backstage/config'; + +// Think this file will probably go away once we move to backend system +// And restructure into the /dev folder +// eslint-disable-next-line @backstage/no-undeclared-imports import { TestDatabases } from '@backstage/backend-test-utils'; import { TaskScheduler } from '@backstage/backend-tasks'; diff --git a/plugins/vault/CHANGELOG.md b/plugins/vault/CHANGELOG.md index 60fe5c4c8b..3b79e99c42 100644 --- a/plugins/vault/CHANGELOG.md +++ b/plugins/vault/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-vault +## 0.1.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.4.0-next.0 + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/catalog-model@1.2.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.1.9 + +### Patch Changes + +- fd7a77b9c4: Surface additional context and details to the Backstage UI when the Vault plugin encounters non-successful HTTP responses from the Vault API. +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/catalog-model@1.2.0 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/plugin-catalog-react@1.3.0 + - @backstage/errors@1.1.4 + ## 0.1.9-next.2 ### Patch Changes diff --git a/plugins/vault/package.json b/plugins/vault/package.json index 15bae8c3ad..e0754b9c8d 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault", "description": "A Backstage plugin that integrates towards Vault", - "version": "0.1.9-next.2", + "version": "0.1.10-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -57,7 +57,7 @@ "@testing-library/user-event": "^14.0.0", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md index af4665e980..7a727aa92a 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,26 @@ # @backstage/plugin-xcmetrics +## 0.2.36-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.4.1-next.0 + - @backstage/core-components@0.12.5-next.0 + - @backstage/errors@1.1.4 + - @backstage/theme@0.2.17 + +## 0.2.35 + +### Patch Changes + +- c51efce2a0: Update docs to always use `yarn add --cwd` for app & backend +- Updated dependencies + - @backstage/core-components@0.12.4 + - @backstage/theme@0.2.17 + - @backstage/core-plugin-api@1.4.0 + - @backstage/errors@1.1.4 + ## 0.2.35-next.1 ### Patch Changes diff --git a/plugins/xcmetrics/README.md b/plugins/xcmetrics/README.md index a3bb93d2af..7c003722a0 100644 --- a/plugins/xcmetrics/README.md +++ b/plugins/xcmetrics/README.md @@ -7,10 +7,9 @@ With this plugin, you can view data from XCMetrics directly in Backstage. ## Getting started -From `packages/app`: - ```bash -yarn add @backstage/plugin-xcmetrics +# From your Backstage root directory +yarn add --cwd packages/app @backstage/plugin-xcmetrics ``` In `packages/app/src/App.tsx`, add the following: diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index 775e884f4b..107cb9600e 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-xcmetrics", "description": "A Backstage plugin that shows XCode build metrics for your components", - "version": "0.2.35-next.1", + "version": "0.2.36-next.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -49,7 +49,7 @@ "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.49.0" + "msw": "^1.0.0" }, "files": [ "dist" diff --git a/scripts/check-docs-quality.js b/scripts/check-docs-quality.js index 3dcbd6ef81..2890f1cf33 100755 --- a/scripts/check-docs-quality.js +++ b/scripts/check-docs-quality.js @@ -21,7 +21,7 @@ const IGNORED = [ /^ADOPTERS\.md$/, /^OWNERS\.md$/, /^.*[/\\]CHANGELOG\.md$/, - /^.*[/\\]api-report\.md$/, + /^.*[/\\]([^\/]+-)?api-report\.md$/, /^docs[/\\]releases[/\\].*-changelog\.md$/, /^docs[/\\]reference[/\\]/, ]; diff --git a/scripts/generate-changeset-feedback.js b/scripts/generate-changeset-feedback.js deleted file mode 100644 index b9ad09ca72..0000000000 --- a/scripts/generate-changeset-feedback.js +++ /dev/null @@ -1,314 +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. - */ - -const fs = require('fs'); -const { execFile: execFileCb } = require('child_process'); -const { promisify } = require('util'); -const { - basename, - resolve: resolvePath, - relative: relativePath, -} = require('path'); - -const execFile = promisify(execFileCb); - -// Tells whether a path relative to the package directory has an effect -// on the published package -function isPublishedPath(path) { - if (path.startsWith('dev/')) { - return false; - } - if (path.includes('__mocks__')) { - return false; - } - if (path.includes('__fixtures__')) { - return false; - } - // Don't count manual modifications to the changelog - if (path === 'CHANGELOG.md') { - return false; - } - // API report changes by themselves don't count - if (path === 'api-report.md' || path === 'cli-report.md') { - return false; - } - // Lint changes don't count - if (path === '.eslintrc.js') { - return false; - } - - const name = basename(path); - if (name.startsWith('setupTests.')) { - return false; - } - if (name.includes('.test.')) { - return false; - } - if (name.includes('.stories.')) { - return false; - } - return true; -} - -async function listChangedFiles(ref) { - if (!ref) { - throw new Error('ref is required'); - } - - const { stdout } = await execFile('git', ['diff', '--name-only', ref]); - return stdout.trim().split(/\r?\n/); -} - -async function listPackages() { - const rootPkg = require(resolvePath(process.cwd(), './package.json')); - if (!rootPkg?.workspaces?.packages) { - throw new Error('No workspaces found in root package.json'); - } - - const pkgs = []; - - // Naive workspace lookup implementation, we can't shell out to yarn here as the implementation embedded in the repo - for (const pkgPath of rootPkg?.workspaces?.packages) { - const readDirRecursive = (dir, parts) => { - const [nextPart] = parts; - - // We've reached the end of the path pattern, check if package.json exists - if (!nextPart) { - try { - const pkg = require(resolvePath(dir, 'package.json')); - pkgs.push({ - path: relativePath(process.cwd(), dir), - name: pkg.name, - }); - } catch { - process.stderr.write(`Failed to read package.json in ${dir}\n`); - } - return; - } - - for (const filePath of fs.readdirSync(dir)) { - if (fs.statSync(resolvePath(dir, filePath)).isDirectory()) { - if (filePath === nextPart || nextPart === '*') { - readDirRecursive(resolvePath(dir, filePath), parts.slice(1)); - } - } - } - }; - - // Split the workspace paths by / and check each directory level recursively - readDirRecursive(process.cwd(), pkgPath.split('/')); - } - - return pkgs; -} - -async function loadChangesets(filePaths) { - const changesets = []; - for (const filePath of filePaths) { - if (!filePath.startsWith('.changeset/') || !filePath.endsWith('.md')) { - continue; - } - try { - const content = await fs.promises.readFile(filePath, 'utf8'); - let lines = content.split(/\r?\n/); - - lines = lines.slice(lines.findIndex(line => line === '---') + 1); - lines = lines.slice( - 0, - lines.findIndex(line => line === '---'), - ); - - const bumps = new Map(); - bumps.toJSON = () => Object.fromEntries(bumps); - for (const line of lines) { - const match = line.match(/^'(.*)': (patch|minor|major)$/); - if (!match) { - throw new Error(`Invalid changeset line: ${line}`); - } - - bumps.set(match[1], match[2]); - } - - changesets.push({ - filePath, - bumps, - }); - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; - } - } - } - - return changesets; -} - -async function listChangedPackages(changedFiles, packages) { - const changedPackageMap = new Map(); - for (const filePath of changedFiles) { - for (const pkg of packages) { - if (filePath.startsWith(`${pkg.path}/`)) { - const pkgPath = relativePath(pkg.path, filePath); - if (!isPublishedPath(pkgPath)) { - break; - } - const entry = changedPackageMap.get(pkg.name); - if (entry) { - entry.files.push(pkgPath); - } else { - const pkgJson = require(resolvePath(pkg.path, 'package.json')); - - changedPackageMap.set(pkg.name, { - ...pkg, - version: pkgJson.version, - isStable: !pkgJson.version.startsWith('0.'), - isPrivate: Boolean(pkgJson.private), - files: [pkgPath], - }); - } - break; - } - } - } - return Array.from(changedPackageMap.values()); -} - -function formatSection(prefix = [], generator, suffix = ['']) { - const lines = Array.from(generator()); - if (lines.length === 0) { - return ''; - } - - return [...[prefix].flat(), ...lines, ...[suffix].flat(), '', ''].join('\n'); -} - -function formatSummary(changedPackages, changesets) { - const changedNames = new Set(changedPackages.map(pkg => pkg.name)); - - let output = ''; - - output += formatSection( - `## Missing Changesets - -The following package(s) are changed by this PR but do not have a changeset: -`, - function* section() { - for (const pkg of changedPackages) { - if (changesets.some(c => c.bumps.get(pkg.name))) { - continue; - } - if (pkg.isPrivate) { - continue; - } - yield `- **${pkg.name}**`; - } - }, - ` -See [CONTRIBUTING.md](https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md#creating-changesets) for more information about how to add changesets. -`, - ); - - output += formatSection( - `## Unexpected Changesets - -The following changeset(s) reference packages that have not been changed in this PR: -`, - function* section() { - for (const c of changesets) { - const missing = Array.from(c.bumps.keys()).filter( - b => !changedNames.has(b), - ); - if (missing.length > 0) { - yield `- **${c.filePath}**: ${missing.join(', ')}`; - } - } - }, - ` -Note that only changes that affect the published package require changesets, for example changes to tests and storybook stories do not require changesets. -`, - ); - - output += formatSection( - `## Unnecessary Changesets - -The following package(s) are private and do not need a changeset: -`, - function* section() { - for (const pkg of changedPackages) { - if (changesets.some(c => c.bumps.get(pkg.name)) && pkg.isPrivate) { - yield `- **${pkg.name}**`; - } - } - }, - ); - - output += formatSection( - `## Changed Packages - -| Package Name | Package Path | Changeset Bump | Current Version | -|:-------------|:-------------|:--------------:|:----------------|`, - function* section() { - const bumpMap = { - undefined: -1, - patch: 0, - minor: 1, - major: 2, - }; - - for (const pkg of changedPackages) { - const maxBump = - changesets - .map(c => c.bumps.get(pkg.name)) - .reduce( - (max, bump) => (bumpMap[bump] > bumpMap[max] ? bump : max), - undefined, - ) ?? 'none'; - yield `| ${pkg.name} | ${pkg.path} | **${maxBump}** | \`v${pkg.version}\` |`; - } - }, - ); - - return output; -} - -async function main() { - const [diffRef = 'origin/master'] = process.argv.slice(2); - const changedFiles = await listChangedFiles(diffRef); - const packages = await listPackages(); - - const changesets = await loadChangesets(changedFiles); - const changedPackages = await listChangedPackages(changedFiles, packages); - - process.stderr.write( - JSON.stringify( - { - changesets, - changedPackages, - }, - null, - 2, - ), - ); - process.stderr.write('\n'); - - const summary = formatSummary(changedPackages, changesets); - process.stdout.write(summary); -} - -main().catch(error => { - console.error(error.stack); - process.exit(1); -}); diff --git a/storybook/yarn.lock b/storybook/yarn.lock index f2e0f1c96a..5584e16296 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -2966,90 +2966,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-darwin-arm64@npm:1.3.34" +"@swc/core-darwin-arm64@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-darwin-arm64@npm:1.3.36" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-darwin-x64@npm:1.3.34" +"@swc/core-darwin-x64@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-darwin-x64@npm:1.3.36" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.34" +"@swc/core-linux-arm-gnueabihf@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.36" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.34" +"@swc/core-linux-arm64-gnu@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.36" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.34" +"@swc/core-linux-arm64-musl@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.36" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.34" +"@swc/core-linux-x64-gnu@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.36" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-x64-musl@npm:1.3.34" +"@swc/core-linux-x64-musl@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-x64-musl@npm:1.3.36" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.34" +"@swc/core-win32-arm64-msvc@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.36" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.34" +"@swc/core-win32-ia32-msvc@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.36" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.34" +"@swc/core-win32-x64-msvc@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.36" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.9": - version: 1.3.34 - resolution: "@swc/core@npm:1.3.34" + version: 1.3.36 + resolution: "@swc/core@npm:1.3.36" dependencies: - "@swc/core-darwin-arm64": 1.3.34 - "@swc/core-darwin-x64": 1.3.34 - "@swc/core-linux-arm-gnueabihf": 1.3.34 - "@swc/core-linux-arm64-gnu": 1.3.34 - "@swc/core-linux-arm64-musl": 1.3.34 - "@swc/core-linux-x64-gnu": 1.3.34 - "@swc/core-linux-x64-musl": 1.3.34 - "@swc/core-win32-arm64-msvc": 1.3.34 - "@swc/core-win32-ia32-msvc": 1.3.34 - "@swc/core-win32-x64-msvc": 1.3.34 + "@swc/core-darwin-arm64": 1.3.36 + "@swc/core-darwin-x64": 1.3.36 + "@swc/core-linux-arm-gnueabihf": 1.3.36 + "@swc/core-linux-arm64-gnu": 1.3.36 + "@swc/core-linux-arm64-musl": 1.3.36 + "@swc/core-linux-x64-gnu": 1.3.36 + "@swc/core-linux-x64-musl": 1.3.36 + "@swc/core-win32-arm64-msvc": 1.3.36 + "@swc/core-win32-ia32-msvc": 1.3.36 + "@swc/core-win32-x64-msvc": 1.3.36 dependenciesMeta: "@swc/core-darwin-arm64": optional: true @@ -3071,7 +3071,7 @@ __metadata: optional: true "@swc/core-win32-x64-msvc": optional: true - checksum: a77c286b6b34d40f634ae882aac66f882cf806c165453878c31311070c46f020c607925bd454f64959504f08852b204cc37feba93fc6a3c1a64b295a9b5007d6 + checksum: 36e96e86d1ab8fd84eb51e7264a7ae781ee7e507d36b9ccc028d7f31a2ccf2949f074656e34139c970196774d24d55a54c3aa5c53d04eb6e3569c71cbfed0c0d languageName: node linkType: hard diff --git a/yarn.lock b/yarn.lock index c45112197f..54b5e304d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -373,13 +373,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/abort-controller@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/abort-controller@npm:3.257.0" +"@aws-sdk/abort-controller@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/abort-controller@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: fca54be92f6cbfe8f0675aba19a50960376506a4c9aaa9c44220e8c29a7b3c8c74198537f831c1d4818ec686df97af86d055d8f3265c3a6fde56bbf593241c47 + checksum: 298974b97641732c74272dd645b55c15aaefd891b5a868c279ae2abe3c3e0753e7e6f218e8c3712196ca2d4f19796623cb48f9e9816b5bbbc4eb38247d07d0fe languageName: node linkType: hard @@ -402,477 +402,477 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.261.0" +"@aws-sdk/client-cognito-identity@npm:3.276.0": + version: 3.276.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.276.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.261.0 - "@aws-sdk/config-resolver": 3.259.0 - "@aws-sdk/credential-provider-node": 3.261.0 - "@aws-sdk/fetch-http-handler": 3.257.0 - "@aws-sdk/hash-node": 3.257.0 - "@aws-sdk/invalid-dependency": 3.257.0 - "@aws-sdk/middleware-content-length": 3.257.0 - "@aws-sdk/middleware-endpoint": 3.257.0 - "@aws-sdk/middleware-host-header": 3.257.0 - "@aws-sdk/middleware-logger": 3.257.0 - "@aws-sdk/middleware-recursion-detection": 3.257.0 - "@aws-sdk/middleware-retry": 3.259.0 - "@aws-sdk/middleware-serde": 3.257.0 - "@aws-sdk/middleware-signing": 3.257.0 - "@aws-sdk/middleware-stack": 3.257.0 - "@aws-sdk/middleware-user-agent": 3.257.0 - "@aws-sdk/node-config-provider": 3.259.0 - "@aws-sdk/node-http-handler": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/smithy-client": 3.261.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/url-parser": 3.257.0 + "@aws-sdk/client-sts": 3.276.0 + "@aws-sdk/config-resolver": 3.272.0 + "@aws-sdk/credential-provider-node": 3.272.0 + "@aws-sdk/fetch-http-handler": 3.272.0 + "@aws-sdk/hash-node": 3.272.0 + "@aws-sdk/invalid-dependency": 3.272.0 + "@aws-sdk/middleware-content-length": 3.272.0 + "@aws-sdk/middleware-endpoint": 3.272.0 + "@aws-sdk/middleware-host-header": 3.272.0 + "@aws-sdk/middleware-logger": 3.272.0 + "@aws-sdk/middleware-recursion-detection": 3.272.0 + "@aws-sdk/middleware-retry": 3.272.0 + "@aws-sdk/middleware-serde": 3.272.0 + "@aws-sdk/middleware-signing": 3.272.0 + "@aws-sdk/middleware-stack": 3.272.0 + "@aws-sdk/middleware-user-agent": 3.272.0 + "@aws-sdk/node-config-provider": 3.272.0 + "@aws-sdk/node-http-handler": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/smithy-client": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/url-parser": 3.272.0 "@aws-sdk/util-base64": 3.208.0 "@aws-sdk/util-body-length-browser": 3.188.0 "@aws-sdk/util-body-length-node": 3.208.0 - "@aws-sdk/util-defaults-mode-browser": 3.261.0 - "@aws-sdk/util-defaults-mode-node": 3.261.0 - "@aws-sdk/util-endpoints": 3.257.0 - "@aws-sdk/util-retry": 3.257.0 - "@aws-sdk/util-user-agent-browser": 3.257.0 - "@aws-sdk/util-user-agent-node": 3.259.0 + "@aws-sdk/util-defaults-mode-browser": 3.272.0 + "@aws-sdk/util-defaults-mode-node": 3.272.0 + "@aws-sdk/util-endpoints": 3.272.0 + "@aws-sdk/util-retry": 3.272.0 + "@aws-sdk/util-user-agent-browser": 3.272.0 + "@aws-sdk/util-user-agent-node": 3.272.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: edbaacaa9b2576376aedca110ba6267af25005922e23e9d7c5b0d00572ab758b47493f30bf6223c9462e31b236f7d6194786be0d6e79676726a28d74a6de8989 + checksum: ff79c1c727d956e03510307b001c24534d522b327871b2b0a1d39120e6d6717e17d7b9c2b7a6d28c3e5c3f41cd8ff28e5150ddd1fda9bff0c239fdfef0a78e00 languageName: node linkType: hard "@aws-sdk/client-s3@npm:^3.208.0": - version: 3.261.0 - resolution: "@aws-sdk/client-s3@npm:3.261.0" + version: 3.276.0 + resolution: "@aws-sdk/client-s3@npm:3.276.0" dependencies: "@aws-crypto/sha1-browser": 3.0.0 "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.261.0 - "@aws-sdk/config-resolver": 3.259.0 - "@aws-sdk/credential-provider-node": 3.261.0 - "@aws-sdk/eventstream-serde-browser": 3.258.0 - "@aws-sdk/eventstream-serde-config-resolver": 3.257.0 - "@aws-sdk/eventstream-serde-node": 3.258.0 - "@aws-sdk/fetch-http-handler": 3.257.0 - "@aws-sdk/hash-blob-browser": 3.257.0 - "@aws-sdk/hash-node": 3.257.0 - "@aws-sdk/hash-stream-node": 3.257.0 - "@aws-sdk/invalid-dependency": 3.257.0 - "@aws-sdk/md5-js": 3.258.0 - "@aws-sdk/middleware-bucket-endpoint": 3.259.0 - "@aws-sdk/middleware-content-length": 3.257.0 - "@aws-sdk/middleware-endpoint": 3.257.0 - "@aws-sdk/middleware-expect-continue": 3.257.0 - "@aws-sdk/middleware-flexible-checksums": 3.259.0 - "@aws-sdk/middleware-host-header": 3.257.0 - "@aws-sdk/middleware-location-constraint": 3.257.0 - "@aws-sdk/middleware-logger": 3.257.0 - "@aws-sdk/middleware-recursion-detection": 3.257.0 - "@aws-sdk/middleware-retry": 3.259.0 - "@aws-sdk/middleware-sdk-s3": 3.257.0 - "@aws-sdk/middleware-serde": 3.257.0 - "@aws-sdk/middleware-signing": 3.257.0 - "@aws-sdk/middleware-ssec": 3.257.0 - "@aws-sdk/middleware-stack": 3.257.0 - "@aws-sdk/middleware-user-agent": 3.257.0 - "@aws-sdk/node-config-provider": 3.259.0 - "@aws-sdk/node-http-handler": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/signature-v4-multi-region": 3.257.0 - "@aws-sdk/smithy-client": 3.261.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/url-parser": 3.257.0 + "@aws-sdk/client-sts": 3.276.0 + "@aws-sdk/config-resolver": 3.272.0 + "@aws-sdk/credential-provider-node": 3.272.0 + "@aws-sdk/eventstream-serde-browser": 3.272.0 + "@aws-sdk/eventstream-serde-config-resolver": 3.272.0 + "@aws-sdk/eventstream-serde-node": 3.272.0 + "@aws-sdk/fetch-http-handler": 3.272.0 + "@aws-sdk/hash-blob-browser": 3.272.0 + "@aws-sdk/hash-node": 3.272.0 + "@aws-sdk/hash-stream-node": 3.272.0 + "@aws-sdk/invalid-dependency": 3.272.0 + "@aws-sdk/md5-js": 3.272.0 + "@aws-sdk/middleware-bucket-endpoint": 3.272.0 + "@aws-sdk/middleware-content-length": 3.272.0 + "@aws-sdk/middleware-endpoint": 3.272.0 + "@aws-sdk/middleware-expect-continue": 3.272.0 + "@aws-sdk/middleware-flexible-checksums": 3.272.0 + "@aws-sdk/middleware-host-header": 3.272.0 + "@aws-sdk/middleware-location-constraint": 3.272.0 + "@aws-sdk/middleware-logger": 3.272.0 + "@aws-sdk/middleware-recursion-detection": 3.272.0 + "@aws-sdk/middleware-retry": 3.272.0 + "@aws-sdk/middleware-sdk-s3": 3.272.0 + "@aws-sdk/middleware-serde": 3.272.0 + "@aws-sdk/middleware-signing": 3.272.0 + "@aws-sdk/middleware-ssec": 3.272.0 + "@aws-sdk/middleware-stack": 3.272.0 + "@aws-sdk/middleware-user-agent": 3.272.0 + "@aws-sdk/node-config-provider": 3.272.0 + "@aws-sdk/node-http-handler": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/signature-v4-multi-region": 3.272.0 + "@aws-sdk/smithy-client": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/url-parser": 3.272.0 "@aws-sdk/util-base64": 3.208.0 "@aws-sdk/util-body-length-browser": 3.188.0 "@aws-sdk/util-body-length-node": 3.208.0 - "@aws-sdk/util-defaults-mode-browser": 3.261.0 - "@aws-sdk/util-defaults-mode-node": 3.261.0 - "@aws-sdk/util-endpoints": 3.257.0 - "@aws-sdk/util-retry": 3.257.0 - "@aws-sdk/util-stream-browser": 3.258.0 - "@aws-sdk/util-stream-node": 3.257.0 - "@aws-sdk/util-user-agent-browser": 3.257.0 - "@aws-sdk/util-user-agent-node": 3.259.0 + "@aws-sdk/util-defaults-mode-browser": 3.272.0 + "@aws-sdk/util-defaults-mode-node": 3.272.0 + "@aws-sdk/util-endpoints": 3.272.0 + "@aws-sdk/util-retry": 3.272.0 + "@aws-sdk/util-stream-browser": 3.272.0 + "@aws-sdk/util-stream-node": 3.272.0 + "@aws-sdk/util-user-agent-browser": 3.272.0 + "@aws-sdk/util-user-agent-node": 3.272.0 "@aws-sdk/util-utf8": 3.254.0 - "@aws-sdk/util-waiter": 3.257.0 + "@aws-sdk/util-waiter": 3.272.0 "@aws-sdk/xml-builder": 3.201.0 - fast-xml-parser: 4.0.11 + fast-xml-parser: 4.1.2 tslib: ^2.3.1 - checksum: 3600a38f6828b4fd3e14adf1f5aeb2fbb6693d43f4dd4f8be384adbf2b2218d50aa034f19c4399dececfa072833fa7ddd680c23c4c8ad30e04c0045f37d859ee + checksum: f7f475b92c0cff800536fb910bb6ffefcee6e650208f1791ea64c95bcbb6c63ef7a55e3f72af44e2e730a53865857ac4b974f00cb7da1e369d742cc95e33f02a languageName: node linkType: hard "@aws-sdk/client-sqs@npm:^3.208.0": - version: 3.261.0 - resolution: "@aws-sdk/client-sqs@npm:3.261.0" + version: 3.276.0 + resolution: "@aws-sdk/client-sqs@npm:3.276.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/client-sts": 3.261.0 - "@aws-sdk/config-resolver": 3.259.0 - "@aws-sdk/credential-provider-node": 3.261.0 - "@aws-sdk/fetch-http-handler": 3.257.0 - "@aws-sdk/hash-node": 3.257.0 - "@aws-sdk/invalid-dependency": 3.257.0 - "@aws-sdk/md5-js": 3.258.0 - "@aws-sdk/middleware-content-length": 3.257.0 - "@aws-sdk/middleware-endpoint": 3.257.0 - "@aws-sdk/middleware-host-header": 3.257.0 - "@aws-sdk/middleware-logger": 3.257.0 - "@aws-sdk/middleware-recursion-detection": 3.257.0 - "@aws-sdk/middleware-retry": 3.259.0 - "@aws-sdk/middleware-sdk-sqs": 3.257.0 - "@aws-sdk/middleware-serde": 3.257.0 - "@aws-sdk/middleware-signing": 3.257.0 - "@aws-sdk/middleware-stack": 3.257.0 - "@aws-sdk/middleware-user-agent": 3.257.0 - "@aws-sdk/node-config-provider": 3.259.0 - "@aws-sdk/node-http-handler": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/smithy-client": 3.261.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/url-parser": 3.257.0 + "@aws-sdk/client-sts": 3.276.0 + "@aws-sdk/config-resolver": 3.272.0 + "@aws-sdk/credential-provider-node": 3.272.0 + "@aws-sdk/fetch-http-handler": 3.272.0 + "@aws-sdk/hash-node": 3.272.0 + "@aws-sdk/invalid-dependency": 3.272.0 + "@aws-sdk/md5-js": 3.272.0 + "@aws-sdk/middleware-content-length": 3.272.0 + "@aws-sdk/middleware-endpoint": 3.272.0 + "@aws-sdk/middleware-host-header": 3.272.0 + "@aws-sdk/middleware-logger": 3.272.0 + "@aws-sdk/middleware-recursion-detection": 3.272.0 + "@aws-sdk/middleware-retry": 3.272.0 + "@aws-sdk/middleware-sdk-sqs": 3.272.0 + "@aws-sdk/middleware-serde": 3.272.0 + "@aws-sdk/middleware-signing": 3.272.0 + "@aws-sdk/middleware-stack": 3.272.0 + "@aws-sdk/middleware-user-agent": 3.272.0 + "@aws-sdk/node-config-provider": 3.272.0 + "@aws-sdk/node-http-handler": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/smithy-client": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/url-parser": 3.272.0 "@aws-sdk/util-base64": 3.208.0 "@aws-sdk/util-body-length-browser": 3.188.0 "@aws-sdk/util-body-length-node": 3.208.0 - "@aws-sdk/util-defaults-mode-browser": 3.261.0 - "@aws-sdk/util-defaults-mode-node": 3.261.0 - "@aws-sdk/util-endpoints": 3.257.0 - "@aws-sdk/util-retry": 3.257.0 - "@aws-sdk/util-user-agent-browser": 3.257.0 - "@aws-sdk/util-user-agent-node": 3.259.0 + "@aws-sdk/util-defaults-mode-browser": 3.272.0 + "@aws-sdk/util-defaults-mode-node": 3.272.0 + "@aws-sdk/util-endpoints": 3.272.0 + "@aws-sdk/util-retry": 3.272.0 + "@aws-sdk/util-user-agent-browser": 3.272.0 + "@aws-sdk/util-user-agent-node": 3.272.0 "@aws-sdk/util-utf8": 3.254.0 - fast-xml-parser: 4.0.11 + fast-xml-parser: 4.1.2 tslib: ^2.3.1 - checksum: b15130b021f1af1109236abda0fb83232a37b8cb147bf59e3f09b3f44db6934d19bb3633eeac9c7302b9019714d53d47acc0e66df90ef848f518cf0d11661f15 + checksum: 88139fde34fa6348e841de13fce5e68b2dfb735c5358c959f9956a8c918048bde8b1ff701e8e701807af5f67f6df129056986b62a7e07096cc7097f3491d36b8 languageName: node linkType: hard -"@aws-sdk/client-sso-oidc@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/client-sso-oidc@npm:3.261.0" +"@aws-sdk/client-sso-oidc@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.272.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/config-resolver": 3.259.0 - "@aws-sdk/fetch-http-handler": 3.257.0 - "@aws-sdk/hash-node": 3.257.0 - "@aws-sdk/invalid-dependency": 3.257.0 - "@aws-sdk/middleware-content-length": 3.257.0 - "@aws-sdk/middleware-endpoint": 3.257.0 - "@aws-sdk/middleware-host-header": 3.257.0 - "@aws-sdk/middleware-logger": 3.257.0 - "@aws-sdk/middleware-recursion-detection": 3.257.0 - "@aws-sdk/middleware-retry": 3.259.0 - "@aws-sdk/middleware-serde": 3.257.0 - "@aws-sdk/middleware-stack": 3.257.0 - "@aws-sdk/middleware-user-agent": 3.257.0 - "@aws-sdk/node-config-provider": 3.259.0 - "@aws-sdk/node-http-handler": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/smithy-client": 3.261.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/url-parser": 3.257.0 + "@aws-sdk/config-resolver": 3.272.0 + "@aws-sdk/fetch-http-handler": 3.272.0 + "@aws-sdk/hash-node": 3.272.0 + "@aws-sdk/invalid-dependency": 3.272.0 + "@aws-sdk/middleware-content-length": 3.272.0 + "@aws-sdk/middleware-endpoint": 3.272.0 + "@aws-sdk/middleware-host-header": 3.272.0 + "@aws-sdk/middleware-logger": 3.272.0 + "@aws-sdk/middleware-recursion-detection": 3.272.0 + "@aws-sdk/middleware-retry": 3.272.0 + "@aws-sdk/middleware-serde": 3.272.0 + "@aws-sdk/middleware-stack": 3.272.0 + "@aws-sdk/middleware-user-agent": 3.272.0 + "@aws-sdk/node-config-provider": 3.272.0 + "@aws-sdk/node-http-handler": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/smithy-client": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/url-parser": 3.272.0 "@aws-sdk/util-base64": 3.208.0 "@aws-sdk/util-body-length-browser": 3.188.0 "@aws-sdk/util-body-length-node": 3.208.0 - "@aws-sdk/util-defaults-mode-browser": 3.261.0 - "@aws-sdk/util-defaults-mode-node": 3.261.0 - "@aws-sdk/util-endpoints": 3.257.0 - "@aws-sdk/util-retry": 3.257.0 - "@aws-sdk/util-user-agent-browser": 3.257.0 - "@aws-sdk/util-user-agent-node": 3.259.0 + "@aws-sdk/util-defaults-mode-browser": 3.272.0 + "@aws-sdk/util-defaults-mode-node": 3.272.0 + "@aws-sdk/util-endpoints": 3.272.0 + "@aws-sdk/util-retry": 3.272.0 + "@aws-sdk/util-user-agent-browser": 3.272.0 + "@aws-sdk/util-user-agent-node": 3.272.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: d33870aed0db77246812b99d05d5536df4b51a36fc0f1717aa883e82c5c8460bb867a6a3b817b06f41e86732390305dced75f99aee1d58ae3635102a89562ae7 + checksum: a1ee61c2fc86a74439e06c98aa10c8246e31579eb480b625321f7dfe8fd26af49bd6ead803da2443700c5943eab5ba90dfc33fc4d9f23b1a680850d73526da4d languageName: node linkType: hard -"@aws-sdk/client-sso@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/client-sso@npm:3.261.0" +"@aws-sdk/client-sso@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/client-sso@npm:3.272.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/config-resolver": 3.259.0 - "@aws-sdk/fetch-http-handler": 3.257.0 - "@aws-sdk/hash-node": 3.257.0 - "@aws-sdk/invalid-dependency": 3.257.0 - "@aws-sdk/middleware-content-length": 3.257.0 - "@aws-sdk/middleware-endpoint": 3.257.0 - "@aws-sdk/middleware-host-header": 3.257.0 - "@aws-sdk/middleware-logger": 3.257.0 - "@aws-sdk/middleware-recursion-detection": 3.257.0 - "@aws-sdk/middleware-retry": 3.259.0 - "@aws-sdk/middleware-serde": 3.257.0 - "@aws-sdk/middleware-stack": 3.257.0 - "@aws-sdk/middleware-user-agent": 3.257.0 - "@aws-sdk/node-config-provider": 3.259.0 - "@aws-sdk/node-http-handler": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/smithy-client": 3.261.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/url-parser": 3.257.0 + "@aws-sdk/config-resolver": 3.272.0 + "@aws-sdk/fetch-http-handler": 3.272.0 + "@aws-sdk/hash-node": 3.272.0 + "@aws-sdk/invalid-dependency": 3.272.0 + "@aws-sdk/middleware-content-length": 3.272.0 + "@aws-sdk/middleware-endpoint": 3.272.0 + "@aws-sdk/middleware-host-header": 3.272.0 + "@aws-sdk/middleware-logger": 3.272.0 + "@aws-sdk/middleware-recursion-detection": 3.272.0 + "@aws-sdk/middleware-retry": 3.272.0 + "@aws-sdk/middleware-serde": 3.272.0 + "@aws-sdk/middleware-stack": 3.272.0 + "@aws-sdk/middleware-user-agent": 3.272.0 + "@aws-sdk/node-config-provider": 3.272.0 + "@aws-sdk/node-http-handler": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/smithy-client": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/url-parser": 3.272.0 "@aws-sdk/util-base64": 3.208.0 "@aws-sdk/util-body-length-browser": 3.188.0 "@aws-sdk/util-body-length-node": 3.208.0 - "@aws-sdk/util-defaults-mode-browser": 3.261.0 - "@aws-sdk/util-defaults-mode-node": 3.261.0 - "@aws-sdk/util-endpoints": 3.257.0 - "@aws-sdk/util-retry": 3.257.0 - "@aws-sdk/util-user-agent-browser": 3.257.0 - "@aws-sdk/util-user-agent-node": 3.259.0 + "@aws-sdk/util-defaults-mode-browser": 3.272.0 + "@aws-sdk/util-defaults-mode-node": 3.272.0 + "@aws-sdk/util-endpoints": 3.272.0 + "@aws-sdk/util-retry": 3.272.0 + "@aws-sdk/util-user-agent-browser": 3.272.0 + "@aws-sdk/util-user-agent-node": 3.272.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: aa2b71a0be6c5ca92940eacdb008d89c007b595f8c5cb80ff7c5c697d83e1de44432463f5d20b7074939c806612165c47345b197e8dd1743f523858117a4b70b + checksum: 7549e813ef8088d22a0a1f9c8a42532d2d2050c932fd6e7d4f717aea2cd554938283f3af0f1fe9597b24724c6b2438947b3089452ed9c0dfafb1efad15f3ac60 languageName: node linkType: hard -"@aws-sdk/client-sts@npm:3.261.0, @aws-sdk/client-sts@npm:^3.208.0": - version: 3.261.0 - resolution: "@aws-sdk/client-sts@npm:3.261.0" +"@aws-sdk/client-sts@npm:3.276.0, @aws-sdk/client-sts@npm:^3.208.0": + version: 3.276.0 + resolution: "@aws-sdk/client-sts@npm:3.276.0" dependencies: "@aws-crypto/sha256-browser": 3.0.0 "@aws-crypto/sha256-js": 3.0.0 - "@aws-sdk/config-resolver": 3.259.0 - "@aws-sdk/credential-provider-node": 3.261.0 - "@aws-sdk/fetch-http-handler": 3.257.0 - "@aws-sdk/hash-node": 3.257.0 - "@aws-sdk/invalid-dependency": 3.257.0 - "@aws-sdk/middleware-content-length": 3.257.0 - "@aws-sdk/middleware-endpoint": 3.257.0 - "@aws-sdk/middleware-host-header": 3.257.0 - "@aws-sdk/middleware-logger": 3.257.0 - "@aws-sdk/middleware-recursion-detection": 3.257.0 - "@aws-sdk/middleware-retry": 3.259.0 - "@aws-sdk/middleware-sdk-sts": 3.257.0 - "@aws-sdk/middleware-serde": 3.257.0 - "@aws-sdk/middleware-signing": 3.257.0 - "@aws-sdk/middleware-stack": 3.257.0 - "@aws-sdk/middleware-user-agent": 3.257.0 - "@aws-sdk/node-config-provider": 3.259.0 - "@aws-sdk/node-http-handler": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/smithy-client": 3.261.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/url-parser": 3.257.0 + "@aws-sdk/config-resolver": 3.272.0 + "@aws-sdk/credential-provider-node": 3.272.0 + "@aws-sdk/fetch-http-handler": 3.272.0 + "@aws-sdk/hash-node": 3.272.0 + "@aws-sdk/invalid-dependency": 3.272.0 + "@aws-sdk/middleware-content-length": 3.272.0 + "@aws-sdk/middleware-endpoint": 3.272.0 + "@aws-sdk/middleware-host-header": 3.272.0 + "@aws-sdk/middleware-logger": 3.272.0 + "@aws-sdk/middleware-recursion-detection": 3.272.0 + "@aws-sdk/middleware-retry": 3.272.0 + "@aws-sdk/middleware-sdk-sts": 3.272.0 + "@aws-sdk/middleware-serde": 3.272.0 + "@aws-sdk/middleware-signing": 3.272.0 + "@aws-sdk/middleware-stack": 3.272.0 + "@aws-sdk/middleware-user-agent": 3.272.0 + "@aws-sdk/node-config-provider": 3.272.0 + "@aws-sdk/node-http-handler": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/smithy-client": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/url-parser": 3.272.0 "@aws-sdk/util-base64": 3.208.0 "@aws-sdk/util-body-length-browser": 3.188.0 "@aws-sdk/util-body-length-node": 3.208.0 - "@aws-sdk/util-defaults-mode-browser": 3.261.0 - "@aws-sdk/util-defaults-mode-node": 3.261.0 - "@aws-sdk/util-endpoints": 3.257.0 - "@aws-sdk/util-retry": 3.257.0 - "@aws-sdk/util-user-agent-browser": 3.257.0 - "@aws-sdk/util-user-agent-node": 3.259.0 + "@aws-sdk/util-defaults-mode-browser": 3.272.0 + "@aws-sdk/util-defaults-mode-node": 3.272.0 + "@aws-sdk/util-endpoints": 3.272.0 + "@aws-sdk/util-retry": 3.272.0 + "@aws-sdk/util-user-agent-browser": 3.272.0 + "@aws-sdk/util-user-agent-node": 3.272.0 "@aws-sdk/util-utf8": 3.254.0 - fast-xml-parser: 4.0.11 + fast-xml-parser: 4.1.2 tslib: ^2.3.1 - checksum: e7be888c97351bb3b52e50de5e6830849c97c9d2b2ad2b14daea66f7dd2e7a4eaae26ccb78aeb874b1719c73a8d8ccf2bb02915eca4cabeb34226e1a10ae1ebd + checksum: 3250322448500789588d24b6fac295b551ab4c1661ab9aa93f173e63b4673260bb2e551c079d811da752115e583b76f5c7ffb16d94b3c66275e75e52a93f35f3 languageName: node linkType: hard -"@aws-sdk/config-resolver@npm:3.259.0": - version: 3.259.0 - resolution: "@aws-sdk/config-resolver@npm:3.259.0" +"@aws-sdk/config-resolver@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/config-resolver@npm:3.272.0" dependencies: - "@aws-sdk/signature-v4": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/signature-v4": 3.272.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-config-provider": 3.208.0 - "@aws-sdk/util-middleware": 3.257.0 + "@aws-sdk/util-middleware": 3.272.0 tslib: ^2.3.1 - checksum: c461dfd62291c8dbc3394d586aa44a14326c0a9f02e4cc84dfa6569c6003890d21343aaa28a067337949837f7e2c2e3533465e3e2e5f2ee3e42bb30cc69de0d4 + checksum: d2a2fa4f013ad04f50522aec1001efd34c62ababbc809b176d2e31e41828d867de616ff01bfcaa12603b344ca6838ea5946c72d21e5f2573b90828e29bad6e35 languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.261.0" +"@aws-sdk/credential-provider-cognito-identity@npm:3.276.0": + version: 3.276.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.276.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.261.0 - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/client-cognito-identity": 3.276.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 678098f0079cef01ed10c7c06f838b30ec50a047dd67cadd898a134347c31d9dfc9cdd18880eeae26f2d1f700b8d5ae120181f0b1889a20da981076edef5c2c6 + checksum: 2d255475f08beeccd000745b2f2c46553559fd6fe15c0ea9960956655535fb927df9ec3431cf743b80f9a460d033ede7e1c47e91aff44956559a70c5f43f7bab languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/credential-provider-env@npm:3.257.0" +"@aws-sdk/credential-provider-env@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.272.0" dependencies: - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: e268c46ff374eddb5cd5bef62a8b969a5bfd5202e15122ecbd2baa7882c99f75c2e2b6dfc0c294fcfc331e9e2028620c827278f1eec6f7158c30f079ae67dc5f + checksum: 74195ecb608e3e6dedfc40e052bd7d0ef3a9e531ecf404f40d05869e23328bd156e458e9770d30458137438de92efd3dcb9fc3ff5f1319c49b55e057323f3ea6 languageName: node linkType: hard -"@aws-sdk/credential-provider-imds@npm:3.259.0": - version: 3.259.0 - resolution: "@aws-sdk/credential-provider-imds@npm:3.259.0" +"@aws-sdk/credential-provider-imds@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/credential-provider-imds@npm:3.272.0" dependencies: - "@aws-sdk/node-config-provider": 3.259.0 - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/url-parser": 3.257.0 + "@aws-sdk/node-config-provider": 3.272.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/url-parser": 3.272.0 tslib: ^2.3.1 - checksum: 7149bb155e9f169f6d9a4e17d16c683b5eed6f71871230f1c786b884f22fe438b3f29e6179a5538ad540f025d2eb3cfa1a4d9a1bd1e1ec495a539f8d164903da + checksum: c6adfcaa8dada3f99bbbd241aee3e568474c93df97e9b3f5e4feb9b000a91e5b3f0491556f712ebbd4d67de9c77c1072e6d444ac63ad9c6be31cf26acb2bc72c languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.261.0" +"@aws-sdk/credential-provider-ini@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.272.0" dependencies: - "@aws-sdk/credential-provider-env": 3.257.0 - "@aws-sdk/credential-provider-imds": 3.259.0 - "@aws-sdk/credential-provider-process": 3.257.0 - "@aws-sdk/credential-provider-sso": 3.261.0 - "@aws-sdk/credential-provider-web-identity": 3.257.0 - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/shared-ini-file-loader": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/credential-provider-env": 3.272.0 + "@aws-sdk/credential-provider-imds": 3.272.0 + "@aws-sdk/credential-provider-process": 3.272.0 + "@aws-sdk/credential-provider-sso": 3.272.0 + "@aws-sdk/credential-provider-web-identity": 3.272.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/shared-ini-file-loader": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 72834195a9a2fad9d6a8011d904ed0a59b29c043bcc98e226b2381d123c57b9b528dd924aa2c94283e38cbddb98198892c0f428b363565678ca992276062cc8d + checksum: 06c1dfc6bff09472e11dd7e2c295cfdf71c36af11cb6ba33ce0328aaf9d0baee3f99de8ceec32ff473925b55ad190c9f85f125cf43874c25e22c37e8e3c648d3 languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:3.261.0, @aws-sdk/credential-provider-node@npm:^3.208.0": - version: 3.261.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.261.0" +"@aws-sdk/credential-provider-node@npm:3.272.0, @aws-sdk/credential-provider-node@npm:^3.208.0": + version: 3.272.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.272.0" dependencies: - "@aws-sdk/credential-provider-env": 3.257.0 - "@aws-sdk/credential-provider-imds": 3.259.0 - "@aws-sdk/credential-provider-ini": 3.261.0 - "@aws-sdk/credential-provider-process": 3.257.0 - "@aws-sdk/credential-provider-sso": 3.261.0 - "@aws-sdk/credential-provider-web-identity": 3.257.0 - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/shared-ini-file-loader": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/credential-provider-env": 3.272.0 + "@aws-sdk/credential-provider-imds": 3.272.0 + "@aws-sdk/credential-provider-ini": 3.272.0 + "@aws-sdk/credential-provider-process": 3.272.0 + "@aws-sdk/credential-provider-sso": 3.272.0 + "@aws-sdk/credential-provider-web-identity": 3.272.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/shared-ini-file-loader": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: af393f142f1305438f5ac5be79a120ad1566d57edca8b1577dc0fcfe50bfb31c721de2d04dd49abbf3086676ad5c4b809d136841e2e25451facf9599dda7322c + checksum: 25c5ab8583821f63c7eb1a5257869dd21159d0b7643ff9a9c094e9b5c78c887bc441f1a2f974eaace62c1879d13e7d590bb3ea2623f5a5de822bf773b1aab100 languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.257.0" +"@aws-sdk/credential-provider-process@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.272.0" dependencies: - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/shared-ini-file-loader": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/shared-ini-file-loader": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: cb34261ae87463245e4cc3ddab306201c52a8fbcfedc122ae9782bdf9263ab8fabc33cde028def52d069452a842338033829aaecfec2d0fc00547513a76c9b6f + checksum: fda290aea2417137f333c8ad0a94d7789054b464bdf5f9a7eef06341f88d4bd0c96ca02b84b58e0af2a9c490cee4febf6ee84254dfbff192bfccccbb0c8c1876 languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.261.0" +"@aws-sdk/credential-provider-sso@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.272.0" dependencies: - "@aws-sdk/client-sso": 3.261.0 - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/shared-ini-file-loader": 3.257.0 - "@aws-sdk/token-providers": 3.261.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/client-sso": 3.272.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/shared-ini-file-loader": 3.272.0 + "@aws-sdk/token-providers": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 0f3fc6ceb69e537f2e5751283aac473dcc5a4f8da798b0340995cb5996ca8201844c2f5b6cdcaa7ce642e1375cbdd039fa4b9962b84f27d500eaaa1f80725199 + checksum: ac1ada61e67f6f0a82ed8507c0218a03fe40e2d1e4ee064578e63573f868195800088dc3e33d58d7d04877e464342987005aceb300e4db9a141080cdc695e46e languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.257.0" +"@aws-sdk/credential-provider-web-identity@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.272.0" dependencies: - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 2d3ee4975af680337cd6a9f25b6eb874201f4787ddc0217f80cb7ebb36c70424108fa8c04e5a9f0f8c2130d06685a3de3938c41b8c78e238b9faeb348c0cd361 + checksum: aad84e2bfd90495ed4eb76b83940729bd2fb652398f7e477cfd8053f9c986132b4ff8682854a91e3f23c7daaab66e1c31320188561104fea710cd87be1221e9d languageName: node linkType: hard "@aws-sdk/credential-providers@npm:^3.208.0": - version: 3.261.0 - resolution: "@aws-sdk/credential-providers@npm:3.261.0" + version: 3.276.0 + resolution: "@aws-sdk/credential-providers@npm:3.276.0" dependencies: - "@aws-sdk/client-cognito-identity": 3.261.0 - "@aws-sdk/client-sso": 3.261.0 - "@aws-sdk/client-sts": 3.261.0 - "@aws-sdk/credential-provider-cognito-identity": 3.261.0 - "@aws-sdk/credential-provider-env": 3.257.0 - "@aws-sdk/credential-provider-imds": 3.259.0 - "@aws-sdk/credential-provider-ini": 3.261.0 - "@aws-sdk/credential-provider-node": 3.261.0 - "@aws-sdk/credential-provider-process": 3.257.0 - "@aws-sdk/credential-provider-sso": 3.261.0 - "@aws-sdk/credential-provider-web-identity": 3.257.0 - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/shared-ini-file-loader": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/client-cognito-identity": 3.276.0 + "@aws-sdk/client-sso": 3.272.0 + "@aws-sdk/client-sts": 3.276.0 + "@aws-sdk/credential-provider-cognito-identity": 3.276.0 + "@aws-sdk/credential-provider-env": 3.272.0 + "@aws-sdk/credential-provider-imds": 3.272.0 + "@aws-sdk/credential-provider-ini": 3.272.0 + "@aws-sdk/credential-provider-node": 3.272.0 + "@aws-sdk/credential-provider-process": 3.272.0 + "@aws-sdk/credential-provider-sso": 3.272.0 + "@aws-sdk/credential-provider-web-identity": 3.272.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/shared-ini-file-loader": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 56880bab2a99c2c9710622be905091c1316dbcd9ce44c5a567021ce809134cf52d5a920649ab715157b408ff73cf03bdee4da4d410c448ffa72b90bb9a9b03db + checksum: 825fb0feda57ef98cc11ab3febc2a337161193dfa24bcc31ad2b47ecb4af564b3b5a5a0d9c17fd1a3ec118321d21fc515948980ba50c323e21ed79905c13dfe4 languageName: node linkType: hard -"@aws-sdk/eventstream-codec@npm:3.258.0": - version: 3.258.0 - resolution: "@aws-sdk/eventstream-codec@npm:3.258.0" +"@aws-sdk/eventstream-codec@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/eventstream-codec@npm:3.272.0" dependencies: "@aws-crypto/crc32": 3.0.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-hex-encoding": 3.201.0 tslib: ^2.3.1 - checksum: b2fca764b9c105a355a18af565c3a5bbd50ce6cf385b86668c1451f429a1fac31114bf88eec3d4ea2160a368f48e06f6b3ce83d273035e4824464de9c322f9d8 + checksum: bea8599a72657d698de169643950031624e0b61179240c8d8eb3c17f01bfc4579c507a861be6c703f318fcdff4217a4cb4279223cad93fb21e69f4b5d10d6102 languageName: node linkType: hard -"@aws-sdk/eventstream-serde-browser@npm:3.258.0": - version: 3.258.0 - resolution: "@aws-sdk/eventstream-serde-browser@npm:3.258.0" +"@aws-sdk/eventstream-serde-browser@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/eventstream-serde-browser@npm:3.272.0" dependencies: - "@aws-sdk/eventstream-serde-universal": 3.258.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/eventstream-serde-universal": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 3155f6bc39ef914be1950d8ba310029d5f8ffacaf9a516b20da4890d68b2bde6c636367bb4391c12ce4a3518041aca1afae0179aa5d76f9208133e7423bd86d9 + checksum: a4fa42e1a8658eca191f567046741192e6e04f5c58744655ec0112a1d46b57d5ce04432e2fec0e6fe16d486c30abdc58b734ed67879c10e0fcc4820530eaff35 languageName: node linkType: hard -"@aws-sdk/eventstream-serde-config-resolver@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/eventstream-serde-config-resolver@npm:3.257.0" +"@aws-sdk/eventstream-serde-config-resolver@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/eventstream-serde-config-resolver@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 6658916cebfbdc74407cfdf1bda622bd9c7731a5f855b9cfb8870e3dd558f802ccc99ee30e9dcc05109d2a4c253cac799506afad5947c8526ab49973a567c0fb + checksum: feee058288bbf5a97d78dfee5084c2dc224d771499848dcaedbfd671c8889f52329f96ce87c291d29e66b46c8e25923bd55f64d8ed744089fc40723296eb003c languageName: node linkType: hard -"@aws-sdk/eventstream-serde-node@npm:3.258.0": - version: 3.258.0 - resolution: "@aws-sdk/eventstream-serde-node@npm:3.258.0" +"@aws-sdk/eventstream-serde-node@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/eventstream-serde-node@npm:3.272.0" dependencies: - "@aws-sdk/eventstream-serde-universal": 3.258.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/eventstream-serde-universal": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 298b60866c8b10cec812766f0a8f9fba482dcd19b48c0c6dceb5bda10e85a64c5c1216a61d288c0fd3b7be4a6e1dfba4f30a41b01a6bbb60a1cb419b21f0902a + checksum: 02fa0c5f992df253713bbe19515bf898e332e3bc51da28da28bdf2cde584df90689bb9b54afa57354798c8b01e4b592d63fb575d7652fd5df2c00bf1e45e689a languageName: node linkType: hard -"@aws-sdk/eventstream-serde-universal@npm:3.258.0": - version: 3.258.0 - resolution: "@aws-sdk/eventstream-serde-universal@npm:3.258.0" +"@aws-sdk/eventstream-serde-universal@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/eventstream-serde-universal@npm:3.272.0" dependencies: - "@aws-sdk/eventstream-codec": 3.258.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/eventstream-codec": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 038ed604878f31478c2b00e86fdeeeee38905349be2fbf8104954d176b94996863e5e6e8a15c4849acac7ccaa537718762c1619d436ccef87c8a8b0bbf9d68cb + checksum: 3d8031e84af1a0cdf5f22f98aee868cd62b6fa87e432231bbe32a400874dc44b030cffdf9dce3194281bf04a1669b23bf8ce16759123ba10980676fe9388e63b languageName: node linkType: hard @@ -889,61 +889,61 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/fetch-http-handler@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/fetch-http-handler@npm:3.257.0" +"@aws-sdk/fetch-http-handler@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/fetch-http-handler@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/querystring-builder": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/querystring-builder": 3.272.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-base64": 3.208.0 tslib: ^2.3.1 - checksum: de25f542db072225c23403254be7ff4e642f12e348eb703cdb30a5e9b0ac5e4f18930947490f6bb27a31b8f8a462abfdd7b9344b16e41b6b52e1fe969ac95396 + checksum: 63d047db7b7ebfee49af8bf42f3a7aa1bea37cc687e7046bc77913c23ed99056e91b5ab77739157428be73b2a2f29783a7a659ccf29a440dd63b750d313d46cc languageName: node linkType: hard -"@aws-sdk/hash-blob-browser@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/hash-blob-browser@npm:3.257.0" +"@aws-sdk/hash-blob-browser@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/hash-blob-browser@npm:3.272.0" dependencies: "@aws-sdk/chunked-blob-reader": 3.188.0 "@aws-sdk/chunked-blob-reader-native": 3.208.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 85dfb814cbb24cb00a52fc6232e0f0c2f4c359fabf44c52cef7938c39c059c1b0b2722895394b9a4e544a63fa7e3998fb8d8bacd2582ca1beb1197e93f55a16b + checksum: ab0564672606760b934973ef33a8a8d567d52d3fa4be2a7a8919daa1b9ac1c3afaaee975ae7ad20940f51e1057e3321c39f5dcd2246ca85aad03e1f7aed68669 languageName: node linkType: hard -"@aws-sdk/hash-node@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/hash-node@npm:3.257.0" +"@aws-sdk/hash-node@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/hash-node@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-buffer-from": 3.208.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: 26f8f2fca7ad13a1dc64753ee1ef85014eb89adfef9f500f5003e479807c5f2ec6ee185ae8e88d6bcb68e26512702fd6886fe211486531e4388e40fd003678a5 + checksum: 1b3d5b288133af9294df36cec2377589f45c82f61cb824b14ac38955541357826cf5a8f95d7906cbf284ed9ffbd928a37b2f94581f7281715879aa4c0e7c7b24 languageName: node linkType: hard -"@aws-sdk/hash-stream-node@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/hash-stream-node@npm:3.257.0" +"@aws-sdk/hash-stream-node@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/hash-stream-node@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: 7aa9e69fb47c05f557fe79f382e20b99a87f9ada068a9458834afba550cdac13256d47baf42a50287aebe37e2f99de9747f80ea206c5da86e556855ec6b9d8bc + checksum: 4cb90a9ae442e0722d651d7e7558a8b0abcbc1b45670e194d51d0a9b2ea6cad6e3a02433d506a8d96ac94a26cd8e5746514c09f05f0da2acb2dc06c60218d3c5 languageName: node linkType: hard -"@aws-sdk/invalid-dependency@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/invalid-dependency@npm:3.257.0" +"@aws-sdk/invalid-dependency@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/invalid-dependency@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: fe99f546cc041a9ccc8b29654fd3e8e466aef41697d4c69f4afc1aab1f1f83f2e7f0b9e0e20b3fe23843a01008902f00aeeb24cf26b7df0594c75a4ebf3bb3f3 + checksum: 4ef63ed9a9275e20bdcec551ee92a9d60a6a688c120f968fd51af235d357d39ec522752592075dad752be9a8439d93b4d1848e12fa9a88cda595920d78b008d2 languageName: node linkType: hard @@ -957,11 +957,11 @@ __metadata: linkType: hard "@aws-sdk/lib-storage@npm:^3.208.0": - version: 3.261.0 - resolution: "@aws-sdk/lib-storage@npm:3.261.0" + version: 3.276.0 + resolution: "@aws-sdk/lib-storage@npm:3.276.0" dependencies: - "@aws-sdk/middleware-endpoint": 3.257.0 - "@aws-sdk/smithy-client": 3.261.0 + "@aws-sdk/middleware-endpoint": 3.272.0 + "@aws-sdk/smithy-client": 3.272.0 buffer: 5.6.0 events: 3.3.0 stream-browserify: 3.0.0 @@ -969,268 +969,268 @@ __metadata: peerDependencies: "@aws-sdk/abort-controller": ^3.0.0 "@aws-sdk/client-s3": ^3.0.0 - checksum: 649d5ea5a9aa5723d2cfdecee9457a8b64662387b8a279e6a29a0c36e605c7b307b1666f76b3eb9422e27fc6235dcd506bfa0f0dbb00e2c6575346bf385a7d2e + checksum: 1e34d3569c8cf2f7c42efdd7966a9faea64bf49f4fe1fcb0ff30ed86670a5ba2361bb14279e7dc1bc110a1ff9e5cec3551bc8a56b3c9c4d19f98ff4842a8de19 languageName: node linkType: hard -"@aws-sdk/md5-js@npm:3.258.0": - version: 3.258.0 - resolution: "@aws-sdk/md5-js@npm:3.258.0" +"@aws-sdk/md5-js@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/md5-js@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: e1812a1aae620d242d42b2425d40169e7af94c0a29275704d9dbb2ec68161207cc79a75cdc66b60b5ad24fd1607e6fcc14dc3aa3adb18fb71446b546898ea730 + checksum: d59010c1b48ba1992298ed23b605e7395a4aa964430d41012492faac24c7fa50856b565a523b0262b2c8b667904fdc57748d98475ba8c2e24b4550e17211e5ab languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.259.0": - version: 3.259.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.259.0" +"@aws-sdk/middleware-bucket-endpoint@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-arn-parser": 3.208.0 "@aws-sdk/util-config-provider": 3.208.0 tslib: ^2.3.1 - checksum: 4ad5c0ece9723e52b70129f39737a66d8778eb538868af7dcbc574264f95d9705aa3a178c043c05861aac91487e76c3a663badce8022fa5aa9aa89622ca5f58a + checksum: 2c9dffb5545e085ce6323e9628d5998b551332f213f33cdbd606e889b4ca4fdac61648e2c0d8cadcf11aa5908049a764083a794082fce611980056a093c78e55 languageName: node linkType: hard -"@aws-sdk/middleware-content-length@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-content-length@npm:3.257.0" +"@aws-sdk/middleware-content-length@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-content-length@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 4f6129653b98185624c66bf2114417d492ec3cf91063da4cbce0e07ad3b1831766ff684491f0c14f92c8b9b39599a9781ca883f2d5ee42c3d38b273b6664f361 + checksum: e1a9c3e6fec8dcfed90bb44b25a8f4786b4ed0cbd79c6f69e3d8e91d394402ad4f2667231aafdcc05caf136a331434d54fac286a72ab5870dd90705a2e56243b languageName: node linkType: hard -"@aws-sdk/middleware-endpoint@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-endpoint@npm:3.257.0" +"@aws-sdk/middleware-endpoint@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-endpoint@npm:3.272.0" dependencies: - "@aws-sdk/middleware-serde": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/signature-v4": 3.257.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/url-parser": 3.257.0 + "@aws-sdk/middleware-serde": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/signature-v4": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/url-parser": 3.272.0 "@aws-sdk/util-config-provider": 3.208.0 - "@aws-sdk/util-middleware": 3.257.0 + "@aws-sdk/util-middleware": 3.272.0 tslib: ^2.3.1 - checksum: e709f6b5dc6bee4659caa7740847f53be359b215d307210f093629f5013f3d0521e060ef6f7797c82dd02a9ac0528b47581e6e19fb0e2f38aa2ff3a8f1b9abc0 + checksum: c3acd1a35d33cff87a43df371ae138faf6c9569497c36b009cafc2fdb1f21e352671df6eb56730634d7f135bef2a47ac588ac7cdd2905676292a418b79a0eab1 languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.257.0" +"@aws-sdk/middleware-expect-continue@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 911e087f822ce384f69a1f1d28449c99b81fa464af854f0a253656615104a047bcceb5a93837a9073a8466d2ec255550e5306a17c19087f5e3f060c27d1f930b + checksum: 19f32623758ccc1d08e2ff08db8efc62c3e04c3e89b15a7ca4b1719fa15ce7bfaad0eea3cceadc395f769405181a356a6a4efdadb2e6f6bd90afd31f8532ca40 languageName: node linkType: hard -"@aws-sdk/middleware-flexible-checksums@npm:3.259.0": - version: 3.259.0 - resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.259.0" +"@aws-sdk/middleware-flexible-checksums@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.272.0" dependencies: "@aws-crypto/crc32": 3.0.0 "@aws-crypto/crc32c": 3.0.0 "@aws-sdk/is-array-buffer": 3.201.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: b20e03676b38d8ba13b67c7bfe92b1802d8685fefd86934df472d51ec0ea856f470597e9cee98086b84bd6a8e8c02527c69961c9eac988e07a4bb805e5612e7b + checksum: 06d0f9edd3c78d17e0669dd913daed67f0c45d59be54bf39e68ad1184fd0dc80d544545bbe09f6dd51ca6dca8a42b585ba83e5be3aa665c6486fb5210b08f8df languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-host-header@npm:3.257.0" +"@aws-sdk/middleware-host-header@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 426f6a6a9964ef993d4e7d8401162b62f758a7247872c6b58163d40ec8320738a84dbd2dbaccd008b24801642f6fd2d24b6af11331f00a204ed48e814f1e6e3c + checksum: 3e191fe72de35b517a20fe47f647527579458091d4d66d55ef7e6b08107a4f4d7abe77afdcdd061776db906309d414525ff63e472c2c05d6e2447f41582f64fb languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.257.0" +"@aws-sdk/middleware-location-constraint@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 3894591a69b09987d6f4e9e85078167aff7fd836d819d0c06e2c5a0c191eb39e724ff3048280ba8763c02656cfbf06f4d9a47a602cc6e5c51ac50fec2127d16e + checksum: 42cb878c4a2b4e1c0884277a9cacc4611111e1d6de649c4fb41f770e60ddceef27de433667c4e4d29882f6c9ad746859e53e0724fbfc5aff23720496a4007a0b languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-logger@npm:3.257.0" +"@aws-sdk/middleware-logger@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-logger@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 3b4ac39d4be50dde9b806500a50a6d2c4ab267f6e02e780fe70adf0d07f4026c09131e3f787d86833f4295987cbad6858839884d1c5f1ea56df729fc4a8d7d49 + checksum: 128163d39522017ffb0099334f283ba82806b0c5b82965b47fff8b3b8648ae2b542b1733c69934bbca65fded9d26b8b93fa587547eeb8db2a3f5249841848f96 languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.257.0" +"@aws-sdk/middleware-recursion-detection@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: ce972140735fb040d00e1356409beac6dc5d9c477f975c73776de8294a91f81ac2a87e11c02581ff6c8b8c6f84e455e77a081291bbc536d22c9e128b07928fcd + checksum: cdc150a4f3cbd5d7c6926befcf7eb49daea1d0ca054dbe7b82e013eb74f3850056b78603f61989c2bb3cdc748798674b6811c3011c6a8c1773e13dfa11ea3ae7 languageName: node linkType: hard -"@aws-sdk/middleware-retry@npm:3.259.0": - version: 3.259.0 - resolution: "@aws-sdk/middleware-retry@npm:3.259.0" +"@aws-sdk/middleware-retry@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-retry@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/service-error-classification": 3.257.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/util-middleware": 3.257.0 - "@aws-sdk/util-retry": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/service-error-classification": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/util-middleware": 3.272.0 + "@aws-sdk/util-retry": 3.272.0 tslib: ^2.3.1 uuid: ^8.3.2 - checksum: 22ae9d575cafbc9c3806a10871e2b6749d12b8109bc15e8eabe82e24613dc60196c2ab48df62fcf39e3dae33319146a58d3983c51a68c6c1da89e941ac2d4efa + checksum: 208e8f1b96f5ee47d28d76d0f7738f0ae7e355cb9aa24dcb88a8c4d9aa35bf833bf333c1ad4a6d11d18ec27b1713cac0ee04e0fdac17462059416a214f366944 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.257.0" +"@aws-sdk/middleware-sdk-s3@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-arn-parser": 3.208.0 tslib: ^2.3.1 - checksum: 67742b8c34552f1b69c7d4d7c58d68bf698203e094d399f7936959318daef47d060496f451babc727970942c9699c83b3a0b57d49da26812e70888a74d6ef585 + checksum: 464f38d1593866724ce4e793e065c4e23b875ec889384a99c64d7aa34baf765ebdc18b218ed5e83f4f6c257d7b56c560aab8c0b617960a200484970ec8d55526 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sqs@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.257.0" +"@aws-sdk/middleware-sdk-sqs@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-sdk-sqs@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-hex-encoding": 3.201.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: 54cea36a767a3d7621eea7b22e59fb7268914228d3b26f6dbcd9cf17d9dc51a542c117249c992f5fd6e5804cdb04c675593ec150a41f564773b32ebf4c103b9b + checksum: 2338c5865fb797f5e9f0963cf0045e991a9aa816c4fefb86943e129be68ff3b94a662741692999c2a212e4491db299241453d9b432c3eee63781850f22772a29 languageName: node linkType: hard -"@aws-sdk/middleware-sdk-sts@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-sdk-sts@npm:3.257.0" +"@aws-sdk/middleware-sdk-sts@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-sdk-sts@npm:3.272.0" dependencies: - "@aws-sdk/middleware-signing": 3.257.0 - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/signature-v4": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/middleware-signing": 3.272.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/signature-v4": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 9171f0fc8a9518b8344c58f26446c9b39a19d00b747f2ae02b92b022d8fdcdb65528f05e753999676b3c04bffa38d008a599d86c2e0fa65b2196cd9633ab4308 + checksum: d808f945ae7354ef7102737418794565f26af3ca3241c3873235284400a13faf118242e92eba1831c25fc249d9c6a15f3c16e4ae3101cd6d5ab175a669b70fcb languageName: node linkType: hard -"@aws-sdk/middleware-serde@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-serde@npm:3.257.0" +"@aws-sdk/middleware-serde@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-serde@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: ceda3cb7bb7ceced0d5b69363dca51fa92b4f6defcd8299910eee0fe65d557871aa7777dade4abc64aa91347d038727fa65ff7ff0cc3d9716d0065dfd939c724 + checksum: d33c07ff8c7fb9682115220ae035de5414124fd81319d7490ed3f2c235b3c0b536634a5939b311dbd735050deca4702503ee26d9e17b97ba8a1ff9e46093573e languageName: node linkType: hard -"@aws-sdk/middleware-signing@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-signing@npm:3.257.0" +"@aws-sdk/middleware-signing@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-signing@npm:3.272.0" dependencies: - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/signature-v4": 3.257.0 - "@aws-sdk/types": 3.257.0 - "@aws-sdk/util-middleware": 3.257.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/signature-v4": 3.272.0 + "@aws-sdk/types": 3.272.0 + "@aws-sdk/util-middleware": 3.272.0 tslib: ^2.3.1 - checksum: dfa31f59675427f7aff83852f24e2393bd7d1295421d68c2bb060faca001ce385d7a1d7231c92c48e841e58581ceeffef0209c7c91b51b19361af29120342a50 + checksum: 0b711de21b0f2b28178b211ae2de962676038ed49ff9247810c2213018b77ca399285278a0b448a0242f92796e1360b83c09aa268fe64a7f153428b9ed919edc languageName: node linkType: hard -"@aws-sdk/middleware-ssec@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-ssec@npm:3.257.0" +"@aws-sdk/middleware-ssec@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 562d601a70f15446bf863d22427e8ee0949789a6cbebd2e82f5f513ff40e0da1f98c57f87677861e4347bad47e718388ea7cfd9478fb2ce47af14b89f7639aa9 + checksum: 81836fd3235f455d79d7cdc0bc193b321024dab2f6443f16e013c5eb4b3e06c3ca283152cb560f7f2bd2e2accf81f773f95278e8c9094806c1ddb54b5af0db8f languageName: node linkType: hard -"@aws-sdk/middleware-stack@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-stack@npm:3.257.0" +"@aws-sdk/middleware-stack@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-stack@npm:3.272.0" dependencies: tslib: ^2.3.1 - checksum: f7520d3e53d026f46c6504bcebef2a5732b724ab79079ccd2db0c052f6d4fd3cc4f06b951ff02723ef9ba46c6a0a0deca3282f152172ae7b1c3b2f493d35d584 + checksum: 7006c4168c2e5c7b15edd4e87001a6e4edbd2f549908ac0e68bb61f12c232048ac1d351b0714e7a79115aeaf251838877b2ef9ac829a6b1ab04913015a3c87a3 languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/middleware-user-agent@npm:3.257.0" +"@aws-sdk/middleware-user-agent@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: b2fc45a734845d40d1e69bf7f0890613aad8357d4830f704c7ee6c1339ab51cbb0cef51920dc22718d29eb258fc1024f8c23cbc53a4f93b9b857f8bcacc442a1 + checksum: a392a8c68509f118f008002e4ef6ba7fea9f93ade97963449e6eec951c0319a7cc8fd40cf77bda1540ff25ebbbe75785a6fc5ed4be63676144e5242892940732 languageName: node linkType: hard -"@aws-sdk/node-config-provider@npm:3.259.0": - version: 3.259.0 - resolution: "@aws-sdk/node-config-provider@npm:3.259.0" +"@aws-sdk/node-config-provider@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/node-config-provider@npm:3.272.0" dependencies: - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/shared-ini-file-loader": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/shared-ini-file-loader": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 72e4818b1ab641d1aa3b85c7901f7d64ad0399eb384cda1c875b41a37021c2be9e68021e6b0aa3f7298d2d46017259ee10356f07c314b4bc40146a44f355135a + checksum: 57f1f107ae4e213ffedf648d46fe0e026af83b13eeb8c13bd8f812cbbb226a0b2c2793afec0e29165ee64cc948182499ad44fe62f63ac58b06d0dd2cab7f1461 languageName: node linkType: hard -"@aws-sdk/node-http-handler@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/node-http-handler@npm:3.257.0" +"@aws-sdk/node-http-handler@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/node-http-handler@npm:3.272.0" dependencies: - "@aws-sdk/abort-controller": 3.257.0 - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/querystring-builder": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/abort-controller": 3.272.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/querystring-builder": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 37531827bc9e0b590c67ce57b87315fab8639a5feff1cb6cda8effdf6ac2d2fbc8a645765f004b52b03ff39c896da88a090b0dbcf5cfcf5d3d65d0b995f628fb + checksum: cbcdab82a7611d1d776197e921563ac6248173aa6e5a6f6e6486a735c71763ae69d1d6ae6de8acebcb8020cdfa089a776d9180929397291623db8f11a1f7b8a9 languageName: node linkType: hard -"@aws-sdk/property-provider@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/property-provider@npm:3.257.0" +"@aws-sdk/property-provider@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/property-provider@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 066290e9b88bcbc7d6bace37482ce955c782386a6cd75dc789efeb368bc87d0c410d01fd6b25bf66918e3328c6ffe1942aa643f4fdd4fa604feee36af9114894 + checksum: 7f01794e93276e13339034dac816b2b5da2370fbc1ff304d451e2d0344957e94ba53f5c54de44eca4cb53e2847c7be820db25d6164ca9e489a4a39787fb6c8b3 languageName: node linkType: hard @@ -1244,13 +1244,13 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/protocol-http@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/protocol-http@npm:3.257.0" +"@aws-sdk/protocol-http@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/protocol-http@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: c51539e2f617d5d84e51ad9feeb93d51a310d808da18ceb53317aaf35af99bb8bea52eca532ab68d546b0ff5156b92cef5c3e98245f0b425795bd7910b608dad + checksum: 59d7c97b1a46bc3c072f56caec365472c9d94638923799ad2418cee52bb0eab945ab080cd63f5351ff45ad943dde9d88b294e096af36524e184c0764b2ea6cc5 languageName: node linkType: hard @@ -1265,51 +1265,51 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/querystring-builder@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/querystring-builder@npm:3.257.0" +"@aws-sdk/querystring-builder@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/querystring-builder@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-uri-escape": 3.201.0 tslib: ^2.3.1 - checksum: a66b07cd1c4af544c7c6f903a735d1e8359f7d3b5c74803fc63b16b854eafec21f4b1c8874761edeebc4c2341f1f0b72190f03e0a005e8fff7b619e30cd59896 + checksum: 8164bb5547c556a2b3933b0a93d55d9f205ebe096f2dbcea6d3be4aa23bb0b4e7996ba24363b9ac3f80b4026903b267b759efdf9f72379f1eea9250c182238b9 languageName: node linkType: hard -"@aws-sdk/querystring-parser@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/querystring-parser@npm:3.257.0" +"@aws-sdk/querystring-parser@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/querystring-parser@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: cd391b7993a8e2397e3f0abd25e9b0b43747fe1b1415e9c5af6a3895567bb8dc9267d97e7d494c504f721b0b868bf9e0b93ec3677a5a7bc4ef2ff7252a402985 + checksum: fe5a29a265f48ad02b3161e888a66e4ac08fe07d52a67e811ac1da1734bfa9ac87ead637b595efcbc163f64f2280c8b56c867a8399f4c816b3683b6308837f93 languageName: node linkType: hard -"@aws-sdk/service-error-classification@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/service-error-classification@npm:3.257.0" - checksum: 231440f52a1c6c6d5ab62c13491736273fda49bb68bc278954dfaa3b7fa874946576c87a529504d6268472e646b3235cacb5c0fe5acc9af2398d87a56fabda3d +"@aws-sdk/service-error-classification@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/service-error-classification@npm:3.272.0" + checksum: 9507f74c909a968aa9bf835a05a9cfc93a0892e7c685de37da485e74a61b4fff271621d7c841aa0c9aedbcc57b19f171e6bc74925a82007be6c6750b3c7d0198 languageName: node linkType: hard -"@aws-sdk/shared-ini-file-loader@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/shared-ini-file-loader@npm:3.257.0" +"@aws-sdk/shared-ini-file-loader@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/shared-ini-file-loader@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 27738db81e2b9c8e0bd248e1c0ed7f21b65b52204b247cb8119b3b48b55844c2450e5fe20bb1193311177a8a18e8bb99594d3bfde71dacd1ee9ed8bbad9a915b + checksum: 1245658ad6efbeda0181aca64b00259749abc76d6200ac8fb481fe627eb88932a5cf2e9c366583ccba9fa540706a08b611552fff5233d66835c0e525c51f97c4 languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.257.0" +"@aws-sdk/signature-v4-multi-region@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.272.0" dependencies: - "@aws-sdk/protocol-http": 3.257.0 - "@aws-sdk/signature-v4": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/protocol-http": 3.272.0 + "@aws-sdk/signature-v4": 3.272.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-arn-parser": 3.208.0 tslib: ^2.3.1 peerDependencies: @@ -1317,46 +1317,46 @@ __metadata: peerDependenciesMeta: "@aws-sdk/signature-v4-crt": optional: true - checksum: 260d37db48e90addbaa302358a98307c8c61561953e37986f6f4571258784decf3e582f9da3c8cc4d545b3ddc63592e983949890e6204872469f7c837b3bb939 + checksum: 231eac2d4203a9ed3829d55a93d503d629bbd43301516d4e06c461dd16eba3a72373c004a59789de43487804266ca4ced259adcb1d26b6916f7b3545401ff544 languageName: node linkType: hard -"@aws-sdk/signature-v4@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/signature-v4@npm:3.257.0" +"@aws-sdk/signature-v4@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/signature-v4@npm:3.272.0" dependencies: "@aws-sdk/is-array-buffer": 3.201.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-hex-encoding": 3.201.0 - "@aws-sdk/util-middleware": 3.257.0 + "@aws-sdk/util-middleware": 3.272.0 "@aws-sdk/util-uri-escape": 3.201.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: 6faf6a3d8f51603240f6375b76bfd031223aa5cf1f0385cfa97833e6b188fb9b746caab53a45d0e7a311ca9735c82b56c67aed68b1fbcdf4bbcbf93e288fd09f + checksum: bdf997ed7779e173797bd31a9ae39bc9860e12cb7d0a734b4a47c76bde435c5c1d5f56dbb3c5f1a2b26a828367fd88f34a4527b8a12d4c1a60b3b0049aacf706 languageName: node linkType: hard -"@aws-sdk/smithy-client@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/smithy-client@npm:3.261.0" +"@aws-sdk/smithy-client@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/smithy-client@npm:3.272.0" dependencies: - "@aws-sdk/middleware-stack": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/middleware-stack": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 1394ce351d52bc3bd17b484acbfb9171a57203b64741a21d1f8c9d89443f165186539194d463ccdd2dfad18a981ff9561088d2d2c52e0467d8225400312b5486 + checksum: 8ba3c4733a32c7c28ec06735b0fc3dbc33a1657bfc54dc28f6770b021fda74680c693812d8c6db2291197a275f32fd80be909dddda4eb726328bf34e8d18bccc languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/token-providers@npm:3.261.0" +"@aws-sdk/token-providers@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/token-providers@npm:3.272.0" dependencies: - "@aws-sdk/client-sso-oidc": 3.261.0 - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/shared-ini-file-loader": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/client-sso-oidc": 3.272.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/shared-ini-file-loader": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: ca65f92443726c14860cd4adc7fde0f6eb073cdfa93d27d05495dbede3b6ead9157ad4dc5471398f47b3202527cfaf0e44f0d184d6a4be7a0290e9ae0bd9b9ab + checksum: 8d49846f4ad124707879a9b8adaea089c4d02dfd1c15dcceb083fecd538ecce1db65f1104e6178b13941acb2a4ae275c5cf9eb586d5d25757eb9fb454bdbb70c languageName: node linkType: hard @@ -1367,23 +1367,23 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.257.0, @aws-sdk/types@npm:^3.208.0, @aws-sdk/types@npm:^3.222.0": - version: 3.257.0 - resolution: "@aws-sdk/types@npm:3.257.0" +"@aws-sdk/types@npm:3.272.0, @aws-sdk/types@npm:^3.208.0, @aws-sdk/types@npm:^3.222.0": + version: 3.272.0 + resolution: "@aws-sdk/types@npm:3.272.0" dependencies: tslib: ^2.3.1 - checksum: eab2154f7d27d0bec29df41374481652525e1658ad987c64ed02cbe7b7388c563e6a8d317c8fc564ac6fbd97c98be700a29352c9acebc3903cf3305431bf0a86 + checksum: c4e4f09dd2672eab4fc15b08006c730c1d07d4b54ae35e03167d99f6110751e36b5332165e03c71c28724037f623f8da87a45a018eb631a1ce86d406f9d08da6 languageName: node linkType: hard -"@aws-sdk/url-parser@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/url-parser@npm:3.257.0" +"@aws-sdk/url-parser@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/url-parser@npm:3.272.0" dependencies: - "@aws-sdk/querystring-parser": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/querystring-parser": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 3b781c7fe94572e673e0651a47806cf023f60fb1268d2abbad9364c70112b1ad37d2261f631e0d7ce5c5ec543faa7e316d987e519091db68bf121384ad557043 + checksum: 4a66e733b336b0e28eceef89271f255dcd7079cfa8ba1c854e6c147ced211242e00016e3f22752e5ea3e49b35457568c5ae8df574f729d6e60cd1f5054f5a57d languageName: node linkType: hard @@ -1443,39 +1443,39 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-defaults-mode-browser@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/util-defaults-mode-browser@npm:3.261.0" +"@aws-sdk/util-defaults-mode-browser@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-defaults-mode-browser@npm:3.272.0" dependencies: - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/types": 3.272.0 bowser: ^2.11.0 tslib: ^2.3.1 - checksum: 218c97dc362549796a318048d496f8e105d023dd040ecf811c1cab8bc807c80afb43b8cae8bb6ac3c87f5bdfe07f9248fccd825554287cb5c39f84dddcb521b1 + checksum: 56594cc954c6431ced3646668fd92d8229eb1c20a37d6c66b0ebf3ce88a7f9803c63d432c78412768ebf0d141fdacef01644ea0f3507e6fb295a22c80f728c1a languageName: node linkType: hard -"@aws-sdk/util-defaults-mode-node@npm:3.261.0": - version: 3.261.0 - resolution: "@aws-sdk/util-defaults-mode-node@npm:3.261.0" +"@aws-sdk/util-defaults-mode-node@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-defaults-mode-node@npm:3.272.0" dependencies: - "@aws-sdk/config-resolver": 3.259.0 - "@aws-sdk/credential-provider-imds": 3.259.0 - "@aws-sdk/node-config-provider": 3.259.0 - "@aws-sdk/property-provider": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/config-resolver": 3.272.0 + "@aws-sdk/credential-provider-imds": 3.272.0 + "@aws-sdk/node-config-provider": 3.272.0 + "@aws-sdk/property-provider": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: d784ae1aaf51640b0b591028b91522c8c6dc58558245c6dfcd253adbfcc42e2496d4f8139df47b8b9932edd5eccbcdf8829a5d0adcf91b634ff8a506934d4399 + checksum: ee0e44d78d70b6eab73d6e8455972218cb1a15950f47d81d72d094420b2719add34bf46218016f85242a2a155216d2a0542ed5f4e68e171efc09691125fcb6fd languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/util-endpoints@npm:3.257.0" +"@aws-sdk/util-endpoints@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-endpoints@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: ba1aec13c8ceb9519400f2c77db1743b34dec4380b27598a8862e94c9df43e3e8b4e183f230fb6bdaaeb89653d232e6a13dcc2016c6a9d12246f58b630fd3ec0 + checksum: d701e0245930df2000974f9d7c8398fde65924fe5aaa72f2c314fa40a8842e1868a6e285aa78479f741e40b8be54060a4607c9b5b3ac0386839a45df8df238f2 languageName: node linkType: hard @@ -1497,48 +1497,48 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-middleware@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/util-middleware@npm:3.257.0" +"@aws-sdk/util-middleware@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-middleware@npm:3.272.0" dependencies: tslib: ^2.3.1 - checksum: 77ac007288fa98ec55c10af5a097f7f829d7ec53b6eecc43bc00a18b9ea011194aec42fb69e58421f87363490cef89b811330eaf174739fdf6b810b40cd46768 + checksum: e9a0b55317c474d3eecd65765443eff68f5130ac6f982a41450e0cb949169ff2cf13273282337f2067dfdb5cc7d25137b3bd2fa5f5228cfe541003cf387a6101 languageName: node linkType: hard -"@aws-sdk/util-retry@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/util-retry@npm:3.257.0" +"@aws-sdk/util-retry@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-retry@npm:3.272.0" dependencies: - "@aws-sdk/service-error-classification": 3.257.0 + "@aws-sdk/service-error-classification": 3.272.0 tslib: ^2.3.1 - checksum: 7d7054c5a73f3acaf59b620386ad0a6226ec6b2761e5c59f304694f8a7f5cb8ab0eb7d51be102e81d6e2a5ec97b20bd8814cf245ff44fcc5587d4e5b80a3b892 + checksum: 7449d9b5daef1244a1601c9892bdd57abeb71ee87357e9dac71d53a77b80648b8cd0db1e99749a76e241ab01fce71a753360d0c8e130f6ae6e71a94b462242f0 languageName: node linkType: hard -"@aws-sdk/util-stream-browser@npm:3.258.0": - version: 3.258.0 - resolution: "@aws-sdk/util-stream-browser@npm:3.258.0" +"@aws-sdk/util-stream-browser@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-stream-browser@npm:3.272.0" dependencies: - "@aws-sdk/fetch-http-handler": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/fetch-http-handler": 3.272.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-base64": 3.208.0 "@aws-sdk/util-hex-encoding": 3.201.0 "@aws-sdk/util-utf8": 3.254.0 tslib: ^2.3.1 - checksum: c3a99e5d5fd2e6c7aff63bc7041d1f49a5a328071421aa050ee57bdeeceb5e34005f4895df5fd2e358e245ca513c67717a896d8f2402b431d41bc22abe6b135b + checksum: 18e3dfa4efcf12e5e4eda55da14c9a98154f063b1bbf0a926fc406ffdf791363a1881e93194fa5a160e7bd26dd1b1933d6a57b19134e6f0a4feda8c6f5cfcb13 languageName: node linkType: hard -"@aws-sdk/util-stream-node@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/util-stream-node@npm:3.257.0" +"@aws-sdk/util-stream-node@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-stream-node@npm:3.272.0" dependencies: - "@aws-sdk/node-http-handler": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/node-http-handler": 3.272.0 + "@aws-sdk/types": 3.272.0 "@aws-sdk/util-buffer-from": 3.208.0 tslib: ^2.3.1 - checksum: d2773a857f8400aaef45237dff4f454b233eeed2644739f1dbd90f88ef02dfdfbc456ee6b92fb13b9fea6c29d0e5853f9eb942407487f51528128ed23f5a04a7 + checksum: 7fa500251680e3eb5fa63d47c6d4846ca66f8c781ee0d990ed79d16a12b0bb074eb7d5c9e26390afd7a18159a758fbc333ce1b788c2a8dea7438cbe2f4c6c7c3 languageName: node linkType: hard @@ -1556,30 +1556,30 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.257.0" +"@aws-sdk/util-user-agent-browser@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.272.0" dependencies: - "@aws-sdk/types": 3.257.0 + "@aws-sdk/types": 3.272.0 bowser: ^2.11.0 tslib: ^2.3.1 - checksum: f475d6096ff92ba2292de6cc78e2e1512df96c7fff3d8ef39148884533c14cc341a84ce3c4969f78cca2d8d4098c4cefefd72edf7cb480c33f8597f5828245c3 + checksum: e5ac1b88f9af45c2e0dbec40d2aa9c616634df252ac437f2dfd3aeb316fe561a5c09d481c075945843b3a7f5edafbc10ef26741c6ccacc4d435d8be7eeab179c languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:3.259.0": - version: 3.259.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.259.0" +"@aws-sdk/util-user-agent-node@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.272.0" dependencies: - "@aws-sdk/node-config-provider": 3.259.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/node-config-provider": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 peerDependencies: aws-crt: ">=1.0.0" peerDependenciesMeta: aws-crt: optional: true - checksum: ed2ae75ef0ccd5f58f16887c8cfd521006e8efaa8431420d1b55c3f885c501bbb06e6a4f262c0239a88fbec9100923cd277b4539838df9fe9f391c411c5767ee + checksum: 25d5f39349190e6323f893de4f0e7a931751bf1521808210515ef8d951c1a6a3e5f1dc1773cbd5ca9f999c5d00f3a421ad570b5f79b20dc2692012a9f833ff24 languageName: node linkType: hard @@ -1602,14 +1602,14 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-waiter@npm:3.257.0": - version: 3.257.0 - resolution: "@aws-sdk/util-waiter@npm:3.257.0" +"@aws-sdk/util-waiter@npm:3.272.0": + version: 3.272.0 + resolution: "@aws-sdk/util-waiter@npm:3.272.0" dependencies: - "@aws-sdk/abort-controller": 3.257.0 - "@aws-sdk/types": 3.257.0 + "@aws-sdk/abort-controller": 3.272.0 + "@aws-sdk/types": 3.272.0 tslib: ^2.3.1 - checksum: 4dd7310ca0b9cdda7c55e3e4a80c7b0b323961ea238cc3ab512e78495d356840ddd5eb0b99add4baf1abf19759ab9ab6bb5d528fe86b61193e0e4f3a854c223b + checksum: e931a9359dc582db9e5dcd62539572aecff5320ce424e5462c2f8d4a2d83acde07f87fe9ffc83850aaf70eaf17b06b6ffd4554350bab0f0f3a4427d1b7e776c6 languageName: node linkType: hard @@ -2224,12 +2224,12 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.16.8, @babel/parser@npm:^7.18.10, @babel/parser@npm:^7.19.1, @babel/parser@npm:^7.9.4": - version: 7.19.1 - resolution: "@babel/parser@npm:7.19.1" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.16.8, @babel/parser@npm:^7.18.10, @babel/parser@npm:^7.19.1, @babel/parser@npm:^7.20.15": + version: 7.20.15 + resolution: "@babel/parser@npm:7.20.15" bin: parser: ./bin/babel-parser.js - checksum: b1e0acb346b2a533c857e1e97ac0886cdcbd76aafef67835a2b23f760c10568eb53ad8a27dd5f862d8ba4e583742e6067f107281ccbd68959d61bc61e4ddaa51 + checksum: 1d0f47ca67ff2652f1c0ff1570bed8deccbc4b53509e7cd73476af9cc7ed23480c99f1179bd6d0be01612368b92b39e206d330ad6054009d699934848a89298b languageName: node linkType: hard @@ -3485,7 +3485,7 @@ __metadata: minimist: ^1.2.5 mock-fs: ^5.1.0 morgan: ^1.10.0 - msw: ^0.49.0 + msw: ^1.0.0 mysql2: ^2.2.5 node-fetch: ^2.6.7 node-forge: ^1.3.1 @@ -3514,6 +3514,7 @@ __metadata: resolution: "@backstage/backend-defaults@workspace:packages/backend-defaults" dependencies: "@backstage/backend-app-api": "workspace:^" + "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-test-utils": "workspace:^" "@backstage/cli": "workspace:^" @@ -3582,7 +3583,7 @@ __metadata: better-sqlite3: ^8.0.0 express: ^4.17.1 knex: ^2.0.0 - msw: ^0.49.0 + msw: ^1.0.0 mysql2: ^2.2.5 pg: ^8.3.0 supertest: ^6.1.3 @@ -3591,14 +3592,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/catalog-client@npm:^1.3.0": - version: 1.3.0 - resolution: "@backstage/catalog-client@npm:1.3.0" +"@backstage/catalog-client@npm:^1.3.1": + version: 1.3.1 + resolution: "@backstage/catalog-client@npm:1.3.1" dependencies: - "@backstage/catalog-model": ^1.1.5 + "@backstage/catalog-model": ^1.2.0 "@backstage/errors": ^1.1.4 cross-fetch: ^3.1.5 - checksum: 7062e9796b5b26cc1b39690af47eacfef90f61241b1f6e775687671e15aaf9b5d3357e670e59b7ca0786fe1b08a3e76d0a00cbfd7328de79acef0f8970659021 + checksum: e2e0050d93f509fbaed40d89228ce9af7c9f32372c721d5faea29ef312e488cbfc1426959f39d61790d41406fbd6bc895bed2c3427bbdf6cab6a412f449c2efe languageName: node linkType: hard @@ -3610,13 +3611,13 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/errors": "workspace:^" cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 languageName: unknown linkType: soft -"@backstage/catalog-model@npm:^1.1.3, @backstage/catalog-model@npm:^1.1.5": - version: 1.1.5 - resolution: "@backstage/catalog-model@npm:1.1.5" +"@backstage/catalog-model@npm:^1.1.3, @backstage/catalog-model@npm:^1.1.5, @backstage/catalog-model@npm:^1.2.0": + version: 1.2.0 + resolution: "@backstage/catalog-model@npm:1.2.0" dependencies: "@backstage/config": ^1.0.6 "@backstage/errors": ^1.1.4 @@ -3625,7 +3626,7 @@ __metadata: json-schema: ^0.4.0 lodash: ^4.17.21 uuid: ^8.0.0 - checksum: 4a3418994047b616ae154202ef062b7b76bcbc00665998269a0f2242cb7b84e4200e3c3c3df57e10448479c70139ba09484795571f489edf1dd98ade85cc039a + checksum: d4e07e91e501b4ecbc9d0b754518277dd2ed93f22f801740cc539dbcbd905ba8111b1651d20fb725e44d7cd99a96faec6fd56cd51fdf8e1d7f39a6e177f31efa languageName: node linkType: hard @@ -3723,7 +3724,7 @@ __metadata: commander: ^9.1.0 cross-spawn: ^7.0.3 css-loader: ^6.5.1 - del: ^6.0.0 + del: ^7.0.0 diff: ^5.0.0 esbuild: ^0.17.0 esbuild-loader: ^2.18.0 @@ -3754,7 +3755,7 @@ __metadata: mini-css-extract-plugin: ^2.4.2 minimatch: ^5.1.1 mock-fs: ^5.1.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 node-libs-browser: ^2.2.1 nodemon: ^2.0.2 @@ -3836,7 +3837,7 @@ __metadata: json-schema-merge-allof: ^0.8.1 json-schema-traverse: ^1.0.0 mock-fs: ^5.1.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 typescript-json-schema: ^0.55.0 yaml: ^2.0.0 @@ -3874,7 +3875,7 @@ __metadata: "@types/prop-types": ^15.7.3 "@types/zen-observable": ^0.8.0 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 prop-types: ^15.7.2 react-router-beta: "npm:react-router@6.0.0-beta.0" react-router-dom-beta: "npm:react-router-dom@6.0.0-beta.0" @@ -3890,14 +3891,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-components@npm:^0.12.0, @backstage/core-components@npm:^0.12.3": - version: 0.12.3 - resolution: "@backstage/core-components@npm:0.12.3" +"@backstage/core-components@npm:^0.12.0, @backstage/core-components@npm:^0.12.3, @backstage/core-components@npm:^0.12.4": + version: 0.12.4 + resolution: "@backstage/core-components@npm:0.12.4" dependencies: "@backstage/config": ^1.0.6 - "@backstage/core-plugin-api": ^1.3.0 + "@backstage/core-plugin-api": ^1.4.0 "@backstage/errors": ^1.1.4 - "@backstage/theme": ^0.2.16 + "@backstage/theme": ^0.2.17 "@backstage/version-bridge": ^1.0.3 "@material-table/core": ^3.1.0 "@material-ui/core": ^4.12.2 @@ -3936,7 +3937,7 @@ __metadata: react: ^16.13.1 || ^17.0.0 react-dom: ^16.13.1 || ^17.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: f9c242af07b500f0de738591848776ad3864fb52e30f1979e547d6d607a0eb96df5c1464c8dadb4f5c1d7dd6c10ae74e4c2f60eba5380b704f4b01ac6711131c + checksum: 476160ad54a399e7393bb70fc34fc01b69519431606797fdecc974d5e826315527d8ab71af5dd4d1c8d88bfe797aa37e781fd5fd31d8293c19982704e4f7cfdc languageName: node linkType: hard @@ -3986,7 +3987,7 @@ __metadata: history: ^5.0.0 immer: ^9.0.1 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 pluralize: ^8.0.0 prop-types: ^15.7.2 qs: ^6.9.4 @@ -4011,7 +4012,25 @@ __metadata: languageName: unknown linkType: soft -"@backstage/core-plugin-api@^1.1.0, @backstage/core-plugin-api@^1.3.0, @backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": +"@backstage/core-plugin-api@npm:^1.1.0, @backstage/core-plugin-api@npm:^1.3.0, @backstage/core-plugin-api@npm:^1.4.0": + version: 1.4.0 + resolution: "@backstage/core-plugin-api@npm:1.4.0" + dependencies: + "@backstage/config": ^1.0.6 + "@backstage/types": ^1.0.2 + "@backstage/version-bridge": ^1.0.3 + history: ^5.0.0 + prop-types: ^15.7.2 + zen-observable: ^0.10.0 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: 046d0fcb52b3110d6a926eeaf766486c753c2eeca70f7897f4ded45e0cf7da8591ec7df337433427bc50de7193e7a6d875356a027a8d1733fa07d87509e561a1 + languageName: node + linkType: hard + +"@backstage/core-plugin-api@workspace:^, @backstage/core-plugin-api@workspace:packages/core-plugin-api": version: 0.0.0-use.local resolution: "@backstage/core-plugin-api@workspace:packages/core-plugin-api" dependencies: @@ -4030,7 +4049,7 @@ __metadata: "@types/zen-observable": ^0.8.0 cross-fetch: ^3.1.5 history: ^5.0.0 - msw: ^0.49.0 + msw: ^1.0.0 prop-types: ^15.7.2 zen-observable: ^0.10.0 peerDependencies: @@ -4040,7 +4059,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/create-app@workspace:*, @backstage/create-app@workspace:packages/create-app": +"@backstage/create-app@workspace:*, @backstage/create-app@workspace:^, @backstage/create-app@workspace:packages/create-app": version: 0.0.0-use.local resolution: "@backstage/create-app@workspace:packages/create-app" dependencies: @@ -4138,21 +4157,21 @@ __metadata: linkType: soft "@backstage/integration-react@npm:^1.1.9": - version: 1.1.9 - resolution: "@backstage/integration-react@npm:1.1.9" + version: 1.1.10 + resolution: "@backstage/integration-react@npm:1.1.10" dependencies: "@backstage/config": ^1.0.6 - "@backstage/core-components": ^0.12.3 - "@backstage/core-plugin-api": ^1.3.0 + "@backstage/core-components": ^0.12.4 + "@backstage/core-plugin-api": ^1.4.0 "@backstage/integration": ^1.4.2 - "@backstage/theme": ^0.2.16 + "@backstage/theme": ^0.2.17 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 - checksum: 28d94f05e65944308ac6b0709e22336e6e745fe6143f7c3851ccf200725066fc73f53d238e559599d003818c764a86645e3d3f3178e2e5fd0d7cc968d7cc6375 + checksum: 248e11c74fed7fb6d5fcc9cf7f7d7baffe94a6a4091aff60afc46c797b08a63486baaffe32812c237e29e3cb295d429b1cd740ca704b43b7dc4704a910184716 languageName: node linkType: hard @@ -4176,7 +4195,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4199,7 +4218,7 @@ __metadata: git-url-parse: ^13.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 languageName: unknown linkType: soft @@ -4216,14 +4235,14 @@ __metadata: "@backstage/integration": "workspace:^" "@backstage/plugin-adr-common": "workspace:^" "@backstage/plugin-search-common": "workspace:^" - "@types/express": ^4.17.15 + "@types/express": ^4.17.6 "@types/marked": ^4.0.0 "@types/supertest": ^2.0.8 - express: ^4.18.2 - express-promise-router: ^4.1.1 + express: ^4.17.1 + express-promise-router: ^4.1.0 luxon: ^3.0.0 marked: ^4.0.14 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.5 supertest: ^6.1.3 winston: ^3.2.1 @@ -4268,7 +4287,7 @@ __metadata: "@types/git-url-parse": ^9.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-markdown: ^8.0.0 react-use: ^17.2.4 remark-gfm: ^3.0.1 @@ -4292,7 +4311,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 http-proxy-middleware: ^2.0.0 - msw: ^0.49.0 + msw: ^1.0.0 supertest: ^6.1.6 winston: ^3.2.1 yn: ^4.0.0 @@ -4320,7 +4339,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4349,7 +4368,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4377,7 +4396,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-ga: ^3.3.0 react-use: ^17.2.4 peerDependencies: @@ -4403,7 +4422,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.10.1 react-use: ^17.2.4 peerDependencies: @@ -4452,7 +4471,7 @@ __metadata: graphql: ^16.0.0 graphql-ws: ^5.4.1 isomorphic-form-data: ^2.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 swagger-ui-react: ^4.11.1 peerDependencies: @@ -4482,7 +4501,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 use-deep-compare-effect: ^1.8.1 peerDependencies: @@ -4513,7 +4532,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 mock-fs: ^5.1.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.1.3 winston: ^3.2.1 @@ -4533,6 +4552,7 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/plugin-auth-node": "workspace:^" + "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" "@davidzemon/passport-okta-oauth": ^0.0.5 "@google-cloud/firestore": ^6.0.0 @@ -4545,7 +4565,7 @@ __metadata: "@types/passport-auth0": ^1.0.5 "@types/passport-github2": ^1.2.4 "@types/passport-google-oauth20": ^2.0.3 - "@types/passport-microsoft": ^0.0.0 + "@types/passport-microsoft": ^1.0.0 "@types/passport-saml": ^1.1.3 "@types/passport-strategy": ^0.2.35 "@types/xml2js": ^0.4.7 @@ -4564,7 +4584,7 @@ __metadata: luxon: ^3.0.0 minimatch: ^5.0.0 morgan: ^1.10.0 - msw: ^0.49.0 + msw: ^1.0.0 node-cache: ^5.1.2 node-fetch: ^2.6.7 openid-client: ^5.2.1 @@ -4598,7 +4618,7 @@ __metadata: express: ^4.17.1 jose: ^4.6.0 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -4619,7 +4639,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 mime-types: ^2.1.27 - msw: ^0.49.0 + msw: ^1.0.0 p-limit: ^3.1.0 supertest: ^6.1.6 winston: ^3.2.1 @@ -4660,7 +4680,7 @@ __metadata: cross-fetch: ^3.1.5 humanize-duration: ^3.27.0 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4683,7 +4703,7 @@ __metadata: "@types/supertest": ^2.0.8 express: ^4.17.1 express-promise-router: ^4.1.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 winston: ^3.2.1 yn: ^4.0.0 @@ -4721,7 +4741,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4772,7 +4792,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -4838,7 +4858,7 @@ __metadata: "@backstage/integration": "workspace:^" "@openapitools/openapi-generator-cli": ^2.4.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 ts-morph: ^17.0.0 languageName: unknown linkType: soft @@ -4867,7 +4887,7 @@ __metadata: cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.9.6 react-use: ^17.2.4 recharts: ^2.0.0 @@ -4890,7 +4910,9 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" "@backstage/plugin-catalog-backend": "workspace:^" + "@backstage/plugin-catalog-common": "workspace:^" "@backstage/plugin-catalog-node": "workspace:^" + "@backstage/plugin-kubernetes-common": "workspace:^" "@backstage/types": "workspace:^" "@types/lodash": ^4.14.151 aws-sdk: ^2.840.0 @@ -4923,7 +4945,7 @@ __metadata: "@types/lodash": ^4.14.151 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -4949,7 +4971,7 @@ __metadata: "@backstage/plugin-catalog-node": "workspace:^" "@backstage/plugin-events-node": "workspace:^" luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 uuid: ^8.0.0 winston: ^3.2.1 languageName: unknown @@ -4972,7 +4994,7 @@ __metadata: "@backstage/plugin-catalog-node": "workspace:^" "@types/node-fetch": ^2.5.12 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -4995,7 +5017,7 @@ __metadata: "@backstage/types": "workspace:^" "@types/lodash": ^4.14.151 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 winston: ^3.2.1 languageName: unknown @@ -5019,7 +5041,7 @@ __metadata: "@types/fs-extra": ^9.0.1 fs-extra: 10.1.0 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -5052,7 +5074,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 minimatch: ^5.1.2 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -5079,7 +5101,7 @@ __metadata: "@types/uuid": ^8.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 uuid: ^8.0.0 winston: ^3.2.1 @@ -5092,6 +5114,7 @@ __metadata: dependencies: "@backstage/backend-app-api": "workspace:^" "@backstage/backend-common": "workspace:^" + "@backstage/backend-defaults": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/backend-tasks": "workspace:^" "@backstage/backend-test-utils": "workspace:^" @@ -5154,7 +5177,7 @@ __metadata: "@types/node-fetch": ^2.5.12 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 p-limit: ^3.0.2 qs: ^6.9.4 @@ -5224,7 +5247,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 minimatch: ^5.0.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 p-limit: ^3.0.2 prom-client: ^14.0.1 @@ -5238,14 +5261,14 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-common@npm:^1.0.10, @backstage/plugin-catalog-common@npm:^1.0.8": - version: 1.0.10 - resolution: "@backstage/plugin-catalog-common@npm:1.0.10" +"@backstage/plugin-catalog-common@npm:^1.0.11, @backstage/plugin-catalog-common@npm:^1.0.8": + version: 1.0.11 + resolution: "@backstage/plugin-catalog-common@npm:1.0.11" dependencies: - "@backstage/catalog-model": ^1.1.5 + "@backstage/catalog-model": ^1.2.0 "@backstage/plugin-permission-common": ^0.7.3 "@backstage/plugin-search-common": ^1.2.1 - checksum: 3e09f8546aa3c58b4c6dd84beb8ca98378984463e6f05c3a73c9021a26bcf180f76607b735e00cb5af47b10122054781c7d1c7faa385e0708ba3e42e50676acf + checksum: e0e37a96b4d97230c590fc4f1e17f252167a3cbbc79533c7e29a26d3480e82435c57ae6f7952aaf694bd8dc22245410c9fd29853249b1b73ed3a009dd49bce6b languageName: node linkType: hard @@ -5304,17 +5327,17 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^" - "@graphql-codegen/cli": ^2.3.1 - "@graphql-codegen/graphql-modules-preset": ^2.3.2 - "@graphql-codegen/typescript": ^2.4.2 - "@graphql-codegen/typescript-resolvers": ^2.4.3 + "@graphql-codegen/cli": ^3.0.0 + "@graphql-codegen/graphql-modules-preset": ^3.0.0 + "@graphql-codegen/typescript": ^3.0.0 + "@graphql-codegen/typescript-resolvers": ^3.0.0 "@graphql-tools/schema": ^9.0.0 apollo-server: ^3.0.0 graphql: ^16.0.0 graphql-modules: ^2.0.0 graphql-tag: ^2.11.0 graphql-type-json: ^0.3.2 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 winston: ^3.2.1 languageName: unknown @@ -5350,7 +5373,7 @@ __metadata: git-url-parse: ^13.0.0 js-base64: ^3.6.0 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 react-hook-form: ^7.12.2 react-use: ^17.2.4 yaml: ^2.0.0 @@ -5377,20 +5400,20 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-catalog-react@npm:^1.2.1, @backstage/plugin-catalog-react@npm:^1.2.4": - version: 1.2.4 - resolution: "@backstage/plugin-catalog-react@npm:1.2.4" +"@backstage/plugin-catalog-react@npm:^1.2.1, @backstage/plugin-catalog-react@npm:^1.2.4, @backstage/plugin-catalog-react@npm:^1.3.0": + version: 1.3.0 + resolution: "@backstage/plugin-catalog-react@npm:1.3.0" dependencies: - "@backstage/catalog-client": ^1.3.0 - "@backstage/catalog-model": ^1.1.5 - "@backstage/core-components": ^0.12.3 - "@backstage/core-plugin-api": ^1.3.0 + "@backstage/catalog-client": ^1.3.1 + "@backstage/catalog-model": ^1.2.0 + "@backstage/core-components": ^0.12.4 + "@backstage/core-plugin-api": ^1.4.0 "@backstage/errors": ^1.1.4 "@backstage/integration": ^1.4.2 - "@backstage/plugin-catalog-common": ^1.0.10 + "@backstage/plugin-catalog-common": ^1.0.11 "@backstage/plugin-permission-common": ^0.7.3 - "@backstage/plugin-permission-react": ^0.4.9 - "@backstage/theme": ^0.2.16 + "@backstage/plugin-permission-react": ^0.4.10 + "@backstage/theme": ^0.2.17 "@backstage/types": ^1.0.2 "@backstage/version-bridge": ^1.0.3 "@material-ui/core": ^4.12.2 @@ -5408,7 +5431,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 react: ^16.13.1 || ^17.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 2cbc65f713d2b04af21536e08756d49303030d8ae2e3450d228f81e44d59f9a1f52f3d3961d23169de4213f31414618d4dad7307e4e242b87899487eb118932c + checksum: 03cd5a270154c0cde63bd33104d11ba5811690205c697441f207606d961935f5c45ad2a8e17f591c5ac8b294601c1855852bac35ccb30125e2ab6df13daf82d2 languageName: node linkType: hard @@ -5566,7 +5589,7 @@ __metadata: humanize-duration: ^3.27.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5596,7 +5619,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.9.4 react-use: ^17.2.4 peerDependencies: @@ -5629,7 +5652,7 @@ __metadata: cross-fetch: ^3.1.5 humanize-duration: ^3.27.1 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -5655,7 +5678,7 @@ __metadata: express-promise-router: ^4.1.0 express-xml-bodyparser: ^0.3.0 knex: ^2.0.0 - msw: ^0.49.0 + msw: ^1.0.0 supertest: ^6.1.6 uuid: ^8.3.2 winston: ^3.2.1 @@ -5692,7 +5715,7 @@ __metadata: cross-fetch: ^3.1.5 highlight.js: ^10.6.0 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 recharts: ^2.0.0 peerDependencies: @@ -5722,7 +5745,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 rc-progress: 3.4.1 react-use: ^17.2.4 peerDependencies: @@ -5754,7 +5777,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 jsonschema: ^1.2.6 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 zen-observable: ^0.10.0 peerDependencies: @@ -5802,7 +5825,7 @@ __metadata: cross-fetch: ^3.1.5 history: ^5.0.0 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 pluralize: ^8.0.0 qs: ^6.9.4 react-use: ^17.2.4 @@ -5836,7 +5859,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" express: ^4.18.1 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: "@backstage/plugin-catalog-react": "workspace:^" @@ -5861,7 +5884,7 @@ __metadata: express: ^4.18.1 express-promise-router: ^4.1.0 knex: ^2.0.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.2.4 winston: ^3.2.1 @@ -5901,7 +5924,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -5940,7 +5963,7 @@ __metadata: "@uiw/react-codemirror": ^4.9.3 cross-fetch: ^3.1.5 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 yaml: ^2.0.0 peerDependencies: @@ -6093,7 +6116,7 @@ __metadata: express: ^4.18.1 express-promise-router: ^4.1.0 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.2.4 winston: ^3.2.1 @@ -6123,7 +6146,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 languageName: unknown linkType: soft @@ -6155,7 +6178,7 @@ __metadata: "@types/node": ^16.11.26 classnames: ^2.2.6 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -6185,7 +6208,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6215,7 +6238,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 p-limit: ^3.0.2 react-use: ^17.2.4 peerDependencies: @@ -6252,7 +6275,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 material-ui-popup-state: ^1.9.3 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6279,7 +6302,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 peerDependencies: react: ^16.13.1 || ^17.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 @@ -6310,7 +6333,7 @@ __metadata: "@types/recharts": ^1.8.15 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.10.1 react-use: ^17.2.4 recharts: ^2.0.0 @@ -6345,7 +6368,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6379,7 +6402,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6412,7 +6435,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 octokit: ^2.0.4 react-use: ^17.4.0 peerDependencies: @@ -6444,7 +6467,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 p-limit: ^4.0.0 react-use: ^17.2.4 peerDependencies: @@ -6472,7 +6495,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6506,7 +6529,7 @@ __metadata: cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.10.1 react-use: ^17.2.4 peerDependencies: @@ -6537,7 +6560,7 @@ __metadata: graphiql: ^1.5.12 graphql: ^16.0.0 graphql-ws: ^5.4.1 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6563,7 +6586,7 @@ __metadata: graphql: ^16.0.0 graphql-modules: ^2.0.0 helmet: ^6.0.0 - msw: ^0.49.0 + msw: ^1.0.0 reflect-metadata: ^0.1.13 supertest: ^6.1.3 winston: ^3.2.1 @@ -6591,7 +6614,7 @@ __metadata: "@types/node": "*" cross-fetch: ^3.1.5 graphql-voyager: ^1.0.0-rc.31 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6599,16 +6622,15 @@ __metadata: linkType: soft "@backstage/plugin-home@npm:^0.4.30": - version: 0.4.30 - resolution: "@backstage/plugin-home@npm:0.4.30" + version: 0.4.31 + resolution: "@backstage/plugin-home@npm:0.4.31" dependencies: - "@backstage/catalog-model": ^1.1.5 + "@backstage/catalog-model": ^1.2.0 "@backstage/config": ^1.0.6 - "@backstage/core-components": ^0.12.3 - "@backstage/core-plugin-api": ^1.3.0 - "@backstage/plugin-catalog-react": ^1.2.4 - "@backstage/plugin-stack-overflow": ^0.1.10 - "@backstage/theme": ^0.2.16 + "@backstage/core-components": ^0.12.4 + "@backstage/core-plugin-api": ^1.4.0 + "@backstage/plugin-catalog-react": ^1.3.0 + "@backstage/theme": ^0.2.17 "@material-ui/core": ^4.12.2 "@material-ui/icons": ^4.9.1 "@material-ui/lab": 4.0.0-alpha.57 @@ -6618,7 +6640,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 react: ^16.13.1 || ^17.0.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 68420c7b2f94eec976bfeb9c8f704ef37554370e9c646e51de5582bc6fe7184b3021b08f85fbfca92a92b2efbe22261ac866799db4a75c9d10e9f14508cdcfb4 + checksum: 2ba5d377713540a4f9ab7083bc1595361678b59c80d57f26f2fe0bd660ec77926a6bfdeb52a2c6179e809e5186360333ae1bb41f51e741c4bdb7fc3edfda60c3 languageName: node linkType: hard @@ -6645,7 +6667,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -6680,7 +6702,7 @@ __metadata: cross-fetch: ^3.1.5 humanize-duration: ^3.26.0 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6706,7 +6728,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 jenkins: ^1.0.0 - msw: ^0.49.0 + msw: ^1.0.0 supertest: ^6.1.6 winston: ^3.2.1 yn: ^4.0.0 @@ -6748,7 +6770,7 @@ __metadata: "@types/testing-library__jest-dom": ^5.9.1 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6803,7 +6825,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 jest-when: ^3.1.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6846,7 +6868,7 @@ __metadata: luxon: ^3.0.0 mock-fs: ^5.2.0 morgan: ^1.10.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 stream-buffers: ^3.0.2 supertest: ^6.1.3 @@ -6895,7 +6917,7 @@ __metadata: js-yaml: ^4.0.0 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6953,7 +6975,7 @@ __metadata: "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -6961,6 +6983,77 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-linguist-backend@workspace:^, @backstage/plugin-linguist-backend@workspace:plugins/linguist-backend": + version: 0.0.0-use.local + resolution: "@backstage/plugin-linguist-backend@workspace:plugins/linguist-backend" + dependencies: + "@backstage/backend-common": "workspace:^" + "@backstage/backend-tasks": "workspace:^" + "@backstage/catalog-client": "workspace:^" + "@backstage/catalog-model": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/config": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-linguist-common": "workspace:^" + "@backstage/types": "workspace:^" + "@types/express": "*" + "@types/supertest": ^2.0.8 + express: ^4.18.1 + express-promise-router: ^4.1.0 + fs-extra: ^10.0.0 + knex: ^2.0.0 + linguist-js: ^2.5.3 + luxon: ^2.0.2 + msw: ^1.0.0 + node-fetch: ^2.6.7 + supertest: ^6.2.4 + uuid: ^8.3.2 + winston: ^3.2.1 + yn: ^4.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-linguist-common@workspace:^, @backstage/plugin-linguist-common@workspace:plugins/linguist-common": + version: 0.0.0-use.local + resolution: "@backstage/plugin-linguist-common@workspace:plugins/linguist-common" + dependencies: + "@backstage/cli": "workspace:^" + languageName: unknown + linkType: soft + +"@backstage/plugin-linguist@workspace:^, @backstage/plugin-linguist@workspace:plugins/linguist": + version: 0.0.0-use.local + resolution: "@backstage/plugin-linguist@workspace:plugins/linguist" + dependencies: + "@backstage/catalog-model": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/plugin-catalog-react": "workspace:^" + "@backstage/plugin-linguist-common": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/theme": "workspace:^" + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.57 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/user-event": ^14.0.0 + "@types/node": "*" + cross-fetch: ^3.1.5 + luxon: ^2.0.2 + msw: ^1.0.0 + react-use: ^17.2.4 + slugify: ^1.6.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-microsoft-calendar@workspace:^, @backstage/plugin-microsoft-calendar@workspace:plugins/microsoft-calendar": version: 0.0.0-use.local resolution: "@backstage/plugin-microsoft-calendar@workspace:plugins/microsoft-calendar" @@ -6987,7 +7080,7 @@ __metadata: lodash: ^4.17.21 luxon: ^3.0.0 material-ui-popup-state: ^1.9.3 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -7036,7 +7129,35 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + languageName: unknown + linkType: soft + +"@backstage/plugin-octopus-deploy@workspace:plugins/octopus-deploy": + version: 0.0.0-use.local + resolution: "@backstage/plugin-octopus-deploy@workspace:plugins/octopus-deploy" + dependencies: + "@backstage/catalog-model": "workspace:^" + "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/plugin-catalog-react": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/theme": "workspace:^" + "@material-ui/core": ^4.9.13 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": 4.0.0-alpha.57 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/user-event": ^14.0.0 + "@types/node": "*" + cross-fetch: ^3.1.5 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -7065,7 +7186,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -7094,7 +7215,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 p-limit: ^3.1.0 pluralize: ^8.0.0 qs: ^6.10.1 @@ -7129,7 +7250,7 @@ __metadata: classnames: ^2.2.6 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -7150,7 +7271,7 @@ __metadata: "@types/supertest": ^2.0.8 express: ^4.17.1 express-promise-router: ^4.1.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.1.6 winston: ^3.2.1 @@ -7182,7 +7303,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -7208,7 +7329,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.1.6 winston: ^3.2.1 @@ -7226,7 +7347,7 @@ __metadata: "@backstage/errors": "workspace:^" "@backstage/types": "workspace:^" cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 uuid: ^8.0.0 zod: ~3.18.0 languageName: unknown @@ -7247,14 +7368,32 @@ __metadata: "@types/supertest": ^2.0.8 express: ^4.17.1 express-promise-router: ^4.1.0 - msw: ^0.49.0 + msw: ^1.0.0 supertest: ^6.1.3 zod: ~3.18.0 zod-to-json-schema: ~3.18.0 languageName: unknown linkType: soft -"@backstage/plugin-permission-react@^0.4.9, @backstage/plugin-permission-react@workspace:^, @backstage/plugin-permission-react@workspace:plugins/permission-react": +"@backstage/plugin-permission-react@npm:^0.4.10": + version: 0.4.10 + resolution: "@backstage/plugin-permission-react@npm:0.4.10" + dependencies: + "@backstage/config": ^1.0.6 + "@backstage/core-plugin-api": ^1.4.0 + "@backstage/plugin-permission-common": ^0.7.3 + cross-fetch: ^3.1.5 + react-use: ^17.2.4 + swr: ^2.0.0 + peerDependencies: + "@types/react": ^16.13.1 || ^17.0.0 + react: ^16.13.1 || ^17.0.0 + react-router-dom: 6.0.0-beta.0 || ^6.3.0 + checksum: f7a82648a31a8fe9873492abdbcc524549205e3fd11fe144ab225e6263ce2b2e46abd642e6c370d692d424c51e7c55b9259d8178500f9bfbfc9267d09596843c + languageName: node + linkType: hard + +"@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: @@ -7295,7 +7434,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 knex: ^2.0.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.1.3 uuid: ^8.2.0 @@ -7343,7 +7482,7 @@ __metadata: "@types/node": "*" cross-fetch: ^3.1.5 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.9.4 react-hook-form: ^7.13.0 react-use: ^17.2.4 @@ -7371,7 +7510,7 @@ __metadata: express-promise-router: ^4.1.0 http-proxy-middleware: ^2.0.0 morgan: ^1.10.0 - msw: ^0.49.0 + msw: ^1.0.0 supertest: ^6.1.3 uuid: ^8.0.0 winston: ^3.2.1 @@ -7399,7 +7538,7 @@ __metadata: fs-extra: 10.1.0 lodash: ^4.17.21 morgan: ^1.10.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.1.3 winston: ^3.2.1 @@ -7431,7 +7570,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 react-sparklines: ^1.7.0 react-use: ^17.2.4 peerDependencies: @@ -7458,7 +7597,7 @@ __metadata: command-exists: ^1.2.9 fs-extra: 10.1.0 mock-fs: ^5.1.0 - msw: ^0.49.0 + msw: ^1.0.0 winston: ^3.2.1 yn: ^4.0.0 languageName: unknown @@ -7562,7 +7701,7 @@ __metadata: luxon: ^3.0.0 mock-fs: ^5.1.0 morgan: ^1.10.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 nunjucks: ^3.2.3 octokit: ^2.0.0 @@ -7687,6 +7826,7 @@ __metadata: "@rjsf/core": ^3.2.1 "@rjsf/material-ui": ^3.2.1 "@rjsf/utils": 5.1.0 + "@rjsf/validator-ajv8": 5.1.0 "@testing-library/jest-dom": ^5.10.1 "@testing-library/react": ^12.1.3 "@testing-library/react-hooks": ^8.0.0 @@ -7705,7 +7845,7 @@ __metadata: json-schema-library: ^7.3.9 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.9.4 react-use: ^17.2.4 use-immer: ^0.8.0 @@ -7818,30 +7958,6 @@ __metadata: languageName: unknown linkType: soft -"@backstage/plugin-search-react@npm:^1.4.0": - version: 1.4.0 - resolution: "@backstage/plugin-search-react@npm:1.4.0" - dependencies: - "@backstage/core-components": ^0.12.3 - "@backstage/core-plugin-api": ^1.3.0 - "@backstage/plugin-search-common": ^1.2.1 - "@backstage/theme": ^0.2.16 - "@backstage/types": ^1.0.2 - "@backstage/version-bridge": ^1.0.3 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@material-ui/lab": 4.0.0-alpha.57 - lodash: ^4.17.21 - qs: ^6.9.4 - react-use: ^17.3.2 - peerDependencies: - "@types/react": ^16.13.1 || ^17.0.0 - react: ^16.13.1 || ^17.0.0 - react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 0fe18ee991bea12ba4b525b1ed4934f53a2cb2172851762c67d844405206ef8ed335ce8ad6412b4c4f133ae2b1f654b5086cf9997521e2e2cb2ef9cad6891e0a - languageName: node - linkType: hard - "@backstage/plugin-search-react@workspace:^, @backstage/plugin-search-react@workspace:plugins/search-react": version: 0.0.0-use.local resolution: "@backstage/plugin-search-react@workspace:plugins/search-react" @@ -7900,7 +8016,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.9.4 react-use: ^17.2.4 peerDependencies: @@ -7935,7 +8051,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-sparklines: ^1.7.0 react-use: ^17.2.4 peerDependencies: @@ -7965,7 +8081,7 @@ __metadata: "@types/node": ^16.11.26 "@types/zen-observable": ^0.8.2 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-hook-form: ^7.12.2 react-use: ^17.2.4 uuid: ^8.3.2 @@ -7989,7 +8105,7 @@ __metadata: "@types/supertest": ^2.0.12 express: ^4.18.1 express-promise-router: ^4.1.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 supertest: ^6.2.4 winston: ^3.2.1 @@ -8032,7 +8148,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 rc-progress: 3.4.1 react-use: ^17.2.4 peerDependencies: @@ -8064,7 +8180,7 @@ __metadata: classnames: ^2.2.6 cross-fetch: ^3.1.5 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -8082,38 +8198,13 @@ __metadata: "@backstage/config": "workspace:^" "@backstage/plugin-search-backend-node": "workspace:^" "@backstage/plugin-search-common": "workspace:^" - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 qs: ^6.9.4 winston: ^3.2.1 languageName: unknown linkType: soft -"@backstage/plugin-stack-overflow@npm:^0.1.10": - version: 0.1.10 - resolution: "@backstage/plugin-stack-overflow@npm:0.1.10" - dependencies: - "@backstage/config": ^1.0.6 - "@backstage/core-components": ^0.12.3 - "@backstage/core-plugin-api": ^1.3.0 - "@backstage/plugin-home": ^0.4.30 - "@backstage/plugin-search-common": ^1.2.1 - "@backstage/plugin-search-react": ^1.4.0 - "@backstage/theme": ^0.2.16 - "@material-ui/core": ^4.12.2 - "@material-ui/icons": ^4.9.1 - "@testing-library/jest-dom": ^5.10.1 - cross-fetch: ^3.1.5 - lodash: ^4.17.21 - qs: ^6.9.4 - react-use: ^17.2.4 - peerDependencies: - "@types/react": ^16.13.1 || ^17.0.0 - react: ^16.13.1 || ^17.0.0 - checksum: 118f98739a69e3baea4bd72cc165ef3a38166983c6ac3b94668c8dd6709ffedaeec186f21cc871af291a2243565305e4ccea030837020d2b32765ff565cbd2c1 - languageName: node - linkType: hard - "@backstage/plugin-stack-overflow@workspace:^, @backstage/plugin-stack-overflow@workspace:plugins/stack-overflow": version: 0.0.0-use.local resolution: "@backstage/plugin-stack-overflow@workspace:plugins/stack-overflow" @@ -8137,7 +8228,7 @@ __metadata: "@types/node": ^16.11.26 cross-fetch: ^3.1.5 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.9.4 react-use: ^17.2.4 peerDependencies: @@ -8146,6 +8237,33 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-stackstorm@workspace:^, @backstage/plugin-stackstorm@workspace:plugins/stackstorm": + version: 0.0.0-use.local + resolution: "@backstage/plugin-stackstorm@workspace:plugins/stackstorm" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/core-app-api": "workspace:^" + "@backstage/core-components": "workspace:^" + "@backstage/core-plugin-api": "workspace:^" + "@backstage/dev-utils": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/test-utils": "workspace:^" + "@backstage/theme": "workspace:^" + "@material-ui/core": ^4.12.2 + "@material-ui/icons": ^4.9.1 + "@material-ui/lab": ^4.0.0-alpha.57 + "@testing-library/jest-dom": ^5.10.1 + "@testing-library/react": ^12.1.3 + "@testing-library/user-event": ^14.0.0 + "@types/node": "*" + cross-fetch: ^3.1.5 + msw: ^1.0.0 + react-use: ^17.2.4 + peerDependencies: + react: ^16.13.1 || ^17.0.0 + languageName: unknown + linkType: soft + "@backstage/plugin-tech-insights-backend-module-jsonfc@workspace:^, @backstage/plugin-tech-insights-backend-module-jsonfc@workspace:plugins/tech-insights-backend-module-jsonfc": version: 0.0.0-use.local resolution: "@backstage/plugin-tech-insights-backend-module-jsonfc@workspace:plugins/tech-insights-backend-module-jsonfc" @@ -8248,7 +8366,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 qs: ^6.9.4 react-use: ^17.2.4 peerDependencies: @@ -8282,7 +8400,7 @@ __metadata: color: ^4.0.1 cross-fetch: ^3.1.5 d3-force: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 prop-types: ^15.7.2 react-use: ^17.2.4 peerDependencies: @@ -8314,7 +8432,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 testing-library__dom: ^7.29.4-beta.1 peerDependencies: @@ -8350,7 +8468,7 @@ __metadata: fs-extra: 10.1.0 knex: ^2.0.0 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 p-limit: ^3.1.0 supertest: ^6.1.3 @@ -8384,7 +8502,7 @@ __metadata: "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 git-url-parse: ^13.0.0 - msw: ^0.49.0 + msw: ^1.0.0 photoswipe: ^5.3.5 react-use: ^17.2.4 peerDependencies: @@ -8502,7 +8620,7 @@ __metadata: git-url-parse: ^13.0.0 jss: ~10.9.0 lodash: ^4.17.21 - msw: ^0.49.0 + msw: ^1.0.0 react-helmet: 6.1.0 react-use: ^17.2.4 peerDependencies: @@ -8518,18 +8636,20 @@ __metadata: resolution: "@backstage/plugin-todo-backend@workspace:plugins/todo-backend" dependencies: "@backstage/backend-common": "workspace:^" + "@backstage/backend-plugin-api": "workspace:^" "@backstage/catalog-client": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/integration": "workspace:^" + "@backstage/plugin-catalog-node": "workspace:^" "@types/express": ^4.17.6 "@types/supertest": ^2.0.8 express: ^4.17.1 express-promise-router: ^4.1.0 leasot: ^12.0.0 - msw: ^0.49.0 + msw: ^1.0.0 supertest: ^6.1.3 winston: ^3.2.1 yn: ^4.0.0 @@ -8558,7 +8678,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -8612,7 +8732,7 @@ __metadata: "@types/node": ^16.11.26 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 zen-observable: ^0.10.0 peerDependencies: @@ -8639,7 +8759,7 @@ __metadata: express: ^4.17.1 express-promise-router: ^4.1.0 helmet: ^6.0.0 - msw: ^0.49.0 + msw: ^1.0.0 node-fetch: ^2.6.7 p-limit: ^3.1.0 supertest: ^6.1.6 @@ -8670,7 +8790,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": "*" cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -8700,7 +8820,7 @@ __metadata: cross-fetch: ^3.1.5 lodash: ^4.17.21 luxon: ^3.0.0 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 recharts: ^2.0.0 peerDependencies: @@ -8716,7 +8836,7 @@ __metadata: "@backstage/test-utils": "workspace:^" "@types/node": ^16.0.0 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 languageName: unknown linkType: soft @@ -8727,6 +8847,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/types": "workspace:^" "@manypkg/get-packages": ^1.1.3 "@microsoft/api-documenter": ^7.19.27 "@microsoft/api-extractor": ^7.33.7 @@ -8773,7 +8894,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 zen-observable: ^0.10.0 peerDependencies: "@types/react": ^16.13.1 || ^17.0.0 @@ -8783,7 +8904,7 @@ __metadata: languageName: unknown linkType: soft -"@backstage/theme@^0.2.16, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": +"@backstage/theme@^0.2.16, @backstage/theme@^0.2.17, @backstage/theme@workspace:^, @backstage/theme@workspace:packages/theme": version: 0.0.0-use.local resolution: "@backstage/theme@workspace:packages/theme" dependencies: @@ -9104,8 +9225,8 @@ __metadata: linkType: hard "@codemirror/language@npm:^6.0.0": - version: 6.4.0 - resolution: "@codemirror/language@npm:6.4.0" + version: 6.6.0 + resolution: "@codemirror/language@npm:6.6.0" dependencies: "@codemirror/state": ^6.0.0 "@codemirror/view": ^6.0.0 @@ -9113,7 +9234,7 @@ __metadata: "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 607072e234db59a9a21eb41b8777b62d68a55ed28298edc4f6aaedfcf52349db1fe3ff3e7747ccfc77f03757bad45ba9a657d59a0e9c67be1231902586dec7a3 + checksum: bb9411620e2f231653a3f0c4429e0d19a3843bff5dbc117df4649d7bf783ec4ad809c0add8bc0887a4ec3f48b4f8f941621168e47d76101d5383f0d670af1722 languageName: node linkType: hard @@ -9168,13 +9289,13 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0": - version: 6.7.3 - resolution: "@codemirror/view@npm:6.7.3" + version: 6.9.1 + resolution: "@codemirror/view@npm:6.9.1" dependencies: "@codemirror/state": ^6.1.4 style-mod: ^4.0.0 w3c-keyname: ^2.2.4 - checksum: 37c0458cf45e52a1af9b9bef29108dd84bb91c6818ecad432d89627039d92f6b234b033cf14ecbc1c5b533694127478942fcc9641fdf52b9a1b20eccc018e27c + checksum: 485d54d338a27ebde6bec489e3008db80a2a801fe27db0d4a3c70181c8739f806f035855ba13d5b311d186ad2b130db07196e8b465ec102b0142df0689bff2f8 languageName: node linkType: hard @@ -9369,9 +9490,16 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/android-arm64@npm:0.17.6" +"@esbuild/android-arm64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/android-arm64@npm:0.16.17" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/android-arm64@npm:0.17.10" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -9383,65 +9511,128 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/android-arm@npm:0.17.6" +"@esbuild/android-arm@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/android-arm@npm:0.16.17" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/android-x64@npm:0.17.6" +"@esbuild/android-arm@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/android-arm@npm:0.17.10" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/android-x64@npm:0.16.17" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/darwin-arm64@npm:0.17.6" +"@esbuild/android-x64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/android-x64@npm:0.17.10" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/darwin-arm64@npm:0.16.17" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/darwin-x64@npm:0.17.6" +"@esbuild/darwin-arm64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/darwin-arm64@npm:0.17.10" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/darwin-x64@npm:0.16.17" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/freebsd-arm64@npm:0.17.6" +"@esbuild/darwin-x64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/darwin-x64@npm:0.17.10" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/freebsd-arm64@npm:0.16.17" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/freebsd-x64@npm:0.17.6" +"@esbuild/freebsd-arm64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/freebsd-arm64@npm:0.17.10" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/freebsd-x64@npm:0.16.17" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/linux-arm64@npm:0.17.6" +"@esbuild/freebsd-x64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/freebsd-x64@npm:0.17.10" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/linux-arm64@npm:0.16.17" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/linux-arm@npm:0.17.6" +"@esbuild/linux-arm64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/linux-arm64@npm:0.17.10" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/linux-arm@npm:0.16.17" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/linux-ia32@npm:0.17.6" +"@esbuild/linux-arm@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/linux-arm@npm:0.17.10" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/linux-ia32@npm:0.16.17" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/linux-ia32@npm:0.17.10" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -9453,86 +9644,170 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/linux-loong64@npm:0.17.6" +"@esbuild/linux-loong64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/linux-loong64@npm:0.16.17" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/linux-mips64el@npm:0.17.6" +"@esbuild/linux-loong64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/linux-loong64@npm:0.17.10" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/linux-mips64el@npm:0.16.17" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/linux-ppc64@npm:0.17.6" +"@esbuild/linux-mips64el@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/linux-mips64el@npm:0.17.10" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/linux-ppc64@npm:0.16.17" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/linux-riscv64@npm:0.17.6" +"@esbuild/linux-ppc64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/linux-ppc64@npm:0.17.10" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/linux-riscv64@npm:0.16.17" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/linux-s390x@npm:0.17.6" +"@esbuild/linux-riscv64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/linux-riscv64@npm:0.17.10" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/linux-s390x@npm:0.16.17" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/linux-x64@npm:0.17.6" +"@esbuild/linux-s390x@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/linux-s390x@npm:0.17.10" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/linux-x64@npm:0.16.17" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/netbsd-x64@npm:0.17.6" +"@esbuild/linux-x64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/linux-x64@npm:0.17.10" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/netbsd-x64@npm:0.16.17" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/openbsd-x64@npm:0.17.6" +"@esbuild/netbsd-x64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/netbsd-x64@npm:0.17.10" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/openbsd-x64@npm:0.16.17" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/sunos-x64@npm:0.17.6" +"@esbuild/openbsd-x64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/openbsd-x64@npm:0.17.10" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/sunos-x64@npm:0.16.17" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/win32-arm64@npm:0.17.6" +"@esbuild/sunos-x64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/sunos-x64@npm:0.17.10" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/win32-arm64@npm:0.16.17" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/win32-ia32@npm:0.17.6" +"@esbuild/win32-arm64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/win32-arm64@npm:0.17.10" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/win32-ia32@npm:0.16.17" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.17.6": - version: 0.17.6 - resolution: "@esbuild/win32-x64@npm:0.17.6" +"@esbuild/win32-ia32@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/win32-ia32@npm:0.17.10" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.16.17": + version: 0.16.17 + resolution: "@esbuild/win32-x64@npm:0.16.17" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.17.10": + version: 0.17.10 + resolution: "@esbuild/win32-x64@npm:0.17.10" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -9695,23 +9970,23 @@ __metadata: linkType: hard "@google-cloud/container@npm:^4.0.0": - version: 4.4.0 - resolution: "@google-cloud/container@npm:4.4.0" + version: 4.7.1 + resolution: "@google-cloud/container@npm:4.7.1" dependencies: google-gax: ^3.5.2 - checksum: 39e7ba3b8cd7e50908315eee5c42461b8cee909c5653ffc817503757e867d63815c5ca8f540b7566f38be9ae0454ed89d2efe95b64961a8692a9348ddf92074f + checksum: e622ddc2522fcffadd72a0cc6fa3f12e6a337b9e53ff1886a2057a8d4f3f0fc13b60b806c35946da0a1211fe52d66f65b4ab59c06b5e7cd725cd588477c0bde1 languageName: node linkType: hard "@google-cloud/firestore@npm:^6.0.0": - version: 6.4.2 - resolution: "@google-cloud/firestore@npm:6.4.2" + version: 6.4.3 + resolution: "@google-cloud/firestore@npm:6.4.3" dependencies: fast-deep-equal: ^3.1.1 functional-red-black-tree: ^1.0.1 - google-gax: ^3.5.2 + google-gax: ^3.5.3 protobufjs: ^7.0.0 - checksum: c259f59905d4939f0b1fff2fdfa3db38a0436454af9e4a8939ea951ee700d5f801375ed090e77f610fbf3f02db1aeba9d70437eb6a8ca6f0ba2088c8964c58d0 + checksum: 8bbde2c9bad94459c231d41855e65866b2383f20e2741aa93d86204370172dd62af94e1eb66d977e000e0c7292c986eb25fe967db7ee847593fd9a68c9fb91e3 languageName: node linkType: hard @@ -9740,8 +10015,8 @@ __metadata: linkType: hard "@google-cloud/storage@npm:^6.0.0": - version: 6.9.2 - resolution: "@google-cloud/storage@npm:6.9.2" + version: 6.9.3 + resolution: "@google-cloud/storage@npm:6.9.3" dependencies: "@google-cloud/paginator": ^3.0.7 "@google-cloud/projectify": ^3.0.0 @@ -9760,7 +10035,7 @@ __metadata: retry-request: ^5.0.0 teeny-request: ^8.0.0 uuid: ^8.0.0 - checksum: e4962be29ca3dd722019db95f99b095993534915d663a82b41c95beaf284d878de5b1357102441e4e375de838299f6d82eff55a2c4e9f610f9a12feac21e2735 + checksum: 32bd3b49509b823504f0007d1d5cb1ec854bbc84e6be1ef397879b99c0f198c6251b85ddec81226428e046a06c0346356d82d26485e9d1f9e7ef943e091db06f languageName: node linkType: hard @@ -9797,17 +10072,17 @@ __metadata: languageName: node linkType: hard -"@graphql-codegen/cli@npm:^2.3.1": - version: 2.16.5 - resolution: "@graphql-codegen/cli@npm:2.16.5" +"@graphql-codegen/cli@npm:^3.0.0": + version: 3.1.0 + resolution: "@graphql-codegen/cli@npm:3.1.0" dependencies: "@babel/generator": ^7.18.13 "@babel/template": ^7.18.10 "@babel/types": ^7.18.13 - "@graphql-codegen/core": ^2.6.8 - "@graphql-codegen/plugin-helpers": ^3.1.2 + "@graphql-codegen/core": ^3.1.0 + "@graphql-codegen/plugin-helpers": ^4.1.0 "@graphql-tools/apollo-engine-loader": ^7.3.6 - "@graphql-tools/code-file-loader": ^7.3.13 + "@graphql-tools/code-file-loader": ^7.3.17 "@graphql-tools/git-loader": ^7.2.13 "@graphql-tools/github-loader": ^7.3.20 "@graphql-tools/graphql-file-loader": ^7.5.0 @@ -9816,7 +10091,7 @@ __metadata: "@graphql-tools/prisma-loader": ^7.2.49 "@graphql-tools/url-loader": ^7.13.2 "@graphql-tools/utils": ^9.0.0 - "@whatwg-node/fetch": ^0.6.0 + "@whatwg-node/fetch": ^0.8.0 chalk: ^4.1.0 chokidar: ^3.5.2 cosmiconfig: ^7.0.0 @@ -9843,105 +10118,105 @@ __metadata: graphql-code-generator: cjs/bin.js graphql-codegen: cjs/bin.js graphql-codegen-esm: esm/bin.js - checksum: d1fdc1a0e678d03995bc7e4927ccd1683b7e50686f13b81d01ad6b295e2033876d05cc71d1d489270d314ac25801a9b82e16aa79982a04e982813854990e4a53 + checksum: 8e445196cb95165c715fbc2656763764c4ac3b15d370abd8b3321cf19a5a93fb66a0a53e38c121b18256f820c536c7a686dd3776ff2e3c7be5b989230503129b languageName: node linkType: hard -"@graphql-codegen/core@npm:^2.6.8": - version: 2.6.8 - resolution: "@graphql-codegen/core@npm:2.6.8" +"@graphql-codegen/core@npm:^3.1.0": + version: 3.1.0 + resolution: "@graphql-codegen/core@npm:3.1.0" dependencies: - "@graphql-codegen/plugin-helpers": ^3.1.1 + "@graphql-codegen/plugin-helpers": ^4.1.0 "@graphql-tools/schema": ^9.0.0 "@graphql-tools/utils": ^9.1.1 - tslib: ~2.4.0 + tslib: ~2.5.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 33a222798fd99adcaf5d6d48fcd6949798a62d7a25e9b2af5b13e4def3de4338e5a743e5ea87661d2b32ae3279e3ad8b555d0e212efe86018088cb85a7d59d6a + checksum: 7ace2b185242d00575b877b0bbb884c66915d246ba17a98c0ab82c2ee3a93ff2c9ae9d7d75a1d346de02ca8f12eb02801ffe2da4846da6e164b43176cd02dd8c languageName: node linkType: hard -"@graphql-codegen/graphql-modules-preset@npm:^2.3.2": - version: 2.5.12 - resolution: "@graphql-codegen/graphql-modules-preset@npm:2.5.12" +"@graphql-codegen/graphql-modules-preset@npm:^3.0.0": + version: 3.1.0 + resolution: "@graphql-codegen/graphql-modules-preset@npm:3.1.0" dependencies: - "@graphql-codegen/plugin-helpers": ^3.1.2 - "@graphql-codegen/visitor-plugin-common": 2.13.8 + "@graphql-codegen/plugin-helpers": ^4.1.0 + "@graphql-codegen/visitor-plugin-common": 3.0.1 "@graphql-tools/utils": ^9.0.0 change-case-all: 1.0.15 parse-filepath: ^1.0.2 - tslib: ~2.4.0 + tslib: ~2.5.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: ca2354d5eb899bca7af2ddb68a1ad96fd046b53c07bb0323478d18e155e0bb988bb6bae4ed1578e37ffb9cb004900e7abb92b4a8b3826b6fe903b422501f8ef2 + checksum: cee2e7f8afbc0b0d81592abfc8894422b791f0eca6e878a789de980bf1710a3c726786ade296e653cc83f920b2618aa9f5c9dbb6934ee9da0122b2d10ef5bdb5 languageName: node linkType: hard -"@graphql-codegen/plugin-helpers@npm:^3.1.1, @graphql-codegen/plugin-helpers@npm:^3.1.2": - version: 3.1.2 - resolution: "@graphql-codegen/plugin-helpers@npm:3.1.2" +"@graphql-codegen/plugin-helpers@npm:^4.1.0": + version: 4.1.0 + resolution: "@graphql-codegen/plugin-helpers@npm:4.1.0" dependencies: "@graphql-tools/utils": ^9.0.0 change-case-all: 1.0.15 common-tags: 1.8.2 import-from: 4.0.0 lodash: ~4.17.0 - tslib: ~2.4.0 + tslib: ~2.5.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 4d0c615738570681b5ffd3c07305a35d6aa3e5fd87c9199c0a670b95529ab865b1df978ce584d5b415107a567ac484e56a48db129a6d1d2eb8a254fbd3260e39 + checksum: a4d89909d7a62bd7a93041b6073b1d46e912b42f7af1d15c44f7ed595ab1185b6c257cccf8272e0ae36ba22724578449d0e21524e8dbc21fb375da0620687868 languageName: node linkType: hard -"@graphql-codegen/schema-ast@npm:^2.6.1": - version: 2.6.1 - resolution: "@graphql-codegen/schema-ast@npm:2.6.1" +"@graphql-codegen/schema-ast@npm:^3.0.1": + version: 3.0.1 + resolution: "@graphql-codegen/schema-ast@npm:3.0.1" dependencies: - "@graphql-codegen/plugin-helpers": ^3.1.2 + "@graphql-codegen/plugin-helpers": ^4.1.0 "@graphql-tools/utils": ^9.0.0 - tslib: ~2.4.0 + tslib: ~2.5.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: f44338ac66e6a1f6238c33cdf65778bb467fe5a93767988135cb4e112d3be4d3c7e8aeeffe323754e8d6b0cbc5a52cb71452bfc42a15bc7031ebaa9b3d5da676 + checksum: 620aa67a4ae59ccb4609763b7347d05e2cec62bf1362be3e1e01fc00969cdbb858398542aa261128e5b5e3cb6808b77861bdcf82662e80326e72b418f25f465f languageName: node linkType: hard -"@graphql-codegen/typescript-resolvers@npm:^2.4.3": - version: 2.7.13 - resolution: "@graphql-codegen/typescript-resolvers@npm:2.7.13" +"@graphql-codegen/typescript-resolvers@npm:^3.0.0": + version: 3.1.0 + resolution: "@graphql-codegen/typescript-resolvers@npm:3.1.0" dependencies: - "@graphql-codegen/plugin-helpers": ^3.1.2 - "@graphql-codegen/typescript": ^2.8.8 - "@graphql-codegen/visitor-plugin-common": 2.13.8 + "@graphql-codegen/plugin-helpers": ^4.1.0 + "@graphql-codegen/typescript": ^3.0.1 + "@graphql-codegen/visitor-plugin-common": 3.0.1 "@graphql-tools/utils": ^9.0.0 auto-bind: ~4.0.0 - tslib: ~2.4.0 + tslib: ~2.5.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 9ddfeb295e55055d450f30942c476edbc05722943d5265e9eaea9f89cef9eecb749be1ece9ce9247d53bdcc7688ca305100327d28096f5fe6aee387cf3f275f5 + checksum: 05888a9dfd1556fe15465a524750c36881334c231297e2e89bccb536450bed61fde2ba182ba4e79e34be846ce2e2439f3f6b31a67e7437f03a4e4ace62e84dcd languageName: node linkType: hard -"@graphql-codegen/typescript@npm:^2.4.2, @graphql-codegen/typescript@npm:^2.8.8": - version: 2.8.8 - resolution: "@graphql-codegen/typescript@npm:2.8.8" +"@graphql-codegen/typescript@npm:^3.0.0, @graphql-codegen/typescript@npm:^3.0.1": + version: 3.0.1 + resolution: "@graphql-codegen/typescript@npm:3.0.1" dependencies: - "@graphql-codegen/plugin-helpers": ^3.1.2 - "@graphql-codegen/schema-ast": ^2.6.1 - "@graphql-codegen/visitor-plugin-common": 2.13.8 + "@graphql-codegen/plugin-helpers": ^4.1.0 + "@graphql-codegen/schema-ast": ^3.0.1 + "@graphql-codegen/visitor-plugin-common": 3.0.1 auto-bind: ~4.0.0 - tslib: ~2.4.0 + tslib: ~2.5.0 peerDependencies: graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: ebc338bc88fd239b9ef70d900778791af2c68f7a0fa074d870cc5fcaee3ea182dfce8a1f366f53bcd5e81f95bb9e26e00e1b41e6b2ad3305cf7e6f44bf57d649 + checksum: 56a369237971cc4a5a4987628ec0fcceed66ec03a292b3d17b6ffb64279185cd085be351268c55be6b152634c430e885b9c584d816aaa25f067d91c6996c329a languageName: node linkType: hard -"@graphql-codegen/visitor-plugin-common@npm:2.13.8": - version: 2.13.8 - resolution: "@graphql-codegen/visitor-plugin-common@npm:2.13.8" +"@graphql-codegen/visitor-plugin-common@npm:3.0.1": + version: 3.0.1 + resolution: "@graphql-codegen/visitor-plugin-common@npm:3.0.1" dependencies: - "@graphql-codegen/plugin-helpers": ^3.1.2 + "@graphql-codegen/plugin-helpers": ^4.1.0 "@graphql-tools/optimize": ^1.3.0 "@graphql-tools/relay-operation-optimizer": ^6.5.0 "@graphql-tools/utils": ^9.0.0 @@ -9950,10 +10225,10 @@ __metadata: dependency-graph: ^0.11.0 graphql-tag: ^2.11.0 parse-filepath: ^1.0.2 - tslib: ~2.4.0 + tslib: ~2.5.0 peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 4ca8074bfb84a7c6f88216c2b327a600b57da35eae9b659656592c48f197e44004dcc5c2ab500a5d3a94e2753f47903e5e113162c8a362de08e307e564d416a5 + checksum: 32bf553f73938581f634b1bbdf8616b1cb30cc85c73d7a8f6088d2a81a957e198c7c278edf6582c1eee7328a4463cea4725316b1743b87b26dc3e9fdd8318648 languageName: node linkType: hard @@ -9999,18 +10274,18 @@ __metadata: languageName: node linkType: hard -"@graphql-tools/code-file-loader@npm:^7.3.13": - version: 7.3.13 - resolution: "@graphql-tools/code-file-loader@npm:7.3.13" +"@graphql-tools/code-file-loader@npm:^7.3.17": + version: 7.3.21 + resolution: "@graphql-tools/code-file-loader@npm:7.3.21" dependencies: - "@graphql-tools/graphql-tag-pluck": 7.4.0 - "@graphql-tools/utils": 9.1.1 + "@graphql-tools/graphql-tag-pluck": 7.5.0 + "@graphql-tools/utils": 9.2.1 globby: ^11.0.3 tslib: ^2.4.0 unixify: ^1.0.0 peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: 18eeea4d3a89c15cf74d89630b647b6951487072f70a1b193d39c47b03533d3fe89f3e8f232b604db21b597768802b4884446b9820bf1febbdf1c094924be279 + checksum: 5d0d0a70bac673b4925a65f2283e3fcc5c093d2466a144cc577cb515d3de92ca2458d92842e02fe82a95d57d30ce6d2998b8ee5674393f7cd3df52f69671d565 languageName: node linkType: hard @@ -10174,6 +10449,22 @@ __metadata: languageName: node linkType: hard +"@graphql-tools/graphql-tag-pluck@npm:7.5.0": + version: 7.5.0 + resolution: "@graphql-tools/graphql-tag-pluck@npm:7.5.0" + dependencies: + "@babel/parser": ^7.16.8 + "@babel/plugin-syntax-import-assertions": 7.20.0 + "@babel/traverse": ^7.16.8 + "@babel/types": ^7.16.8 + "@graphql-tools/utils": 9.2.1 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 47edaacdeafc4a464f8a51e047cafbb82a9a2700536a5b075eb4afad43c80b513a7b0ac4ad49a1e8a74b566ed7dfd677ebb0d0a967fe1e2ee66408cd5d4f294b + languageName: node + linkType: hard + "@graphql-tools/import@npm:6.7.1": version: 6.7.1 resolution: "@graphql-tools/import@npm:6.7.1" @@ -10552,13 +10843,13 @@ __metadata: languageName: node linkType: hard -"@grpc/grpc-js@npm:~1.7.0": - version: 1.7.0 - resolution: "@grpc/grpc-js@npm:1.7.0" +"@grpc/grpc-js@npm:~1.8.0": + version: 1.8.9 + resolution: "@grpc/grpc-js@npm:1.8.9" dependencies: "@grpc/proto-loader": ^0.7.0 "@types/node": ">=12.12.47" - checksum: 22eee49f9f5aea1abf9566426d993fe4457c94c2afacd3dfb932cc46dbc06ad6ce8f1422fac357d592dd0c75a5cf03405ea15310064ab3c45e1e418f22c48c2b + checksum: 40408af0c0e2b61dbb0fe1c246ae30404c89c601f3e9f9f8447f82d01d8dc0c8befccf2afe9ded07dfc8bd89c927bcbfb5925d4b1ae887299112b2ab549f519c languageName: node linkType: hard @@ -10667,7 +10958,7 @@ __metadata: "@types/uuid": ^8.0.0 express: ^4.17.1 express-promise-router: ^4.1.0 - msw: ^0.49.0 + msw: ^1.0.0 supertest: ^6.1.6 uuid: ^8.3.2 winston: ^3.2.1 @@ -10686,7 +10977,7 @@ __metadata: "@backstage/test-utils": "workspace:^" "@types/node": ^16.11.26 cross-fetch: ^3.1.5 - msw: ^0.49.0 + msw: ^1.0.0 languageName: unknown linkType: soft @@ -10708,7 +10999,7 @@ __metadata: "@testing-library/react": ^12.1.3 "@testing-library/user-event": ^14.0.0 "@types/node": ^16.11.26 - msw: ^0.49.0 + msw: ^1.0.0 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 @@ -11117,6 +11408,15 @@ __metadata: languageName: node linkType: hard +"@jsdoc/salty@npm:^0.2.1": + version: 0.2.3 + resolution: "@jsdoc/salty@npm:0.2.3" + dependencies: + lodash: ^4.17.21 + checksum: d2b29089e6ba942bf3228087d35379ada248c34f136357d1a4bf5c0350a0d5bde0f90dc68d5e7271728bac1951f85fe749075df0a32a9d584ad5d198492bf7f1 + languageName: node + linkType: hard + "@juggle/resize-observer@npm:^3.3.1": version: 3.3.1 resolution: "@juggle/resize-observer@npm:3.3.1" @@ -11125,12 +11425,12 @@ __metadata: linkType: hard "@keyv/memcache@npm:^1.3.5": - version: 1.3.5 - resolution: "@keyv/memcache@npm:1.3.5" + version: 1.3.6 + resolution: "@keyv/memcache@npm:1.3.6" dependencies: json-buffer: ^3.0.1 memjs: ^1.3.0 - checksum: c457863aeff1c5886c273eafa5fd79a4287cae1d9d3721b6ce5aa699033428ec8930db044224a6ab63d951cdac2408850737d0adc65f0a502bf04cd7dbe0d15e + checksum: 3360055b6e22d1be7a77341dc99bafb5434d3288dace94067f3307f6d9498f984dcb0d8452a5b2d97ddca8f8c973caf7cc1332e0ffada1c6dbfb0b2a2d42451a languageName: node linkType: hard @@ -11639,7 +11939,7 @@ __metadata: languageName: node linkType: hard -"@mswjs/cookies@npm:^0.2.0, @mswjs/cookies@npm:^0.2.2": +"@mswjs/cookies@npm:^0.2.2": version: 0.2.2 resolution: "@mswjs/cookies@npm:0.2.2" dependencies: @@ -11649,20 +11949,6 @@ __metadata: languageName: node linkType: hard -"@mswjs/interceptors@npm:^0.15.1": - version: 0.15.3 - resolution: "@mswjs/interceptors@npm:0.15.3" - dependencies: - "@open-draft/until": ^1.0.3 - "@xmldom/xmldom": ^0.7.5 - debug: ^4.3.3 - headers-polyfill: ^3.0.4 - outvariant: ^1.2.1 - strict-event-emitter: ^0.2.0 - checksum: 4c8e1d16f4a7b6133c02f1e13e9fc20af82dfa90106209036a9b3d85bb6ef4cce3b41312abde4bc9ccf59aa0b448e506d670bc6877b2ba25aad4f4b348d1454a - languageName: node - linkType: hard - "@mswjs/interceptors@npm:^0.17.5": version: 0.17.5 resolution: "@mswjs/interceptors@npm:0.17.5" @@ -12744,10 +13030,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.2.1": - version: 1.2.1 - resolution: "@remix-run/router@npm:1.2.1" - checksum: 71c947f83e130bf006226332aca395f626ad599b6d35dfe936f6a8f139cf37278bc1b36bce38c30f6062724402358296329f31c385b11ae59b13b76a2716d701 +"@remix-run/router@npm:1.3.2": + version: 1.3.2 + resolution: "@remix-run/router@npm:1.3.2" + checksum: ee2108b87d4a1241cdea137dd7e1741ee679228bd33fd81e22a6bb2940f81186cefe9a85e26d60cc49bbcc1bdbc57d1954b7d4d62f8a51ef69feddfc899f55fa languageName: node linkType: hard @@ -12847,8 +13133,8 @@ __metadata: linkType: hard "@roadiehq/backstage-plugin-buildkite@npm:^2.0.8": - version: 2.1.3 - resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.1.3" + version: 2.1.5 + resolution: "@roadiehq/backstage-plugin-buildkite@npm:2.1.5" dependencies: "@backstage/catalog-model": ^1.1.5 "@backstage/core-components": ^0.12.3 @@ -12866,13 +13152,13 @@ __metadata: react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: d7716bc6588863ae845630beac21b2a0ea8e2af4d01af1be432161007576c9c73419b2496ce868062e5af4ef9e3d02e9140eee8840c48223ded79c63d3efbb24 + checksum: d5ed0560401c621ae08b5eab82d5a9ebb36427f60ed2794071a7afcbc417c39c224438680234136aaaa992df19ed6b279b0292a03bdacac79359690d02256bcd languageName: node linkType: hard "@roadiehq/backstage-plugin-github-insights@npm:^2.0.5": - version: 2.3.3 - resolution: "@roadiehq/backstage-plugin-github-insights@npm:2.3.3" + version: 2.3.5 + resolution: "@roadiehq/backstage-plugin-github-insights@npm:2.3.5" dependencies: "@backstage/catalog-model": ^1.1.5 "@backstage/core-components": ^0.12.3 @@ -12894,13 +13180,13 @@ __metadata: react: ^16.13.1 || ^17.0.0 react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: e92b46ee34f8ae65a2cb796ae0d011a66e6dd5f731270b5925a314c706af471474316f2d489ef444c33747c3b5656e7ac74b8a39d6e4d777f5ccd3a992144f6a + checksum: 66e68cb85251df7be8d97e23810ab1d3b686ab99a76452e7daa8d4d3d44a0aee623defbbe83712601120af76d1d5a504fd62f6600edf6bfc623115d3a0f4ab00 languageName: node linkType: hard "@roadiehq/backstage-plugin-github-pull-requests@npm:^2.2.7": - version: 2.4.3 - resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:2.4.3" + version: 2.5.1 + resolution: "@roadiehq/backstage-plugin-github-pull-requests@npm:2.5.1" dependencies: "@backstage/catalog-model": ^1.1.5 "@backstage/core-components": ^0.12.3 @@ -12916,20 +13202,20 @@ __metadata: history: ^5.0.0 lodash: ^4.17.21 moment: ^2.27.0 - msw: ^0.39.2 + msw: ^1.0.1 node-fetch: ^2.6.1 react-use: ^17.2.4 peerDependencies: react: ^16.13.1 || ^17.0.0 react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 - checksum: 3d2d5d754921835088f1a34339e67938d3abdf673e267ee347526dac6c03afd4e0fdceca38090625654427c211ac2f52e78a7d2cad2347b56198bcfb9e00b95e + checksum: 769991ac46d4466261f2765eaab6eca903e751dc003d94a21dfb0376fca69af8edb2a8b9b12b375e903694278d32a95f8745d1f724a19429df34adeb3fb3e58c languageName: node linkType: hard "@roadiehq/backstage-plugin-travis-ci@npm:^2.0.5": - version: 2.1.3 - resolution: "@roadiehq/backstage-plugin-travis-ci@npm:2.1.3" + version: 2.1.4 + resolution: "@roadiehq/backstage-plugin-travis-ci@npm:2.1.4" dependencies: "@backstage/catalog-model": ^1.1.5 "@backstage/core-components": ^0.12.3 @@ -12949,7 +13235,7 @@ __metadata: react-dom: ^16.13.1 || ^17.0.0 react-router: 6.0.0-beta.0 || ^6.3.0 react-router-dom: 6.0.0-beta.0 || ^6.3.0 - checksum: 8051bd38465f73c1d09c7a88fe86f3c32fcd8d32924d7a5c0100cad0b6fba5e48684dc4b15ebdbbdc8f351c9e05286e1546b0a4499ad1385848e205737354d89 + checksum: 11e2823352c8e0d23ef9d577e8802d33e2c6e92bca0b269228224132f01ddced463436b43891dfd6b9ad4b4f7247291cb293426a899db87292c5500885029c9d languageName: node linkType: hard @@ -13449,90 +13735,90 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-darwin-arm64@npm:1.3.34" +"@swc/core-darwin-arm64@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-darwin-arm64@npm:1.3.36" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-darwin-x64@npm:1.3.34" +"@swc/core-darwin-x64@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-darwin-x64@npm:1.3.36" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.34" +"@swc/core-linux-arm-gnueabihf@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.36" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-arm64-gnu@npm:1.3.34" +"@swc/core-linux-arm64-gnu@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.36" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-arm64-musl@npm:1.3.34" +"@swc/core-linux-arm64-musl@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.36" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-x64-gnu@npm:1.3.34" +"@swc/core-linux-x64-gnu@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.36" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-linux-x64-musl@npm:1.3.34" +"@swc/core-linux-x64-musl@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-linux-x64-musl@npm:1.3.36" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-win32-arm64-msvc@npm:1.3.34" +"@swc/core-win32-arm64-msvc@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.36" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-win32-ia32-msvc@npm:1.3.34" +"@swc/core-win32-ia32-msvc@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.36" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.3.34": - version: 1.3.34 - resolution: "@swc/core-win32-x64-msvc@npm:1.3.34" +"@swc/core-win32-x64-msvc@npm:1.3.36": + version: 1.3.36 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.36" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.9": - version: 1.3.34 - resolution: "@swc/core@npm:1.3.34" + version: 1.3.36 + resolution: "@swc/core@npm:1.3.36" dependencies: - "@swc/core-darwin-arm64": 1.3.34 - "@swc/core-darwin-x64": 1.3.34 - "@swc/core-linux-arm-gnueabihf": 1.3.34 - "@swc/core-linux-arm64-gnu": 1.3.34 - "@swc/core-linux-arm64-musl": 1.3.34 - "@swc/core-linux-x64-gnu": 1.3.34 - "@swc/core-linux-x64-musl": 1.3.34 - "@swc/core-win32-arm64-msvc": 1.3.34 - "@swc/core-win32-ia32-msvc": 1.3.34 - "@swc/core-win32-x64-msvc": 1.3.34 + "@swc/core-darwin-arm64": 1.3.36 + "@swc/core-darwin-x64": 1.3.36 + "@swc/core-linux-arm-gnueabihf": 1.3.36 + "@swc/core-linux-arm64-gnu": 1.3.36 + "@swc/core-linux-arm64-musl": 1.3.36 + "@swc/core-linux-x64-gnu": 1.3.36 + "@swc/core-linux-x64-musl": 1.3.36 + "@swc/core-win32-arm64-msvc": 1.3.36 + "@swc/core-win32-ia32-msvc": 1.3.36 + "@swc/core-win32-x64-msvc": 1.3.36 dependenciesMeta: "@swc/core-darwin-arm64": optional: true @@ -13554,7 +13840,7 @@ __metadata: optional: true "@swc/core-win32-x64-msvc": optional: true - checksum: a77c286b6b34d40f634ae882aac66f882cf806c165453878c31311070c46f020c607925bd454f64959504f08852b204cc37feba93fc6a3c1a64b295a9b5007d6 + checksum: 36e96e86d1ab8fd84eb51e7264a7ae781ee7e507d36b9ccc028d7f31a2ccf2949f074656e34139c970196774d24d55a54c3aa5c53d04eb6e3569c71cbfed0c0d languageName: node linkType: hard @@ -13588,18 +13874,18 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:4.24.4": - version: 4.24.4 - resolution: "@tanstack/query-core@npm:4.24.4" - checksum: b357e950a41e5769878a3bfe9dd56a66828ccebb2f9396e568e8835bed71eb37926770a461e3aa5bafb7e1121c5141cee86aedf3ced88a2eacf754d545b107cd +"@tanstack/query-core@npm:4.24.10": + version: 4.24.10 + resolution: "@tanstack/query-core@npm:4.24.10" + checksum: 8268b9dca4a2ed39f8575976d8a3e2f839bb6f4fb821dc00ba8e2aeffffe2f73e23344bcc24b9cb6dae9dbfe3ba2b14c76a1e0a38b4064c83beb9aa607fd94bc languageName: node linkType: hard "@tanstack/react-query@npm:^4.1.3": - version: 4.24.4 - resolution: "@tanstack/react-query@npm:4.24.4" + version: 4.24.10 + resolution: "@tanstack/react-query@npm:4.24.10" dependencies: - "@tanstack/query-core": 4.24.4 + "@tanstack/query-core": 4.24.10 use-sync-external-store: ^1.2.0 peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -13610,7 +13896,7 @@ __metadata: optional: true react-native: optional: true - checksum: 8cf008d690fc5d336f6471ea2bc0751189f03874dcc7930cf8944fb57fa34e3b5347823775dbd36629d53a7aacb9ce87482b1adb3ad80d277a3a6c73b797f6a2 + checksum: 576a2c73e98cf6a3c9584283989383d5ac63b01efe546cc7580ec7b1edf0c0cb8958a3071778cb0af908f5269d45c7516fa388e5f856e37f5b2d3c6110974cbe languageName: node linkType: hard @@ -14382,11 +14668,11 @@ __metadata: linkType: hard "@types/express-session@npm:^1.17.2": - version: 1.17.5 - resolution: "@types/express-session@npm:1.17.5" + version: 1.17.6 + resolution: "@types/express-session@npm:1.17.6" dependencies: "@types/express": "*" - checksum: f6995f7720a18546bcb10cc707cf8c9c92455eb4319c0c50c57e9b9b10ed20dc379d74d5e4c3323fe4e924238b75e13c97822c9d81a80fa064ddc71654c1059d + checksum: f5f2201d6b9568d8b9319735a4f6806b5ca144cee450274965aec54bc0a0331ba8bfffc1ad5addadf2e625769e13813a48cb5aea5b166fa05f474a12302dbb38 languageName: node linkType: hard @@ -14400,7 +14686,7 @@ __metadata: languageName: node linkType: hard -"@types/express@npm:*, @types/express@npm:^4.17.13, @types/express@npm:^4.17.15, @types/express@npm:^4.17.6": +"@types/express@npm:*, @types/express@npm:^4.17.13, @types/express@npm:^4.17.6": version: 4.17.16 resolution: "@types/express@npm:4.17.16" dependencies: @@ -14534,11 +14820,11 @@ __metadata: linkType: hard "@types/http-proxy@npm:*, @types/http-proxy@npm:^1.17.4, @types/http-proxy@npm:^1.17.8": - version: 1.17.9 - resolution: "@types/http-proxy@npm:1.17.9" + version: 1.17.10 + resolution: "@types/http-proxy@npm:1.17.10" dependencies: "@types/node": "*" - checksum: 7a6746d00729b2a9fe9f9dd3453430b099931df879ec8f7a7b5f07b1795f6d99b0512640c45a67390b1e4bacb9401e36824952aeeaf089feba8627a063cf8e00 + checksum: 8fabee5d01715e338f426715325121d6c4b7a9694dee716ab61c874e0aaccee9a0fff7ccc3c9d7e37a8feeaab7c783c17aaa9943efbc8849c5e79ecd7eaf02ab languageName: node linkType: hard @@ -14550,11 +14836,12 @@ __metadata: linkType: hard "@types/inquirer@npm:^8.1.3": - version: 8.2.5 - resolution: "@types/inquirer@npm:8.2.5" + version: 8.2.6 + resolution: "@types/inquirer@npm:8.2.6" dependencies: "@types/through": "*" - checksum: 932c432e634697bcff5d50fdc9e64f90d2e31c5ebcda909f2e9704d0433b5ec608b6ece985c6e57a283f3b62434f1cd3619b64ca61433d7c3bdb41d3c5f27586 + rxjs: ^7.2.0 + checksum: d09c3b6bbfb1aff8bdb8fc938d43536be55dfb51af0c91d0105e3f7c5e3950c12618ac00e2e91f10b5abeba38f4b903289be1df5aa31f213b58c3cc675a19f81 languageName: node linkType: hard @@ -15001,9 +15288,9 @@ __metadata: linkType: hard "@types/nunjucks@npm:^3.1.4": - version: 3.2.1 - resolution: "@types/nunjucks@npm:3.2.1" - checksum: 40f3dd8968cd30c19a99c6eec55e3bf354da39ce08840a8d652a7c9754a7e5a8a59f92fb258862c56d223f9908b62c347006d0a26f685a5dc72f13bdb68ce778 + version: 3.2.2 + resolution: "@types/nunjucks@npm:3.2.2" + checksum: e0fdc68f01635b34ea6f5e8845ed6d2e8d11be6347b2f28c8093636454e2401f02c26a2ad6aa459da56f2459f2d59bf72914b6e4774bcd058fa12e2ae5f0f6ef languageName: node linkType: hard @@ -15055,12 +15342,12 @@ __metadata: languageName: node linkType: hard -"@types/passport-microsoft@npm:^0.0.0": - version: 0.0.0 - resolution: "@types/passport-microsoft@npm:0.0.0" +"@types/passport-microsoft@npm:^1.0.0": + version: 1.0.0 + resolution: "@types/passport-microsoft@npm:1.0.0" dependencies: "@types/passport-oauth2": "*" - checksum: fee27b238975ba86982616d713247bd9f8ab4e325270dd42841c140710ece3f32655b2536fcbffe0166f25b51e1b25316006718f037b5a88018406c64351ae27 + checksum: d7c8b439b18cddcf707ea0c575748ecb344b6fb3c78a847aaad83246abf081c8b485efa86a3788cd5f49f4ca84a1444d813697a433fab9d04f35fb67d628cb23 languageName: node linkType: hard @@ -15096,11 +15383,11 @@ __metadata: linkType: hard "@types/passport@npm:*, @types/passport@npm:^1.0.3": - version: 1.0.11 - resolution: "@types/passport@npm:1.0.11" + version: 1.0.12 + resolution: "@types/passport@npm:1.0.12" dependencies: "@types/express": "*" - checksum: 7fea92aeb0d05bd872c17deadc1f1219dbdb23bae1b8f50e1c432ef755bce2b5f3fd60af76c38815f1fbaa047960d3638a4144221c4330457091be1f6e492168 + checksum: 2bce41b248566d8c2aeafcb38f105e3521d42a572e92da9edc5eb669f1b3cb02e5911c9d124191f67d432b677562a885b6ad7f56320c712df1e87ba7619eb8a4 languageName: node linkType: hard @@ -15322,6 +15609,16 @@ __metadata: languageName: node linkType: hard +"@types/rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "@types/rimraf@npm:3.0.2" + dependencies: + "@types/glob": "*" + "@types/node": "*" + checksum: b47fa302f46434cba704d20465861ad250df79467d3d289f9d6490d3aeeb41e8cb32dd80bd1a8fd833d1e185ac719fbf9be12e05ad9ce9be094d8ee8f1405347 + languageName: node + linkType: hard + "@types/rollup-plugin-peer-deps-external@npm:^2.2.0": version: 2.2.1 resolution: "@types/rollup-plugin-peer-deps-external@npm:2.2.1" @@ -15529,12 +15826,12 @@ __metadata: linkType: hard "@types/tar@npm:^6.1.1": - version: 6.1.3 - resolution: "@types/tar@npm:6.1.3" + version: 6.1.4 + resolution: "@types/tar@npm:6.1.4" dependencies: "@types/node": "*" - minipass: ^3.3.5 - checksum: 3a221f74adfcef8555b9c4cc951907dfd567630744ffe5211da1b44caf2a4c3b02297b73c9fb02d171e93a7a7c74fb15c1826e3f0438f0e5e8f4c790db59ddcf + minipass: ^4.0.0 + checksum: 48a1f6b8665ed03f37f74966cfe991a33d6e85cee28aaa6ef42c7ca8448cdbc1e2ca96b473b6b53f1d7bd91423ae0dcfe54a295607d7ac4b4cbb9dbf167df7fa languageName: node linkType: hard @@ -15581,6 +15878,13 @@ __metadata: languageName: node linkType: hard +"@types/triple-beam@npm:^1.3.2": + version: 1.3.2 + resolution: "@types/triple-beam@npm:1.3.2" + checksum: dd7b4a563fb710abc992e5d59eac481bed9e303fada2e276e37b00be31c392e03300ee468e57761e616512872e77935f92472877d0704a19688d15a726cee17b + languageName: node + linkType: hard + "@types/trusted-types@npm:*": version: 2.0.2 resolution: "@types/trusted-types@npm:2.0.2" @@ -15720,13 +16024,14 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^5.9.0": - version: 5.48.1 - resolution: "@typescript-eslint/eslint-plugin@npm:5.48.1" + version: 5.53.0 + resolution: "@typescript-eslint/eslint-plugin@npm:5.53.0" dependencies: - "@typescript-eslint/scope-manager": 5.48.1 - "@typescript-eslint/type-utils": 5.48.1 - "@typescript-eslint/utils": 5.48.1 + "@typescript-eslint/scope-manager": 5.53.0 + "@typescript-eslint/type-utils": 5.53.0 + "@typescript-eslint/utils": 5.53.0 debug: ^4.3.4 + grapheme-splitter: ^1.0.4 ignore: ^5.2.0 natural-compare-lite: ^1.4.0 regexpp: ^3.2.0 @@ -15738,7 +16043,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: d8d73d123d16fc9b50b500ef21816dcabdffe0d2dcfdb15089dc5a1015d57cbad709de565d1c830f5058c0d7b410069e2554c0b53d1485fe7b237ea8089e58be + checksum: 12dffe65969d8e5248c86a700fe46a737e55ecafb276933e747b4731eab6266fe55e2d43a34b8b340179fe248e127d861cd016a7614b1b9804cd0687c99616d1 languageName: node linkType: hard @@ -15759,39 +16064,29 @@ __metadata: linkType: hard "@typescript-eslint/parser@npm:^5.9.0": - version: 5.48.1 - resolution: "@typescript-eslint/parser@npm:5.48.1" + version: 5.53.0 + resolution: "@typescript-eslint/parser@npm:5.53.0" dependencies: - "@typescript-eslint/scope-manager": 5.48.1 - "@typescript-eslint/types": 5.48.1 - "@typescript-eslint/typescript-estree": 5.48.1 + "@typescript-eslint/scope-manager": 5.53.0 + "@typescript-eslint/types": 5.53.0 + "@typescript-eslint/typescript-estree": 5.53.0 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: c624d24eb209b4ce7f0a6c8116712363f10a9c9a5138f240e254ff265526ee4b0fd73b7b6b4b6a0e7611bd9934c42036350dd27f96ae2fa4efdade1a7ebd0e9e + checksum: 979e5d63793a9e64998b1f956ba0f00f8a2674db3a664fafce7b2433323f5248bd776af8305e2419d73a9d94c55176fee099abc5c153b4cc52e5765c725c1edd languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.48.1": - version: 5.48.1 - resolution: "@typescript-eslint/scope-manager@npm:5.48.1" +"@typescript-eslint/scope-manager@npm:5.53.0": + version: 5.53.0 + resolution: "@typescript-eslint/scope-manager@npm:5.53.0" dependencies: - "@typescript-eslint/types": 5.48.1 - "@typescript-eslint/visitor-keys": 5.48.1 - checksum: f60a7efe917798cccf8652925de6be58b023ded6c6ee44ce74d074f0c2a1927680398a6d73bab33d500c69474ad8c54d63b90fcc6e13256712707d12a60e0a64 - languageName: node - linkType: hard - -"@typescript-eslint/scope-manager@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/scope-manager@npm:5.49.0" - dependencies: - "@typescript-eslint/types": 5.49.0 - "@typescript-eslint/visitor-keys": 5.49.0 - checksum: 466047e24ff8a4195f14aadde39375f22891bdaced09e58c89f2c32af0aa4a0d87e71a5f006f6ab76858e6f30c4b764b1e0ef7bc26713bb78add30638108c45f + "@typescript-eslint/types": 5.53.0 + "@typescript-eslint/visitor-keys": 5.53.0 + checksum: 51f31dc01e95908611f402441f58404da80a338c0237b2b82f4a7b0b2e8868c4bfe8f7cf44b2567dd56533de609156a5d4ac54bb1f9f09c7014b99428aef2543 languageName: node linkType: hard @@ -15805,12 +16100,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.48.1": - version: 5.48.1 - resolution: "@typescript-eslint/type-utils@npm:5.48.1" +"@typescript-eslint/type-utils@npm:5.53.0": + version: 5.53.0 + resolution: "@typescript-eslint/type-utils@npm:5.53.0" dependencies: - "@typescript-eslint/typescript-estree": 5.48.1 - "@typescript-eslint/utils": 5.48.1 + "@typescript-eslint/typescript-estree": 5.53.0 + "@typescript-eslint/utils": 5.53.0 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -15818,21 +16113,14 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 2739b35caf48c9edbeab82936de58ce0759ab34955ce7eec1786690d6a63146ae0a6c5d9c76034605d9fe200c87a73ede0772c6244c5df6e66df992d9ebbab72 + checksum: 52c40967c5fabd58c2ae8bf519ef89e4feb511e4df630aeaeac8335661a79b6b3a32d30a61a5f1d8acc703f21c4d90751a5d41cda1b35d08867524da11bc2e1d languageName: node linkType: hard -"@typescript-eslint/types@npm:5.48.1": - version: 5.48.1 - resolution: "@typescript-eslint/types@npm:5.48.1" - checksum: 8437986e9d86d792b23327517ae2f9861ec55992d5a9cd55991e525409b6244169436cd708f3987ab7c579e45e59b6eab5a9d3583f7729219e25691164293094 - languageName: node - linkType: hard - -"@typescript-eslint/types@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/types@npm:5.49.0" - checksum: 41f72a043007fc3f3356b5a38d7bfa54871545b4a309810a062f044cff25122413a9660ce6d83d1221762f60d067351d020b0cb68f7e1279817f53e77ce8f33d +"@typescript-eslint/types@npm:5.53.0": + version: 5.53.0 + resolution: "@typescript-eslint/types@npm:5.53.0" + checksum: b0eaf23de4ab13697d4d2095838c959a3f410c30f0d19091e5ca08e62320c3cc3c72bcb631823fb6a4fbb31db0a059e386a0801244930d0a88a6a698e5f46548 languageName: node linkType: hard @@ -15843,12 +16131,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.48.1": - version: 5.48.1 - resolution: "@typescript-eslint/typescript-estree@npm:5.48.1" +"@typescript-eslint/typescript-estree@npm:5.53.0": + version: 5.53.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.53.0" dependencies: - "@typescript-eslint/types": 5.48.1 - "@typescript-eslint/visitor-keys": 5.48.1 + "@typescript-eslint/types": 5.53.0 + "@typescript-eslint/visitor-keys": 5.53.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -15857,25 +16145,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 2b26e5848ef131e1bb99ed54d8c0efa8279cf8e8f7d8b72de00c2ca6cf2799d96c20f5bbbcf26e14e81b7b9d1035ba509bff30f2d852c174815879e8f14c27ed - languageName: node - linkType: hard - -"@typescript-eslint/typescript-estree@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.49.0" - dependencies: - "@typescript-eslint/types": 5.49.0 - "@typescript-eslint/visitor-keys": 5.49.0 - debug: ^4.3.4 - globby: ^11.1.0 - is-glob: ^4.0.3 - semver: ^7.3.7 - tsutils: ^3.21.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: f331af9f0ef3ce3157c421b8cc727dec5aa0a60add305aa4c676a02c63ec07799105268af192c5ed193a682b7ed804564d29d49bdbd2019678e495d80e65e29a + checksum: 6e119c8e4167c8495d728c5556a834545a9c064918dd5e7b79b0d836726f4f8e2a0297b0ac82bf2b71f1e5427552217d0b59d8fb1406fd79bd3bf91b75dca873 languageName: node linkType: hard @@ -15897,59 +16167,31 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.48.1": - version: 5.48.1 - resolution: "@typescript-eslint/utils@npm:5.48.1" +"@typescript-eslint/utils@npm:5.53.0, @typescript-eslint/utils@npm:^5.10.0, @typescript-eslint/utils@npm:^5.43.0": + version: 5.53.0 + resolution: "@typescript-eslint/utils@npm:5.53.0" dependencies: "@types/json-schema": ^7.0.9 "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.48.1 - "@typescript-eslint/types": 5.48.1 - "@typescript-eslint/typescript-estree": 5.48.1 + "@typescript-eslint/scope-manager": 5.53.0 + "@typescript-eslint/types": 5.53.0 + "@typescript-eslint/typescript-estree": 5.53.0 eslint-scope: ^5.1.1 eslint-utils: ^3.0.0 semver: ^7.3.7 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 2d112cbb6a920f147c6c3322e404ca3c56c1170e1ede3bcbf16fb779960dc24cdba688b1f2d06acd242859fc1dbc8702da5f8fa8bbf53e7081e41d80bec4c236 + checksum: 18e6bac14ae853385a74123759850bca367904723e170c37416fc014673eb714afb6bb090367bff61494a8387e941b6af65ee5f4f845f7177fabb4df85e01643 languageName: node linkType: hard -"@typescript-eslint/utils@npm:^5.10.0, @typescript-eslint/utils@npm:^5.43.0": - version: 5.49.0 - resolution: "@typescript-eslint/utils@npm:5.49.0" +"@typescript-eslint/visitor-keys@npm:5.53.0": + version: 5.53.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.53.0" dependencies: - "@types/json-schema": ^7.0.9 - "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.49.0 - "@typescript-eslint/types": 5.49.0 - "@typescript-eslint/typescript-estree": 5.49.0 - eslint-scope: ^5.1.1 - eslint-utils: ^3.0.0 - semver: ^7.3.7 - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 8218c566637d5104dfb2346216f8cb4c244f31c2a39e261aafe554b8abd48bd630a0d0807a0a8d776af8f9d9914c8776d86abf0a523049f3c5619c498a7e5b1e - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:5.48.1": - version: 5.48.1 - resolution: "@typescript-eslint/visitor-keys@npm:5.48.1" - dependencies: - "@typescript-eslint/types": 5.48.1 + "@typescript-eslint/types": 5.53.0 eslint-visitor-keys: ^3.3.0 - checksum: 2bda10cf4e6bc48b0d463767617e48a832d708b9434665dff6ed101f7d33e0d592f02af17a2259bde1bd17e666246448ae78d0fe006148cb93d897fff9b1d134 - languageName: node - linkType: hard - -"@typescript-eslint/visitor-keys@npm:5.49.0": - version: 5.49.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.49.0" - dependencies: - "@typescript-eslint/types": 5.49.0 - eslint-visitor-keys: ^3.3.0 - checksum: 46dc7bc713e8825d1fccba521fdf7c6e2f8829e491c2afd44dbe4105c6432e3c3dfe7e1ecb221401269d639264bb4af77b60a7b65521fcff9ab02cd31d8ef782 + checksum: 090695883c15364c6f401e97f56b13db0f31c1114f3bd22562bd41734864d27f6a3c80de33957e9dedab2d5f94b0f4480ba3fde1d4574e74dca4593917b7b54a languageName: node linkType: hard @@ -15963,9 +16205,9 @@ __metadata: languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.19.7": - version: 4.19.7 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.19.7" +"@uiw/codemirror-extensions-basic-setup@npm:4.19.9": + version: 4.19.9 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.19.9" dependencies: "@codemirror/autocomplete": ^6.0.0 "@codemirror/commands": ^6.0.0 @@ -15982,19 +16224,19 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: 4c32d3b41b78776fd41b229edc8777dff4137ff6125836df5a6573e01a0a74f2ae66293a09a3b095a1fbe660b2fc8b2bde93ba4aa92636702a74baea261fcf94 + checksum: f248d1623f33b88b61dd75955441d1b5925b2b2c78d595eac1d4603dc31f107d5973d9cff42c3ade4a2493828d679a8908e5dad03a570511e6095d0028089f85 languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.9.3": - version: 4.19.7 - resolution: "@uiw/react-codemirror@npm:4.19.7" + version: 4.19.9 + resolution: "@uiw/react-codemirror@npm:4.19.9" 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.19.7 + "@uiw/codemirror-extensions-basic-setup": 4.19.9 codemirror: ^6.0.0 peerDependencies: "@babel/runtime": ">=7.11.0" @@ -16004,7 +16246,7 @@ __metadata: codemirror: ">=6.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 333c7b0c7181219bb0506cd956eb10fa07aad5f26d3c5a9e7b9875e6c60f1e9bf1c8f74bf160735c75b7dbe9e9b05879c17f5ea641e212ba8f454887f04b0e7e + checksum: ed0d9a7b927df718535bccf553fa7cdabd2cb776f74e6ae75eab0ba321bc60468b5f1b8576a12543729770a11e5438fd4fc925f3f74643985c34a2184c5ae7f6 languageName: node linkType: hard @@ -16159,6 +16401,13 @@ __metadata: languageName: node linkType: hard +"@whatwg-node/events@npm:^0.0.2": + version: 0.0.2 + resolution: "@whatwg-node/events@npm:0.0.2" + checksum: 6d491801d36967d5d62443cca6ef39d41cf882d575839d2e9d1a5f394722cd24ef84fe9e897bb72c01bd198871fda9ff0e8b1ac5aa6f3f814f87d92b7f28fdcc + languageName: node + linkType: hard + "@whatwg-node/fetch@npm:0.5.3, @whatwg-node/fetch@npm:^0.5.0": version: 0.5.3 resolution: "@whatwg-node/fetch@npm:0.5.3" @@ -16192,20 +16441,31 @@ __metadata: languageName: node linkType: hard -"@whatwg-node/fetch@npm:^0.6.0": - version: 0.6.1 - resolution: "@whatwg-node/fetch@npm:0.6.1" +"@whatwg-node/fetch@npm:^0.8.0": + version: 0.8.1 + resolution: "@whatwg-node/fetch@npm:0.8.1" dependencies: "@peculiar/webcrypto": ^1.4.0 - abort-controller: ^3.0.0 + "@whatwg-node/node-fetch": ^0.3.0 busboy: ^1.6.0 - form-data-encoder: ^1.7.1 - formdata-node: ^4.3.1 - node-fetch: ^2.6.7 - undici: ^5.12.0 urlpattern-polyfill: ^6.0.2 - web-streams-polyfill: ^3.2.0 - checksum: 81b469c03e53f49f6a1a2d8059ba28d40b710611e01a60f6396cf95f0d4b48d596c176dccc19876e32b3c67b77b1e72c1053cea05f6417f1c5340150037a3da1 + web-streams-polyfill: ^3.2.1 + checksum: b827ac2299676705d98d31be4b68e70741200618b38daaae0d70e587f61fae573854170e2ca219d64bbd910b96960e26b64aa9869e9194a4d162e2a751d6f7a7 + languageName: node + linkType: hard + +"@whatwg-node/node-fetch@npm:^0.3.0": + version: 0.3.0 + resolution: "@whatwg-node/node-fetch@npm:0.3.0" + dependencies: + "@whatwg-node/events": ^0.0.2 + busboy: ^1.6.0 + fast-querystring: ^1.1.1 + fast-url-parser: ^1.1.3 + tslib: ^2.3.1 + peerDependencies: + "@types/node": ^18.0.6 + checksum: 141deb3f44d1978218c64ca285120b3e2427159773056774f2251f9d5d418c8e1d6f27f4b593d031ff4124f9cd00cb4bd9fd681e4528c9f498c72356a520b69f languageName: node linkType: hard @@ -16405,6 +16665,16 @@ __metadata: languageName: node linkType: hard +"aggregate-error@npm:^4.0.0": + version: 4.0.1 + resolution: "aggregate-error@npm:4.0.1" + dependencies: + clean-stack: ^4.0.0 + indent-string: ^5.0.0 + checksum: bb3ffdfd13447800fff237c2cba752c59868ee669104bb995dfbbe0b8320e967d679e683dabb640feb32e4882d60258165cde0baafc4cd467cc7d275a13ad6b5 + languageName: node + linkType: hard + "ajv-formats@npm:^2.1.1": version: 2.1.1 resolution: "ajv-formats@npm:2.1.1" @@ -17646,10 +17916,10 @@ __metadata: languageName: node linkType: hard -"binary-extensions@npm:^2.0.0": - version: 2.0.0 - resolution: "binary-extensions@npm:2.0.0" - checksum: 554f65d3378cf71c3185c17dec3ca58334b8ff6ae242db3107284765ce33b2af19efd20c11faec41907a40534929e34b3a98e7d391c61e4211b45732dccb1115 +"binary-extensions@npm:^2.0.0, binary-extensions@npm:^2.2.0": + version: 2.2.0 + resolution: "binary-extensions@npm:2.2.0" + checksum: ccd267956c58d2315f5d3ea6757cf09863c5fc703e50fbeb13a7dc849b812ef76e3cf9ca8f35a0c48498776a7478d7b4a0418e1e2b8cb9cb9731f2922aaad7f8 languageName: node linkType: hard @@ -18583,6 +18853,15 @@ __metadata: languageName: node linkType: hard +"clean-stack@npm:^4.0.0": + version: 4.2.0 + resolution: "clean-stack@npm:4.2.0" + dependencies: + escape-string-regexp: 5.0.0 + checksum: 373f656a31face5c615c0839213b9b542a0a48057abfb1df66900eab4dc2a5c6097628e4a0b5aa559cdfc4e66f8a14ea47be9681773165a44470ef5fb8ccc172 + languageName: node + linkType: hard + "cli-cursor@npm:^3.1.0": version: 3.1.0 resolution: "cli-cursor@npm:3.1.0" @@ -19009,7 +19288,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:*, commander@npm:^9.1.0, commander@npm:^9.4.1": +"commander@npm:*, commander@npm:^9.1.0, commander@npm:^9.4.1, commander@npm:^9.5.0": version: 9.5.0 resolution: "commander@npm:9.5.0" checksum: c7a3e27aa59e913b54a1bafd366b88650bc41d6651f0cbe258d4ff09d43d6a7394232a4dadd0bf518b3e696fdf595db1028a0d82c785b88bd61f8a440cecfade @@ -19426,9 +19705,9 @@ __metadata: linkType: hard "core-js@npm:^3.6.5": - version: 3.27.2 - resolution: "core-js@npm:3.27.2" - checksum: 718debd426f55a6b97cf9b757c936be258afd6d4f7052f89d0f96c982d7013e9000b0b006df42831a0cf32adad298e34d6a19052dce9ae1c7ab87162c0c665e0 + version: 3.28.0 + resolution: "core-js@npm:3.28.0" + checksum: 3155fd0ec16d0089106b145e9595280a4ea4bde0d7ff26aa14364cd4f1c203baf6620c3025acd284f363d08b9f21104101692766ca9a36ffeee7307bdf3e1881 languageName: node linkType: hard @@ -19592,11 +19871,11 @@ __metadata: linkType: hard "cronstrue@npm:^2.2.0": - version: 2.22.0 - resolution: "cronstrue@npm:2.22.0" + version: 2.23.0 + resolution: "cronstrue@npm:2.23.0" bin: cronstrue: bin/cli.js - checksum: 5017cccddee819c162d3b71c2a517c2468834f6454e9ce6a21016149848a69cf7f7433584c61dd1b92adea79ea461da291d32f48129c0a5ccef93019be93494f + checksum: 050140ac6452468d6f9032f18038f41b16968502d411a996efd5d42243cfd882271ff20ed4a3cdb25c45bf8f88beeb0579e45e974a11987401e9d383af2641a8 languageName: node linkType: hard @@ -20274,13 +20553,20 @@ __metadata: languageName: node linkType: hard -"dataloader@npm:2.1.0, dataloader@npm:^2.0.0": +"dataloader@npm:2.1.0": version: 2.1.0 resolution: "dataloader@npm:2.1.0" checksum: bbd43496c41697766f8611f60ed3bae437b450985499140b9603a2447c10d45975d3a0661caaebaa9750bc1bc9fd154676a314423294916c8b8ca1a59a08d139 languageName: node linkType: hard +"dataloader@npm:^2.0.0": + version: 2.2.2 + resolution: "dataloader@npm:2.2.2" + checksum: 4dabd247089c29f194e94d5434d504f99156c5c214a03463c20f3f17f40398d7e179edee69a27c16e315519ac8739042a810090087ae26449a0e685156a02c65 + languageName: node + linkType: hard + "date-fns@npm:^2.16.1, date-fns@npm:^2.18.0, date-fns@npm:^2.29.1": version: 2.29.3 resolution: "date-fns@npm:2.29.3" @@ -20520,19 +20806,19 @@ __metadata: languageName: node linkType: hard -"del@npm:^6.0.0": - version: 6.1.1 - resolution: "del@npm:6.1.1" +"del@npm:^7.0.0": + version: 7.0.0 + resolution: "del@npm:7.0.0" dependencies: - globby: ^11.0.1 - graceful-fs: ^4.2.4 - is-glob: ^4.0.1 - is-path-cwd: ^2.2.0 - is-path-inside: ^3.0.2 - p-map: ^4.0.0 + globby: ^13.1.2 + graceful-fs: ^4.2.10 + is-glob: ^4.0.3 + is-path-cwd: ^3.0.0 + is-path-inside: ^4.0.0 + p-map: ^5.5.0 rimraf: ^3.0.2 - slash: ^3.0.0 - checksum: 563288b73b8b19a7261c47fd21a330eeab6e2acd7c6208c49790dfd369127120dd7836cdf0c1eca216b77c94782a81507eac6b4734252d3bef2795cb366996b6 + slash: ^4.0.0 + checksum: 33e5077f18b5dfbe81971d1f8a2cd8bf676dd5ede491bab85ec17a4a1d59001bd3ec47fd38e9a4ae01a3c98c07b98c7b3dc56190b86d88926798802d7858d827 languageName: node linkType: hard @@ -21010,6 +21296,7 @@ __metadata: dependencies: "@backstage/cli": "workspace:^" "@backstage/cli-common": "workspace:^" + "@backstage/create-app": "workspace:^" "@backstage/errors": "workspace:^" "@types/fs-extra": ^9.0.1 "@types/node": ^16.11.26 @@ -21473,18 +21760,18 @@ __metadata: linkType: hard "esbuild-loader@npm:^2.18.0": - version: 2.20.0 - resolution: "esbuild-loader@npm:2.20.0" + version: 2.21.0 + resolution: "esbuild-loader@npm:2.21.0" dependencies: - esbuild: ^0.15.6 + esbuild: ^0.16.17 joycon: ^3.0.1 json5: ^2.2.0 loader-utils: ^2.0.0 tapable: ^2.2.0 - webpack-sources: ^2.2.0 + webpack-sources: ^1.4.3 peerDependencies: webpack: ^4.40.0 || ^5.0.0 - checksum: 81faee7155b35af1fdef3dffa273a14ec83e56b9efa1efb76cb1eb64964dd738809c147a87ab9d3507de11946eed51fd1ee42d476b2c9654cbda145da0d9479b + checksum: a0456ed7794e2c220a6068e92d739bc19765bff352bf7e44442aa8127631cc517ecd02a3ee969e31fa6b6a91befeac928296488c95e3818a776cd3b11d46348c languageName: node linkType: hard @@ -21530,7 +21817,161 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.15.6, esbuild@npm:~0.15.10": +"esbuild@npm:^0.16.17": + version: 0.16.17 + resolution: "esbuild@npm:0.16.17" + dependencies: + "@esbuild/android-arm": 0.16.17 + "@esbuild/android-arm64": 0.16.17 + "@esbuild/android-x64": 0.16.17 + "@esbuild/darwin-arm64": 0.16.17 + "@esbuild/darwin-x64": 0.16.17 + "@esbuild/freebsd-arm64": 0.16.17 + "@esbuild/freebsd-x64": 0.16.17 + "@esbuild/linux-arm": 0.16.17 + "@esbuild/linux-arm64": 0.16.17 + "@esbuild/linux-ia32": 0.16.17 + "@esbuild/linux-loong64": 0.16.17 + "@esbuild/linux-mips64el": 0.16.17 + "@esbuild/linux-ppc64": 0.16.17 + "@esbuild/linux-riscv64": 0.16.17 + "@esbuild/linux-s390x": 0.16.17 + "@esbuild/linux-x64": 0.16.17 + "@esbuild/netbsd-x64": 0.16.17 + "@esbuild/openbsd-x64": 0.16.17 + "@esbuild/sunos-x64": 0.16.17 + "@esbuild/win32-arm64": 0.16.17 + "@esbuild/win32-ia32": 0.16.17 + "@esbuild/win32-x64": 0.16.17 + 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: 4c2cc609ecfb426554bc3f75beb92d89eb2d0c515cfceebaa36c7599d7dcaab7056b70f6d6b51e72b45951ddf9021ee28e356cf205f8e42cc055d522312ea30c + languageName: node + linkType: hard + +"esbuild@npm:^0.17.0": + version: 0.17.10 + resolution: "esbuild@npm:0.17.10" + dependencies: + "@esbuild/android-arm": 0.17.10 + "@esbuild/android-arm64": 0.17.10 + "@esbuild/android-x64": 0.17.10 + "@esbuild/darwin-arm64": 0.17.10 + "@esbuild/darwin-x64": 0.17.10 + "@esbuild/freebsd-arm64": 0.17.10 + "@esbuild/freebsd-x64": 0.17.10 + "@esbuild/linux-arm": 0.17.10 + "@esbuild/linux-arm64": 0.17.10 + "@esbuild/linux-ia32": 0.17.10 + "@esbuild/linux-loong64": 0.17.10 + "@esbuild/linux-mips64el": 0.17.10 + "@esbuild/linux-ppc64": 0.17.10 + "@esbuild/linux-riscv64": 0.17.10 + "@esbuild/linux-s390x": 0.17.10 + "@esbuild/linux-x64": 0.17.10 + "@esbuild/netbsd-x64": 0.17.10 + "@esbuild/openbsd-x64": 0.17.10 + "@esbuild/sunos-x64": 0.17.10 + "@esbuild/win32-arm64": 0.17.10 + "@esbuild/win32-ia32": 0.17.10 + "@esbuild/win32-x64": 0.17.10 + 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: 803de327036528c140b3d1d8e148604fd1446062b63d2b5a49cd8fe5fa607dc41be915f28dec1242be77164378e3ca27a2ed2968692a73cc833896c7bebc0e12 + languageName: node + linkType: hard + +"esbuild@npm:~0.15.10": version: 0.15.18 resolution: "esbuild@npm:0.15.18" dependencies: @@ -21607,83 +22048,6 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.17.0": - version: 0.17.6 - resolution: "esbuild@npm:0.17.6" - dependencies: - "@esbuild/android-arm": 0.17.6 - "@esbuild/android-arm64": 0.17.6 - "@esbuild/android-x64": 0.17.6 - "@esbuild/darwin-arm64": 0.17.6 - "@esbuild/darwin-x64": 0.17.6 - "@esbuild/freebsd-arm64": 0.17.6 - "@esbuild/freebsd-x64": 0.17.6 - "@esbuild/linux-arm": 0.17.6 - "@esbuild/linux-arm64": 0.17.6 - "@esbuild/linux-ia32": 0.17.6 - "@esbuild/linux-loong64": 0.17.6 - "@esbuild/linux-mips64el": 0.17.6 - "@esbuild/linux-ppc64": 0.17.6 - "@esbuild/linux-riscv64": 0.17.6 - "@esbuild/linux-s390x": 0.17.6 - "@esbuild/linux-x64": 0.17.6 - "@esbuild/netbsd-x64": 0.17.6 - "@esbuild/openbsd-x64": 0.17.6 - "@esbuild/sunos-x64": 0.17.6 - "@esbuild/win32-arm64": 0.17.6 - "@esbuild/win32-ia32": 0.17.6 - "@esbuild/win32-x64": 0.17.6 - 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: 13c4c3bcaa7ff291810d2c8294a1eb997b4672c60a9285b32d8eafcbc552e4468e06efe9d1a15067f5cbd41adcb12ddb4362618845e2e916e437f281c9aa80ab - languageName: node - linkType: hard - "escalade@npm:^3.1.1": version: 3.1.1 resolution: "escalade@npm:3.1.1" @@ -21698,6 +22062,13 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:5.0.0, escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e + languageName: node + linkType: hard + "escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" @@ -21719,13 +22090,6 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:^5.0.0": - version: 5.0.0 - resolution: "escape-string-regexp@npm:5.0.0" - checksum: 20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e - languageName: node - linkType: hard - "escodegen@npm:^1.13.0": version: 1.14.3 resolution: "escodegen@npm:1.14.3" @@ -21952,13 +22316,13 @@ __metadata: linkType: hard "eslint-plugin-testing-library@npm:^5.9.1": - version: 5.10.1 - resolution: "eslint-plugin-testing-library@npm:5.10.1" + version: 5.10.2 + resolution: "eslint-plugin-testing-library@npm:5.10.2" dependencies: "@typescript-eslint/utils": ^5.43.0 peerDependencies: eslint: ^7.5.0 || ^8.0.0 - checksum: fbc24ce8cbd03bee283ae520f023bd52f10d21fb25bd66c5a09a0e0ad17997bae559450438ce0b4fcc38b4e14b6802f18482c41d2bc72bf1a8e1a12a91766572 + checksum: 3b2b330e62f4a6dc438050006f0d0c97605f6861828b153271dc6d2fafb1e60f4e86fbaa8166c7afd452e3b6cad39413738fd4c8e2eb2def1915c678154676da languageName: node linkType: hard @@ -22294,6 +22658,8 @@ __metadata: "@backstage/plugin-kafka": "workspace:^" "@backstage/plugin-kubernetes": "workspace:^" "@backstage/plugin-lighthouse": "workspace:^" + "@backstage/plugin-linguist": "workspace:^" + "@backstage/plugin-linguist-common": "workspace:^" "@backstage/plugin-microsoft-calendar": "workspace:^" "@backstage/plugin-newrelic": "workspace:^" "@backstage/plugin-newrelic-dashboard": "workspace:^" @@ -22310,6 +22676,7 @@ __metadata: "@backstage/plugin-sentry": "workspace:^" "@backstage/plugin-shortcuts": "workspace:^" "@backstage/plugin-stack-overflow": "workspace:^" + "@backstage/plugin-stackstorm": "workspace:^" "@backstage/plugin-tech-insights": "workspace:^" "@backstage/plugin-tech-radar": "workspace:^" "@backstage/plugin-techdocs": "workspace:^" @@ -22361,6 +22728,7 @@ __metadata: "@backstage/plugin-app-backend": "workspace:^" "@backstage/plugin-catalog-backend": "workspace:^" "@backstage/plugin-scaffolder-backend": "workspace:^" + "@backstage/plugin-todo-backend": "workspace:^" languageName: unknown linkType: soft @@ -22394,6 +22762,7 @@ __metadata: "@backstage/plugin-kafka-backend": "workspace:^" "@backstage/plugin-kubernetes-backend": "workspace:^" "@backstage/plugin-lighthouse-backend": "workspace:^" + "@backstage/plugin-linguist-backend": "workspace:^" "@backstage/plugin-permission-backend": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" @@ -22552,7 +22921,7 @@ __metadata: languageName: node linkType: hard -"express-promise-router@npm:^4.1.0, express-promise-router@npm:^4.1.1": +"express-promise-router@npm:^4.1.0": version: 4.1.1 resolution: "express-promise-router@npm:4.1.1" dependencies: @@ -22594,7 +22963,7 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1, express@npm:^4.18.2": +"express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.18.1": version: 4.18.2 resolution: "express@npm:4.18.2" dependencies: @@ -22724,7 +23093,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.9": +"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.9": version: 3.2.12 resolution: "fast-glob@npm:3.2.12" dependencies: @@ -22765,6 +23134,15 @@ __metadata: languageName: node linkType: hard +"fast-querystring@npm:^1.1.1": + version: 1.1.1 + resolution: "fast-querystring@npm:1.1.1" + dependencies: + fast-decode-uri-component: ^1.0.1 + checksum: 86d2b75b9b299a552353532fb1a542f09730ee2a61e657d68710971d9a2afc9a3c5c7b7e106b6534f4cc506d2ff1c08ab0fda4ae614b4e7720798c9ac2a88e02 + languageName: node + linkType: hard + "fast-redact@npm:^2.0.0": version: 2.1.0 resolution: "fast-redact@npm:2.1.0" @@ -22793,7 +23171,7 @@ __metadata: languageName: node linkType: hard -"fast-url-parser@npm:1.1.3": +"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" dependencies: @@ -22802,14 +23180,14 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:4.0.11": - version: 4.0.11 - resolution: "fast-xml-parser@npm:4.0.11" +"fast-xml-parser@npm:4.1.2": + version: 4.1.2 + resolution: "fast-xml-parser@npm:4.1.2" dependencies: strnum: ^1.0.5 bin: fxparser: src/cli/cli.js - checksum: d8a08e4d5597e0fc00a86735195872eeb03008913e298830941516f3766e16ee555e2d431acc92e1dda887938edc445252ec5b59494aab60a8389888bd13719c + checksum: 6a7d1b17057f8470e70603eddfa75f990625735d068d57ece861d0154ad8d27fda63c2831d07e1ecd7e68e993738b2448925cb9277d8c0ed68009623bbcd63c6 languageName: node linkType: hard @@ -23885,6 +24263,19 @@ __metadata: languageName: node linkType: hard +"globby@npm:^13.1.2": + version: 13.1.3 + resolution: "globby@npm:13.1.3" + dependencies: + dir-glob: ^3.0.1 + fast-glob: ^3.2.11 + ignore: ^5.2.0 + merge2: ^1.4.1 + slash: ^4.0.0 + checksum: 93f06e02002cdf368f7e3d55bd59e7b00784c7cc8fe92c7ee5082cc7171ff6109fda45e1c97a80bb48bc811dedaf7843c7c9186f5f84bde4883ab630e13c43df + languageName: node + linkType: hard + "good-listener@npm:^1.2.2": version: 1.2.2 resolution: "good-listener@npm:1.2.2" @@ -23911,13 +24302,14 @@ __metadata: languageName: node linkType: hard -"google-gax@npm:^3.5.2": - version: 3.5.2 - resolution: "google-gax@npm:3.5.2" +"google-gax@npm:^3.5.2, google-gax@npm:^3.5.3": + version: 3.5.7 + resolution: "google-gax@npm:3.5.7" dependencies: - "@grpc/grpc-js": ~1.7.0 + "@grpc/grpc-js": ~1.8.0 "@grpc/proto-loader": ^0.7.0 "@types/long": ^4.0.0 + "@types/rimraf": ^3.0.2 abort-controller: ^3.0.0 duplexify: ^4.0.0 fast-text-encoding: ^1.0.3 @@ -23926,13 +24318,13 @@ __metadata: node-fetch: ^2.6.1 object-hash: ^3.0.0 proto3-json-serializer: ^1.0.0 - protobufjs: 7.1.2 - protobufjs-cli: 1.0.2 + protobufjs: 7.2.2 + protobufjs-cli: 1.1.1 retry-request: ^5.0.0 bin: compileProtos: build/tools/compileProtos.js minifyProtoJson: build/tools/minify.js - checksum: 619a961acba742c30eaba85f5e0fb5903f8fc6713e26bf1736549cbbd43d7fac3ba3379dbc96850117263199ea8e3e74635b078e9464c7fadbbcba8822949135 + checksum: 1f3c647fc1ddc00a6a017be0f83b89691997358720763db13a69a94c7a74f6d31a49b0fd56f7bab18689914c784328901b118bdf150d742719995c705d0fa65d languageName: node linkType: hard @@ -23982,7 +24374,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.1.9, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": +"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.1.9, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.10, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.10 resolution: "graceful-fs@npm:4.2.10" checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da @@ -24136,7 +24528,7 @@ __metadata: languageName: node linkType: hard -"graphql@npm:^15.0.0 || ^16.0.0, graphql@npm:^16.0.0, graphql@npm:^16.3.0": +"graphql@npm:^15.0.0 || ^16.0.0, graphql@npm:^16.0.0": version: 16.6.0 resolution: "graphql@npm:16.6.0" checksum: bf1d9e3c1938ce3c1a81e909bd3ead1ae4707c577f91cff1ca2eca474bfbc7873d5d7b942e1e9777ff5a8304421dba57a4b76d7a29eb19de8711cb70e3c2415e @@ -24385,7 +24777,7 @@ __metadata: languageName: node linkType: hard -"headers-polyfill@npm:^3.0.4, headers-polyfill@npm:^3.1.0": +"headers-polyfill@npm:^3.1.0": version: 3.1.0 resolution: "headers-polyfill@npm:3.1.0" checksum: a95257065684653b7185efbb9a380c547ea832002991b5adf0d90cd222073da2701be9dc2849d1970ecf15e8c35b383984358566afe6e76ca8ff1dbd7cdce3af @@ -24761,9 +25153,9 @@ __metadata: linkType: hard "humanize-duration@npm:^3.25.1, humanize-duration@npm:^3.26.0, humanize-duration@npm:^3.27.0, humanize-duration@npm:^3.27.1": - version: 3.27.3 - resolution: "humanize-duration@npm:3.27.3" - checksum: 17193537334676cbff156a5f60ea6349e4e981f33062fdae901ac10ed096d4f05e7b8839d362cbda7a06ade2a499f0a655e3c1bf9da6d4a234d99ed0498ba516 + version: 3.28.0 + resolution: "humanize-duration@npm:3.28.0" + checksum: dde595ab4729d82147db41d8ca0afa86bf3f20d74cd1323ea52f299091a4f1dcb2a45b2d27ce78ab9bb0d9e66d8eb8f2628a67be36a535af645eb282a963ff7f languageName: node linkType: hard @@ -24874,10 +25266,10 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.1.4, ignore@npm:^5.2.0": - version: 5.2.0 - resolution: "ignore@npm:5.2.0" - checksum: 6b1f926792d614f64c6c83da3a1f9c83f6196c2839aa41e1e32dd7b8d174cef2e329d75caabb62cb61ce9dc432f75e67d07d122a037312db7caa73166a1bdb77 +"ignore@npm:^5.1.4, ignore@npm:^5.2.0, ignore@npm:^5.2.4": + version: 5.2.4 + resolution: "ignore@npm:5.2.4" + checksum: 3d4c309c6006e2621659311783eaea7ebcd41fe4ca1d78c91c473157ad6666a57a2df790fe0d07a12300d9aac2888204d7be8d59f9aaf665b1c7fcdb432517ef languageName: node linkType: hard @@ -24995,6 +25387,13 @@ __metadata: languageName: node linkType: hard +"indent-string@npm:^5.0.0": + version: 5.0.0 + resolution: "indent-string@npm:5.0.0" + checksum: e466c27b6373440e6d84fbc19e750219ce25865cb82d578e41a6053d727e5520dc5725217d6eb1cc76005a1bb1696a0f106d84ce7ebda3033b963a38583fb3b3 + languageName: node + linkType: hard + "infer-owner@npm:^1.0.4": version: 1.0.4 resolution: "infer-owner@npm:1.0.4" @@ -25562,10 +25961,10 @@ __metadata: languageName: node linkType: hard -"is-path-cwd@npm:^2.2.0": - version: 2.2.0 - resolution: "is-path-cwd@npm:2.2.0" - checksum: 46a840921bb8cc0dc7b5b423a14220e7db338072a4495743a8230533ce78812dc152548c86f4b828411fe98c5451959f07cf841c6a19f611e46600bd699e8048 +"is-path-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "is-path-cwd@npm:3.0.0" + checksum: bc34d13b6a03dfca4a3ab6a8a5ba78ae4b24f4f1db4b2b031d2760c60d0913bd16a4b980dcb4e590adfc906649d5f5132684079a3972bd219da49deebb9adea8 languageName: node linkType: hard @@ -25576,6 +25975,13 @@ __metadata: languageName: node linkType: hard +"is-path-inside@npm:^4.0.0": + version: 4.0.0 + resolution: "is-path-inside@npm:4.0.0" + checksum: 8810fa11c58e6360b82c3e0d6cd7d9c7d0392d3ac9eb10f980b81f9839f40ac6d1d6d6f05d069db0d227759801228f0b072e1b6c343e4469b065ab5fe0b68fe5 + languageName: node + linkType: hard + "is-plain-obj@npm:^1.1.0": version: 1.1.0 resolution: "is-plain-obj@npm:1.1.0" @@ -25894,7 +26300,7 @@ __metadata: languageName: node linkType: hard -"isbinaryfile@npm:^4.0.10, isbinaryfile@npm:^4.0.8": +"isbinaryfile@npm:^4.0.10, isbinaryfile@npm:^4.0.8, isbinaryfile@npm:^4.0.8 <5": version: 4.0.10 resolution: "isbinaryfile@npm:4.0.10" checksum: a6b28db7e23ac7a77d3707567cac81356ea18bd602a4f21f424f862a31d0e7ab4f250759c98a559ece35ffe4d99f0d339f1ab884ffa9795172f632ab8f88e686 @@ -26688,9 +27094,9 @@ __metadata: linkType: hard "jose@npm:^4.10.0, jose@npm:^4.6.0": - version: 4.11.4 - resolution: "jose@npm:4.11.4" - checksum: ab870d61e3721cfa1059b1a79cfc2fce06586c8afd4164362e1725934a635191bd938893ebdfac55a0811efbe9b6fd650bbf82d36d87e8a0b7cb4b0379328dab + version: 4.12.0 + resolution: "jose@npm:4.12.0" + checksum: 09e67611768127ab54b6b507401de4b1f87e1e285cf2c2fc917e931e001b7e584c90081b421f483f13a6eec4fc44936e4a5f4b8ae2d59928061e886e35d33fa2 languageName: node linkType: hard @@ -26702,9 +27108,9 @@ __metadata: linkType: hard "js-base64@npm:^3.6.0": - version: 3.7.4 - resolution: "js-base64@npm:3.7.4" - checksum: b8f6b10033b57bbb87fa34629f44bc665cb8b7bcba49610a29b296592616e633e9c186afaa02de5a54d60c08aaa36c8c8ad585db095a96fb331fe022f54792a2 + version: 3.7.5 + resolution: "js-base64@npm:3.7.5" + checksum: 67a78c8b1c47b73f1c6fba1957e9fe6fd9dc78ac93ac46cc2e43472dcb9cf150d126fb0e593192e88e0497354fa634d17d255add7cc6ee3c7b4d29870faa8e18 languageName: node linkType: hard @@ -26846,11 +27252,12 @@ __metadata: languageName: node linkType: hard -"jsdoc@npm:^3.6.3": - version: 3.6.11 - resolution: "jsdoc@npm:3.6.11" +"jsdoc@npm:^4.0.0": + version: 4.0.2 + resolution: "jsdoc@npm:4.0.2" dependencies: - "@babel/parser": ^7.9.4 + "@babel/parser": ^7.20.15 + "@jsdoc/salty": ^0.2.1 "@types/markdown-it": ^12.2.3 bluebird: ^3.7.2 catharsis: ^0.9.0 @@ -26863,11 +27270,10 @@ __metadata: mkdirp: ^1.0.4 requizzle: ^0.2.3 strip-json-comments: ^3.1.0 - taffydb: 2.6.2 underscore: ~1.13.2 bin: jsdoc: jsdoc.js - checksum: 7920b5cba6200c8f56c9ac2ac5e89d06b6581dd1ce22e66976409fad8b68c16bfd8cd30fe9af58baeacc9f6bd9ba06d901ca4f5e234944f42a3c37e55e4ddcf0 + checksum: 04bf5ab005349b7581bd0e72ed99933eb71a41dcb47235b486b7d9146fbdf212a53e0cc044abe48ccf46012bd812dc1dfc007c6d679660ebdd053cd000242515 languageName: node linkType: hard @@ -27024,15 +27430,15 @@ __metadata: linkType: hard "json-schema-library@npm:^7.3.9": - version: 7.4.5 - resolution: "json-schema-library@npm:7.4.5" + version: 7.4.6 + resolution: "json-schema-library@npm:7.4.6" dependencies: "@sagold/json-pointer": ^5.0.0 "@sagold/json-query": ^6.0.0 deepmerge: ^4.2.2 fast-deep-equal: ^3.1.3 valid-url: ^1.0.9 - checksum: 3e7a070ab81dca119ae259c71eec01f81a9287573c5e47de366d1ee48cf85c694fc5402a7c090947e3367cc9118bdbb34d1ce131135077f9f83b7387f6a0471c + checksum: 4639464c3c25cc6ca04b1aea081c97426598f2477bdd20e4df57e39408bcf2de7a5f54f3e108c497b3e63f41904a251fbb5444451cf7a60fd83020941c55cdda languageName: node linkType: hard @@ -27767,6 +28173,25 @@ __metadata: languageName: node linkType: hard +"linguist-js@npm:^2.5.3": + version: 2.5.4 + resolution: "linguist-js@npm:2.5.4" + dependencies: + binary-extensions: ^2.2.0 + commander: ^9.5.0 + common-path-prefix: ^3.0.0 + cross-fetch: ^3.1.5 + ignore: ^5.2.4 + isbinaryfile: ^4.0.8 <5 + js-yaml: ^4.1.0 + node-cache: ^5.1.2 + bin: + linguist: bin/index.js + linguist-js: bin/index.js + checksum: 92ebfc45f0f17a056153068f7e939a3e6755307d3696673597e824011d83b698063241aa7d082a7f9059416efce85a49056f0a31b3158c25f79e273e2f51e309 + languageName: node + linkType: hard + "linkify-it@npm:^3.0.1": version: 3.0.2 resolution: "linkify-it@npm:3.0.2" @@ -27777,8 +28202,8 @@ __metadata: linkType: hard "lint-staged@npm:^13.0.0": - version: 13.1.1 - resolution: "lint-staged@npm:13.1.1" + version: 13.1.2 + resolution: "lint-staged@npm:13.1.2" dependencies: cli-truncate: ^3.1.0 colorette: ^2.0.19 @@ -27795,7 +28220,7 @@ __metadata: yaml: ^2.1.3 bin: lint-staged: bin/lint-staged.js - checksum: 8e5093c7e982a2f6d6449927a40156a812644479df1d2760aee8bf05df3a314e022d8f7e275e57fd61769ee57e3cf7b062ed3c6e4934a63848300b877e269daa + checksum: f854ad5c88542b8f06e27f3b4046927a4f3d4a451a04e079526559d819a325762268f65bd2df7156bcc0cb5f531f621c42cdb824b403f537c78305adc9e56a54 languageName: node linkType: hard @@ -28184,15 +28609,16 @@ __metadata: linkType: hard "logform@npm:^2.3.2, logform@npm:^2.4.0": - version: 2.4.2 - resolution: "logform@npm:2.4.2" + version: 2.5.1 + resolution: "logform@npm:2.5.1" dependencies: "@colors/colors": 1.5.0 + "@types/triple-beam": ^1.3.2 fecha: ^4.2.0 ms: ^2.1.1 safe-stable-stringify: ^2.3.1 triple-beam: ^1.3.0 - checksum: 3d00f4e1ccaf0a86886aabbf66d1f1d207441d5b408f103457da6d64d055aee76c02af4b40a31ca77a1db4cbcdecb007149f731536c39cbd89b7b6ba3dda6d7b + checksum: 08fdf03be5bb69af33bac214eb4f6a0c83ad3821a30de498925fccb61e993e5a4a87470aab356ca2110c11e4643685bed5597ca5f46dd1cd11437c44a0e0e3c2 languageName: node linkType: hard @@ -28312,6 +28738,13 @@ __metadata: languageName: node linkType: hard +"luxon@npm:^2.0.2": + version: 2.5.2 + resolution: "luxon@npm:2.5.2" + checksum: d8b671ffd2ff0b438af862ac11082a81b3aedd9f8b6a4ca636f944224f8dd381125cd4d274ca0a8aedcaf2cfca0fc2ca96fe4cc1b16a28b7af701afb95c0bff8 + languageName: node + linkType: hard + "luxon@npm:^3.0.0, luxon@npm:^3.2.1": version: 3.2.1 resolution: "luxon@npm:3.2.1" @@ -29364,9 +29797,9 @@ __metadata: linkType: hard "minimist@npm:>=1.2.2, minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.7": - version: 1.2.7 - resolution: "minimist@npm:1.2.7" - checksum: 7346574a1038ca23c32e02252f603801f09384dd1d78b69a943a4e8c2c28730b80e96193882d3d3b22a063445f460e48316b29b8a25addca2d7e5e8f75478bec + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 languageName: node linkType: hard @@ -29455,7 +29888,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^3.0.0, minipass@npm:^3.1.0, minipass@npm:^3.1.1, minipass@npm:^3.1.3, minipass@npm:^3.1.6, minipass@npm:^3.3.5": +"minipass@npm:^3.0.0, minipass@npm:^3.1.0, minipass@npm:^3.1.1, minipass@npm:^3.1.3, minipass@npm:^3.1.6": version: 3.3.5 resolution: "minipass@npm:3.3.5" dependencies: @@ -29588,38 +30021,9 @@ __metadata: languageName: node linkType: hard -"msw@npm:^0.39.2": - version: 0.39.2 - resolution: "msw@npm:0.39.2" - dependencies: - "@mswjs/cookies": ^0.2.0 - "@mswjs/interceptors": ^0.15.1 - "@open-draft/until": ^1.0.3 - "@types/cookie": ^0.4.1 - "@types/js-levenshtein": ^1.1.1 - chalk: 4.1.1 - chokidar: ^3.4.2 - cookie: ^0.4.2 - graphql: ^16.3.0 - headers-polyfill: ^3.0.4 - inquirer: ^8.2.0 - is-node-process: ^1.0.1 - js-levenshtein: ^1.1.6 - node-fetch: ^2.6.7 - path-to-regexp: ^6.2.0 - statuses: ^2.0.0 - strict-event-emitter: ^0.2.0 - type-fest: ^1.2.2 - yargs: ^17.3.1 - bin: - msw: cli/index.js - checksum: 4802f5568cbaadedd488f03b953523fb5dd7e1b8e48a85f142d7cfd1b8c25241729a0af4a06b9f2be543c18b67475c8777fa4924bdc6f1de19dbe142ea4a8405 - languageName: node - linkType: hard - -"msw@npm:^0.49.0": - version: 0.49.3 - resolution: "msw@npm:0.49.3" +"msw@npm:^1.0.0, msw@npm:^1.0.1": + version: 1.0.1 + resolution: "msw@npm:1.0.1" dependencies: "@mswjs/cookies": ^0.2.2 "@mswjs/interceptors": ^0.17.5 @@ -29647,7 +30051,7 @@ __metadata: optional: true bin: msw: cli/index.js - checksum: 8322cd42cd69f289c05517d02bde22fc2f10e86fc2d0d209d9df54bd03d10b8123723c5587a2654dcd2cd0f314a016f9eccac88cffa30fafd1f9fead16db639e + checksum: e5d6cbe67067ca46f42aaa33011f53a4e5a873abcf81c52a6996536b3c41a88f522821d3a4cf589658252581506afddb58fd8c3dfd79a5cbf06e26e14f9570b6 languageName: node linkType: hard @@ -30599,14 +31003,14 @@ __metadata: linkType: hard "openid-client@npm:^5.2.1, openid-client@npm:^5.3.0": - version: 5.3.2 - resolution: "openid-client@npm:5.3.2" + version: 5.4.0 + resolution: "openid-client@npm:5.4.0" dependencies: jose: ^4.10.0 lru-cache: ^6.0.0 object-hash: ^2.0.1 oidc-token-hash: ^5.0.1 - checksum: 59dc58d5b5cb795f3500f2d9d7ce604f6fb4c00623b16660fdf635d2789c3b2bb32e328ff10c918f9fa4e7fb269c768658d00769761d301be2d96d6150e07051 + checksum: d198dbcaf0aa1d8b9f0f1d99ae30e90ec594eaf9ae668b5d61f2ee9af94a4460968d8dea7e53bd18903a1fb9c445e05aefca965bb88be3688a4bac273d1634d9 languageName: node linkType: hard @@ -30799,6 +31203,15 @@ __metadata: languageName: node linkType: hard +"p-map@npm:^5.5.0": + version: 5.5.0 + resolution: "p-map@npm:5.5.0" + dependencies: + aggregate-error: ^4.0.0 + checksum: 065cb6fca6b78afbd070dd9224ff160dc23eea96e57863c09a0c8ea7ce921043f76854be7ee0abc295cff1ac9adcf700e79a1fbe3b80b625081087be58e7effb + languageName: node + linkType: hard + "p-queue@npm:^6.6.2": version: 6.6.2 resolution: "p-queue@npm:6.6.2" @@ -32119,13 +32532,13 @@ __metadata: linkType: hard "postcss@npm:^8.1.0, postcss@npm:^8.4.19": - version: 8.4.20 - resolution: "postcss@npm:8.4.20" + version: 8.4.21 + resolution: "postcss@npm:8.4.21" dependencies: nanoid: ^3.3.4 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: 1a5609ea1c1b204f9c2974a0019ae9eef2d99bf645c2c9aac675166c4cb1005be7b5e2ba196160bc771f5d9ac896ed883f236f888c891e835e59d28fff6651aa + checksum: e39ac60ccd1542d4f9d93d894048aac0d686b3bb38e927d8386005718e6793dbbb46930f0a523fe382f1bbd843c6d980aaea791252bf5e176180e5a4336d9679 languageName: node linkType: hard @@ -32436,16 +32849,16 @@ __metadata: languageName: node linkType: hard -"protobufjs-cli@npm:1.0.2": - version: 1.0.2 - resolution: "protobufjs-cli@npm:1.0.2" +"protobufjs-cli@npm:1.1.1": + version: 1.1.1 + resolution: "protobufjs-cli@npm:1.1.1" dependencies: chalk: ^4.0.0 escodegen: ^1.13.0 espree: ^9.0.0 estraverse: ^5.1.0 glob: ^8.0.0 - jsdoc: ^3.6.3 + jsdoc: ^4.0.0 minimist: ^1.2.0 semver: ^7.1.2 tmp: ^0.2.1 @@ -32455,13 +32868,13 @@ __metadata: bin: pbjs: bin/pbjs pbts: bin/pbts - checksum: 75dfa8bb76ea390c4f4926120439892fce6c730ec56960e85d5f03cac9c390fd7467d1254833542d722616ab4cb64a622e6de2fb7c75e7c42972878ae447b773 + checksum: 124a2cb10d6fccdd6e8f2984b0f7d9a351d9c1efd17f237acd4a9e7c4b82d63265364b1c86bfa5c6a6fa17d7119182c4c323a8972c0078e1ac5c5f653d096f9b languageName: node linkType: hard -"protobufjs@npm:7.1.2, protobufjs@npm:^7.0.0": - version: 7.1.2 - resolution: "protobufjs@npm:7.1.2" +"protobufjs@npm:7.2.2, protobufjs@npm:^7.0.0": + version: 7.2.2 + resolution: "protobufjs@npm:7.2.2" dependencies: "@protobufjs/aspromise": ^1.1.2 "@protobufjs/base64": ^1.1.2 @@ -32475,7 +32888,7 @@ __metadata: "@protobufjs/utf8": ^1.1.0 "@types/node": ">=13.7.0" long: ^5.0.0 - checksum: ae41669b1b0372fb1d49f506f2d1f2b0fb3dc3cece85987b17bcb544e4cef7c8d27f480486cdec324146ad0a5d22a327166a7ea864a9b3e49cc3c92a5d3f6500 + checksum: 86166e8f3e46789fa4d117ae72c17356db36bf87c0e0710d224be32e543b1c378a94e66dc2b1de5af45edfc25f56acfc7e688c50c956426a3ae97bc474f4445c languageName: node linkType: hard @@ -32780,7 +33193,7 @@ __metadata: languageName: node linkType: hard -"raw-body@npm:2.5.1, raw-body@npm:^2.4.1": +"raw-body@npm:2.5.1": version: 2.5.1 resolution: "raw-body@npm:2.5.1" dependencies: @@ -32792,6 +33205,18 @@ __metadata: languageName: node linkType: hard +"raw-body@npm:^2.4.1": + version: 2.5.2 + resolution: "raw-body@npm:2.5.2" + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + checksum: ba1583c8d8a48e8fbb7a873fdbb2df66ea4ff83775421bfe21ee120140949ab048200668c47d9ae3880012f6e217052690628cf679ddfbd82c9fc9358d574676 + languageName: node + linkType: hard + "rc-progress@npm:3.4.1": version: 3.4.1 resolution: "rc-progress@npm:3.4.1" @@ -33169,26 +33594,26 @@ __metadata: linkType: hard "react-router-dom-stable@npm:react-router-dom@^6.3.0, react-router-dom@npm:^6.3.0": - version: 6.6.2 - resolution: "react-router-dom@npm:6.6.2" + version: 6.8.1 + resolution: "react-router-dom@npm:6.8.1" dependencies: - "@remix-run/router": 1.2.1 - react-router: 6.6.2 + "@remix-run/router": 1.3.2 + react-router: 6.8.1 peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: e0ee89a2b3768d2eb406ecefedfa24b55428145359b4138f6d38b8a99b60a4f275418910f4cdb12c069ed0237711acced3787b0c7febfa6568d7ea9cd624ff3b + checksum: fb1a9f5c7e4c83536ee7e6493f3c13f6abda66da69f9191fb8b087ab188ecc18a3a32575813a280cbeca67bcb8b0dcb6dbcef7ed599e03f38a44d694f4abcf14 languageName: node linkType: hard -"react-router-stable@npm:react-router@^6.3.0, react-router@npm:6.6.2": - version: 6.6.2 - resolution: "react-router@npm:6.6.2" +"react-router-stable@npm:react-router@^6.3.0, react-router@npm:6.8.1": + version: 6.8.1 + resolution: "react-router@npm:6.8.1" dependencies: - "@remix-run/router": 1.2.1 + "@remix-run/router": 1.3.2 peerDependencies: react: ">=16.8" - checksum: 5960d774bb3a8f697a57ee2e82a3eb0a300b7186a62b27e02773c94f1682e59435bd876d6162a08cc8daf27cac72aaab66d348fcc4d8f59240a63a911cf0050b + checksum: 8e7cc7a516adeb6060911861af99d9b512893c15ec732cbf8574872919be4f3fe439ffa8c0876d1bcbced880d081bfeda3c01cb505b5a243565d10500ee0ac36 languageName: node linkType: hard @@ -34472,7 +34897,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.0.0, rxjs@npm:^7.5.1, rxjs@npm:^7.5.5, rxjs@npm:^7.5.6, rxjs@npm:^7.8.0": +"rxjs@npm:^7.0.0, rxjs@npm:^7.2.0, rxjs@npm:^7.5.1, rxjs@npm:^7.5.5, rxjs@npm:^7.5.6, rxjs@npm:^7.8.0": version: 7.8.0 resolution: "rxjs@npm:7.8.0" dependencies: @@ -35111,6 +35536,13 @@ __metadata: languageName: node linkType: hard +"slash@npm:^4.0.0": + version: 4.0.0 + resolution: "slash@npm:4.0.0" + checksum: da8e4af73712253acd21b7853b7e0dbba776b786e82b010a5bfc8b5051a1db38ed8aba8e1e8f400dd2c9f373be91eb1c42b66e91abb407ff42b10feece5e1d2d + languageName: node + linkType: hard + "slice-ansi@npm:^3.0.0": version: 3.0.0 resolution: "slice-ansi@npm:3.0.0" @@ -35143,6 +35575,13 @@ __metadata: languageName: node linkType: hard +"slugify@npm:^1.6.4": + version: 1.6.5 + resolution: "slugify@npm:1.6.5" + checksum: a955a1b600201030f4c1daa9bb74a17d4402a0693fc40978bbd17e44e64fd72dad3bac4037422aa8aed55b5170edd57f3f4cd8f59ba331f5cf0f10f1a7795609 + languageName: node + linkType: hard + "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -35229,7 +35668,7 @@ __metadata: languageName: node linkType: hard -"source-list-map@npm:^2.0.1": +"source-list-map@npm:^2.0.0": version: 2.0.1 resolution: "source-list-map@npm:2.0.1" checksum: 806efc6f75e7cd31e4815e7a3aaf75a45c704871ea4075cb2eb49882c6fca28998f44fc5ac91adb6de03b2882ee6fb02f951fdc85e6a22b338c32bfe19557938 @@ -35588,8 +36027,8 @@ __metadata: linkType: hard "start-server-and-test@npm:^1.10.11": - version: 1.15.3 - resolution: "start-server-and-test@npm:1.15.3" + version: 1.15.4 + resolution: "start-server-and-test@npm:1.15.4" dependencies: arg: ^5.0.2 bluebird: 3.7.2 @@ -35603,11 +36042,11 @@ __metadata: server-test: src/bin/start.js start-server-and-test: src/bin/start.js start-test: src/bin/start.js - checksum: 3489c5146e26bc3bfa34d12f546f78fa6d883fdd49d0c60cbf4fb76ef627df6cde0a878253f5ca8e2177b938c00f47c613a811f6e7aa519af3be58576fbc2ab0 + checksum: 0df9a4710ea45ddb1a9f719e0865faa8e26a973beff693dfe244ae2d914bfc6eed4d2db8529cdcad3d53658c4655356e5aca3520485a3ef4d9d9f320956b0e7d languageName: node linkType: hard -"statuses@npm:2.0.1, statuses@npm:^2.0.0": +"statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" checksum: 18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb @@ -35709,7 +36148,7 @@ __metadata: languageName: node linkType: hard -"strict-event-emitter@npm:^0.2.0, strict-event-emitter@npm:^0.2.4": +"strict-event-emitter@npm:^0.2.4": version: 0.2.7 resolution: "strict-event-emitter@npm:0.2.7" dependencies: @@ -36307,13 +36746,6 @@ __metadata: languageName: node linkType: hard -"taffydb@npm:2.6.2": - version: 2.6.2 - resolution: "taffydb@npm:2.6.2" - checksum: 8fea9cdff71735a40320c4beeb80cb98837076cb89614bc55ac5d67561f35ebae158cfc07a193a1099b5e32746433b2c086b0cd6d56f29aa7c7678e74968335b - languageName: node - linkType: hard - "tapable@npm:^1.0.0": version: 1.1.3 resolution: "tapable@npm:1.1.3" @@ -36992,7 +37424,14 @@ __metadata: languageName: node linkType: hard -"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.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:~2.4.0": +"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.1, tslib@npm:^2.4.0, tslib@npm:^2.4.1, tslib@npm:~2.5.0": + version: 2.5.0 + resolution: "tslib@npm:2.5.0" + checksum: ae3ed5f9ce29932d049908ebfdf21b3a003a85653a9a140d614da6b767a93ef94f460e52c3d787f0e4f383546981713f165037dc2274df212ea9f8a4541004e1 + languageName: node + linkType: hard + +"tslib@npm:~2.4.0": version: 2.4.1 resolution: "tslib@npm:2.4.1" checksum: 19480d6e0313292bd6505d4efe096a6b31c70e21cf08b5febf4da62e95c265c8f571f7b36fcc3d1a17e068032f59c269fab3459d6cd3ed6949eafecf64315fca @@ -37117,7 +37556,7 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^1.2.1, type-fest@npm:^1.2.2": +"type-fest@npm:^1.2.1": version: 1.4.0 resolution: "type-fest@npm:1.4.0" checksum: b011c3388665b097ae6a109a437a04d6f61d81b7357f74cbcb02246f2f5bd72b888ae33631b99871388122ba0a87f4ff1c94078e7119ff22c70e52c0ff828201 @@ -37307,11 +37746,11 @@ __metadata: linkType: hard "undici@npm:^5.12.0, undici@npm:^5.8.0": - version: 5.12.0 - resolution: "undici@npm:5.12.0" + version: 5.19.1 + resolution: "undici@npm:5.19.1" dependencies: busboy: ^1.6.0 - checksum: fbc227704943c05aa3dc1630695e10309c17d0a535678594d136db107c50593248e9ace70e1ab77496a6c837bf14aa2ab3c501a7a6c45fb6277dbf0846e15ffe + checksum: 57ee94ee74d944faa41dbcb2faf4e0c90069708d3aaae860185884e51376b5d457728352a8396d69a3c9cb752b62ff99a19a664c5aacb7ee61cc488af499a01c languageName: node linkType: hard @@ -38107,10 +38546,10 @@ __metadata: languageName: node linkType: hard -"web-streams-polyfill@npm:^3.2.0": - version: 3.2.0 - resolution: "web-streams-polyfill@npm:3.2.0" - checksum: e23ad0649392fa0159dbfc6bb27474c308c3f332d9078cfef3c06c154165bef18732c5814126147c6c712f604216ddc950c171c854e3821f020e0d2d721a5958 +"web-streams-polyfill@npm:^3.2.0, web-streams-polyfill@npm:^3.2.1": + version: 3.2.1 + resolution: "web-streams-polyfill@npm:3.2.1" + checksum: b119c78574b6d65935e35098c2afdcd752b84268e18746606af149e3c424e15621b6f1ff0b42b2676dc012fc4f0d313f964b41a4b5031e525faa03997457da02 languageName: node linkType: hard @@ -38221,13 +38660,13 @@ __metadata: languageName: node linkType: hard -"webpack-sources@npm:^2.2.0": - version: 2.3.1 - resolution: "webpack-sources@npm:2.3.1" +"webpack-sources@npm:^1.4.3": + version: 1.4.3 + resolution: "webpack-sources@npm:1.4.3" dependencies: - source-list-map: ^2.0.1 - source-map: ^0.6.1 - checksum: 6fd67f2274a84c5f51ad89767112ec8b47727134bf0f2ba0cff458c970f18966939a24128bdbddba621cd66eeb2bef0552642a9333cd8e54514f7b2a71776346 + source-list-map: ^2.0.0 + source-map: ~0.6.1 + checksum: 37463dad8d08114930f4bc4882a9602941f07c9f0efa9b6bc78738cd936275b990a596d801ef450d022bb005b109b9f451dd087db2f3c9baf53e8e22cf388f79 languageName: node linkType: hard @@ -38948,8 +39387,8 @@ __metadata: linkType: hard "yeoman-environment@npm:^3.9.1": - version: 3.13.0 - resolution: "yeoman-environment@npm:3.13.0" + version: 3.15.1 + resolution: "yeoman-environment@npm:3.15.1" dependencies: "@npmcli/arborist": ^4.0.4 are-we-there-yet: ^2.0.0 @@ -38992,7 +39431,7 @@ __metadata: mem-fs-editor: ^8.1.2 || ^9.0.0 bin: yoe: cli/index.js - checksum: 2d622d18d2e3fff179477b6dabbdee8b380d58b5d639d300c3ace75e0533223cecb9b325baaf0f46f71879eaa5778d64b11fa660403a26ec3086b2a428484ce6 + checksum: 7ea7bb0a210f2e0702f54420916075cda329ee2b71243fb911af9bcfc1e59a934daef1027dd9e95a410f5dae1eeb1fcdb85f4c697a0429477a3a50d2e48d0d58 languageName: node linkType: hard